# Hardhat Development Framework Guide ## Initialization ```bash npm install --save-dev hardhat npx hardhat init # Select TypeScript project npm install --save-dev @nomicfoundation/hardhat-toolbox # Includes ethers, chai, mocha ``` ## Key hardhat.config.ts Configuration ```typescript import { HardhatUserConfig } from "hardhat/config"; import "@nomicfoundation/hardhat-toolbox"; const config: HardhatUserConfig = { solidity: { version: "0.8.24", settings: { optimizer: { enabled: true, runs: 200 } } }, networks: { sepolia: { url: process.env.SEPOLIA_RPC_URL!, accounts: [process.env.PRIVATE_KEY!] }, mainnet: { url: process.env.MAINNET_RPC_URL!, accounts: [process.env.PRIVATE_KEY!] }, }, etherscan: { apiKey: process.env.ETHERSCAN_API_KEY }, }; export default config; ``` ## Writing Tests ```typescript import { expect } from "chai"; import { ethers } from "hardhat"; describe("MyToken", function () { async function deployFixture() { const [owner, user] = await ethers.getSigners(); const Token = await ethers.getContractFactory("MyToken"); const token = await Token.deploy(ethers.parseEther("1000000")); return { token, owner, user }; } it("should mint tokens to owner", async function () { const { token, owner } = await loadFixture(deployFixture); expect(await token.balanceOf(owner.address)).to.equal(ethers.parseEther("1000000")); }); it("should transfer tokens", async function () { const { token, owner, user } = await loadFixture(deployFixture); await token.transfer(user.address, ethers.parseEther("100")); expect(await token.balanceOf(user.address)).to.equal(ethers.parseEther("100")); }); }); ``` ## Fork Mainnet Testing ```typescript // hardhat.config.ts networks: { hardhat: { forking: { url: process.env.MAINNET_RPC_URL!, blockNumber: 19000000 } } } // Impersonate whale in tests const whale = await ethers.getImpersonatedSigner("0xWhaleAddress") await ethers.provider.send("hardhat_setBalance", [whale.address, "0x56BC75E2D63100000"]) ``` ## Deployment Script ```typescript import { ethers } from "hardhat"; async function main() { const Token = await ethers.getContractFactory("MyToken"); const token = await Token.deploy(ethers.parseEther("1000000")); await token.waitForDeployment(); console.log("Token deployed to:", await token.getAddress()); } main().catch(console.error); ``` ```bash npx hardhat run scripts/deploy.ts --network sepolia npx hardhat verify --network sepolia DEPLOYED_ADDRESS "1000000000000000000000000" ``` ## Common Commands ```bash npx hardhat compile # Compile npx hardhat test # Run tests npx hardhat test --grep "transfer" # Filter tests npx hardhat coverage # Coverage report npx hardhat node # Local node npx hardhat console # Interactive console ``` ## Common Pitfalls - `loadFixture` uses snapshots for rollback, 10x faster than redeploying each time - When fork testing, pay attention to `blockNumber` — blocks that are too old may have incorrect state - When verifying, constructor parameter order must match exactly with deployment