Alert Source Discuss
🚧 Stagnant Standards Track: Core

EIP-3978: 回退时的 Gas 退款

通过 gas 退款机制重新定价已回退的 SSTORE/CREATE/SELFDESTRUCT/LOGX 操作 gas

Authors Anton Bukov (@k06a), Mikhail Melnik (@ZumZoom)
Created 2021-09-16
Discussion Link https://ethereum-magicians.org/t/eip-3978-gas-refunds-on-reverts/7071/
Requires EIP-2929

摘要

对于回退的状态修改操作,保留访问成本,但退还修改成本。

动机

回退一个交易,或其任何子调用,会丢弃内部发生的任何状态修改。 但现在,用户需要为丢弃的修改付费,就好像它们已经持久化了一样。

自从 EIP-3298 以来,gas 退款机制仅适用于同一交易中的存储恢复。但是在回退时,gas 退款不会增加;它会被完全擦除。 在交易结束时转回 tokens 甚至可能比回退更便宜,以保留现有的 gas 退款。 这应该改变。

  • 回退的 SSTORE 应该被重新定价为 SLOAD gas(100 gas)
  • 回退的 LOG0、LOG1、LOG2、LOG3 和 LOG4 应该被重新定价为 100 gas
  • 带有 value 的回退的 CALL (positive_value_cost = 9,000 gas) 应该被重新定价为 100 gas
  • 带有 value 和账户创建的回退的 CALL (value_to_empty_account_cost = 25,000 gas) 应该被重新定价为 100 gas
  • 回退的 CREATE 和 CREATE2 (32,000 gas) 应该被重新定价为 100 gas
  • 回退的 SELFDESTRUCT (5,000 或 25,000 gas) 应该被重新定价为 100 gas

此外,似乎只有在返回的 bytecode 不为空时,才有条件地对 CREATE 和 CREATE2 操作收取 32,000 的固定价格是公平的。

规范

对于每个调用帧,跟踪 revert_gas_refund,初始值为 0。

修改 revert_gas_refund 的操作集合是:

  • SSTORE
  • LOG0, LOG1, LOG2, LOG3, LOG4
  • CALL
  • CREATE, CREATE2
  • SELFDESTRUCT

它们按如下方式增加 revert_gas_refund

call.revert_gas_refund += operation.gas - WARM_STORAGE_READ_COST

在回退的情况下,让我们使用这个值来代替直接擦除 gas_refund

if (call.reverted) {
    // 现有的行为
    tx.gas_refund -= call.gas_refund;
    
    // 根据 EIP-3978 添加到现有的新行为
    tx.gas_refund += call.revert_gas_refund;
}

理由

Gas 应该反映使用的成本。 回退成本反映了执行期间的访问成本,但不反映修改的成本。

向后兼容性

没有已知的向后不兼容性。

测试用例

待定

参考实现

待定

安全注意事项

待定

版权

CC0 下放弃版权及相关权利。

Citation

Please cite this document as:

Anton Bukov (@k06a), Mikhail Melnik (@ZumZoom), "EIP-3978: 回退时的 Gas 退款 [DRAFT]," Ethereum Improvement Proposals, no. 3978, September 2021. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-3978.