Hardhat 主网分叉功能允许开发者基于以太坊主网或测试网的当前状态创建本地开发环境,这对于测试 DeFi 协议和与现有合约交互非常有用。
基本用法:
在 hardhat.config.js 中配置分叉:
javascriptnetworks: { hardhat: { forking: { url: process.env.MAINNET_RPC_URL, blockNumber: 15000000 // 可选:指定分叉区块 } } }
使用场景:
- 测试与主网合约的交互
javascriptconst uniswapRouter = await ethers.getContractAt( "IUniswapV2Router02", "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D" );
- 模拟真实市场条件
javascript// 获取主网上的代币价格 const dai = await ethers.getContractAt("IERC20", DAI_ADDRESS); const price = await someOracle.getPrice(dai.address);
- 测试 DeFi 协议集成
javascript// 在分叉环境中测试 Aave 集成 const pool = await ethers.getContractAt( "IPool", "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2" );
高级配置:
javascriptnetworks: { hardhat: { forking: { url: process.env.MAINNET_RPC_URL, blockNumber: 15000000, enabled: true }, chainId: 1 // 保持与主网相同的 chainId } }
测试中的使用:
javascriptdescribe("Mainnet Fork Tests", function () { it("should interact with Uniswap", async function () { // 获取测试账户 const [signer] = await ethers.getSigners(); // 获取主网 USDC const usdc = await ethers.getContractAt("IERC20", USDC_ADDRESS); const balance = await usdc.balanceOf(signer.address); console.log("USDC Balance:", balance.toString()); }); });
注意事项:
- 需要 RPC 节点支持归档数据
- 分叉会增加内存使用
- 确保有足够的测试 ETH
- 考虑使用固定的区块号以确保测试可重复性
最佳实践:
- 使用环境变量存储 RPC URL
- 指定固定的区块号以确保测试稳定性
- 在 CI/CD 中使用归档节点
- 定期更新分叉区块号