使用 Foundry 工具套件构建和测试 Solidity 智能合约。适用于以太坊合约开发、编写 Forge 测试、脚本部署及调试。
创始人团结发展:与创始人1.5.0和团结组织0.8.30建立安全高效智能合同的完整指南.是一项面向实际任务的技能,主要用于When to use this Skill.;Developing Ethereum/EVM智能合同。
从功能定位来看,该技能强调把分散的操作要求整理成清晰、可复用的处理流程,使用户能够围绕既定目标快速准备输入、选择执行方式并获得结构化结果。实际使用前应先确认任务范围、数据来源、运行环境、必要权限和关键参数,再依据技能说明逐步执行;
若输入条件不完整,应先补齐信息或采用保守配置,避免因错误假设导致结果偏离需求。执行过程中需要关注工具调用是否成功、接口或依赖是否可用、输出格式是否符合预期,并对异常提示、缺失字段和边界情况进行处理;涉及批量任务时,还应保存进度,避免中断后重复操作。
使用 Foundry 1.5.0 和 Solidity 0.8.30 构建安全、高效智能合约的完整指南。
foundry.toml、*.t.sol、*.s.sol 文件# 创建新项目 forge init my-project && cd my-project # 编译合约 forge build # 运行测试 forge test # 部署(预执行) forge script script/Deploy.s.sol --rpc-url sepolia # 部署(广播上链) forge script script/Deploy.s.sol --rpc-url sepolia --broadcast --verify
my-project/
├── foundry.toml # 配置文件
├── src/ # 合约源码目录
│ └── Counter.sol
├── test/ # 测试文件(*.t.sol)
│ └── Counter.t.sol
├── script/ # 部署脚本(*.s.sol)
│ └── Deploy.s.sol
└── lib/ # 依赖库目录
└── forge-std/
forge build # 编译合约 forge test # 运行全部测试 forge test -vvvv # 显示执行轨迹(trace) forge test --match-test testDeposit # 按测试函数名过滤 forge test --match-contract Vault # 按合约名过滤 forge test --fork-url $RPC_URL # 分叉测试 forge test --gas-report # 输出 Gas 消耗报告
# 单合约部署 forge create src/Token.sol:Token --rpc-url sepolia --private-key $KEY --broadcast # 脚本化部署(推荐方式) forge script script/Deploy.s.sol:Deploy --rpc-url sepolia --broadcast --verify # 验证已部署合约 forge verify-contract $ADDRESS src/Token.sol:Token --chain sepolia
cast call $CONTRACT "balanceOf(address)" $USER --rpc-url mainnet cast send $CONTRACT "transfer(address,uint256)" $TO $AMOUNT --private-key $KEY cast decode-tx $TX_HASH cast storage $CONTRACT 0 --rpc-url mainnet
anvil # 启动本地节点 anvil --fork-url $RPC_URL # 分叉主网状态 anvil --fork-block-number 18000000
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
import {Test, console} from "forge-std/Test.sol";
import {Counter} from "../src/Counter.sol";
contract CounterTest is Test {
Counter public counter;
address public user;
function setUp() public {
counter = new Counter();
user = makeAddr("user");
deal(user, 10 ether);
}
function test_Increment() public {
counter.increment();
assertEq(counter.number(), 1);
}
function test_RevertWhen_Unauthorized() public {
vm.expectRevert("Unauthorized");
vm.prank(user);
counter.adminFunction();
}
function testFuzz_SetNumber(uint256 x) public {
x = bound(x, 0, 1000);
counter.setNumber(x);
assertEq(counter.number(), x);
}
}
// 账户与 ETH 操作
address alice = makeAddr("alice"); // 创建带标签的地址
deal(alice, 10 ether); // 向地址发放 ETH
deal(address(token), alice, 1000e18); // 向地址发放 ERC20 代币
// 账户伪装(Impersonation)
vm.prank(alice); // 下一次调用以 alice 身份执行
vm.startPrank(alice); // 后续所有调用均以 alice 身份执行
vm.stopPrank();
// 时间与区块控制
vm.warp(block.timestamp + 1 days); // 设置区块时间戳
vm.roll(block.number + 100); // 设置区块高度
// 断言与预期行为
vm.expectRevert("Error message"); // 预期发生 revert 并匹配错误消息
vm.expectRevert(CustomError.selector); // 预期发生自定义错误
vm.expectEmit(true, true, false, true); // 预期下一次 emit 的事件(参数:logTopic1, logTopic2, logData, logAddress)
emit Transfer(from, to, amount); // 必须紧随其后,用于匹配预期事件
// 存储读写
vm.store(addr, slot, value); // 写入存储槽
vm.load(addr, slot); // 读取存储槽
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
import {Script, console} from "forge-std/Script.sol";
import {Counter} from "../src/Counter.sol";
contract Deploy is Script {
function run() external {
uint256 deployerKey = vm.envUint("PRIVATE_KEY");
vm.startBroadcast(deployerKey);
Counter counter = new Counter();
counter.setNumber(42);
vm.stopBroadcast();
console.log("已部署至:", address(counter));
}
}
// 自定义错误(更省 Gas)
error InsufficientBalance(uint256 available, uint256 required);
// 瞬态存储(Transient Storage,0.8.28+)——低成本重入防护
bool transient locked;
modifier nonReentrant() {
require(!locked, "Reentrancy");
locked = true;
_;
locked = false;
}
// 不可变变量(immutable,读取成本低)
address public immutable owner;
// 命名映射键(Named mapping parameters)
mapping(address user => uint256 balance) public balances;
// require 配合自定义错误(0.8.26+)
require(amount <= balance, InsufficientBalance(balance, amount));
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
solc = "0.8.30"
optimizer = true
optimizer_runs = 200
evm_version = "prague"
fuzz.runs = 256
invariant.runs = 256
invariant.depth = 50
[rpc_endpoints]
mainnet = "${MAINNET_RPC_URL}"
sepolia = "${SEPOLIA_RPC_URL}"
[etherscan]
mainnet = { key = "${ETHERSCAN_API_KEY}" }
sepolia = { key = "${ETHERSCAN_API_KEY}" }
[profile.ci]
fuzz.runs = 10000
invariant.runs = 1000
详细指南请参阅:
references/testing.md,涵盖完整测试模式(单元、模糊、不变式、分叉)、全部 Cheatcodes 及最佳实践references/forge-std-api.md,完整函数参考(150+ 个函数)references/solidity-modern.md,了解新特性与现代语法references/deployment.md,涵盖脚本编写、合约验证与多链部署references/configuration.md,详述所有 foundry.toml 配置项references/gas-optimization.md,涵盖存储打包、编译器设置与性能分析references/patterns.md,涵盖访问控制、重入防护、工厂模式及常见编程范式references/security.md,涵盖常见漏洞、防御性编码模式与审计准备要点references/resources.md,含官方文档、常用库、安全工具与学习路径references/debugging.md,涵盖执行轨迹(traces)、断点、console.log 及交互式调试器使用方法references/dependencies.md,涵盖 forge install、remappings 与 Soldeer 包管理器references/cicd.md,涵盖 GitHub Actions 工作流、缓存策略与 Gas 消耗追踪references/chisel.md,了解交互式 Solidity REPL 的使用references/cast-advanced.md,涵盖数据解码/编码、钱包管理与批量操作references/anvil-advanced.md,涵盖账户伪装、状态操控与挖矿模式相关专题
热门下载
相关下载
精品课程
共6课时 | 54.7万人学习
共89课时 | 134.1万人学习
共49课时 | 82.6万人学习
最新文章