状态树清除 (保持不变性的替代方案)

该文本详细说明了以太坊 Spurious Dragon 硬分叉的规范,主要围绕账户状态变化和 Gas 费用调整。它规定了账户创建时 nonce 的递增规则、非零价值转移对非存在账户的 Gas 费用收取,以及“空账户”和“死亡账户”的处理逻辑,包括何时账户会变为非存在状态。还提到了一个共识 bug 及其修复。

硬分叉

Spurious Dragon

参数

  • FORK_BLKNUM: 2,675,000
  • CHAIN_ID: 1 (主网)

规范

a. 账户创建交易和 CREATE 操作在初始化代码执行之前,递增nonce,使其超出正常起始值 (对于普通网络,这仅为 1,但默认起始 nonce 非零的测试网会不同)。

b. 尽管 CALLSUICIDE 在目标不存在时会收取 25,000 gas,但现在只有当操作转移大于零的值且目标账户处于 dead 状态时,才收取费用。

c. 任何账户都不能从不存在状态改变状态到存在但empty状态。如果操作会导致这种情况,则该账户应保持不存在。

d. 在交易结束时,任何被该交易执行触及的、现在处于empty状态的账户,应转变为不存在(即被删除)。

其中:

当账户参与任何可能改变状态的操作时,即被视为触及。这包括但不限于作为零值转移的接收方。

当账户没有代码nonce 为零余额为零时,即被视为empty

当账户不存在或处于empty状态时,即被视为dead

在交易结束时指紧随 suicide 列表执行之后,在确定用于填充收据的 state trie root 之前。

账户改变状态时:

  • 它是 SUICIDE 操作的目标或退款方,涉及零或更多值;
  • 它是 CALL 操作或消息调用交易的来源或目标,转移零或更多值;
  • 它是 CREATE 操作或合约创建交易的来源或创建方,赋予零或更多值;
  • 作为区块作者(“矿工”),它是区块奖励或交易费用的接收方,涉及零或更多值。

注意

在当前的 Ethereum 协议中,需要注意的是,很少有状态变更最终会导致在交易执行后账户为空。实际上,目前只有四种情况需要实现跟踪:

  • 通过 CALL 向空账户转移零值;
  • 通过 SUICIDE 向空账户转移零值;
  • 通过消息调用交易向空账户转移零值;
  • 通过零gas费率费用转移向空账户转移零值。

原理

与 #158 相同,只是避免了一些边缘情况,因为我们没有破坏不变量:

  • 账户在交易执行过程中,不能从有代码和存储变为没有代码和存储; [已更正]
  • 新创建的账户在部署之前不能被删除。

CREATE 避免 nonce 为零,以避免 CREATEd 账户在其创建过程中途被回收的任何奇怪之处。

附录 (2017-08-15)

2016年11月24日,由于两种实现方案在状态回滚的情况下行为不同,导致了一个共识 bug。[3] 规范经过修订,澄清了当状态回滚时,空账户删除也会回滚。

参考资料

  1. EIP-158 问题与讨论:https://github.com/ethereum/EIPs/issues/158
  2. EIP-161 问题与讨论:https://github.com/ethereum/EIPs/issues/161
  3. https://blog.ethereum.org/2016/11/25/security-alert-11242016-consensus-bug-geth-v1-4-19-v1-5-2/

    详情:Geth 未能回滚空账户删除,当导致空账户删除的交易以 out-of-gas 异常结束时。Parity 中发现了另一个问题,即 Parity 客户端在涉及对预编译合约的 out-of-gas 调用时,在一个更有限的上下文中错误地未能回滚空账户删除;新的 Geth 行为与 Parity 匹配,并且在大约一周后状态清理过程完成后,空账户将不再是普遍关注的问题。

  • 原文链接: github.com/nerolation/EI...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Nerolation
Nerolation
江湖只有他的大名,没有他的介绍。