EIP150 - IO 密集型操作的 Gas 成本变化

# 元参考

橘子口哨(Tangerine Whistle)

# 参数

FORK_BLKNUM CHAIN_ID CHAIN_NAME
2,463,000 1 Main net

# 规格

如果 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 命中一个新创建的账户,它会触发额外的 25000 gas 的成本(类似于 CALLs)。
  • 将建议的 gas 限制提高到 550 万。
  • N 的 “1/64以外” 定义为 N - floor(N / 64)
  • 如果一个调用请求的 gas 超过了最大允许量(即减去调用的 gas 成本和内存扩展后剩余的 gas 总量),不返回 OOG 错误;相反,如果调用请求的 gas 超过最大允许量的 1/64,则调用最大允许量的 1/64 以外的 gas (这相当于 EIP-901 (opens new window) 加 EIP-1142 (opens new window))。 CREATE 只向子调用提供父区块 gas 1/64 以外的 gas。

将:

        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)
1
2
3
4
5

替换为:

        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)
1
2
3
4
5
6
7
8
9
10

# 基本原理

最近的 DoS 攻击表明,相对于其他操作码,读取状态树的操作码价格偏低。有些允许被修改的软件已经做了修改或正在做,旨在缓解这种情况。然而,事实仍然是,这种操作码将是通过交易垃圾信息降低网络性能的最简单的已知机制。这种担忧的产生是因为从磁盘上读取需要很长的时间,而且对未来的分片建议也是一种风险,因为迄今为止在降低网络性能方面最成功的“攻击交易”也需要几十兆字节来提供默克尔证明。 这个 EIP 增加了存储读取操作码的成本来解决这个问题。成本来自用于生成 1.0 gas 成本的计算表的更新版本:https://docs.google.com/spreadsheets/d/15wghZr-Z6sRSMdmRmhls9dVXTOpxKy8Y64oy9MvDZEQ/edit#gid=0 ; 这些规则试图将处理一个区块需要读取的数据限制设为 8 MB,并包括估计 500 字节的 SLOAD 默克尔证明和 1000 字节的账户。

这个 EIP 的目的很简单,并在此表中计算的成本之上添加 300 gas 的固定惩罚,以考虑加载代码的成本(在最坏的情况下约为 17-21kb)。

引入 EIP 90 gas 机制是因为如果没有它,所有当前调用的合约都将停止工作,因为它们使用类似的表达式 msg.gas - 40 确定调用需要多少 gas。 此外,引入 EIP 114 是因为我们正在使调用的成本更高、更难预测,我们有机会在不付出额外成本的情况下做到这一点,因此我们也实现了用基于 gas 的“柔和”限制取代调用栈深度限制的好处,从而消除了调用堆栈深度攻击这类合约开发者不得不担心的攻击,提高了合约开发的安全性。 注意,对于给定的参数,实际最大调用堆栈深度被限制大约为 340(从 1024 降到 340),从而减轻了依赖于调用的任何潜在二次方复杂性 DoS 攻击(quadratic-complexity DoS attacks)造成的损失。

建议增加 gas 限制,以保持系统对平均合约的实际每秒处理能力。

# 参考资料

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