Alert Source Discuss
🚧 Stagnant Standards Track: Core

EIP-3403: 部分移除退款

Authors Vitalik Buterin (@vbuterin), Martin Swende (@holiman)
Created 2021-03-16
Discussion Link https://ethereum-magicians.org/t/eip-3298-removal-of-refunds/5430

简述

移除 SELFDESTRUCT 的 gas 退款,并将 SSTORE 的 gas 退款限制在一种特定情况下。

动机

最初引入 SSTORE 和 SELFDESTRUCT 的 gas 退款是为了激励应用程序开发者编写实践“良好状态卫生”的应用程序,清除不再需要的存储槽和合约。然而,它们并没有被广泛用于此,并且不良的状态卫生仍然是常态。现在人们普遍认为,解决状态增长的唯一方法是某种形式的无状态化或状态过期,如果实现了这样的解决方案,那么废弃的存储槽和合约将开始被自动忽略。

此外,gas 退款还有多个有害后果:

  • 退款催生了 GasToken。GasToken 在将 gas 空间从低费用时期转移到高费用时期方面具有优势,但它也对网络具有不利影响,尤其是在加剧状态大小(因为状态槽实际上被用作“电池”来节省 gas)和低效地阻塞区块链 gas 使用方面。
  • 退款增加了区块大小的差异。区块中实际消耗的 gas 的理论最大量几乎是纸面 gas 限制的两倍(因为退款为区块中的后续交易增加了 gas 空间,尽管退款上限为交易已用 gas 的 50%)。这并不是致命的,但仍然是不受欢迎的,特别是考虑到退款可以用于维持 2 倍的使用峰值,比 EIP 1559 持续的时间更长。

互斥锁用例

实现互斥锁有两种典型方法:“0-1-0”和“1-2-1”。让我们看看它们有何不同

  • ‘0-1-0’:
    • Istanbul: 1612
    • Berlin: 212
    • NoRefund: 20112
    • EIP-3403: 1112
  • ‘1-2-1’:
    • Istanbul: 1612
    • Berlin: 212
    • NoRefund: 3012
    • EIP-3403: 3012

注意:实际上,永远不会有负的 gas 成本,因为退款上限为 0.5 * gasUsed。 但是,这些表显示了负值,因为更实际的情况可能会将额外的 gas 花费在其他操作上。’

规范

参数

Constant Value
FORK_BLOCK TBD
SSTORE_REFUND_GAS 19000

对于 block.number >= FORK_BLOCK 的区块,适用以下更改。

  1. 移除 SELFDESTRUCT 退款。
  2. 移除所有情况下的 SSTORE 退款,但一种特定情况除外:如果存储槽的_新值_和_原始值_都等于 0,但_当前值_不等于 0(这些术语的定义与 EIP-1283 中的定义相同),则退还 SSTORE_REFUND_GAS gas。

理由

new = original = 0 != current 情况下保留退款,可确保一些值得优惠 gas 成本待遇的关键用例继续获得优惠 gas 成本待遇,特别是:

  • 防重入锁(通常在子调用开始之前从 0 翻转到 1,然后在子调用结束时翻转回 0)
  • ERC20 批准和发送(“批准值”在批准 token 转移时从零变为非零,然后在 token 转移处理时变回零)

它还保留了 EIP 3298 的两个关键目标:

  1. Gas token 继续不可行,因为每次 19000 的退款只有在同一交易中早些时候因将该存储槽从零翻转为非零而支付了 19000 额外 gas 的情况下才有可能,因此您无法清除某些存储槽并使用节省的 gas 来填充其他存储槽。
  2. _执行花费_的 gas 总量上限为 gas 限制。每次将存储槽从非零 -> 零翻转的 19000 退款只有在同一交易中早先为将该槽从零 -> 非零翻转而支付的 19000 额外 gas 的情况下才有可能;为存储写入和扩展支付的 gas 都被恢复了,因此实际上不需要将其应用于 Merkle 树。因此,这种额外的 gas 不会增加风险。

向后兼容性

退款目前仅在交易执行_之后_应用,因此它们不会影响执行期间任何特定调用帧可用的 gas 量。因此,移除它们不会破坏任何代码的执行能力,但会使一些应用程序在经济上不可行。

特别是 Gas token 将变得毫无价值。DeFi 套利机器人今天经常使用已建立的 gas token 方案或自定义替代方案来降低链上成本,它们将受益于重写其代码以删除对这些不再起作用的 gas 存储机制的调用。

测试用例

2929 Gas 成本

请注意,“热”槽和“冷”槽之间存在差异。下表显示了 EIP-2929 中的值,假设所有已触及的存储槽都已经是“热”的(差异是一次性成本为 2100 gas)。

Code Used Gas Refund Original 1st 2nd 3rd Effective gas (after refund)
0x60006000556000600055 212 0 0 0 0   212
0x60006000556001600055 20112 0 0 0 1   20112
0x60016000556000600055 20112 19900 0 1 0   212
0x60016000556002600055 20112 0 0 1 2   20112
0x60016000556001600055 20112 0 0 1 1   20112
0x60006000556000600055 3012 15000 1 0 0   -11988
0x60006000556001600055 3012 2800 1 0 1   212
0x60006000556002600055 3012 0 1 0 2   3012
0x60026000556000600055 3012 15000 1 2 0   -11988
0x60026000556003600055 3012 0 1 2 3   3012
0x60026000556001600055 3012 2800 1 2 1   212
0x60026000556002600055 3012 0 1 2 2   3012
0x60016000556000600055 3012 15000 1 1 0   -11988
0x60016000556002600055 3012 0 1 1 2   3012
0x60016000556001600055 212 0 1 1 1   212
0x600160005560006000556001600055 40118 19900 0 1 0 1 20218
0x600060005560016000556000600055 5918 17800 1 0 1 0 -11882

具有 EIP-3403 部分退款

如果按照此处的规定部分移除退款,这将是比较表。此表还假设已触及的存储槽已经是“热”的

Code Used Gas Refund Original 1st 2nd 3rd Effective gas (after refund)
0x60006000556000600055 212 0 0 0 0   212
0x60006000556001600055 20112 0 0 0 1   20112
0x60016000556000600055 20112 19000 0 1 0   1112
0x60016000556002600055 20112 0 0 1 2   20112
0x60016000556001600055 20112 0 0 1 1   20112
0x60006000556000600055 3012 0 1 0 0   3012
0x60006000556001600055 3012 0 1 0 1   3012
0x60006000556002600055 3012 0 1 0 2   3012
0x60026000556000600055 3012 0 1 2 0   3012
0x60026000556003600055 3012 0 1 2 3   3012
0x60026000556001600055 3012 0 1 2 1   3012
0x60026000556002600055 3012 0 1 2 2   3012
0x60016000556000600055 3012 0 1 1 0   3012
0x60016000556002600055 3012 0 1 1 2   3012
0x60016000556001600055 212 0 1 1 1   212
0x600160005560006000556001600055 40118 19000 0 1 0 1 21118
0x600060005560016000556000600055 5918 0 1 0 1 0 5918

安全考虑

退款对交易执行不可见,因此这不应对交易执行逻辑产生任何影响。

如果我们在不计算后来重置为零的从零到非零的 SSTORE 的情况下,可以在区块中花费在执行上的 gas 最大量限制为 gas 限制。不计算这些是可以的,因为如果这样的 SSTORE 被重置,则存储不会扩展,并且客户端不需要实际调整 Merke 树;gas 消耗被退还,但客户端通常处理这些操作码所需的工作也被取消了。客户端应确保在 new_value = original_value 时不进行存储写入;自以太坊开始以来,这是一种谨慎的优化,但现在变得更加重要。

版权

通过 CC0 放弃版权及相关权利。

Citation

Please cite this document as:

Vitalik Buterin (@vbuterin), Martin Swende (@holiman), "EIP-3403: 部分移除退款 [DRAFT]," Ethereum Improvement Proposals, no. 3403, March 2021. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-3403.