Hardhat主网分叉环境调用合约函数报错的解决方法
Hardhat主网分叉环境合约调用CALL_EXCEPTION错误解决方法
问题背景
尝试调用部署在Hardhat主网分叉环境的自定义合约函数时触发CALL_EXCEPTION错误,但合约部署到Goerli测试网可正常调用。操作流程如下:
- 在
hardhat.config.js添加分叉配置:
networks: { hardhat: { forking: { url: "https://eth-mainnet.alchemyapi.io/v2/<key>", } } }
- 运行
npx hardhat node启动RPC服务器 - 使用
--network hardhat参数部署合约,记录合约地址 - 编写ethers.js脚本调用合约纯函数
myTestFunction(),脚本代码:
const { ethers } = require('ethers'); const provider2 = new ethers.providers.getDefaultProvider('http://127.0.0.1:8545/') const hrdhatAccountPrivate = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"//owner const hrdhatAccountPublic = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"//owner const ERC_20_ABI = require("./erc20_abi.json") const FORK_MAIN_ABI = [ "function myTestFunction() pure returns (uint256)", ] const walletFork = new ethers.Wallet(hrdhatAccountPrivate, provider2) async function main() { const fundxPoolAddr = '0xBbc18b580256A82dC0F9A86152b8B22E7C1C8005'//forking const fundxPoolContract = new ethers.Contract(fundxPoolAddr, FORK_MAIN_ABI, provider2) const fundxPoolContractWithWallet = fundxPoolContract.connect(hrdhatAccountPublic)//walletFork const tx = await fundxPoolContractWithWallet.myTestFunction()//{gasLimit:300000} console.log(tx); } main() .catch((error) => { console.error(error); process.exitCode = 1; });
运行脚本后出现错误:
Error: call revert exception [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ] (method="myTestFunction()", data="0x", errorArgs=null, errorName=null, errorSignature=null, reason=null, code=CALL_EXCEPTION, version=abi/5.6.3) at Logger.makeError (C:\Users\***\node_modules\@ethersproject\logger\lib\index.js:233:21) at Logger.throwError (C:\Users\***\node_modules\@ethersproject\logger\lib\index.js:242:20) at Interface.decodeFunctionResult (C:\Users\***\node_modules\@ethersproject\abi\lib\interface.js:388:23) at Contract.<anonymous> (C:\Users\***\node_modules\@ethersproject\contracts\lib\index.js:395:56) at step (C:\Users\***\node_modules\@ethersproject\contracts\lib\index.js:48:23) at Object.next (C:\Users\***\node_modules\@ethersproject\contracts\lib\index.js:29:53) at fulfilled (C:\Users\***\node_modules\@ethersproject\contracts\lib\index.js:20:58) at processTicksAndRejections (node:internal/process/task_queues:96:5) { reason: null, code: 'CALL_EXCEPTION', method: 'myTestFunction()', data: '0x', errorArgs: null, errorName: null, errorSignature: null, address: '0xB9d9e972100a1dD01cd441774b45b5821e136043', args: [], transaction: { data: '0xd100387c', to: '0xB9d9e972100a1dD01cd441774b45b5821e136043', from: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266' } }
解决步骤
1. 修正合约部署目标网络
npx hardhat node启动的是本地RPC服务器(端口8545),对应Hardhat的localhost网络,而非hardhat内置临时网络。部署合约时需指定--network localhost:
npx hardhat run scripts/你的部署脚本.js --network localhost
部署完成后,控制台会输出正确的合约地址,务必记录该地址。
2. 核对合约地址一致性
从错误信息可以看到,实际调用的地址是0xB9d9e972100a1dD01cd441774b45b5821e136043,但脚本中写的是0xBbc18b580256A82dC0F9A86152b8B22E7C1C8005,两者完全不符。将脚本中的fundxPoolAddr替换为部署后控制台输出的正确地址。
3. 修正合约签名者连接方式
ethers.Contract.connect()方法需要传入Signer或Wallet实例,而非地址字符串。将脚本中的:
const fundxPoolContractWithWallet = fundxPoolContract.connect(hrdhatAccountPublic)
替换为:
const fundxPoolContractWithWallet = fundxPoolContract.connect(walletFork)
4. 验证ABI与合约定义匹配
确认FORK_MAIN_ABI中的函数定义和合约源码完全一致:
- 函数名拼写正确(区分大小写)
- 状态修饰符(
pure)正确 - 返回值类型(
uint256)正确
完成以上修正后,重新运行脚本即可正常调用合约函数。
内容的提问来源于stack exchange,提问作者Turgay ÇABALAK
相关产品推荐
相关产品推荐

