在继续以太坊黄皮书的探索之旅中,本次学习笔记(第4部分)将聚焦于整个以太坊系统的“心脏”——以太坊虚拟机(Ethereum Virtual Machine, EVM),EVM是以太坊区块链上智能合约的运行环境,是“代码即法律”理念得以实现的技术基石,黄皮书第9章(以最新版本为准,章节号可能略有差异)对EVM的规范进行了详尽的定义,理解其核心机制对于深入把握以太坊的工作原理至关重要。

EVM概述:一个确定性图灵完备的虚拟机

EVM本质上是一个基于栈的虚拟机,它被设计为确定性的(Deterministic)和图灵完备的(Turing Complete)。

  • 确定性:这意味着对于给定的初始状态和输入,EVM总是会产生相同的输出和最终状态,这是所有区块链节点能够对交易和智能合约的执行结果达成共识的前提,任何依赖于随机数、外部时间或其他非确定性因素的运算都会破坏共识,因此EVM严格禁止此类操作。
  • 图灵完备:这意味着EVM可以执行任何可计算的任务,理论上可以模拟任何其他图灵机,为了防止无限循环等消耗网络资源的行为,EVM引入了Gas机制,对每一步计算都消耗Gas,从而使计算在有限资源内完成。

EVM核心数据结构

黄皮书对EVM的内部状态和操作数进行了精确的数学定义。

  1. EVM状态(EVM State)

    • 主要由账户模型构成,包括外部账户(EOA,由私钥控制)和合约账户。
    • 关键组成部分包括:
      • currentCoinbase:当前区块的矿工/验证者地址。
      • currentDifficulty:当前区块的难度(在PoS后有所调整,但概念保留)。
      • currentNumber:当前区块号。
      • currentTimestamp:当前区块时间戳。
      • currentGasLimit:当前区块的Gas限制。
      • currentRandom:当前区块的随机数(在PoS中为Beacon Chain的随机数)。
      • currentBlockHashes:可能的历史区块哈希列表(用于某些操作码)。
      • accounts:所有账户的状态,包括余额、 nonce、代码和存储。
      • storage:合约账户的存储空间,是一个键值对映射(bytes32 => bytes32)。
      • memory:EVM的内存,是一个字节数组,用于临时存储计算过程中的数据,是线性的,并且会在交易结束后被重置。
      • stack:EVM的操作数栈,是一个后进先出(LIFO)的结构,用于执行操作码时的参数传递和中间结果存储,栈的最大深度为1024。
  2. 执行环境(Execution Environment)

    定义了执行特定代码(如交易调用)时的上下文,包括上述的EVM状态、调用者、被调用者、Gas限制、value(转账金额)等。

EVM操作码(Opcode)与指令集

EVM通过一系列操作码来实现其计算功能,这些操作码构成了EVM的指令集,黄皮书第9章详细列出了所有操作码及其行为、Gas消耗和堆栈/内存交互方式。

  • 算术和比较操作:如 ADD (加法), SUB (减法), MUL (乘法), DIV (除法), MOD (取模), LT (小于), GT (大于), EQ (等于) 等。
  • 位运算操作:如 AND (与), OR (或), XOR (异或), NOT (非), SHL (左移), SHR (右移), SAR (算术右移)。
  • 堆栈、内存和存储操作
    • PUSHn:将n字节的常量压入栈。
    • POP:弹出栈顶元素。
    • DUPn:复制栈顶第n个元素并压入栈。
    • SWAPn:交换栈顶第n个元素与栈顶元素。
    • MLOAD:从内存指定地址加载32字节到栈。
    • MSTORE:将栈顶32字节存储到内存指定地址。
    • MSTORE8:将栈顶1字节存储到内存指定地址。
    • SLOAD:从合约存储指定地址加载32字节到栈。
    • SSTORE:将栈顶值保存到合约存储指定地址(修改存储会消耗较多Gas)。
  • 流程控制操作
    • JUMP:无条件跳转到指令指定位置。
    • JUMPI:有条件跳转,如果栈顶元素为非零则跳转。
    • PC:获取当前指令在代码中的偏移量。
    • JUMPDEST:标记一个有效的跳转目标。
  • 环境信息操作
    • BLOCKHASH:获取指定区块号的哈希。
    • COINBASE:获取当前区块的矿工地址。
    • TIMESTAMP:获取当前区块的时间戳。
    • NUMBER:获取当前区块号。
    • GASLIMIT:获取当前区块的Gas限制。随机配图