Tools·8 min का पठन·Solingo द्वारा

Hardhat Setup Guide — Professional Solidity Development

Hardhat सबसे popular development framework है professional smart contract teams के लिए। जानें कैसे project setup करें, tests लिखें, और production में deploy करें।

# Hardhat Setup Guide — Professional Solidity Development

Hardhat modern Ethereum development का industry standard बन गया है। TypeScript support, powerful testing framework, और rich plugin ecosystem के साथ, यह professional teams और solo developers दोनों के लिए ideal है। इस comprehensive guide में, हम scratch से Hardhat project setup करेंगे, tests लिखेंगे, और contracts deploy करेंगे।

Hardhat क्यों चुनें?

Hardhat के फायदे:

  • TypeScript-first — Type safety और better IDE support
  • Fast compilation — Incremental compilation smart contracts के लिए
  • Rich testing — Mocha, Chai, और Waffle के साथ
  • Debugging — Console.log directly Solidity में
  • Plugin ecosystem — Etherscan verification, gas reporting, coverage, etc.
  • Local network — Built-in Ethereum node testing के लिए
  • Mainnet forking — Test against live blockchain state
  • Active development — Regular updates और improvements

Prerequisites

आपको चाहिए:

  • Node.js (v16+ recommended)
  • npm या yarn
  • Basic command line knowledge
  • Text editor (VS Code recommended)

Installation Check

node --version   # Should be v16 or higher

npm --version # Should be 8 or higher

Project Setup

Step 1: नया Project बनाएं

mkdir my-hardhat-project

cd my-hardhat-project

npm init -y

Step 2: Hardhat Install करें

npm install --save-dev hardhat

Step 3: Hardhat Project Initialize करें

npx hardhat init

Prompts:

? What do you want to do?

> Create a JavaScript project

Create a TypeScript project

Create an empty hardhat.config.js

? Do you want to install dependencies? Yes

TypeScript project चुनें (recommended):

npm install --save-dev @nomicfoundation/hardhat-toolbox

Step 4: Project Structure

Initialization के बाद:

my-hardhat-project/

├── contracts/ # Solidity contracts

│ └── Lock.sol # Sample contract

├── scripts/ # Deployment scripts

│ └── deploy.ts

├── test/ # Test files

│ └── Lock.ts

├── hardhat.config.ts # Hardhat configuration

├── package.json

└── tsconfig.json

अपना पहला Contract लिखना

Contract: SimpleToken.sol

contracts/SimpleToken.sol में नई file बनाएं:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.19;

contract SimpleToken {

string public name = "Simple Token";

string public symbol = "SMP";

uint8 public decimals = 18;

uint256 public totalSupply;

mapping(address => uint256) public balanceOf;

mapping(address => mapping(address => uint256)) public allowance;

event Transfer(address indexed from, address indexed to, uint256 value);

event Approval(address indexed owner, address indexed spender, uint256 value);

constructor(uint256 _initialSupply) {

totalSupply = _initialSupply * 10**uint256(decimals);

balanceOf[msg.sender] = totalSupply;

}

function transfer(address _to, uint256 _value) public returns (bool) {

require(_to != address(0), "Invalid address");

require(balanceOf[msg.sender] >= _value, "Insufficient balance");

balanceOf[msg.sender] -= _value;

balanceOf[_to] += _value;

emit Transfer(msg.sender, _to, _value);

return true;

}

function approve(address _spender, uint256 _value) public returns (bool) {

allowance[msg.sender][_spender] = _value;

emit Approval(msg.sender, _spender, _value);

return true;

}

function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {

require(_to != address(0), "Invalid address");

require(balanceOf[_from] >= _value, "Insufficient balance");

require(allowance[_from][msg.sender] >= _value, "Allowance exceeded");

balanceOf[_from] -= _value;

balanceOf[_to] += _value;

allowance[_from][msg.sender] -= _value;

emit Transfer(_from, _to, _value);

return true;

}

}

Compile करें

npx hardhat compile

Output:

Compiling 1 file with 0.8.19

Compilation finished successfully

Artifacts artifacts/ folder में generate होते हैं।

Tests लिखना

Test File: SimpleToken.test.ts

test/SimpleToken.test.ts में:

import { expect } from "chai";

import { ethers } from "hardhat";

import { SimpleToken } from "../typechain-types";

import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers";

describe("SimpleToken", function () {

let token: SimpleToken;

let owner: SignerWithAddress;

let addr1: SignerWithAddress;

let addr2: SignerWithAddress;

beforeEach(async function () {

// Get signers

[owner, addr1, addr2] = await ethers.getSigners();

// Deploy contract

const Token = await ethers.getContractFactory("SimpleToken");

token = await Token.deploy(1000); // 1000 tokens initial supply

await token.waitForDeployment();

});

describe("Deployment", function () {

it("Should set the correct name and symbol", async function () {

expect(await token.name()).to.equal("Simple Token");

expect(await token.symbol()).to.equal("SMP");

});

it("Should assign total supply to owner", async function () {

const ownerBalance = await token.balanceOf(owner.address);

expect(await token.totalSupply()).to.equal(ownerBalance);

});

});

describe("Transactions", function () {

it("Should transfer tokens between accounts", async function () {

// Transfer 50 tokens from owner to addr1

await token.transfer(addr1.address, 50);

expect(await token.balanceOf(addr1.address)).to.equal(50);

// Transfer 50 tokens from addr1 to addr2

await token.connect(addr1).transfer(addr2.address, 50);

expect(await token.balanceOf(addr2.address)).to.equal(50);

});

it("Should fail if sender doesn't have enough tokens", async function () {

const initialOwnerBalance = await token.balanceOf(owner.address);

// Try to send more than balance

await expect(

token.connect(addr1).transfer(owner.address, 1)

).to.be.revertedWith("Insufficient balance");

// Owner balance shouldn't have changed

expect(await token.balanceOf(owner.address)).to.equal(initialOwnerBalance);

});

it("Should emit Transfer event", async function () {

await expect(token.transfer(addr1.address, 50))

.to.emit(token, "Transfer")

.withArgs(owner.address, addr1.address, 50);

});

});

describe("Allowances", function () {

it("Should approve and transferFrom", async function () {

// Owner approves addr1 to spend 100 tokens

await token.approve(addr1.address, 100);

expect(await token.allowance(owner.address, addr1.address)).to.equal(100);

// addr1 transfers 50 from owner to addr2

await token.connect(addr1).transferFrom(owner.address, addr2.address, 50);

expect(await token.balanceOf(addr2.address)).to.equal(50);

expect(await token.allowance(owner.address, addr1.address)).to.equal(50);

});

it("Should fail if allowance is exceeded", async function () {

await token.approve(addr1.address, 50);

await expect(

token.connect(addr1).transferFrom(owner.address, addr2.address, 100)

).to.be.revertedWith("Allowance exceeded");

});

});

});

Tests Run करें

npx hardhat test

Output:

SimpleToken

Deployment

✓ Should set the correct name and symbol

✓ Should assign total supply to owner

Transactions

✓ Should transfer tokens between accounts

✓ Should fail if sender doesn't have enough tokens

✓ Should emit Transfer event

Allowances

✓ Should approve and transferFrom

✓ Should fail if allowance is exceeded

7 passing (2s)

Gas Reporting

Gas costs analyze करें:

npm install --save-dev hardhat-gas-reporter

hardhat.config.ts में:

import { HardhatUserConfig } from "hardhat/config";

import "@nomicfoundation/hardhat-toolbox";

import "hardhat-gas-reporter";

const config: HardhatUserConfig = {

solidity: "0.8.19",

gasReporter: {

enabled: true,

currency: "USD",

coinmarketcap: process.env.COINMARKETCAP_API_KEY, // Optional

},

};

export default config;

Tests run करें:

npx hardhat test

Output:

·-----------------------|---------------------------|-------------|-----------------------------·

| Solc version: 0.8.19 · Optimizer enabled: true · Runs: 200 · Block limit: 30000000 gas │

·························|···························|·············|······························

| Methods │

·············|··········|·············|·············|·············|···············|··············

| Contract · Method · Min · Max · Avg · # calls · usd (avg) │

·············|··········|·············|·············|·············|···············|··············

| SimpleToken · transfer · 51000 · 66000 · 58500 · 4 · - │

·············|··········|·············|·············|·············|···············|··············

| SimpleToken · approve · 46000 · 46100 · 46050 · 2 · - │

·············|··········|·············|·············|·············|···············|··············

Deployment Scripts

Local Deployment

scripts/deploy.ts में:

import { ethers } from "hardhat";

async function main() {

const [deployer] = await ethers.getSigners();

console.log("Deploying contracts with account:", deployer.address);

console.log("Account balance:", (await ethers.provider.getBalance(deployer.address)).toString());

const Token = await ethers.getContractFactory("SimpleToken");

const token = await Token.deploy(1000000); // 1M tokens

await token.waitForDeployment();

console.log("SimpleToken deployed to:", await token.getAddress());

}

main()

.then(() => process.exit(0))

.catch((error) => {

console.error(error);

process.exit(1);

});

Local network start करें:

npx hardhat node

यह 20 pre-funded accounts के साथ local Ethereum node start करेगा।

Deploy करें:

npx hardhat run scripts/deploy.ts --network localhost

Testnet Deployment

.env file बनाएं:

SEPOLIA_RPC_URL=https://sepolia.infura.io/v3/YOUR_INFURA_KEY

PRIVATE_KEY=your_private_key_here

ETHERSCAN_API_KEY=your_etherscan_api_key

hardhat.config.ts update करें:

import { HardhatUserConfig } from "hardhat/config";

import "@nomicfoundation/hardhat-toolbox";

import * as dotenv from "dotenv";

dotenv.config();

const config: HardhatUserConfig = {

solidity: "0.8.19",

networks: {

sepolia: {

url: process.env.SEPOLIA_RPC_URL || "",

accounts: process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [],

},

},

etherscan: {

apiKey: process.env.ETHERSCAN_API_KEY,

},

};

export default config;

Deploy करें:

npx hardhat run scripts/deploy.ts --network sepolia

Etherscan Verification

npx hardhat verify --network sepolia DEPLOYED_CONTRACT_ADDRESS 1000000

Advanced Features

Console.log in Solidity

Hardhat आपको Solidity में directly console.log use करने देता है!

import "hardhat/console.sol";

contract Debug {

function transfer(address to, uint256 amount) public {

console.log("Transferring", amount, "to", to);

// ... rest of logic

}

}

Tests run करने पर console output दिखेगा।

Mainnet Forking

Live blockchain state के against test करें:

hardhat.config.ts:

networks: {

hardhat: {

forking: {

url: process.env.MAINNET_RPC_URL || "",

blockNumber: 18000000, // Optional: specific block

},

},

},

अब आप real mainnet contracts के साथ interact कर सकते हैं:

const USDC_ADDRESS = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";

const usdc = await ethers.getContractAt("IERC20", USDC_ADDRESS);

const balance = await usdc.balanceOf(WHALE_ADDRESS);

Coverage Reporting

Code coverage check करें:

npx hardhat coverage

Output:

--------------------|----------|----------|----------|----------|----------------|

File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines |

--------------------|----------|----------|----------|----------|----------------|

contracts/ | 100 | 100 | 100 | 100 | |

SimpleToken.sol | 100 | 100 | 100 | 100 | |

--------------------|----------|----------|----------|----------|----------------|

All files | 100 | 100 | 100 | 100 | |

--------------------|----------|----------|----------|----------|----------------|

Useful Plugins

1. Hardhat-Ethers

Contract interactions को simplify करता है:

import { ethers } from "hardhat";

const [owner] = await ethers.getSigners();

const Token = await ethers.getContractFactory("SimpleToken");

const token = await Token.deploy(1000);

2. Hardhat-Etherscan

Automatic contract verification:

npx hardhat verify --network sepolia <address> <constructor-args>

3. Hardhat-Gas-Reporter

हर test में gas costs show करता है।

4. Solidity-Coverage

Code coverage reports generate करता है।

VS Code Setup

Extensions

Install करें:

  • Solidity by Juan Blanco
  • Hardhat Solidity by Nomic Foundation
  • ESLint
  • Prettier

Settings

.vscode/settings.json:

{

"solidity.compileUsingRemoteVersion": "v0.8.19",

"solidity.defaultCompiler": "remote",

"editor.formatOnSave": true,

"solidity.formatter": "prettier"

}

Common Tasks

Clean Artifacts

npx hardhat clean

Run Specific Test

npx hardhat test test/SimpleToken.test.ts

Run Single Test Case

npx hardhat test --grep "Should transfer tokens"

Check Contract Size

npx hardhat size-contracts

Flatten Contract

npx hardhat flatten contracts/SimpleToken.sol > SimpleToken_flat.sol

Best Practices

1. TypeScript Types

TypeChain automatically types generate करता है:

import { SimpleToken } from "../typechain-types";

const token: SimpleToken = await Token.deploy(1000);

// Full type safety!

2. Test Organization

test/

├── SimpleToken.test.ts

├── Staking.test.ts

├── helpers/

│ ├── time.ts

│ └── fixtures.ts

└── utils.ts

3. Environment Variables

Never commit private keys — always use .env:

# .gitignore

.env

node_modules/

artifacts/

cache/

typechain-types/

coverage/

4. Deployment Verification

Always verify contracts on Etherscan:

  • Users को code read करने देता है
  • Trust बढ़ाता है
  • Contract के साथ interact करना easier बनाता है

Hardhat vs. Foundry vs. Remix

| Feature | Hardhat | Foundry | Remix |

|---------|---------|---------|-------|

| Language | TypeScript/JS | Solidity | Browser |

| Speed | Medium | Very Fast | Medium |

| Testing | Mocha/Chai | Solidity | Limited |

| Plugins | Rich | Growing | Built-in |

| Learning Curve | Medium | Medium | Easy |

| Best For | Production | Testing | Learning |

Conclusion

Hardhat professional smart contract development का industry standard है। TypeScript support, comprehensive testing framework, और rich plugin ecosystem इसे teams और solo developers दोनों के लिए ideal बनाते हैं।

Key takeaways:

  • Hardhat TypeScript-first modern development framework है
  • Built-in testing, debugging, और deployment tools
  • Rich plugin ecosystem (gas reporting, coverage, verification)
  • Mainnet forking real blockchain state के against testing के लिए
  • Professional teams industry में Hardhat use करती हैं

Solingo पर, हम Hardhat workflows integrate करते हैं advanced challenges में। Production-grade development practices सीखें।

अभी शुरू करें: solingo.io/tools/hardhat

Practice में लगाने के लिए तैयार हैं?

Solingo पर interactive exercises के साथ इन concepts को apply करें।

मुफ्त में शुरू करें