原文来源:salus security
长话短说:坎昆升级临近,本次升级主要包含六个 EIP 提出的执行层变更,EIP-1153、EIP-4788、EIP-4844、EIP-5656、EIP-6780 和 EIP-7516。EIP-4844 是本次升级的主角,旨在提升以太坊的可扩展性,为 L2 降低交易成本、提升交易速度。坎昆升级已分别于 1 月 17 日、1 月 30 日、2 月 7 日在以太坊 Goerli、Sepolia 和 Holesky 测试网完成升级,并计划在 3 月 13 日在以太坊主网上激活。在升级前,Salus 整理了此次升级的重要安全注意事项,供开发者自行检查。
EIP-1153 引入了临时存储操作码,这些操作码用于操作状态,其行为与存储几乎相同,但每笔交易结束后临时存储将被丢弃。这意味着,临时存储不会从存储中反序列化值,也不会序列化值到存储,因此,由于不需要磁盘访问,临时存储成本更低。通过两个新的操作码 TLOAD 和 TSTORE(其中「T」代表「临时」),智能合约可以访问临时存储。这项提议旨在为 Ethereum 的交易执行中的多个嵌套执行框架之间的通信提供一个专用且高效的解决方案。
EIP-4788 旨在将信标链区块的哈希树根暴露于 EVM 中,以允许在智能合约内部访问这些根。这样做可以无需信任地访问共识层状态,支持 staking pools、restaking 结构、智能合约桥、MEV 缓解等多种用例。该提案通过一个智能合约存储这些根,并使用环形缓冲区来限制存储消耗,确保每个执行区块只需常量空间即可表示这些信息。
EIP-4844 介绍了一种新的事务格式,称为"分片 Blob 事务",旨在以简单、向前兼容的方式扩展以太坊的数据可用性。这项提案通过引入包含大量数据的"blob-carrying transactions",这些数据不能被 EVM 执行访问,但可以访问其承诺。这种格式与将来全分片使用的格式完全兼容,为滚动式扩容提供了临时但显著的缓解。
EIP-5656 引入了一种新的 EVM 指令 MCOPY,用于高效复制内存区域。这项提案旨在降低在 EVM 上执行内存复制操作的开销,通过 MCOPY 指令直接实现内存之间的数据复制。MCOPY 允许源地址和目标地址重叠,其设计考虑到了向后兼容性,并旨在提升包括数据结构构建、内存对象的高效访问和复制在内的多种场景的执行效率。
EIP-6780 修改了 SELFDESTRUCT 操作码的功能。在这个提案中,SELFDESTRUCT 只会在与合约创建相同的交易中删除账户和传输所有以太币,除此之外,执行 SELFDESTRUCT 时,合约将不会被删除,只是将所有以太币转移到指定目标。这一改变是为了适应未来 Verkle 树的使用,旨在简化 EVM 实现,减少状态变化的复杂性,同时保留 SELFDESTRUCT 的部分常用场景。
EIP-7516 引入了一个新的 EVM 指令 BLOBBASEFEE,用于返回当前区块执行中的 blob 基础费用值。这个指令与 EIP-3198 中的 BASEFEE 操作码相似,不同之处在于它返回的是根据 EIP-4844 定义的 blob 基础费用。这个功能使得合约可以编程地考虑 blob 数据的气体价格,例如,允许 rollup 合约无需信任地计算 blob 数据使用成本,或者基于此实现 blob 气体期货,以平滑 blob 数据成本。
智能合约开发人员应在使用前了解瞬态存储变量的生命周期。由于临时存储会在交易结束时自动清除,因此智能合约开发人员可能会试图避免在调用过程中清除插槽以节省 Gas。然而,这可能会阻止在同一事务中与合约进行进一步的交互(例如,在重入锁的情况下)或导致其他错误,因此智能合约开发人员应小心,仅在临时存储槽被保留时保留非零值。旨在供同一事务中的未来调用使用。SSTORE 否则,这些操作码的行为与和完全相同 SLOAD,因此所有常见的安全注意事项都适用,特别是在重入风险方面。
智能合约开发人员也可能会尝试使用瞬态存储作为内存映射的替代方案。他们应该意识到,当调用返回或恢复时,临时存储不会像内存一样被丢弃,并且应该在这些用例中优先选择内存,以免在同一事务中的重入时产生意外的行为。内存上的瞬态存储成本必然很高,这应该已经阻止了这种使用模式。内存中映射的大多数用法可以通过按键排序的条目列表来更好地实现,并且智能合约中很少需要内存中映射(即作者知道生产中没有已知的用例)。
此 EIP 使每个信标块的带宽要求最多增加约 0.75 MB。这比当今区块的理论最大大小(30M Gas / 每个 calldata 字节 16 Gas = 1.875M 字节)大 40%,因此它不会大幅增加最坏情况下的带宽。合并后,区块时间是静态的,而不是不可预测的泊松分布,为大区块的传播提供了保证的时间段。
即使调用数据有限,此 EIP 的持续负载也比可降低调用数据成本的替代方案低得多,因为不需要将 Blob 存储与执行负载一样长的时间。这使得实现这些 blob 必须保留至少一段时间的策略成为可能。选择的具体值是 MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS 纪元,约为 18 天,与建议的(但尚未实施)执行有效负载历史的一年轮换时间相比,延迟要短得多。
客户端应注意其实现不使用中间缓冲区(例如 C stdlibmemmove 函数不使用中间缓冲区),因为这是潜在的拒绝服务 (DoS) 向量。大多数用于移动字节的语言内置函数/标准库函数在这里都具有正确的性能特征。
除此之外,对拒绝服务 (DoS) 和内存耗尽攻击的分析与其他接触内存的操作码相同,因为内存扩展遵循相同的定价规则。
以下应用程序 SELFDESTRUCT 将被破坏,并且以这种方式使用它的应用程序不再安全:
WhereCREATE2 用于在同一位置重新部署合约,以使合约可升级。不再支持此功能,应改用 ERC-2535 或其他类型的代理合约。
如果合约依赖于通过以 SELFDESTRUCT 合约作为受益人燃烧以太币,则合约不是在同一交易中创建的。
设想使用操作码 TLOAD 和 TSTORE 的两种场景:
· 被调用合约使用该操作码
· 发起调用合约使用该操作码
风险 1:
相比于传统的 SSTORE 和 SLOAD,新增的瞬态存储主要改变了数据的存储期限,tstore 存储的数据通过 tload 进行读取,在一笔交易执行结束后该数据将会被释放,而不是同 sstore 一样写入合约被永久性的记录。开发者在使用该操作码时应该认清该操作码的特性,以免错误的使用导致数据不能正确的写入到合约中而造成损失。另外,tstore 的数据属于私有变量,仅合约本身可以访问。如果想要外部使用该数据只能通过参数的形式进行传递或暂存到一个 public stroage 变量中。
风险 2:
另一个潜在风险是,如果智能合约开发人员不正确管理瞬态存储变量的生命周期,可能导致数据在不应该的时间被清除或错误地保留。如果合约期望在事务的后续调用中使用存储在瞬态存储中的数据,但未能适当地管理这些数据的生命周期,可能会在不同调用之间错误地共享或丢失数据,从而导致逻辑错误或安全漏洞。考虑到类似于 Token 项目的 balance 或者 allowance 数据未能正确的存储将会导致合约逻辑的错误,造成损失。或在对 owner 地址进行设置时使用了该操作码将会导致特权地址不能正确的被记录从而丢失对合约重要参数的修改。
考虑一个智能合约,该合约使用瞬态存储来临时记录一个加密货币交易平台上的交易价格。该合约在每笔交易完成时更新价格,并允许用户在短时间内查询最新价格。然而,如果合约设计没有考虑到瞬态存储在交易结束时被自动清除的特性,那么在一笔交易结束后到下一笔交易开始之前的这段时间内,用户可能会得到一个错误或过时的价格。这不仅可能导致用户做出基于错误信息的决策,还可能被恶意利用,影响平台的信誉和用户的资产安全。
该提案改变了之前 selfdestruct 操作码的行为,不销毁合约,仅转移 token,仅与自毁同一交易中创建的合约才会被销毁。这个 EIP 的影响相对较大。
用 create2 在同一地址重新部署合约,以使合合约升级。不再支持此功能,应改用 ERC-2535 或其他类型的代理合约。(这可能会影响到使用 create2 实现可升级合约的链上合约的安全性)
智能合约中的 SELFDESTRUCT 操作允许合约销毁,并将合约余额发送给指定的目标地址。在这种情况下,合约使用 SELFDESTRUCT 销毁以太币,并将销毁的以太币发送给了合约。但是该合约仅能是在同一笔交易中创建的合约(同一笔交易中由本合约或其他合约创建的合约)。否则将仅转账以太而不销毁合约(例如自毁且受益者为自毁合约,这将会不产生任何改变)。这将会影响一切依赖于 selfdestruct 进行提款或其他操作的合约。
一种类似于 1inch CHI Token 的 Gas Token 的工作原理:保持一个偏移量,始终在此偏移量处执行 CREATE2 或 SELFDESTRUCT。在此更新之后,如果当前偏移量的合约尚未正确自毁,则之后的 CREATE2 将不能成功的部署合约。
该提案实施并不能导致直接对合约进行攻击,但会损害原有已部署的依赖 selfdestruct 操作的合约的正常逻辑(仅依赖自毁进行资金转移的合约不受到影响,如果后续操作必须要求自毁的合约被删除,则受到影响),导致合约非预期工作,仅对合约以及用户而言,可能导致合约的罢工,损失资金等危害 (例如原本利用 create2 在原地址部署新合约,自毁原合约进行升级的合约,不再能够成功部署)。长远来看,修改某项操作码的功能可能会带来中心化的问题。
例如现有一个金库合约 vault 进行更新:
● create2 临时存储合约用来临时储备 vault 的资金
● 自毁 vault 合约,资金转账到临时合约(仅转移了资金而没有销毁合约)
● 在原地址 create2 新的 vault 合约(失败,因为原有 vault 合约没有被销毁)
● 自毁临时合约将资金还给 vault(资金损失,vault 合约没有被创建)
坎昆升级将进一步增强以太坊的竞争优势。但此次升级对核心智能合约层的改动带来了风险,这会影响现有的 DApps 的安全运行。在进行智能合约开发的过程中,这些改变以及可能引发的风险同样需要被高度关注。您可以与Salus联系获得风险检查或审计支持,也可以通过进一步阅读相关内容以了解变化。
Cancun Network Upgrade Specification
本文来自投稿,不代表 BlockBeats 观点。
欢迎加入律动 BlockBeats 官方社群:
Telegram 订阅群:https://t.me/theblockbeats
Telegram 交流群:https://t.me/BlockBeats_App
Twitter 官方账号:https://twitter.com/BlockBeatsAsia