在EVM中,合约可以使用一个临时的内存空间——就像一段“工作内存”:只在一次调用上下文中存在;可以通过MSTORE、MLOAD、CALLDATACOPY、CODECOPY等操作使用;这块内存在执行过程中可以增长,初始为0;每次增长都会带来「Gas成本」。什么是内存扩展
在 EVM 中,合约可以使用一个临时的内存空间 —— 就像一段“工作内存”:
MSTORE
、MLOAD
、CALLDATACOPY
、CODECOPY
等操作使用;在 EVM 中内存按 32 字节(word)对齐,初始大小是 0。 当你第一次访问更大的内存范围时,EVM 会自动扩展内存到目标范围,并为此收取一次性 Gas 费用。
📌 重点:扩展时不是每次访问都收费,而是只对 新扩展的部分 收费!
设 newMemorySize
为扩展后的字节数(向上取整到 32 字节对齐):
memoryCost = (newMemorySizeWords)^2 / 512 + 3 * newMemorySizeWords
newMemorySizeWords
= newMemorySize / 32这个公式体现了两层逻辑:
成本项 | 意义 |
---|---|
3 * word |
实际分配的线性成本(内存“越多越贵”) |
word^2 / 512 |
未来 gas 抵御 DoS 攻击的非线性防御机制 |
假设:
CALLDATACOPY(0x100, 0x00, 64)
→ 写入从 0x100 开始;内存扩展区间:从 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)
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!