ETH 之 EVM内存扩展

在EVM中,合约可以使用一个临时的内存空间——就像一段“工作内存”:只在一次调用上下文中存在;可以通过MSTORE、MLOAD、CALLDATACOPY、CODECOPY等操作使用;这块内存在执行过程中可以增长,初始为0;每次增长都会带来「Gas成本」。什么是内存扩展

在 EVM 中,合约可以使用一个临时的内存空间 —— 就像一段“工作内存”:

  • 只在一次调用上下文中存在;
  • 可以通过 MSTOREMLOADCALLDATACOPYCODECOPY 等操作使用;
  • 这块内存在执行过程中可以增长,初始为 0;
  • 每次增长都会带来「Gas 成本」。

什么是内存扩展

在 EVM 中内存按 32 字节(word)对齐,初始大小是 0。 当你第一次访问更大的内存范围时,EVM 会自动扩展内存到目标范围,并为此收取一次性 Gas 费用

📌 重点:扩展时不是每次访问都收费,而是只对 新扩展的部分 收费!

内存扩展的 Gas 成本公式(黄皮书标准)

newMemorySize 为扩展后的字节数(向上取整到 32 字节对齐):

memoryCost = (newMemorySizeWords)^2 / 512 + 3 * newMemorySizeWords
  • newMemorySizeWords = newMemorySize / 32
  • 总成本 = 线性部分 + 二次方部分

这个公式体现了两层逻辑:

成本项 意义
3 * word 实际分配的线性成本(内存“越多越贵”)
word^2 / 512 未来 gas 抵御 DoS 攻击的非线性防御机制

示例讲解

假设:

  • 之前内存访问最大是 0x00 ~ 0x9F(160 字节) → 已使用 5 个 word;【 = 160 / 32】
  • 当前执行 CALLDATACOPY(0x100, 0x00, 64) → 写入从 0x100 开始;
  • 0x100 = 256 = 第 9 个 word → 需要扩展到第 9 个 word。

内存扩展区间:从 word 5 → word 9:

计算 Gas 增量:

prevCost = 3 * 5 + (5^2)/512 = 15 + 0.048 ≈ 15
newCost  = 3 * 9 + (9^2)/512 = 27 + 0.158 ≈ 27
memoryExpansionCost = newCost - prevCost = 12 Gas

内存扩展的成本是非线性增加的,这样可以避免低成本攻击者构造超大内存消耗造成节点拒绝服务(DoS)

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Henry Wei
Henry Wei
Web3 探索者