使用ethers.js v6调用合约函数时铸币失败且result.wait()无限等待的解决方法
问题原因分析
- Gas参数设置不匹配链机制:你手动使用了
gasPrice,但在支持EIP-1559的链上,ethers.js v6默认适配EIP-1559的maxFeePerGas和maxPriorityFeePerGas参数,而非传统gasPrice。强行设置gasPrice会导致交易无法被矿工优先打包,一直处于pending状态,wait()也就会无限等待。 - GasLimit无缓冲空间:
estimateGas()返回的是理论最小Gas用量,但链上实时状态变化可能让实际执行需要更多Gas,导致交易执行失败后卡在未确认状态。 - 节点同步异常:如果连接的Provider节点同步不及时或网络延迟,会无法正确获取交易的确认状态,引发
wait()无限等待。
解决方法
方法1:适配EIP-1559的Gas参数
改用getFeeData()返回的标准参数,代码修改如下:
const gasLimit = await contract.writeResult.estimateGas(args); const { maxFeePerGas, maxPriorityFeePerGas } = await provider.getFeeData(); const result = await contract.writeResult(args, { gasLimit, maxFeePerGas, maxPriorityFeePerGas }); console.log(result.hash); // 明确指定等待1个区块确认 await result.wait(1);
方法2:让ethers自动处理Gas参数
完全不手动设置Gas相关参数,依赖ethers.js自动估算和适配,避免手动配置错误:
const result = await contract.writeResult(args); console.log(result.hash); await result.wait(1);
方法3:给GasLimit增加缓冲
如果必须手动设置GasLimit,在估算值基础上增加10%-20%的缓冲,应对链上状态变化:
const estimatedGas = await contract.writeResult.estimateGas(args); // 增加10%缓冲,取整处理 const gasLimit = estimatedGas.mul(110).div(100); const { maxFeePerGas, maxPriorityFeePerGas } = await provider.getFeeData(); const result = await contract.writeResult(args, { gasLimit, maxFeePerGas, maxPriorityFeePerGas }); console.log(result.hash); await result.wait(1);
辅助排查步骤
- 执行
await provider.getTransaction(result.hash)查看交易状态:若blockNumber为null,说明交易处于pending,基本是Gas费用设置过低导致; - 若交易已打包但
wait()仍等待,可切换到官方节点或第三方可靠节点(如Alchemy、Infura)测试,排除节点同步问题。
内容的提问来源于stack exchange,提问作者code gp
相关产品推荐
相关产品推荐

