Hardhat Cheat Sheet

Last Updated: November 21, 2025

Installation & Setup

npm install --save-dev hardhat
Install Hardhat locally
npx hardhat init
Initialize new Hardhat project
npm install --save-dev @nomicfoundation/hardhat-toolbox
Install recommended plugins bundle
npm install --save-dev @nomiclabs/hardhat-ethers ethers
Install Ethers.js plugin
npm install --save-dev @nomiclabs/hardhat-waffle
Install Waffle for testing
npm install --save-dev @nomiclabs/hardhat-etherscan
Install Etherscan verification plugin
npm install --save-dev hardhat-gas-reporter
Install gas usage reporter
npm install --save-dev solidity-coverage
Install test coverage tool

Core Commands

npx hardhat compile
Compile Solidity contracts
npx hardhat clean
Clear cache and artifacts
npx hardhat test
Run all tests
npx hardhat test --grep "should transfer"
Run specific tests matching pattern
npx hardhat node
Start local Ethereum network
npx hardhat run scripts/deploy.js
Run deployment script on local network
npx hardhat run scripts/deploy.js --network goerli
Deploy to specific network
npx hardhat console
Open interactive console
npx hardhat coverage
Generate test coverage report
npx hardhat verify --network goerli CONTRACT_ADDRESS "arg1" "arg2"
Verify contract on Etherscan

hardhat.config.js Configuration

module.exports = { solidity: "0.8.19" }
Set Solidity compiler version
solidity: { version: "0.8.19", settings: { optimizer: { enabled: true, runs: 200 } } }
Enable optimizer with settings
networks: { goerli: { url: process.env.GOERLI_URL, accounts: [process.env.PRIVATE_KEY] } }
Configure network connection
networks: { hardhat: { chainId: 1337 } }
Configure local network
etherscan: { apiKey: process.env.ETHERSCAN_API_KEY }
Configure Etherscan API key
gasReporter: { enabled: true, currency: 'USD' }
Enable gas reporting
paths: { sources: "./contracts", tests: "./test", cache: "./cache", artifacts: "./artifacts" }
Configure project paths
require("@nomicfoundation/hardhat-toolbox")
Import plugin in config

Testing with Chai & Waffle

const { expect } = require("chai")
Import Chai assertion library
const { ethers } = require("hardhat")
Import Hardhat Ethers
const [owner, addr1] = await ethers.getSigners()
Get test accounts
const Token = await ethers.getContractFactory("Token")
Get contract factory
const token = await Token.deploy()
Deploy contract
await token.deployed()
Wait for deployment
expect(await token.totalSupply()).to.equal(1000)
Assert equality
await expect(token.transfer(addr1.address, 50)).to.emit(token, "Transfer")
Expect event emission
await expect(token.transfer(addr1.address, 9999)).to.be.revertedWith("Insufficient balance")
Expect transaction revert
expect(await token.balanceOf(owner.address)).to.equal(950)
Check state changes
const tx = await token.transfer(addr1.address, 50); await tx.wait()
Wait for transaction confirmation
await ethers.provider.send("evm_mine", [])
Mine a block manually
await network.provider.send("evm_increaseTime", [3600])
Fast-forward time
await network.provider.send("hardhat_impersonateAccount", ["0x..."])
Impersonate account for testing

Deployment Scripts

async function main() { const Contract = await ethers.getContractFactory("MyContract"); ... }
Basic deployment script structure
const contract = await Contract.deploy(arg1, arg2)
Deploy with constructor arguments
await contract.deployed(); console.log("Contract deployed to:", contract.address)
Wait and log deployment address
const contract = await Contract.attach("0x...")
Attach to existing contract
main().catch((error) => { console.error(error); process.exitCode = 1; })
Error handling for scripts
const [deployer] = await ethers.getSigners(); console.log("Deploying with:", deployer.address)
Get deployer account info
const balance = await deployer.getBalance(); console.log("Balance:", ethers.utils.formatEther(balance))
Check deployer balance
await contract.initialize({ gasLimit: 500000 })
Call function with gas limit
const tx = await contract.mint(addr, { value: ethers.utils.parseEther("1.0") })
Send ETH with transaction

Custom Tasks

task("accounts", "Prints the list of accounts", async (taskArgs, hre) => { ... })
Define custom task
task("balance", "Prints an account's balance").addParam("account", "The account's address").setAction(async (taskArgs) => { ... })
Task with parameters
npx hardhat accounts
Run custom task
npx hardhat balance --account 0x...
Run task with parameter
const accounts = await hre.ethers.getSigners()
Access Hardhat Runtime Environment
subtask("my-subtask", async (taskArgs, hre) => { ... })
Define subtask

Console Commands

const Token = await ethers.getContractFactory("Token")
Get contract factory in console
const token = await Token.attach("0x...")
Attach to deployed contract
await token.balanceOf("0x...")
Call view function
const [owner] = await ethers.getSigners()
Get signers in console
await owner.getBalance()
Check account balance
ethers.utils.formatEther(await owner.getBalance())
Format wei to ether
ethers.utils.parseEther("1.0")
Parse ether to wei

Network Configuration Examples

mainnet: { url: `https://mainnet.infura.io/v3/${process.env.INFURA_KEY}`, accounts: [process.env.PRIVATE_KEY] }
Ethereum mainnet via Infura
goerli: { url: `https://goerli.infura.io/v3/${process.env.INFURA_KEY}`, accounts: [process.env.PRIVATE_KEY] }
Goerli testnet configuration
sepolia: { url: `https://sepolia.infura.io/v3/${process.env.INFURA_KEY}`, accounts: [process.env.PRIVATE_KEY] }
Sepolia testnet configuration
polygon: { url: "https://polygon-rpc.com", accounts: [process.env.PRIVATE_KEY], chainId: 137 }
Polygon mainnet
mumbai: { url: "https://rpc-mumbai.maticvigil.com", accounts: [process.env.PRIVATE_KEY], chainId: 80001 }
Polygon Mumbai testnet
arbitrum: { url: "https://arb1.arbitrum.io/rpc", accounts: [process.env.PRIVATE_KEY] }
Arbitrum One
optimism: { url: "https://mainnet.optimism.io", accounts: [process.env.PRIVATE_KEY] }
Optimism mainnet
localhost: { url: "http://127.0.0.1:8545" }
Local Hardhat network

Useful Plugins

@nomicfoundation/hardhat-toolbox
Bundle of most used plugins
@nomiclabs/hardhat-ethers
Ethers.js integration
@nomiclabs/hardhat-etherscan
Contract verification
hardhat-gas-reporter
Gas usage reporting
solidity-coverage
Code coverage for Solidity
hardhat-deploy
Advanced deployment management
@openzeppelin/hardhat-upgrades
Deploy upgradeable contracts
hardhat-contract-sizer
Check contract size limits
@typechain/hardhat
TypeScript bindings for contracts
hardhat-docgen
Generate documentation from NatSpec

Environment Variables (.env)

INFURA_API_KEY=your_infura_key
Infura project ID
PRIVATE_KEY=0x...
Deployer private key (never commit!)
ETHERSCAN_API_KEY=your_key
Etherscan API key for verification
POLYGONSCAN_API_KEY=your_key
Polygonscan API key
require("dotenv").config()
Load .env in hardhat.config.js
npm install --save-dev dotenv
Install dotenv package
Add .env to .gitignore
Never commit secrets!

Debugging & Troubleshooting

console.log("Debug:", value)
Console logging in Solidity (import hardhat/console.sol)
npx hardhat compile --force
Force recompilation
npx hardhat clean && npx hardhat compile
Clean rebuild
HARDHAT_VERBOSE=true npx hardhat test
Verbose output
await network.provider.send("hardhat_reset", [])
Reset local network state
npx hardhat test --network hardhat --verbose
Detailed test output
View transaction traces in console
Hardhat Network shows stack traces
Pro Tip: Use console.log() in your Solidity contracts by importing "hardhat/console.sol" for debugging! Always test on a testnet before mainnet deployment. Enable gas reporter to optimize contract costs. Store private keys in .env and NEVER commit them to version control!
← Back to Data Science & ML | Browse all categories | View all cheat sheets