You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hardhat主网分叉环境调用合约函数报错的解决方法

Hardhat主网分叉环境合约调用CALL_EXCEPTION错误解决方法

问题背景

尝试调用部署在Hardhat主网分叉环境的自定义合约函数时触发CALL_EXCEPTION错误,但合约部署到Goerli测试网可正常调用。操作流程如下:

  1. 在hardhat.config.js添加分叉配置:
networks: {
  hardhat: {
    forking: {
      url: "https://eth-mainnet.alchemyapi.io/v2/<key>",
    }
  }
}
  1. 运行npx hardhat node启动RPC服务器
  2. 使用--network hardhat参数部署合约,记录合约地址
  3. 编写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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 10:55:18