
EIP-3336 深度解析为 EVM 引入分页内存分配模型【免费下载链接】EIPsThe Ethereum Improvement Proposal repository项目地址: https://gitcode.com/GitHub_Trending/ei/EIPs导读EIP-3336Paged memory allocation for the EVMEVM 分页内存分配由 Nick Johnson 于 2021 年 3 月提出是一份状态为 Stagnant 的 Standards Track / Core 类提案目标是从根本上改变以太坊虚拟机EVM的内存计费模型将当前从地址 0 线性扩展的连续内存模型替换为按固定大小页page分配与计费的分页模型。本文以 EIPS/eip-3336.md 为骨架结合本仓库中的配套提案 EIPS/eip-3337.md 与 EVM 内存相关 EIP系统讲解其背景动机、规范细节、气体gas计费公式的推导逻辑、对MLOAD/MSTORE及各类内存操作码的影响、向后兼容性与安全考量。读完本文你将理解 EVM 内存模型的演进方向、分页计费如何为编译器腾出更大的内存布局自由度以及该提案为何最终停留在 Stagnant 状态。一、提案定位EVM 内存模型的一次结构升级EIP-3336 的目标不是引入某个新操作码而是改变 EVM 的内存模型本身因此它被归类为 Core 类共识变更提案。在 EIPS/eip-1.md 定义的 EIP 生命周期中Stagnant 表示提案在 Draft / Review / Last Call 状态下超过 6 个月无更新而被移入的停滞状态作者或编辑仍可将其复活回 Draft。截至当前仓库快照EIP-3336 即处于该状态其FORK_BLOCK分叉区块号与 Test Cases 均标注为 TBD待定说明它是一份设计完整但尚未进入实现阶段的规范草案。与之配套的姊妹提案 EIPS/eip-3337.mdFrame pointer support for memory load and store operations在元数据中通过requires: 3336显式依赖本提案——EIP-3337 引入的MLOADFP/MSTOREFP等帧指针相对寻址操作码正是建立在 EIP-3336 分页内存提供的灵活性之上。理解这一点有助于把握作者的完整意图分页内存是基础层改造帧指针操作码是上层应用。二、动机线性内存模型是编译器设计的枷锁2.1 当前模型的固有缺陷现状下EVM 将内存视为从地址 0 开始、一直延伸到被读写过的最高地址的线性字节数组。这种模型对简单场景足够但存在两个突出问题强制紧凑布局编译器必须生成内存使用紧凑的程序。当程序需要更多内存时只能把已有数据整体搬迁到新区域产生大量重新分配reallocation与拷贝copying开销白白消耗 gas。内存模型单一现代编程语言常需要堆heap与栈stack分离不同生命周期数据分散存放等灵活布局。在线性连续模型下堆区与栈区无法自然隔离这类模型变得不切实际。2.2 现代操作系统的启示EIP-3336 的动机直接借鉴了现代操作系统中的**虚拟内存virtual memory**机制用户态程序拥有巨大的地址空间操作系统按需on-demand为进程分配物理内存页。这让程序可以将数据分散在整个地址空间中最大限度减少重分配与拷贝对不同生命周期的数据灵活使用内存。作者主张在 EVM 内部实现一个简化版的分页内存就能把同样的灵活性交给面向 EVM 的编译器。三、规范详解参数、分页机制与新的 gas 计费规范适用于满足block.number FORK_BLOCK的所有区块。以下是核心参数| 常量 | 值 | | - | - | |FORK_BLOCK| TBD待定 | |PAGE_BITS| 10 | |PAGE_BASE_COST| 96 |3.1 内存按页分配页大小内存按每页2**PAGE_BITS字节分配即2**10 1024字节1 KiB。地址拆分每个内存地址被划分为两部分——最高256 - PAGE_BITS 246位表示页号page number最低PAGE_BITS 10位表示页内偏移location in the page。初始化与惰性分配页在初始化时全部为零字节当页中第一个字节被读取或写入时该页才被分配惰性分配与操作系统的按需调页理念一致。实现建议提案建议 EVM 实现将页表pagetable存储为关联数组如哈希表或 dict键为页号值为该页的字节数组。这一建议意味着内存实现从单一连续缓冲区 最高水位标记转变为稀疏页集合为后文程序可在整个地址空间内分散布局提供了实现基础。3.2 内存扩展 gas 计费从字到页现行公式将内存扩展到a个字word32 字节的总成本为Cmem(a) 3 * a floor(a ** 2 / 512)其中a是从内存地址 0 覆盖到被读写过的最后一个字所需的字数。若内存当前已为b个字则增量成本为Cmem(a) - Cmem(b)。这是一个线性项 二次项的组合线性项对应每条内存操作的固定开销二次项模拟内存从 OS 层面真实占用的边际成本增长。新公式EIP-3336 将计费单位从字改为页基于已分配的页数pCmem(p) max(PAGE_BASE_COST * (p - 1) floor(2 * (p - 1) ** 2), 0)若内存当前已包含q页则增量成本为Cmem(p) - Cmem(q)。代入参数可得Cmem(p) max(96 * (p - 1) floor(2 * (p - 1) ** 2), 0)3.3 对MLOAD与MSTORE的修改读取或写入一个字时需要实例化instantiate该字触及的所有尚未存在的页并产生上述内存扩展 gas。若该字位于单个页内gas 成本维持3 gas不变若该字跨越两个页跨页边界page-aligned 之外的任意地址都可能发生成本为6 gas即按两次访问计费。3.4 对其他内存操作码的修改以下操作码以及任何其他读写内存的操作码按统一规则修改CALLDATACOPY, CODECOPY, EXTCODECOPY, CALL, CALLCODE, DELEGATECALL, STATICCALL, CREATE, MSTORE8修改要点有二任何被读或写的页若尚未存在则立即实例化按上文新公式收取内存扩展 gas。值得注意的是提案对任何其他读写内存的操作码持开放态度——例如本仓库中的 EIPS/eip-5656.mdMCOPY复制内存区域的指令在分析 DoS 与内存耗尽风险时即指出其内存扩展遵循相同的定价规则EIPS/eip-140.mdREVERT也表明其内存语义与RETURN完全一致。这类后续提案说明内存定价规则是全 EVM 通用的基础设施任何新内存操作码都会自动接入同一套计费体系EIP-3336 若落地其影响将辐射所有现有与未来的内存操作。四、设计权衡Rationale解读4.1 新计费曲线与旧曲线同形且永不超支新公式刻意沿用了旧公式的曲线形态线性项 二次项并保证新成本永远小于或等于旧成本Cmem(p) ≤ Cmem(a)对应关系下。这一性质带来两个关键收益不破坏现有程序假设任何对内存分配 gas 成本有预设的存量程序在新模型下不会因成本上涨而出错又不过度折扣内存内存并未被白送。从直觉上理解边界效应一个恰好用到页边界如 1024 字节整倍数的程序在新模型下比旧模型少付一页的成本一个刚好比页边界多用一个字的程序比旧模型少付一个字的成本。作者还论证由于这种减免随程序内存用量增大而比例上越来越小因此不会对有效 gas limit 产生显著影响。4.2 跨页MLOAD/MSTORE的双倍定价折衷而非禁止跨两页的读写为何要收 6 gas原因是实现层面的额外工作EVM 实现必须在页边界处拆分该字并更新两个可能不相邻的页。由于无法保证存量 EVM 程序的内存访问是页对齐的不能直接禁止这种行为否则大量程序会失效因此提案选择按两次访问计费通过额外成本**抑制discourage**跨页访问的滥用同时不彻底禁止保留功能上的灵活性该额外成本计入实现方的真实执行开销。作者也坦承这会让执行此类操作的程序产生额外 gas 开销但预计影响极小并希望未来做进一步分析确认。五、向后兼容性分析EIP-3336 的兼容性设计围绕一个核心原则展开新的内存扩展计费函数在任意场景下收取的费用 ≤ 当前 EVM 的收费。这一只减不增设计专门用于规避向后兼容性问题——存量程序在内存扩展上的花费不会因升级而增加。唯一的例外是跨越页边界的MLOAD和MSTORE会被收取额外费用3 → 6 gas。作者评估认为这类程序占比极小且对其 gas 消耗的影响很小。综合来看本提案属于对存量程序基本透明、对新编译器显著有利的软升级式共识变更。六、安全考量CPU DoS 与内存失控的防线提案回应了两个典型的安全疑虑CPU DoS 风险分页模型下跨页访问迫使实现拆分字、更新两个可能不相邻的页工作量增加。防线是对非页对齐的读写收取更高费用6 gas使攻击者无法廉价地制造实现负担。内存分配失控由于内存扩展费用渐近逼近当前费率asymptotically approach该变更不会允许程序分配远超现状的内存总量——即使采用分页模型经济约束仍然有效。七、配套提案EIP-3337 与分页内存的组合拳EIPS/eip-3337.md 是理解 EIP-3336 价值的关键参照。它提出四个新操作码| 操作码 | 字节码值 | 成本 | 作用 | | - | - | - | - | |SETFP|0x5c| 3 gasG_low | 从栈取一个参数设为帧指针新值 | |GETFP|0x5d| 3 gasG_low | 将当前帧指针压入栈 | |MLOADFP|0x5e| 3 gas | 如同MLOAD但地址先加帧指针负地址按无效操作码处理耗尽 gas 并回滚 | |MSTOREFP|0x5f| 3 gas | 如同MSTORE但地址先加帧指针负地址同上 |其动机正是 EIP-3336 中堆栈/堆分离等内存模型不切实际的痛点帧指针相对寻址让编译器可以把局部变量、函数参数等短暂数据高效卸载到内存从而消除对局部变量数量的限制。文档中给出的对比数据很直观帧指针相对加载原本需要PUSHn xPUSH1 0MLOADADDMLOAD共15 gas / 7 字节字节码配合MLOADFP后只需PUSH1 xMLOADFP共6 gas / 3 字节。MSTOREFP同理15 → 6 gas。EIP-3337 同时解释了为何不引入MSTORE8FP预计使用频率低且希望控制指令集规模、为未来保留操作码空间。这套分页内存 帧指针的设计组合展示了 EVM 内存模型面向编译器友好方向演进的完整图景。八、现状与落地前提需要如实说明本提案的成熟度边界FORK_BLOCK 未定分叉激活区块号为 TBD意味着没有确定的部署时间表Test Cases 为 TBD规范尚未配套形式化测试向量状态为 Stagnant按 EIPS/eip-1.md 的流程定义该提案因长时间未更新进入停滞状态可被作者或编辑复活。因此本文所有规范内容均以 EIPS/eip-3336.md 当前仓库快照为准读者若关注其后续进展应追踪该文件的更新状态及其在以太坊 magicians 论坛discussions-to 字段的讨论线程。从源码结构看本仓库 EIPS 目录收录了自 EIP-1 起的全部提案文本EIP-3336 作为 Core 类规范草案与 EIP-3337、EIP-5656MCOPY、EIP-140REVERT等共同构成理解 EVM 内存语义演进的第一手资料。本文基于开源仓库 GitHub_Trending/ei/EIPs 中的 EIPS/eip-3336.md 编写所有参数、公式与兼容性结论均以该文档原文为准配套信息引用自 EIPS/eip-3337.md、EIPS/eip-1.md、EIPS/eip-5656.md 与 EIPS/eip-140.md。【免费下载链接】EIPsThe Ethereum Improvement Proposal repository项目地址: https://gitcode.com/GitHub_Trending/ei/EIPs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考