在探讨以太坊虚拟机(EVM)的底层机制时,“显存”(Memory)是一个不可或缺却又常被忽视的概念,与常驻硬盘的“存储”(Storage)和短暂易失的“栈”(Stack)不同,以太坊的显存是智能合约在执行过程中的一块临时、可读写的内存区域,理解以太坊显存的范围、特性及其运作机制,对于开发者优化合约性能、控制成本以及避免潜在的安全风险至关重要。
什么是以太坊显存?
以太坊显存可以理解为智能合约在执行期间的一块“工作台”或“草稿纸”,它是一个线性的字节数组,大小在合约执行期间可以动态扩展,与存储(Storage)不同,显存中的数据在合约执行结束后会被立即清除,不永久保存状态,这使得显存读写操作远比存储读写便宜(以“燃气”Gas衡量),但数据不具备持久性。
显存的主要作用包括:
- 存储临时计算结果:在合约逻辑执行过程中,中间变量、复杂运算的临时数据等可以存储在显存中。
- 为参数编码和解码提供空间:特别是在调用外部合约或处理复杂数据结构(如数组、结构体)时,显存用于对输入参数进行编码(如ABI编码)和对输出结果进行解码。
- 支持复杂的内存操作:如复制、比较等,这些操作在显存中执行效率较高。
以太坊显存的范围与特性
以太坊显存的范围主要体现在其大小和生命周期上:
-
动态大小与扩展:
- 显存初始大小为0,当合约首次需要写入数据到显存时,它会分配一定大小的空间(以32字节的“页”为单位)。
- 显存可以动态扩展,当合约需要访问或写入超出当前显存大小的偏移量时,EVM会自动扩展显存,扩展显存需要消耗燃气(Gas),扩展的成本通常与扩展后的总大小相关(每新增一页32字节需要一定的Gas)。
- 显存的大小有一个理论上的上限,这个上限由以太坊的区块Gas限制和EVM的具体实现决定,但在实际应用中,合约很少能达到这个上限,因为过大的显存会消耗大量Gas。
-
线性字节数组结构:
- 显存被组织成一个从0开始的线性字节数组,每个字节都可以通过其偏移量(offset)直接访问。
- 数据在显存中的存储方式需要遵循一定的对齐规则,某些操作(如MLOAD, MSTORE)通常以32字节(256位)为单位进行,以提高效率。
-
生命周期短暂:
- 显存的生命周期与合约的“调用”(Call)或“交易”(Transaction)严格绑定,一旦外部函数调用结束(无论是成功还是失败),该调用期间分配的显存都会被释放。
- 这意味着显存不能用于跨函数调用或跨交易持久化数据。
-
相对低廉的访问成本:
- 相较于存储(Storage)的读写,显存(Memory)的读写操作成本要低得多,MLOAD(从显存读取)和MSTORE(向显存写入)的Gas消耗远低于SLOAD(从存储读取)和SSTORE(向存储写入)。
- 这使得显存适合存储频繁读写但不需要长期保存的数据。
显存操作与燃气消耗
显存的使用与以太坊的燃气机制紧密相关:









