Hardhat分叉主网调用balanceOf查询指定地址返回值为0问题咨询
问题根因排查
以下是导致返回0的高频原因,按出现概率排序:
- 分叉配置未实际生效:如果你的Alchemy API密钥无效、没有替换配置中的占位符
my-api-key,或是网络请求失败,Hardhat会静默降级为本地空链运行,所有主网状态查询都会返回0,不会抛出明显错误。 - 运行测试时未使用配置了分叉的hardhat网络:如果本地启动了其他Hardhat节点、或是测试命令没有指定正确网络,会走未配置分叉的默认环境。
- 方法修饰符问题:
getBalance方法未加view修饰符,部分版本的Hardhat在模拟非view方法调用时,可能出现状态读取异常。
解决方案
步骤1:修正Hardhat配置
替换你的hardhat.config.js为以下内容,注意替换为你实际有效的Alchemy API密钥:
require("@nomiclabs/hardhat-waffle"); module.exports = { solidity: "0.8.0", networks: { hardhat: { forking: { url: "https://eth-mainnet.alchemyapi.io/v2/替换为你的实际Alchemy API密钥", enabled: true, // 强制启用分叉功能 // 可选:指定固定的主网区块号,避免最新区块波动导致的数据不一致 // blockNumber: 17500000 }, }, }, };
步骤2:优化合约方法
给getBalance方法添加view修饰符,避免不必要的交易模拟:
// 仅修改方法定义部分,其余代码保持不变 function getBalance() public view returns (uint) { address ethAddr = address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); address addrWithBalance = 0x00000000219ab540356cBB839Cbe05303d7705Fa; uint balance = IERC20(ethAddr).balanceOf(addrWithBalance); console.log(balance); return balance; }
步骤3:执行测试时指定网络和清除缓存
运行以下命令执行测试,确保使用配置了分叉的网络,同时禁用缓存避免读取旧数据:
npx hardhat test --network hardhat --no-cache
验证分叉是否生效(可选)
如果修改后还是返回0,可以在测试代码中加入以下用例,先验证分叉是否正常拉取了主网数据:
it("verify fork status", async function () { // 查询目标地址的ETH余额,该地址主网ETH余额超过百万枚,返回非0即代表分叉正常 const ethBalance = await ethers.provider.getBalance("0x00000000219ab540356cBB839Cbe05303d7705Fa"); console.log("目标地址ETH余额:", ethers.utils.formatEther(ethBalance)); });
如果以上步骤都完成还是异常,可升级Hardhat及相关依赖到最新版本:
npm update hardhat @nomiclabs/hardhat-waffle @nomiclabs/hardhat-ethers ethers
内容的提问来源于stack exchange,提问作者Edgaras Karka
相关产品推荐
相关产品推荐

