Solidity合约设置mapping值为0时触发out of gas错误问题咨询
问题原因
这是旧版本Truffle的gas估算逻辑缺陷导致的,和Solidity的存储操作gas规则相关:
- Solidity 0.5.x版本遵循的SSTORE操作gas规则中,将存储槽的非0值修改为0时,会产生15000 gas的退款,该退款仅会在交易完全执行完成后返还给调用者,不能用于抵扣交易执行过程中的gas消耗。而将非0值修改为其他非0值(比如你这里的1),不会产生退款,也不会触发额外的消耗异常。
- 你使用的Truffle v5.4.0版本存在gas估算bug:估算交易所需gas时,会直接扣除SSTORE产生的退款金额,把最终需要支付的gas值作为交易的gas limit。但实际交易执行时需要足够的gas覆盖扣除退款前的总消耗,因此估算出来的gas limit低于实际执行需要的峰值,就会抛出
out of gas错误。
解决方法
- 方法1:手动为测试用例的交易指定足够的gas limit,不使用自动估算结果。比如调用合约方法时新增gas参数:
数值可以根据实际业务逻辑调整到足够覆盖执行消耗即可。await yourContract.yourMethod(params, {gas: 100000}) - 方法2:升级Truffle到最新稳定版,该gas估算缺陷在后续版本已经被修复。
- 方法3:不想升级Truffle的话,可以在
truffle-config.js中配置全局固定gas值,设置一个足够大的数值即可,比如:module.exports = { networks: { development: { host: "127.0.0.1", port: 8545, network_id: "*", gas: 8000000 // 配置全局默认gas limit } } }
内容的提问来源于stack exchange,提问作者hupeng
相关产品推荐
相关产品推荐

