入门Hardhat和Foundry

Hardhat 和 Foundry 是当前最主流的两个智能合约开发框架,都致力于简化从编码、测试到部署的完整开发流程。

Hardhat 基于 JavaScript/TypeScript 生态,用 js 或 ts 写测试,依赖 nodejs 环境,需要配置驱动 hardhat.config.js,将 Solidity 开发无缝融入 JavaScript 生态,特别适合全栈开发者(前端+合约)。。

Foundry 基于 Rust(性能相对 nodejs 快很多),可用 Solidity 写测试,测试即合约,消除语言边界,并且约定优于配置:目录结构即配置(src/ → 合约, test/ → 测试)。

Foundry

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
┌─────────────────────────────────────────────────────┐
│           Foundry 四大核心组件(Rust 实现)          │
├───────────┬───────────┬───────────┬─────────────────┤
│  forge    │   cast    │  anvil    │    chisel       │
│ (编译/测试)│ (链交互)  │ (本地链)  │  (REPL 调试)    │
└─────┬─────┴─────┬─────┴─────┬─────┴────────┬────────┘
      │           │           │              │
      ▼           ▼           ▼              ▼
  编译合约    读写链状态   提供测试环境   快速验证逻辑
  运行测试    发送交易     分叉主网       实时计算
  部署合约    解码事件     模拟攻击        调试 Gas

forge

test/ 目录下的 .t.sol 文件本质是继承 Test.sol 的合约,控制台执行 forge test 命令会:

  • 编译所有合约(含测试合约)
  • 部署测试合约到本地 EVM
  • 调用以 test 开头的函数(如 testIncrement)进行测试
  • 捕获断言失败/Gas 消耗/覆盖率

同时还有模糊测试内置,函数参数带 (uint256 x) 会自动运行 256 次随机输入,无需额外配置。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
test/Counter.t.sol

pragma solidity ^0.8.20;
import "forge-std/Test.sol";
import "../src/Counter.sol";

// 测试合约本质是普通合约 + 特殊断言库
contract CounterTest is Test {  // Test 来自 forge-std
    function testFuzz_Increment(uint256 start) public {
        Counter c = new Counter();
        c.setNumber(start);
        c.increment();
        assertEq(c.number(), start + 1); // 断言在 EVM 中执行
    }
}

cast

cast 无需写脚本就可以和任意 EVM 链交互

1
2
3
4
5
6
# 查询指定地址在以太坊主网上的 ETH 余额(单位:wei)
cast balance 0x... --rpc-url https://eth.llamarpc.com
# 调用某个合约地址的只读函数(view/pure),无需支付 Gas,不改变链上状态
cast call 0x... "name()" --rpc-url sepolia
# 广播交易到区块链,调用可修改状态的函数(如转账),需支付 Gas,--private-key $PK是发送方私钥(极度敏感!)
cast send 0x... "transfer(address,uint256)" 0x... 100 --private-key $PK --rpc-url sepolia

cast 本质是 命令行版的 Web3.js,但用 Rust 实现,速度极快且无 JS 依赖。

anvil

快速启动本地以太坊节点

  • anvil –fork-url https://eth.llamarpc.com 瞬间复制主网状态,测试真实合约交互
  • 启动即提供 10 个带 10,000 ETH 的测试账户(私钥固定,方便调试)
  • 测试中用 vm.warp(timestamp) 操控区块时间(无需重启节点)

chisel

REPL(Read-Eval-Print Loop)环境,实时验证 Solidity 逻辑

1
2
3
4
5
6
chisel
>> uint256 x = 100
>> x * 2
200
>> address(this).balance  # 查看当前合约余额
0

hardhat

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
┌──────────────────────────────────────────────────────────────┐
│          Hardhat 核心架构(Node.js + 插件系统)               │
├──────────────┬──────────────┬──────────────┬─────────────────┤
│  Hardhat     │ Hardhat      │  插件系统     │  开发者工具链    │
│  Core        │  Network     │ (Plugins)    │ (VS Code etc.)  │
│ (任务调度)    │ (本地EVM)     │              │                 │
└──────┬───────┴──────┬───────┴──────┬───────┴────────┬────────┘
       │              │              │                │
       ▼              ▼              ▼                ▼
   编译合约      模拟区块链     扩展功能:        深度集成:
   运行测试      捕获堆栈       部署/验证/        调试器/测试覆盖率
   执行脚本      时间旅行       类型生成          实时错误提示

Hardhat 测试(TypeScript)

foundry 使用 solidity 编写测试,而 hardhat 使用 js/ts 编写测试,如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
it('should transfer tokens', async () => {
	await token.transfer(user.address, amount);
	expect(await token.balanceOf(user.address)).to.equal(amount);

	// 复杂逻辑示例:循环测试 100 次不同金额
	for (let i = 0; i < 100; i++) {
		await token.transfer(user.address, ethers.utils.parseEther(i.toString()));
		// ... 验证逻辑
	}
});

hardhat.config.ts 配置中心

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import { HardhatUserConfig } from 'hardhat/config';
import '@nomicfoundation/hardhat-toolbox';
const config: HardhatUserConfig = {
	solidity: {
		version: '0.8.20',
		settings: {
			optimizer: {
				enabled: true,
				runs: 200,
			},
		},
	},
	networks: {
		hardhat: {
			chainId: 1337,
			accounts: [
				{
					privateKey:
						'0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80',
					balance: '10000000000000000000000', // 10,000 ETH
				},
			],
		},
		sepolia: {
			url: process.env.SEPOLIA_RPC_URL || '',
			accounts: [process.env.PRIVATE_KEY || ''],
		},
	},
	paths: {
		sources: './contracts',
		tests: './test',
		cache: './cache',
		artifacts: './artifacts', // 生成的 ABI/字节码存放处
	},
};
export default config;
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 1. Core 编译合约(触发 solidity 任务)
npx hardhat compile

# 2. Network 启动本地链(自动触发)
npx hardhat test  # 内部自动启动 hardhat network

# 3. 插件提供能力
- hardhat-ethers: 部署合约
- typechain: 生成 TS 类型
- chai-matchers: 断言事件
- hardhat-gas-reporter: 测试时显示 Gas 消耗
- hardhat-deploy: 部署脚本管理 + 多网络配置
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计