使用web3.js调用以太坊合约查询状态时出现gas费相关报错如何解决
问题根因
- 以太坊的
call操作虽然不需要上链、不需要用户实际支付gas,但节点本地执行合约代码时仍然会遵循EVM的gas校验规则,不会无限度免费执行合约逻辑。 - 你使用的web3.js 1.5.3是伦敦升级前的老版本,默认硬编码的
maxFeePerGas为3GWei,而以太坊伦敦升级后每个区块的base fee是动态调整的,报错时当前区块base fee已经涨到42.78GWei,远高于你默认的3GWei,节点校验参数不通过就抛出了这个错误,这也是为什么之前功能正常、突然报错的原因——base fee随网络情况上涨超出了默认值。
修复方案
方案1:调用call时手动传入gas费参数
先获取节点当前的建议gas费,再传入call配置中,示例代码如下:
// 先获取当前网络建议的maxFeePerGas web3.eth.getFeeHistory(1, "latest", [10]).then(feeHistory => { const maxFeePerGas = feeHistory.baseFeePerGas[0] * 2 // 留一倍余量,避免校验不通过 return MyContract.methods.actual_balance("0xE8D.........").call({ maxFeePerGas: maxFeePerGas, maxPriorityFeePerGas: web3.utils.toWei('1', 'gwei') }) }).then(r=>{ console.log(r) }).catch(err=>{ console.log(err) })
如果嫌麻烦也可以直接手动写死一个足够高的值(比如50GWei),只要高于当前网络base fee即可:
MyContract.methods.actual_balance("0xE8D.........").call({ maxFeePerGas: web3.utils.toWei('50', 'gwei') }).then(r=>{ console.log(r) }).catch(err=>{ console.log(err) })
方案2:修改web3全局默认配置
一次性修改全局默认的gas费参数,后续所有call和交易都会默认使用该配置:
web3.eth.defaultMaxFeePerGas = web3.utils.toWei('50', 'gwei') web3.eth.defaultMaxPriorityFeePerGas = web3.utils.toWei('1', 'gwei')
方案3:升级web3版本
升级到web3.js 1.7.0及以上版本,新版本会自动根据当前网络的base fee动态计算合理的maxFeePerGas默认值,不需要手动配置。
内容的提问来源于stack exchange,提问作者Igor
相关产品推荐
相关产品推荐

