Alert Source Discuss
Standards Track: Core

EIP-150: I/O密集型操作的 Gas 成本变更

Authors Vitalik Buterin (@vbuterin)
Created 2016-09-24

Meta reference

Tangerine Whistle.

Parameters

FORK_BLKNUM CHAIN_ID CHAIN_NAME
2,463,000 1 Main net

Specification

如果 block.number >= FORK_BLKNUM,那么:

  • 将 EXTCODESIZE 的 gas 成本增加到 700(从 20 增加)。
  • 将 EXTCODECOPY 的基本 gas 成本增加到 700(从 20 增加)。
  • 将 BALANCE 的 gas 成本增加到 400(从 20 增加)。
  • 将 SLOAD 的 gas 成本增加到 200(从 50 增加)。
  • 将 CALL, DELEGATECALL, CALLCODE 的 gas 成本增加到 700(从 40 增加)。
  • 将 SELFDESTRUCT 的 gas 成本增加到 5000(从 0 增加)。
  • 如果 SELFDESTRUCT 命中新创建的帐户,它将触发额外的 gas 成本 25000(类似于 CALL)。
  • 将建议的 gas 限制目标增加到 550 万。
  • 将 “除了 1/64 之外的所有” N 定义为 N - floor(N / 64)
  • 如果一个调用请求的 gas 超过了最大允许量(即,在减去调用和内存扩展的 gas 成本后,父级中剩余 gas 的总量),则不要返回 OOG 错误;相反,如果一个调用请求的 gas 超过了最大允许量的 “除了 1/64 之外的所有”,则使用最大允许量的 “除了 1/64 之外的所有” 的 gas 进行调用(这相当于 EIP-901 加上 EIP-1142 的一个版本)。CREATE 仅向子调用提供父 gas 的 “除了 1/64 之外的所有”。

也就是说,替换:

        extra_gas = (not ext.account_exists(to)) * opcodes.GCALLNEWACCOUNT + \
            (value > 0) * opcodes.GCALLVALUETRANSFER
        if compustate.gas < gas + extra_gas:
            return vm_exception('OUT OF GAS', needed=gas+extra_gas)
        submsg_gas = gas + opcodes.GSTIPEND * (value > 0)

用:

        def max_call_gas(gas):
          return gas - (gas // 64)

        extra_gas = (not ext.account_exists(to)) * opcodes.GCALLNEWACCOUNT + \
            (value > 0) * opcodes.GCALLVALUETRANSFER
        if compustate.gas < extra_gas:
            return vm_exception('OUT OF GAS', needed=extra_gas)
        if compustate.gas < gas + extra_gas:
            gas = min(gas, max_call_gas(compustate.gas - extra_gas))
        submsg_gas = gas + opcodes.GSTIPEND * (value > 0)

Rationale

最近的拒绝服务攻击表明,读取状态树的操作码相对于其他操作码而言,定价过低。已经做出、正在做出和可以做出一些软件更改,以减轻这种情况;然而,事实仍然是,这些操作码将成为通过交易垃圾邮件降低网络性能的最简单已知机制。之所以出现这种担忧,是因为从磁盘读取需要很长时间,并且还会对未来的分片提案构成风险,因为到目前为止在降低网络性能方面最成功的“攻击交易”还需要数十兆字节来提供 Merkle 证明。此 EIP 增加了存储读取操作码的成本,以解决此问题。这些成本源自用于生成 1.0 gas 成本的计算表的更新版本:https://docs.google.com/spreadsheets/d/15wghZr-Z6sRSMdmRmhls9dVXTOpxKy8Y64oy9MvDZEQ/edit#gid=0;这些规则试图将需要读取的数据量限制在 8 MB 以内才能处理区块,并且包括对 SLOAD 的 Merkle 证明的 500 字节估计和对帐户的 1000 字节估计。

此 EIP 旨在简单,并在该表中计算出的成本之上添加 300 gas 的固定惩罚,以解释加载代码的成本(最坏情况下约为 17–21 kb)。

引入 EIP 90 gas 机制是因为如果没有它,所有当前进行调用的合约都将停止工作,因为它们使用诸如 msg.gas - 40 之类的表达式来确定使用多少 gas 进行调用,这是依赖于调用的 gas 成本为 40。此外,引入 EIP 114 是因为,鉴于我们正在使调用的成本更高且更不可预测,因此我们有机会在不增加当前可用保证的额外成本的情况下进行此操作,因此我们还实现了以下好处:用“更软”的基于 gas 的限制取代调用堆栈深度限制,从而消除了调用堆栈深度攻击,使其成为合约开发者必须担心的攻击类型,从而提高了合约编程的安全性。请注意,使用给定的参数,实际的最大调用堆栈深度限制为约 340(从约 1024 降低),从而减轻了任何进一步潜在的二次复杂度 DoS 攻击(依赖于调用)造成的损害。

建议增加 gas 限制,以便为平均合约保留系统的实际每秒交易处理能力。

References

  1. EIP-90, https://github.com/ethereum/EIPs/issues/90
  2. EIP-114, https://github.com/ethereum/EIPs/issues/114

Citation

Please cite this document as:

Vitalik Buterin (@vbuterin), "EIP-150: I/O密集型操作的 Gas 成本变更," Ethereum Improvement Proposals, no. 150, September 2016. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-150.