Hardhat智能合约开发框架 hardhat-framework

Hardhat框架技能是用于以太坊智能合约开发、测试和部署的专业工具集。它提供完整的开发环境,包括合约编译、本地网络部署、自动化测试、Gas费用分析、合约验证等功能。关键词:以太坊开发、智能合约、区块链开发、Solidity、Web3、DApp开发、合约测试、部署管理、TypeChain、网络分叉。

智能合约 0 次安装 0 次浏览 更新于 2/23/2026

name: hardhat-framework description: 精通Hardhat框架,用于智能合约开发、测试和部署。包括TypeChain类型生成、插件生态系统、网络分叉和部署管理。 allowed-tools: Read, Grep, Write, Bash, Edit, Glob, WebFetch

Hardhat框架技能

精通Hardhat,最流行的以太坊开发环境。

能力

  • 配置: 为多网络设置hardhat.config.js
  • 测试: 使用ethers.js/viem编写测试
  • 插件: 使用插件(升级、gas报告、覆盖率)
  • 本地网络: 运行Hardhat Network进行开发
  • 部署: 执行脚本并管理部署
  • 分叉: 分叉主网进行测试
  • TypeChain: 生成TypeScript类型定义

安装

# 创建项目
mkdir my-project && cd my-project
npm init -y

# 安装Hardhat
npm install --save-dev hardhat

# 初始化项目
npx hardhat init

# 安装常用依赖
npm install --save-dev @nomicfoundation/hardhat-toolbox

配置

hardhat.config.js

require("@nomicfoundation/hardhat-toolbox");
require("@openzeppelin/hardhat-upgrades");
require("hardhat-gas-reporter");
require("solidity-coverage");

/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
  solidity: {
    version: "0.8.20",
    settings: {
      optimizer: {
        enabled: true,
        runs: 200,
      },
      viaIR: false,
    },
  },

  networks: {
    hardhat: {
      forking: {
        url: process.env.MAINNET_RPC_URL,
        blockNumber: 18000000,
      },
    },
    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,
  },

  gasReporter: {
    enabled: true,
    currency: "USD",
    coinmarketcap: process.env.COINMARKETCAP_API_KEY,
  },

  paths: {
    sources: "./contracts",
    tests: "./test",
    cache: "./cache",
    artifacts: "./artifacts",
  },
};

TypeScript配置

// hardhat.config.ts
import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";
import "@openzeppelin/hardhat-upgrades";

const config: HardhatUserConfig = {
  solidity: "0.8.20",
  networks: {
    sepolia: {
      url: process.env.SEPOLIA_RPC_URL || "",
      accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : [],
    },
  },
};

export default config;

测试

基础测试

// test/Token.test.js
const { expect } = require("chai");
const { ethers } = require("hardhat");

describe("Token", function () {
  let token;
  let owner;
  let addr1;

  beforeEach(async function () {
    [owner, addr1] = await ethers.getSigners();

    const Token = await ethers.getContractFactory("Token");
    token = await Token.deploy();
    await token.waitForDeployment();
  });

  describe("部署", function () {
    it("应设置正确的所有者", async function () {
      expect(await token.owner()).to.equal(owner.address);
    });

    it("应将总供应量分配给所有者", async function () {
      const ownerBalance = await token.balanceOf(owner.address);
      expect(await token.totalSupply()).to.equal(ownerBalance);
    });
  });

  describe("交易", function () {
    it("应转移代币", async function () {
      await token.transfer(addr1.address, 50);
      expect(await token.balanceOf(addr1.address)).to.equal(50);
    });

    it("应触发Transfer事件", async function () {
      await expect(token.transfer(addr1.address, 50))
        .to.emit(token, "Transfer")
        .withArgs(owner.address, addr1.address, 50);
    });

    it("如果发送方资金不足应失败", async function () {
      await expect(
        token.connect(addr1).transfer(owner.address, 1)
      ).to.be.revertedWith("余额不足");
    });
  });
});

TypeScript测试

// test/Token.test.ts
import { expect } from "chai";
import { ethers } from "hardhat";
import { Token } from "../typechain-types";

describe("Token", function () {
  let token: Token;

  beforeEach(async function () {
    const Token = await ethers.getContractFactory("Token");
    token = await Token.deploy();
  });

  it("应成功部署", async function () {
    expect(await token.getAddress()).to.be.properAddress;
  });
});

分叉测试

const { expect } = require("chai");
const { ethers, network } = require("hardhat");

describe("分叉测试", function () {
  const USDC_ADDRESS = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
  const WHALE = "0x47ac0Fb4F2D84898e4D9E7b4DaB3C24507a6D503";

  beforeEach(async function () {
    // 模拟鲸鱼账户
    await network.provider.request({
      method: "hardhat_impersonateAccount",
      params: [WHALE],
    });
  });

  it("应从鲸鱼账户转移USDC", async function () {
    const whale = await ethers.getSigner(WHALE);
    const usdc = await ethers.getContractAt("IERC20", USDC_ADDRESS);

    const [, recipient] = await ethers.getSigners();
    const amount = ethers.parseUnits("1000", 6);

    await usdc.connect(whale).transfer(recipient.address, amount);
    expect(await usdc.balanceOf(recipient.address)).to.equal(amount);
  });
});

部署脚本

基础部署

// scripts/deploy.js
const hre = require("hardhat");

async function main() {
  const Token = await hre.ethers.getContractFactory("Token");
  const token = await Token.deploy();
  await token.waitForDeployment();

  console.log("Token部署地址:", await token.getAddress());

  // 在Etherscan上验证
  if (hre.network.name !== "hardhat") {
    await hre.run("verify:verify", {
      address: await token.getAddress(),
      constructorArguments: [],
    });
  }
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

可升级部署

// scripts/deploy-upgradeable.js
const { ethers, upgrades } = require("hardhat");

async function main() {
  const Token = await ethers.getContractFactory("TokenV1");

  // 部署代理
  const token = await upgrades.deployProxy(Token, [], {
    initializer: "initialize",
  });
  await token.waitForDeployment();

  console.log("代理部署地址:", await token.getAddress());
}

main();

升级脚本

// scripts/upgrade.js
const { ethers, upgrades } = require("hardhat");

async function main() {
  const PROXY_ADDRESS = "0x...";

  const TokenV2 = await ethers.getContractFactory("TokenV2");
  const token = await upgrades.upgradeProxy(PROXY_ADDRESS, TokenV2);

  console.log("Token已升级");
}

main();

Hardhat任务

// hardhat.config.js
task("accounts", "打印账户", async (taskArgs, hre) => {
  const accounts = await hre.ethers.getSigners();
  for (const account of accounts) {
    console.log(account.address);
  }
});

task("balance", "打印余额")
  .addParam("account", "账户地址")
  .setAction(async (taskArgs, hre) => {
    const balance = await hre.ethers.provider.getBalance(taskArgs.account);
    console.log(hre.ethers.formatEther(balance), "ETH");
  });

命令

# 编译
npx hardhat compile

# 测试
npx hardhat test
npx hardhat test --grep "transfer"

# 覆盖率
npx hardhat coverage

# 运行脚本
npx hardhat run scripts/deploy.js --network sepolia

# 控制台
npx hardhat console --network localhost

# 节点
npx hardhat node

# 验证
npx hardhat verify --network mainnet <address>

流程集成

流程 目的
smart-contract-development-lifecycle.js 完整开发流程
dapp-frontend-development.js dApp前端集成
所有代币流程 代币部署
所有DeFi流程 协议部署

最佳实践

  1. 使用TypeScript确保类型安全
  2. 配置多网络
  3. 使用环境变量
  4. 启用gas报告
  5. 生成覆盖率报告
  6. 在区块浏览器上验证合约

另请参阅

  • skills/foundry-framework/SKILL.md - 替代框架
  • skills/openzeppelin/SKILL.md - 合约库
  • Hardhat文档