ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

EIP-7686 深度解析:线性 EVM 内存限制,为 N Gas 执行建立 N 字节内存硬上限

EIP-7686 深度解析:线性 EVM 内存限制,为 N Gas 执行建立 N 字节内存硬上限 EIP-7686 深度解析线性 EVM 内存限制为 N Gas 执行建立 N 字节内存硬上限【免费下载链接】EIPsThe Ethereum Improvement Proposal repository项目地址: https://gitcode.com/GitHub_Trending/ei/EIPs导读EIP-7686Linear EVM memory limits是提交至以太坊改进提案仓库EIPs的一项 Core 类共识协议提案由 Vitalik Buterin 于 2024 年提出旨在把 EVM 当前复杂的内存计价规则二次方内存扩展费用 EIP-150 的 63/64 子调用规则简化为一套线性模型从而让一笔 N Gas 的交易最多只能消耗 N 字节内存成为可证明的硬性不变量。本文以 EIP-7686 原文为主体结合仓库中 EIP-150、EIP-5656、EIP-2929 与 EIP-8007 等关联文档完整还原其两条核心规范改动内存费用线性化、子调用 gas 上限改造、一条全新硬限制内存字节数不得超过当前执行上下文初始 gas limit并解析其对 EVM 实现尤其是 ZK-SNARK 证明器等受限环境的深层意义。读完本文你将能准确理解该提案的公式推导、与现行规则如 63/64 规则、MCOPY 计价的衔接关系以及它的兼容性风险边界。一、动机现行内存计价规则为何难以计算上界提案的出发点非常明确今天 EVM 的内存定价规则过于复杂导致任何人都很难预先算出一笔给定的 EVM 执行最多会消耗多少内存。复杂度主要来自两个叠加因素二次方内存扩展费用quadratic memory expansion cost内存按 32 字节为一个字word计价费用随字数二次增长63/64 规则EIP-150子调用最多只能获得父上下文中除 1/64 之外的所有 gas这决定了 gas 在调用栈中的分配方式。二次方费用使每多扩一页内存的边际成本不断上升而 63/64 规则又让 gas 在递归调用中被指数级稀释。两者叠加后给定 N gas 的执行到底最多吃多少内存成为一个难以封闭bound的问题EVM 实现方只能做非常保守的假设。值得指出的是63/64 规则并非 EIP-7686 的发明它源自仓库中的 EIP-150Tangerine Whistle 硬分叉。该 EIP 为应对 2016 年的 DoS 攻击而大幅上调了 IO 密集型操作码的 gas 成本并首次定义了N的除一 64 分之一all but one 64th ofN即N - floor(N / 64)这一概念同时用它取代了旧的调用栈深度硬限制把实际最大调用栈深度从约 1024 压到约 340从而消除了调用栈深度攻击这一类威胁。EIP-7686 正是在这一历史规则之上做减法与收口。二、核心设计目标建立N Gas 至多消耗 N 字节内存的紧致上界EIP-7686 的 Abstract 直接给出了提案的最终目标一笔 N gas 的交易最多只能使用 N 字节内存。这个上界不仅是存在而且是**紧致tight**的——原文明确指出存在简单方法让一笔 N-gas 的调用用掉N - O(1)字节的内存也就是说上界在渐近意义下无法再收紧。这一不变量对 EVM 实现有巨大的工程价值。现代 EVM 有大量实现形态除了常规的解释器、JIT 之外还包括受限环境中的实现例如 ZK-SNARK 证明器prover——这类系统要在有限硬件上为整个执行生成证明内存上界可预估意味着内存分配、证明电路规模都可以提前确定从而避免最坏情况下的资源爆炸。该提案通过两条规则共同保障这个不变量规则一硬内存上限当前执行上下文中memory_byte_size一旦严格超过该调用初始 gas limit内存扩展即 revert规则二子调用 gas 上限与内存挂钩子调用可获得的 gas 上限改为gas - max(gas // 64, memory_byte_size)即按内存字节数预留 gas。两条规则配合后递归地看父上下文把内存上限留给内存把 gas 上限留给子调用二者之和被严格约束在初始 gas limit 之内。三、规范细节两处公式改动与一项新硬限制EIP-7686 的 Specification 部分非常简洁只有三处改动全部以可直接落地的伪代码给出。3.1 内存费用从二次方改为线性现行规则原文中的Changememory_costfrommemory_size_word (memory_byte_size 31) / 32 memory_cost (memory_size_word ** 2) / 512 (3 * memory_size_word)新规则Tomemory_size_word (memory_byte_size 31) / 32 memory_cost 3 * memory_size_word两点需要拆解(memory_byte_size 31) / 32是向上取整到 32 字节字的标准写法即ceil(memory_byte_size / 32)这在黄皮书与所有 EVM 实现中都是统一语义旧公式中的(memory_size_word ** 2) / 512即著名的二次方项等价于每 512 字的内存费用翻倍增长也就是内存扩展的边际成本递增新公式将其整体移除只保留线性项3 * memory_size_word即每字 3 gas。3.2 新增硬内存上限不得超过初始 gas limit原文规范原文为Additionally, if a memory expansion would lead tomemory_byte_sizestrictly exceeding the current calls initial gas limit, revert with an error.即在任何内存扩展操作如MSTORE、MSTORE8、CALLDATACOPY、RETURNDATACOPY、MCOPY等触及内存的操作发生前若扩展后的memory_byte_size严格大于strictly exceeding当前调用上下文创建时的初始 gas limit则直接 revert。注意这里的基准不是剩余 gas而是初始 gas limit——这样限制是静态可判定的实现方无需等到 gas 耗尽才发现问题这也是该限制之所以能成为硬上界的原因内存字节数永远不会超过初始 gas limit而初始 gas limit ≤ 交易 gas N于是memory_byte_size ≤ N恒成立。3.3 子调用 gas 上限从 63/64 规则升级为取 max现行规则EIP-150 的定义def max_call_gas(gas): return gas - (gas // 64)新规则def max_call_gas(gas, memory_byte_size): return gas - max(gas // 64, memory_byte_size)含义子调用可获得的最大 gas 不再是父上下文剩余 gas 的 63/64而是剩余 gas 减去max(63/64 规则要求的保留量, 当前内存字节数)。当内存字节数大于剩余 gas 的 1/64 时按内存字节数预留——这保证了父上下文为已占用内存预留了足够的 gas 预算从而让内存上界 子调用 gas 上界的递归求和被严格封顶。需要注意该改动适用于任何类型的调用CALL、DELEGATECALL、STATICCALL、CALLCODE 乃至 CREATE/CREATE2 等是全局性的子调用 gas 封顶规则调整。四、设计原理为什么这样改是自洽的4.1 一个极简的 N 字节实现方案EIP-7686 的 Rationale 给出了一种非常优雅的概念实现一台执行 N-gas 调用的简单 EVM可以只用一个 N 字节的 bytearray 作为整条链的内存为当前上下文分配全部 N 字节执行子调用时从当前内存位置memory_byte_size之后开始为子调用分配其内存依此类推递归向下。因为每次子调用都在父内存尾部切一块且子调用的 gas 上限已被max(gas // 64, memory_byte_size)约束整条执行路径的内存占用总和不会超过 N 字节。这种实现无需处理碎片、无需按需扩容的边界情况非常适合 ZK-SNARK 证明器等需要提前固定电路规模的环境。4.2 保留每字 3 gas与 MCOPY 计价的同构性为什么线性费用恰好取3 gas/wordRationale 明确说明因为这与 EIP-5656MCOPY 内存复制指令 的计价完全一致。EIP-5656 规定MCOPY的 gas 为G_verylow G_copy * ceil(length / 32)其中G_copy 3即每复制一个字 3 gas。这一同构性带来一个实现红利在 ZK-SNARK 等不寻常的执行环境中子调用结束时清空内存在普通机器上很便宜、但在证明器中却很昂贵而有了 3 gas/word 的线性计价清空内存的逻辑可以直接复用 MCOPY 操作码的实现逻辑不必为清内存单独设计一套昂贵且易错的机制。换句话说保留 3 gas/word 是为了让写内存与清内存在证明电路中共享同一条已优化的路径。4.3 保留 63/64 规则维持约 537 层调用栈深度的现状虽然max_call_gas的公式被修改但63/64 规则本身被完整保留作为max(gas // 64, memory_byte_size)中的一项。Rationale 给出的理由是维持当前事实上的调用栈深度上限1 log((gaslimit 6300) / 6400) / log(64/63) ≈ 537也就是说该提案刻意不改变 EIP-150 以来社区已经习惯的调用栈深度行为从当年约 340 层随后续 gas 参数演变到现在的约 537 层避免引入新的兼容性冲击面。这一点与 EIP-150 当年用 gas 规则取代硬编码栈深度限制的思路一脉相承用可计算的费用规则代替实现层面的任意限制。五、向后兼容性谁可能受影响EIP-7686 的 Backwards Compatibility 部分承认该提案理论上存在让今天能跑、明天不能跑的合约失效的可能触发条件是合约访问了内存中的高索引位置却被以较低 gas limit 调用。例如某段代码一次性写入MSTORE(0x2000, ...)之类的高偏移内存而调用方只给了很少的 gas——在新规则下内存扩展会因超过初始 gas limit 而 revert。但原文随即给出了重要的定量安抚几乎所有 EVM 执行消耗的 gas 都远多于其使用的内存字节数。以最保守的示例来说一笔要产生哪怕一次状态变更的调用至少需要 5000 gas而这笔 gas 对应的内存上限是 5000 字节——这个容量超过几乎所有应用的日常内存占用更复杂的应用拥有更高的 gas 上限也就拥有更宽裕的内存空间。因此实际受影响的面被评估为极小。六、安全考量原文的 Security Considerations 非常简短没有发现安全问题No security concerns were raised。这与提案的性质一致——它不是在引入新的攻击面而是在收紧资源使用边界新增内存硬上限方向上天然是防御性的内存上界越清晰内存耗尽类memory exhaustion攻击的可利用空间就越小。七、仓库中的定位状态、分类与关联提案在 EIPs 仓库中EIP-7686 的 front matter 表明其属性为Standards Track / Core 类提案作者 Vitalik Buterinvbuterin创建于 2024-04-15当前状态为Stagnant停滞——即曾进入提案流程但长期未推进。依据仓库 README 与 EIP-1 的流程说明Core 类 EIP 属于对以太坊共识协议的改进最终需要客户端实现与硬分叉纳入才能生效Draft/Stagnant 等非最终状态的 EIP 规范随时可能变更阅读时需注意其非最终性。值得特别关注的是该提案已被纳入后续硬分叉 gas 重定价工作的视野。EIP-8007Glamsterdam Gas Repricings 元提案 以目录形式整理了 Glamsterdam 分叉相关的全部 gas 重定价 EIP并将每个提案归类为Broad harmonization / Pricing extension / Supporting三种类型之一、对应Compute / Data / State / Memory等资源类别。其中EIP-7686 被列入Declined for Inclusion未纳入清单归类为Pricing extension 类型、Memory 资源类别描述为调整内存限制与子调用 gas 限制为一次 EVM 执行消耗的总内存建立清晰的线性上界。同一清单中还包含 EIP-7923将内存计价改为基于页的线性模型等同类内存定价提案说明线性化内存计价、降低最坏情况上界是 Glamsterdam 重定价讨论中的一个持续主题而 EIP-7686 正是这一方向上最早成文的提案之一。该提案与仓库中其他核心 EIP 的关联网络可概括如下关联提案文件与 EIP-7686 的关系EIP-150EIPS/eip-150.md63/64 规则的源头max_call_gas的旧定义出处Tangerine Whistle 分叉引入EIP-5656EIPS/eip-5656.mdMCOPY 指令其 3 gas/word 计价被 EIP-7686 的线性费用直接复用EIP-2929EIPS/eip-2929.md子调用*CALL家族的冷/热访问计价背景与子调用 gas 计量相关EIP-8007EIPS/eip-8007.mdGlamsterdam gas 重定价目录将 EIP-7686 列为未纳入的 Memory 类 Pricing extension八、总结与展望EIP-7686 用三个极其克制的改动——移除二次方内存项、新增内存字节数 ≤ 初始 gas limit硬限制、把子调用 gas 上限与内存字节数挂钩——换来了一个清晰、紧致、可静态判定的资源不变量N gas 的执行至多消耗 N 字节内存。这一不变量本身的价值超越了任何具体公式它为所有 EVM 实现尤其是 ZK-SNARK/STARK 证明器这类受限环境提供了可预先规划的内存上界让电路规模、内存分配、最坏情况分析都变得可计算同时它刻意与现有规则63/64 规则、MCOPY 的 3 gas/word保持同构把兼容性冲击和实现成本压到最低。尽管该提案当前处于 Stagnant 状态、未被 Glamsterdam 重定价目录纳入但它所确立的线性化内存计价 资源上界可证明的思路已经作为后续内存定价类提案如 EIP-7923的共同背景持续影响着以太坊 gas 模型的演进方向。对关注 EVM 底层设计与证明系统实现的开发者而言理解 EIP-7686 的三条规则等于掌握了分析 EVM 资源消耗上界的一把标准钥匙。【免费下载链接】EIPsThe Ethereum Improvement Proposal repository项目地址: https://gitcode.com/GitHub_Trending/ei/EIPs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表