资讯动态

以太坊 Petersburg 硬分叉元提案(EIP-1716)解读:从 Constantinople 中移除 EIP-1283 的完整技术内幕

发布时间:2026/9/15 18:10:21 来源:尧图企业网站定制
以太坊 Petersburg 硬分叉元提案EIP-1716解读从 Constantinople 中移除 EIP-1283 的完整技术内幕【免费下载链接】EIPsThe Ethereum Improvement Proposal repository项目地址: https://gitcode.com/GitHub_Trending/ei/EIPsPetersburg 是以太坊主网历史上一次极为特殊的网络升级它不引入任何新功能而是在 Constantinople 分叉前最后一刻把其中已通过评审的 EIP-1283SSTORE 净气体计量整体移除以消除一个被发现的严重重入攻击向量。本文以本仓库中的元提案 EIP-1716 为核心结合 EIP-1013Constantinople 元提案、EIP-1283 原始规范及其测试用例以及 EIP-2124 的 forkid 定义完整梳理 Petersburg 的升级内容、各网络激活区块号、与 Constantinople 同时激活时的优先级语义以及 EIP-1283 为何会带来重入攻击风险、新气体计量规则到底如何工作。读完本文你将理解这次史上最短命功能回滚的前因后果并能准确区分 Constantinople 与 Petersburg 两条升级清单的边界。一、Petersburg 是什么一份减法式硬分叉元提案EIPEthereum Improvement Proposal仓库中的元提案Meta 类型 EIP并不定义某个具体的 EVM 指令或协议细节而是把多个独立 EIP 打包形成一次完整的网络升级清单。仓库中的 eip-1716.md 就是 Petersburg 升级的权威定义其 frontmatter 给出了提案的元信息字段值EIP 编号1716标题Hardfork Meta: Petersburg作者Afri Schoedon (5chdn)、Marius van der Wijden (MariusVanDerWijden)类型Meta状态Final创建日期2019-01-21依赖EIP-1013、EIP-1283元提案的requires字段非常关键Petersburg 依赖 Constantinople 元提案EIP-1013与被移除的 EIP-1283这直接说明了它的本质——Petersburg 不是 Constantinople 的后续升级而是针对 Constantinople 的一次修正。用提案原文的话说它是从 Constantinople 中移除 EIP-1283 的硬分叉removes EIP-1283 from Constantinople。从提案摘要Abstract可见Petersburg 的完整语义是本元提案定义了将 EIP-1283 从 Constantinople 中移除的以太坊硬分叉所包含的变更。二、SpecificationPetersburg 的完整升级定义EIP-1716 的 Specification 部分定义了升级代号、别名、各网络激活区块号以及被移除的 EIP 清单这是判断节点/客户端是否进入 Petersburg 状态的权威依据代号CodenamePetersburg别名AliasesSt. Petersfork、Peters Fork、Constantinople Fix——注意 Constantinople Fix 这个别名最直白地说明了它的修复性质被移除的 EIP仅有一项——EIP-1283SSTORE 净气体计量Net gas metering for SSTORE without dirty maps。各网络激活区块号EIP-1716 明确给出了四个网络的激活高度网络激活区块号以太坊主网Mainnet 7_280_000Ropsten 测试网 4_939_394Kovan 测试网 10_255_201Rinkeby 测试网 4_321_234Görli 测试网 0创世即启用值得注意的细节是主网的 Petersburg 激活区块号7_280_000与 ConstantinopleEIP-1013的激活区块号完全相同——两条升级在同一条链的同一个区块上同时生效。这正是 Petersburg 提案中下述优先级语义存在的直接原因。Görli 测试网因在分叉计划确定后才启动因此直接以0号区块起启用 Petersburg等于创世即跳过 EIP-1283。作为旁证仓库中的 eip-6953.mdNetwork Upgrade Activation TriggersInformational 类型在 PoW 时代网络升级激活区块一览表中同样记录Constantinople 与 Petersburg 均在主网区块7280000激活进一步印证了两者在同一高度同时生效的事实。与 Constantinople 同块激活的优先级语义Petersburg 提案用两句话精确定义了它与 Constantinople 共存时的行为规则若 Petersburg 与 Constantinople 在同一个区块激活Petersburg 优先净效果是 EIP-1283被禁用with the net effect of EIP-1283 being disabled若 Petersburg 被定义为早于 Constantinople 的区块号则 Petersburg 分叉本身不产生任何即时效果no immediate effect但当 Constantinople 稍后激活时EIP-1283 应当被禁用。第一条规则正是主网实际发生的情况——7_280_000区块同时触发两条升级节点以 Petersburg 的语义覆盖 Constantinople使 EIP-1283 从未在任一正式网络上生效。第二条规则则是一种防御性设计无论客户端实现中两条分叉的配置顺序如何最终语义都收敛为EIP-1283 不可用。三、为什么必须移除EIP-1283 与重入攻击向量Petersburg 不是一次计划内的正常升级而是一次紧急刹车。提案的 References 部分明确指出移除 EIP-1283 的原因是它带来了一个潜在的重入攻击向量potential reentrancy attack vector该问题由 ChainSecurity 在 2019 年 1 月披露移除决定则是在 2019 年 1 月的 All-Core-Devs 第 53 次电话会议上达成的。要理解这个攻击向量必须回到 EIP-1283 的机制本身。EIP-1283 提出了一种净气体计量net gas metering方案核心思想是SSTORE 的 gas 费用不应只取决于本次写入而应结合存储槽的原始值、当前值与新值三者关系动态计费从而大幅降低同一交易内反复读写存储的成本。它的完整计费规则来自 eip-1283.md Specification如下条件扣除 gas退款操作当前值 新值No-op200无当前值 ≠ 新值且原始值 当前值Fresh且原始值为 020000无当前值 ≠ 新值且原始值 当前值Fresh且原始值非 05000新值为 0 时退款 15000当前值 ≠ 新值且原始值 ≠ 当前值Dirty200见下述细化规则Dirty 状态存储槽已被当前执行上下文修改过下的细化规则为若原始值非 0 且当前值为 0则从退款计数器扣除 15000若新值为 0则增加 15000 退款若新值等于原始值槽被重置原始值为 0 时退款 19800否则退款 4800。这套机制降低了合法场景的 gas 成本但同时也带来了隐患同一存储槽在同一交易内反复写入的边际成本被压低到 200 gas使得攻击者可以在一次交易内以极低代价反复触发存储状态变化与重入结合放大攻击收益。ChainSecurity 披露的重入攻击向量正是利用了这一点——在已部署合约的既有安全假设写入成本高昂被打破后某些重入保护模式如基于 SSTORE 的锁的行为发生变化可能被用于构造攻击。由于这一风险在 Constantinople 原定激活2019 年 2 月底前夕才被确认且涉及已通过社区评审的正式 EIP最终决策不是修改 EIP-1283 本身而是通过 Petersburg 这一反向分叉将其整体剔除。从仓库证据看EIP-1283 的动机部分也印证了其设计目标它致力于为 SSTORE 提供一种对实现更友好的计量方式作为 EIP-1087 与 EIP-1153 的替代让存储变更缓存优化策略不同的客户端都能低成本实现并明确列举了两类受益场景——同一调用帧内的连续存储写入如重入锁、同合约多笔转账以及子调用帧与父调用帧之间无需持久化的信息交换如错误码传递。这些恰恰是后来被重入分析聚焦的敏感场景。四、EIP-1283 的计费细节三个值、三种状态、一张转换图为了让读者对被移除的东西有完整认识这里展开 EIP-1283 的完整模型。它定义了三个关键概念原始值original value当前交易发生回滚reversion时存储槽应恢复到的值当前值current value本次 SSTORE 执行前存储槽的值新值new value本次 SSTORE 执行后存储槽的值。基于三者关系存储槽被划分为三种状态No-op当前值等于新值虚拟机无需任何磁盘写入仅扣 200 gasFresh当前值 ≠ 新值且原始值 当前值——该槽在本执行上下文中尚未被修改或刚被重置回原值按传统方案计费Dirty当前值 ≠ 新值且原始值 ≠ 当前值——该槽已被修改过仅扣 200 gas并动态调整退款计数器。每个存储槽的首次非 No-op 写入必然从 Fresh 开始之后进入 Dirty若 Dirty 槽被重置回原始值则触发退款并回到 Fresh。原始提案用下面这张状态转换图源自仓库 assets/eip-1283/state.png直观展示三种状态间的转移与计费上图为 EIP-1283 提案中的状态转换图左侧为原始值为 0 时的简化情形currentorig0与current!orig两态右侧为原始值非 0 时的完整四态currentorig!0、current!orig、currentorig、current0每条边标注了写入方向0/~0/orig/~orig、扣除的 gas 以及退款金额负值表示从退款计数器扣除。对应的状态转移表原始值为 0 时为新值方向Acurrentorig0Bcurrent≠orig~0非零B20000 gasB200 gas0A200 gasA200 gas19800 退款原始值非 0 时新值方向Xcurrentorig≠0Ycurrent≠origZcurrent0orig回到原值X200 gasX200 gas4800 退款X200 gas-10200 退款~orig、~0Y5000 gasY200 gasY200 gas-15000 退款0Z5000 gas15000 退款Z200 gas15000 退款Z200 gasEIP-1283 还给出了 17 个可直接执行的测试用例基于 chfast 在 ethereum/tests 中的工作其中 15 个覆盖连续两次 SSTORE另 2 个覆盖重置后再写入的三次 SSTORE 场景。例如原始值为 0 时执行0x60016000556000600055先写 1 再写 0消耗 20212 gas、退款 19800原始值为 1 时执行0x60016000556000600055写 0 再写 0消耗 5212 gas、退款 15000。这些用例体现了净计量的典型结果与旧方案相比EIP-1283 在绝大多数场景下 gas 消耗不增反降——这是它当初被选入 Constantinople 的原因也正是攻击向量分析的关注点所在。五、节点如何识别 Petersburgforkid 与分叉块号对于运行节点或研究客户端实现的人来说Petersburg 还有一个重要的工程侧面它构成了 EIP-2124Fork identifier for chain compatibilityforkid 校验的重要锚点。EIP-2124 将分叉标识定义为RLP([FORK_HASH, FORK_NEXT])其中FORK_HASH对创世哈希与已经激活的分叉区块号按升序做 IEEE CRC32 校验和4 字节若多个分叉在同一个区块激活该区块号只参与一次校验FORK_NEXT下一个尚未激活的分叉区块号无后续分叉时为 0。由于 Constantinople 与 Petersburg 都在7280000激活根据同块只计一次的规则两者对FORK_HASH的贡献相同——这解释了为什么在 EIP-2124 的测试套件中主网的 Petersburg 区块如7987396提案编写时点仍沿用与 Constantinople 相同的 forkid 哈希0x668db0af。而 Rinkeby 的 Petersburg 激活块4321234、Ropsten 的4939394则分别对应各自网络 forkid 的Next值如 Ropsten 在 Petersburg 之后下一个分叉块为6485846。EIP-2124 中大量针对本地为 Petersburg、远端为 Byzantium/Constantinople的握手兼容性测试也说明 Petersburg 曾长期是以太坊节点 forkid 校验的核心分叉状态之一。六、Petersburg 的遗产从Constantinople Fix到后来的升级节奏回头看Petersburg 留下了几项值得记录的经验升级清单可以反向修改Meta 类型 EIP 不只用于添加功能也可以用于在最后一刻剔除已评审的 EIPPetersburg 是首个也是最典型的一次同块双分叉的优先级语义需要明确Petersburg 提案中同块激活时 Petersburg 优先的规则为后续分叉冲突处理提供了范式测试网络覆盖完整主网与 Ropsten、Kovan、Rinkeby、Görli 全部给出激活高度且 Görli 以创世块直接启用保证任何环境都不会意外启用 EIP-1283影响持久化到 forkid 体系直到 Istanbul9069000之前Petersburg 都作为主网 forkid 校验中的一个有效状态存在于 EIP-2124 的测试矩阵中。最终EIP-1283 的净气体计量思想并未消失——它被后续提案继承和发展例如 EIP-2200 在 Istanbul 中以修订形式重新引入 SSTORE 净计量但 Petersburg 证明了在攻击向量面前撤回一个 EIP 比修复一个 EIP 有时是更稳妥的工程决策。参考资料仓库内一手文档EIPS/eip-1716.mdPetersburg 硬分叉元提案本文主体EIPS/eip-1013.mdConstantinople 硬分叉元提案Petersburg 的依赖与对照对象EIPS/eip-1283.md被移除的 SSTORE 净气体计量完整规范、状态转换表与 17 个测试用例assets/eip-1283/state.pngEIP-1283 状态转换图EIPS/eip-2124.mdforkid 规范及其中的 Petersburg fork 测试矩阵EIPS/eip-6953.md网络升级激活触发器汇总含 Petersburg 主网7280000记录【免费下载链接】EIPsThe Ethereum Improvement Proposal repository项目地址: https://gitcode.com/GitHub_Trending/ei/EIPs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价