;)
Foundry 实战手册
如果你还在用 Hardhat 写 JS 测试,或者被 Truffle 的慢速编译折磨过,Foundry 会是你的解药。
它用 Rust 编写,底层集成 revm(一个极快的 Rust EVM 实现)。最大的卖点就一个:快,而且你可以直接用 Solidity 写测试。
不用在 JS 和 Solidity 之间来回切换心智,测试跑起来像飞一样。
四大组件:各司其职
Foundry 不是单一工具,而是一套命令行全家桶。
🔨 Forge:编译、测试、部署
日常干活的主力。forge test 跑 Solidity 测试,forge script 写部署脚本,forge build 编译合约。
📖 官方文档
常用命令速查
1 | forge init my-project # 初始化项目 |
[!tip] 部署参数小技巧
构造函数参数直接跟在命令末尾。如果参数带空格或特殊字符,用引号包起来。
验证合约时加上--verify,Foundry 会自动把源码推给 Etherscan。
⚡ Cast:链上交互的瑞士军刀
不想开浏览器、不想写脚本?cast 让你在终端里直接跟链上合约对话。
📖 官方文档
1 | cast call 0xContract "balanceOf(address)(uint256)" 0xUser --rpc-url $RPC |
🏠 Anvil:本地节点,秒级启动
比 Ganache 快得多。一键启动本地链,自带 10 个有钱的测试账户。
📖 官方文档
1 | anvil # 默认启动 |
[!example] 分叉测试的杀手级场景
你想测试协议在 Uniswap V3 池子里的交互,但不想花真金白银。anvil --fork-url把主网状态拉到本地,你的测试合约可以直接跟主网上的 Uniswap 交互(只读),随便折腾不花钱。
💻 Chisel:Solidity 的 REPL
类似 Python 的交互式终端。写两行代码立刻看结果,不用建文件、不用编译。
📖 官方文档
1 | chisel |
作弊码(Cheatcodes):测试环境的神
测试时,你需要控制时间、余额、区块高度,甚至伪装成别人调用合约。vm 对象就是干这个的。
1. 伪装身份 & 发钱
1 | vm.prank(alice); // 下一次调用伪装成 alice |
2. 快进时间 & 跳区块
1 | vm.warp(block.timestamp + 1 days); // 时间快进 1 天 |
3. 预期报错 & 事件
1 | vm.expectRevert("Not owner"); // 下一行调用必须 revert,且错误信息匹配 |
4. 直接读写 Storage(上帝模式)
1 | vm.store(targetContract, bytes32(uint256(0)), bytes32(uint256(999))); |
[!warning] 慎用 store/load
直接操作存储槽会绕过合约逻辑。通常用于测试极端边界情况,或者给没有 setter 的私有变量塞数据。
5. 快照与回滚
1 | uint256 snap = vm.snapshot(); |
6. 主网分叉测试
1 | uint256 mainnetFork = vm.createFork(vm.rpcUrl("mainnet")); |
常用参数与调试技巧
| 参数 | 作用 |
|---|---|
-v |
打印 console.log 输出 |
-vv |
失败测试显示断言对比 |
-vvv |
显示所有测试的堆栈跟踪 |
-vvvv |
核弹级:显示完整执行轨迹和内存变化(调试神器) |
--ffi |
允许测试调用外部系统命令(慎用,有安全风险) |
--isolate |
每个测试用例在独立 EVM 实例跑,互不干扰 |
打印调试:console2
Foundry 内置了类似 JS console.log 的功能:
1 | import "forge-std/console2.sol"; |
跑 forge test -vv 就能看到输出。
写在最后
Foundry 的学习曲线比 Hardhat 陡一点,因为你要习惯命令行和 Solidity 测试的写法。但一旦跑通,你会发现:
- 测试速度从分钟级降到秒级
- 不用在 JS 和 Solidity 之间翻译逻辑
cast和anvil让链上调试变得极其顺手
把 forge test 跑成肌肉记忆,你的合约质量会肉眼可见地提升。







