调用DAI合约name()方法触发CALL_EXCEPTION错误,如何解决?
问题:调用ethers.js合约方法触发CALL_EXCEPTION错误
错误信息
未捕获(在 promise 中)错误:调用回滚异常 [ 参考:https://links.ethers.org/v5-errors-CALL_EXCEPTION ](方法="name()",数据="0x",errorArgs=null,errorName=null,errorSignature=null,reason=null,code=CALL_EXCEPTION,version=abi/5.7.0)
代码片段
const provider = new ethers.providers.Web3Provider(window.ethereum); const address = '0x6B175474E89094C44Da98b954EedeAC495271d0F' const abi = [ "function name() view returns (string)", "function symbol() view returns (string)", "function totalSupply() view returns (uint256)" ] const connectWallet = (async()=>{ await provider.send("eth_requestAccounts",[]); }) const contract = new ethers.Contract(address,abi,provider); const getInfo = (async()=>{ const n = await contract.name(); console.log(n) })
尝试通过ethers.js读取上述地址的智能合约信息,但调用name()方法时触发上述错误,请问错误原因是什么?该如何解决?
错误原因与解决方法
错误原因
- 链不匹配:目标地址
0x6B175474E89094C44Da98b954EedeAC495271d0F是以太坊主网的DAI合约,但如果你的钱包当前连接的是测试网(如Sepolia、Goerli)或其他公链,该地址在对应链上没有部署符合ABI的合约,直接调用会触发异常。 - 未执行钱包连接:
connectWallet函数仅定义未调用,部分钱包环境下未连接时,provider可能无法正常获取链上数据(即使是view方法)。 - ABI/地址不匹配:虽然当前地址和ABI看起来正确,但如果地址输入错误或ABI方法签名与实际合约不符,也会导致调用失败。
解决方法
- 切换到正确链:将钱包(如MetaMask)切换至以太坊主网,若需测试网验证,使用对应测试网的DAI合约地址。
- 调用钱包连接函数:在执行
getInfo前调用connectWallet(),确保provider初始化完成,示例:// 页面加载或按钮点击时触发 connectWallet().then(() => { getInfo(); }); - 验证地址与ABI:确认目标链上的地址确实是有效合约,且ABI中的方法签名(如
name() view returns(string))与合约实际方法完全一致。 - 添加错误捕获:在
getInfo中加入try-catch块,方便定位具体问题:const getInfo = async()=>{ try { const n = await contract.name(); console.log(n); } catch (err) { console.error("调用失败详情:", err); } }
内容的提问来源于stack exchange,提问作者Alfaz Sozib
相关产品推荐
相关产品推荐

