新闻加密货币以太坊推迟Hoodi测试网分叉 Glamsterdam Gas重新定价打破合约假设

以太坊推迟Hoodi测试网分叉 Glamsterdam Gas重新定价打破合约假设

作者: Coindoo·

要点速览

  • •在ChainSecurity指出的问题解决之前,核心开发者已推迟Glamsterdam升级的Hoodi测试网分叉,新日期尚未公布。
  • •EIP-8037和EIP-8038大幅提高与状态相关的Gas成本,包括将全新存储槽写入从22,100 gas提升至110,020 gas,代码部署从每字节200提升至1,530 gas。
  • •失败的EIP-7702委托交易可能公开仍然有效的授权,如果委托合约允许任何人调用其setup函数,攻击者可能夺取账户所有权。
  • •分叉前固定的Gas数额可能变得不足,今天能在65,000 gas内完成的转账可能需要超过150,000,最常见于向首次接收者发送时。
  • •基金会将重新定价定位为进一步上调Gas上限的前提,其性能目标支持基础吞吐量提升约三倍,即将召开的开发者会议仍可能调整任一EIP。
以太坊推迟Hoodi测试网分叉 Glamsterdam Gas重新定价打破合约假设

以太坊基金会开发者Marius van der Wijden在11月6日的更新中表示,在安全公司ChainSecurity指出的问题解决之前,核心开发者不会对Hoodi测试网进行分叉。Hoodi是以太坊在协议变更进入主网之前进行演练的公共测试网络。他呼吁合约开发者和审计人员对照即将到来的Glamsterdam升级所打破的八项Gas不变量检查自己的项目。Gas是以太坊为交易执行的每一项操作定价的单位,因此当这些价格发生变化时,按旧数值编写的代码可能表现出不同行为,即使代码本身没有任何改动。

在本文语境中,不变量是指代码视为始终成立的规则,例如"固定的Gas预算足以完成这次调用"或"已上链的委托已经生效"。基金会的不变量仓库列出了在Glamsterdam下将发生变化的八项假设,并表示目前大多数发现涉及其中两项。

两项提案重塑Gas成本

两项提案推动了这一变化。EIP-8037提高了创建新状态的成本——包括新账户、存储槽和已部署代码——并将其与普通执行分开计量。EIP-8038提高了读取和更新已有状态的成本。按照该仓库所测试的规范,写入全新存储槽的成本从22,100 gas升至110,020,更新已访问的热存储槽从2,900升至10,100,部署代码从每字节200 gas升至1,530。如果规范发生变化,这些数字也会随之调整。

Glamsterdam测试暂停之前,ChainSecurity于10月13日发布了审查报告,此前已有报道。该仓库在基金会自身对Sourcify(一个公开的合约源代码注册平台)上已验证合约进行扫描的基础上扩展了这些发现,并涵盖了读取交易回执等链下场景。

已上链的交易不再能证明委托已生效

EIP-7702允许普通以太坊账户通过签署指向委托合约的授权来运行智能合约代码。该机制随2025年的Pectra升级上线,是各钱包此后陆续推出智能账户功能的基础。授权设计上只能使用一次。在Glamsterdam之前,其全部成本是预先收取的,因此无法支付该成本的交易是无效的,不会进入区块。如果交易已上链,则说明委托已生效。

该仓库的INV-8条目解释了EIP-8037带来的变化。现在部分成本取决于账户的状态,并且只在处理授权时收取。从空账户进行委托需要235,606 gas,而此前为25,000。按旧数值预留预算的交易可能被接受,却在应用授权过程中耗尽Gas,并以失败状态进入区块。委托被回滚,账户nonce的增加也随之回滚——nonce是标记授权已被使用的计数器。然而,已签署的授权此时已公开且仍然有效。

就其本身而言,这只是让钱包处于未配置状态,而非被攻破。危险在于当委托合约允许任何人调用其setup函数时。攻击者可以在自己的交易中重新提交暴露的授权,先调用setup并将自己设为账户的所有者。在公共内存池中抢跑授权原本就是可能的。该仓库指出,失败交易本身现在就会公开一个有效授权,因此私下路由它无法提供保护。该模式已附带示例代码进行记录,未点名任何受影响的钱包。

实际调整落在钱包、中继器和索引器身上。该仓库建议在委托交易之后检查账户的代码和nonce,而不是信任交易回执。任何失败的授权都应视为已暴露并加以取消,方式包括推进账户nonce,或重新委托到安全的合约。一项将在最坏情况下预先收取成本的规范修改已被提出但未被采纳,开发者被告知应按现有行为继续不变来构建系统。

Gas预算往往存在于合约之外

范围最广的条目INV-4涵盖分叉前固定的任何Gas数额。无论它写在何处——合约代码、配置值、签名消息或链下软件——现在都可能不足。最后一类包括中继器(代表用户提交交易的服务),以及Keeper和交易所提现系统。

首次接收者是最常见的触发场景。向余额为零的地址发送代币会创建新的余额槽,向空地址发送ETH会创建新账户,而EIP-8037对两者的定价都远高于从前。根据该仓库,今天能在65,000 gas内完成的转账可能需要超过150,000。

固定数值所在的位置决定了缺口有多严重。在链下软件中,整笔交易会回滚,可以附加更多Gas重新发送。在合约、其配置或签名消息中,只有内部调用失败。如果外层合约捕获了该失败,结果往往是最终性的:消息被记录为失败、回调被跳过或奖励被错误记账。其中一些数值完全无法修改,包括分叉前签署的多签交易、已签署的元交易以及已在传输中的跨链消息。

INV-7将同样的问题扩展到预留的Gas上。Solidity的transfer和send函数传递固定的2,300 gas,但接收合约如果写入新的存储槽,现在需要超过110,000。智能钱包、支付分拆合约以及在其receive函数中包含逻辑的金库是显而易见的受影响对象。

以往会回滚的失败路径现在可以执行完成

ChainSecurity 10月13日的分析解释了为什么某些通过了早期审计的保护机制可能不再起作用。合约经常捕获失败的外部调用,以便记录失败、跳过某一项或尝试回退路径。当有人故意提供过少的Gas时,这就变得危险——这种攻击被称为Gas不足干扰(insufficient gas griefing)——因为本应可重试的操作会被标记为永久失败。

合约通常以两种方式防范这一点。一些合约检查调用后剩余多少Gas。另一些则依赖失败处理程序的消耗高到无法完成。Glamsterdam削弱了这两种方式。EIP-8037为Gas上限超过16,777,216的交易提供了一个单独的存储成本储备池,通常的gasleft()检查看不到它。回滚调用或清除刚写入的存储槽也可能返还已消耗的Gas。用ChainSecurity的话说,"即使合约代码不变,以前会回滚的失败路径现在也可以执行完成。"

该公司现在建议不要根据调用后剩余的Gas来推断失败原因。其首选方法是在可能的情况下让整个操作回滚,或保留恢复路径,而不是基于剩余Gas做出不可逆转的决定。

早期审计本身无法弥补这一差距,因为它是根据当时生效的Gas规则来评判代码的。基金会在内部审计之外还聘请了ChainSecurity和Dedaub,但其11月6日的帖子承认无法审查每一个项目,尤其是链下代码。设计选择也会影响修复方式:作为可调整配置存储的Gas上限可以直接调高,而硬编码为固定常量的Gas上限可能只剩下重新部署和迁移这一条路。

以太坊为何坚持推进重新定价

基金会支持这一变化的理由基于定价的准确性。其在8月发布的指引中表示,状态操作的Gas价格上次调整是在2021年的Berlin分叉,该分叉确立了目前读取状态的冷热定价机制。此后以太坊的状态——节点跟踪的账户、余额和合约存储的持续记录——显著增长,近期的Gas上限提升也加快了这一增长。帖子称,重新定价是进一步上调Gas上限的前提,并表示新的定价表源自一个支持基础吞吐量提升约三倍的性能目标。

同一帖子报告称,按新价格回放历史主网交易后,绝大多数交易结果保持不变,且大多数被标记的问题可以通过提高Gas上限解决。它告知普通用户无需采取任何行动,因为更新后的钱包和基础设施会处理这一变化。11月的发现使这最后一句的分量更重。现在应对这一变化包括在委托失败后检查账户状态,以及为首次接收者调整中继器预算——旧Gas规则从未要求过这些工作。

下一次核心开发者会议将决定什么

根据该仓库,基金会正在下一次全核心开发者电话会议(以太坊协议变更达成一致的常设论坛)之前征集反馈。视反馈情况而定,它可能对EIP-8037和EIP-8038稍作修改,或维持原样。在问题解决之前,Hoodi保持不分叉状态,11月6日的帖子没有给出新的日期。同一帖子称,Glamsterdam之后计划的升级Hegota的工作仍在并行推进。

Hoodi分叉之前:谁该检查什么

  • **合约团队:**将地址粘贴到基金会的受影响合约查询工具中,然后审查任何硬编码Gas数值或基于剩余Gas进行分支判断的代码,无论是否被列入名单。
  • **钱包和RPC提供商:**为新定价表更新Gas估算。基金会警告,缓存的Gas常量会低估成本并导致交易失败。
  • **中继器、Keeper和打包器:**将上限设为可调整,并在新规则下留出余量重新估算,在储备池阈值两侧分别测试交易。
  • **审计人员:**该仓库包含使用AI编码代理运行其检查的说明,代码和结果均保留在本地。

值得关注的信号包括:基金会博客上公布的Hoodi分叉日期、任一EIP规范的任何修订,以及受影响项目确认修复。基金会要求团队将问题私下报告至glamsterdam@ethereum.org,而不是在公开议题中提交,以便在细节扩散之前修复问题。

本文最初发表于Coindoo。