foundry-solidity
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseFoundry Solidity Development
Foundry Solidity 智能合约开发
Complete guide for building secure, efficient smart contracts with Foundry 1.5.0 and Solidity 0.8.30.
这是一份使用Foundry 1.5.0和Solidity 0.8.30构建安全、高效智能合约的完整指南。
When to Use This Skill
何时使用本技能
- Developing Ethereum/EVM smart contracts
- Writing Forge tests (unit, fuzz, invariant, fork)
- Deploying contracts with scripts
- Using Foundry tools (forge, cast, anvil, chisel)
- Working with ,
foundry.toml,*.t.solfiles*.s.sol - Debugging transactions and contract interactions
- 开发以太坊/EVM智能合约
- 编写Forge测试(单元测试、模糊测试、不变量测试、分叉测试)
- 通过脚本部署合约
- 使用Foundry工具(forge、cast、anvil、chisel)
- 处理、
foundry.toml、*.t.sol文件*.s.sol - 调试交易和合约交互
Quick Start
快速开始
bash
undefinedbash
undefinedCreate new project
Create new project
forge init my-project && cd my-project
forge init my-project && cd my-project
Build contracts
Build contracts
forge build
forge build
Run tests
Run tests
forge test
forge test
Deploy (dry-run)
Deploy (dry-run)
forge script script/Deploy.s.sol --rpc-url sepolia
forge script script/Deploy.s.sol --rpc-url sepolia
Deploy (broadcast)
Deploy (broadcast)
forge script script/Deploy.s.sol --rpc-url sepolia --broadcast --verify
undefinedforge script script/Deploy.s.sol --rpc-url sepolia --broadcast --verify
undefinedProject Structure
项目结构
my-project/
├── foundry.toml # Configuration
├── src/ # Contracts
│ └── Counter.sol
├── test/ # Tests (*.t.sol)
│ └── Counter.t.sol
├── script/ # Deploy scripts (*.s.sol)
│ └── Deploy.s.sol
└── lib/ # Dependencies
└── forge-std/my-project/
├── foundry.toml # Configuration
├── src/ # Contracts
│ └── Counter.sol
├── test/ # Tests (*.t.sol)
│ └── Counter.t.sol
├── script/ # Deploy scripts (*.s.sol)
│ └── Deploy.s.sol
└── lib/ # Dependencies
└── forge-std/Core Commands
核心命令
Build & Test
构建与测试
bash
forge build # Compile
forge test # Run all tests
forge test -vvvv # With traces
forge test --match-test testDeposit # Filter by test name
forge test --match-contract Vault # Filter by contract
forge test --fork-url $RPC_URL # Fork testing
forge test --gas-report # Gas usage reportbash
forge build # Compile
forge test # Run all tests
forge test -vvvv # With traces
forge test --match-test testDeposit # Filter by test name
forge test --match-contract Vault # Filter by contract
forge test --fork-url $RPC_URL # Fork testing
forge test --gas-report # Gas usage reportDeployment
部署
bash
undefinedbash
undefinedSingle contract
Single contract
forge create src/Token.sol:Token --rpc-url sepolia --private-key $KEY --broadcast
forge create src/Token.sol:Token --rpc-url sepolia --private-key $KEY --broadcast
Script deployment (recommended)
Script deployment (recommended)
forge script script/Deploy.s.sol:Deploy --rpc-url sepolia --broadcast --verify
forge script script/Deploy.s.sol:Deploy --rpc-url sepolia --broadcast --verify
Verify existing contract
Verify existing contract
forge verify-contract $ADDRESS src/Token.sol:Token --chain sepolia
undefinedforge verify-contract $ADDRESS src/Token.sol:Token --chain sepolia
undefinedCast - Blockchain Interactions
Cast - 区块链交互
bash
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 mainnetbash
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 mainnetAnvil - Local Node
Anvil - 本地节点
bash
anvil # Start local node
anvil --fork-url $RPC_URL # Fork mainnet
anvil --fork-block-number 18000000bash
anvil # Start local node
anvil --fork-url $RPC_URL # Fork mainnet
anvil --fork-block-number 18000000Basic Test Contract
基础测试合约
solidity
// 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);
}
}solidity
// 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);
}
}Essential Cheatcodes
核心 Cheatcode
solidity
// Identity & ETH
address alice = makeAddr("alice"); // Create labeled address
deal(alice, 10 ether); // Give ETH
deal(address(token), alice, 1000e18); // Give ERC20
// Impersonation
vm.prank(alice); // Next call as alice
vm.startPrank(alice); // All calls as alice
vm.stopPrank();
// Time & Block
vm.warp(block.timestamp + 1 days); // Set timestamp
vm.roll(block.number + 100); // Set block number
// Assertions
vm.expectRevert("Error message"); // Expect revert
vm.expectRevert(CustomError.selector); // Custom error
vm.expectEmit(true, true, false, true); // Expect event
emit Transfer(from, to, amount); // Must match next emit
// Storage
vm.store(addr, slot, value); // Write storage
vm.load(addr, slot); // Read storagesolidity
// Identity & ETH
address alice = makeAddr("alice"); // Create labeled address
deal(alice, 10 ether); // Give ETH
deal(address(token), alice, 1000e18); // Give ERC20
// Impersonation
vm.prank(alice); // Next call as alice
vm.startPrank(alice); // All calls as alice
vm.stopPrank();
// Time & Block
vm.warp(block.timestamp + 1 days); // Set timestamp
vm.roll(block.number + 100); // Set block number
// Assertions
vm.expectRevert("Error message"); // Expect revert
vm.expectRevert(CustomError.selector); // Custom error
vm.expectEmit(true, true, false, true); // Expect event
emit Transfer(from, to, amount); // Must match next emit
// Storage
vm.store(addr, slot, value); // Write storage
vm.load(addr, slot); // Read storageDeploy Script
部署脚本
solidity
// 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("Deployed to:", address(counter));
}
}solidity
// 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("Deployed to:", address(counter));
}
}Modern Solidity Patterns (0.8.30)
现代Solidity模式(0.8.30版本)
solidity
// Custom errors (gas efficient)
error InsufficientBalance(uint256 available, uint256 required);
// Transient storage (0.8.28+) - cheap reentrancy guard
bool transient locked;
modifier nonReentrant() {
require(!locked, "Reentrancy");
locked = true;
_;
locked = false;
}
// Immutable variables (cheap reads)
address public immutable owner;
// Named mapping parameters
mapping(address user => uint256 balance) public balances;
// require with custom error (0.8.26+)
require(amount <= balance, InsufficientBalance(balance, amount));solidity
// Custom errors (gas efficient)
error InsufficientBalance(uint256 available, uint256 required);
// Transient storage (0.8.28+) - cheap reentrancy guard
bool transient locked;
modifier nonReentrant() {
require(!locked, "Reentrancy");
locked = true;
_;
locked = false;
}
// Immutable variables (cheap reads)
address public immutable owner;
// Named mapping parameters
mapping(address user => uint256 balance) public balances;
// require with custom error (0.8.26+)
require(amount <= balance, InsufficientBalance(balance, amount));Configuration (foundry.toml)
配置(foundry.toml)
toml
[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 = 1000toml
[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 = 1000References
参考资料
For detailed guides, see:
- Testing: See for complete testing patterns (unit, fuzz, invariant, fork), all cheatcodes, and best practices
references/testing.md - forge-std API: See for complete library reference (150+ functions)
references/forge-std-api.md - Solidity 0.8.30: See for new features and modern syntax
references/solidity-modern.md - Deployment: See for scripting, verification, and multi-chain deployment
references/deployment.md - Configuration: See for all foundry.toml options
references/configuration.md - Gas Optimization: See for storage packing, compiler settings, and profiling
references/gas-optimization.md - Patterns: See for access control, reentrancy guards, factories, and common idioms
references/patterns.md - Security: See for vulnerabilities, defensive patterns, and audit preparation
references/security.md - Resources: See for official docs, libraries, security tools, and learning paths
references/resources.md - Debugging: See for traces, breakpoints, console.log, and the interactive debugger
references/debugging.md - Dependencies: See for forge install, remappings, and Soldeer package manager
references/dependencies.md - CI/CD: See for GitHub Actions workflows, caching, and gas tracking
references/cicd.md - Chisel: See for the interactive Solidity REPL
references/chisel.md - Cast Advanced: See for decoding, encoding, wallet management, and batch operations
references/cast-advanced.md - Anvil Advanced: See for impersonation, state manipulation, and mining modes
references/anvil-advanced.md
如需详细指南,请参阅:
- 测试:详见,包含完整的测试模式(单元、模糊、不变量、分叉测试)、所有cheatcode及最佳实践
references/testing.md - forge-std API:详见,包含完整的库参考(150+个函数)
references/forge-std-api.md - Solidity 0.8.30:详见,包含新特性和现代语法
references/solidity-modern.md - 部署:详见,包含脚本编写、验证及多链部署内容
references/deployment.md - 配置:详见,包含foundry.toml的所有配置选项
references/configuration.md - Gas优化:详见,包含存储打包、编译器设置及性能分析内容
references/gas-optimization.md - 设计模式:详见,包含访问控制、重入防护、工厂模式及常见设计范式
references/patterns.md - 安全:详见,包含漏洞、防御模式及审计准备内容
references/security.md - 资源:详见,包含官方文档、库、安全工具及学习路径
references/resources.md - 调试:详见,包含追踪、断点、console.log及交互式调试器使用方法
references/debugging.md - 依赖管理:详见,包含forge install、重映射及Soldeer包管理器使用方法
references/dependencies.md - CI/CD:详见,包含GitHub Actions工作流、缓存及Gas追踪内容
references/cicd.md - Chisel:详见,包含交互式Solidity REPL使用方法
references/chisel.md - Cast进阶:详见,包含解码、编码、钱包管理及批量操作内容
references/cast-advanced.md - Anvil进阶:详见,包含地址 impersonation、状态操纵及挖矿模式内容
references/anvil-advanced.md