它是一套嵌入执行客户端的虚拟机规范与运行时;许多节点各自运行自己的实现。
Ethereum 08.01 · EVM positioning
为什么全网会算出同一个答案?EVM · Re-execution · Determinism
以太坊不是把程序交给某一台服务器,而是让相互独立的验证节点,按照同一套规则, 对同一批有序交易重新计算。EVM,就是让这些计算可以被复现、比较与拒绝作弊结果的执行规则。
正式目录主题:EVM 的定位:由全网重复执行并验证的确定性虚拟机
前状态、交易顺序、区块上下文、Gas 与协议版本都相同,结果才必须相同。
接收区块的执行节点会重新执行交易并核对承诺值,错误结果不能靠“多数复读”变正确。
00 / ORIENTATION
先把 EVM 放对位置
“以太坊是一台世界计算机”是一个好入口,但不是完整答案。现实中没有一台藏在云端的巨型电脑; 有的是许多互不隶属的节点,各自保存状态、接收区块,并用自己的执行客户端重算交易。 Ethereum.org 因此把以太坊描述为分布式状态机,而 EVM 定义了状态如何变化。[1]
EVM 是以太坊执行层中的确定性、隔离、按 Gas 计量的状态转换运行时: 它读取既定输入,执行 EVM 字节码,并产生可被其他验证节点独立复算的结果。
这一定义里每个词都有任务:“执行层”说明它不负责 PoS 选链;“确定性”让不同节点可比较答案; “隔离”限制合约直接接触外部世界;“Gas 计量”给每步计算设置成本与终止边界;“状态转换” 则说明它的目标不是生成网页,而是把一个合法的以太坊状态推进到下一个合法状态。
三个层次,不能互相画等号
EVM 规则
定义字节码指令、执行环境、状态读写、Gas 与异常行为;不同实现应遵守同一协议规则。
执行客户端
Geth、Nethermind、Besu、Erigon、Reth 等软件分别实现执行规则,并承担更多节点职责。
以太坊
还包括 P2P 网络、PoS 共识、验证者、数据结构、经济激励、应用与所有参与者。
01 / STATE TRANSITION
从“记录转账”到“运行状态机”
普通账本告诉你“发生过什么”;状态机还必须告诉你“在当前状态与既定输入下,下一状态唯一应该是什么”。 以太坊世界状态包含账户余额、nonce、合约代码与合约存储等数据,并可被压缩承诺为一个 state root。[1]
上式可以读作:在协议规则 R 下,状态转换函数 Y 读取旧状态 S、
按顺序排列的交易 T₀…Tₙ 与区块/调用上下文 C,计算新状态 S′,
同时产生收据、日志、Gas 消耗、返回数据或失败信息等输出 O。
Ethereum.org 用更简化的 Y(S,T)=S′ 表达同一核心。[1]
贯穿全课的例子:把计数器从 7 加到 8
假设地址 0xCounter 存着合约字节码,其持久化存储中 count = 7。
Alice 签名一笔调用 increment() 的交易。交易进入某个区块后,执行客户端读取合约代码与状态,
EVM 逐步执行,若成功则把 count 更新为 8,记录日志与 Gas 消耗,并形成新的状态承诺。
Interactive 01
推进一次状态转换
起点:节点拥有旧状态,区块中包含 Alice 对 0xCounter 的调用。点击“下一步”查看本地验证过程。
Alice nonce = 12
规则版本 R
state root 为什么重要?
state root 是对整份执行层世界状态的密码学承诺。节点无需在区块头里塞入每个账户和每个存储槽, 只需承诺一个固定长度的根;接收区块的执行节点本地重算后,如果得到不同的根,就知道至少有一处输入、 顺序、规则或执行结果不一致。它不是“状态本身”,而是让巨大状态可以被紧凑核对的指纹。
02 / NODE ARCHITECTURE
EVM 究竟运行在哪里?
合并后的以太坊节点通常由执行客户端与共识客户端协作组成。执行客户端包含 EVM、维护执行层状态并重执行交易; 共识客户端处理 PoS 分叉选择、证明与最终性。两者通过本地 Engine API 协作。[2]
API
| 问题 | 主要负责者 | 为什么不能混为一谈 |
|---|---|---|
| 这笔交易算出了什么? | 执行客户端中的 EVM 与状态转换逻辑 | 它依据前状态、字节码、上下文和规则计算成功/失败、Gas 与新状态。 |
| 这个执行载荷有效吗? | 本地执行客户端 | 它重执行交易并核对执行结果;无效载荷会报告给共识客户端。 |
| 竞争区块里跟哪条链? | 共识客户端 | 它依据 PoS 证明与分叉选择规则确定链头,而不是由某条合约决定。 |
| 用户怎样提交与查询? | 执行客户端 RPC | RPC 是接口;一次查询可能触发本地模拟,但 RPC 本身不是虚拟机。 |
一个区块从提出到被接受
- 01区块生产相关组件组织候选执行载荷;执行客户端执行其中交易,计算新状态与收据承诺。
- 02区块通过共识层网络传播;其他节点收到区块与其中的执行载荷。
- 03接收节点把载荷交给自己的执行客户端,在本地按同一顺序重执行。
- 04若交易或状态转换违反执行规则,执行客户端判定载荷无效;共识客户端不会把它当作有效区块继续跟随。
- 05执行有效只是必要条件;区块能否成为规范历史,还要经过 PoS 分叉选择、证明与最终性过程。
所以“EVM 让全网达成共识”只说对了一半。EVM 让节点能对执行结果独立达成一致; 共识层则让节点对哪一段有效历史成为规范链达成一致。执行提供 validity,共识提供 ordering 与 finality。
03 / DETERMINISM
“确定性”究竟保证了什么?
确定性不是“这段合约无论何时运行都返回同一个值”,而是: 当完整输入与协议规则相同,合规 EVM 实现必须产生相同输出。 Ethereum.org 把它比作数学函数——给定输入,得到确定输出。[1]
transition
改变一个边界条件,还是“确定性”吗?
是。不同输入得出不同结果,并不破坏确定性;恰恰相反,这说明我们必须把输入说完整。 用下面的实验比较两个节点的执行环境。只有“完整相同”时,两个短哈希才应一致。
Interactive 02
寻找确定性的输入边界
两个节点拥有相同前状态、交易顺序、区块上下文与规则版本;合规实现必须得到同一结果。
为什么交易顺序也是输入?
状态转换是逐笔发生的。后一笔交易看到的是前一笔已经产生的新状态。即使交易集合相同,只要顺序不同, 最终状态就可能不同,这也是抢跑、清算排序与 MEV 等现象的技术基础之一。
04 / RE-EXECUTION
重复执行,如何变成“不要信任,自己验证”?
区块生产者不是把一句“我算过了,结果正确”发给全网。它发布交易列表与执行承诺; 接收区块的执行客户端会重新执行交易,确认它们没有违反规则,并核对计算出的新状态。官方节点架构说明明确指出, 执行客户端负责重执行新区块中的交易以确认其有效。[2]
0x8e17…4c2a0x8e17…4c2a0x8e17…4c2a0x8e17…4c2aInteractive 03
注入一个错误执行结果
当前四个节点都根据完整输入重算出 0x8e17…4c2a;执行承诺匹配。
实际协议中,不是“另外三个节点投票把 Node C 的数学答案改回来”。如果某个客户端因为 bug 在相同输入下算出不同结果, 它会与规范链失去一致;如果区块载荷本身的承诺错误,正确实现会判它无效。确定性提供的是一把可重复测量的尺, PoS 共识则决定哪条有效历史得到证明并最终确定。
为什么允许多个独立客户端实现?
共同规则
执行规范、EIP、网络升级与测试向量共同界定某一协议版本下的预期行为。
独立实现
客户端可用 Go、Java、C#、Rust 等不同语言编写,内部优化不同,但共识可见结果必须一致。
降低单点风险
多实现能减少对一个代码库的依赖;同时也要求严格的一致性测试与升级协调。
客户端多样性不是让每个节点“自由解释规则”,而是让不同团队独立实现同一协议。 以太坊执行规范项目与执行规范测试项目把规则变成可读代码与跨客户端测试素材,帮助发现分歧。[7][8]
05 / BOUNDARIES
六个最容易带偏后续学习的误解
学 EVM 最危险的不是记不住 opcode,而是一开始把边界画错。下面六张卡片值得当作长期纠错清单。
它主要处理执行;P2P 传播、PoS 共识、分叉选择、最终性、钱包界面与经济激励不都属于 EVM。
执行客户端还管理状态数据库、交易池、区块验证、执行层网络与 RPC;EVM 是其中的执行核心。
Solidity 编译器把高级语言变成字节码;EVM 执行字节码。编译和执行是两步。
EVM 环境与文件系统、网络和其他进程隔离;外部事实必须经交易、预言机等机制进入链上。
完整验证执行载荷的执行节点会重算;普通钱包与轻客户端可以依赖 RPC 或密码学证明。
前状态、发送者、calldata、交易顺序、区块上下文或协议版本变化,都可合法改变结果。
“世界计算机”这个比喻,哪里对,哪里不对?
| 比喻有效之处 | 比喻失真之处 |
|---|---|
| 有统一可编程的执行规则,程序与状态可被全球访问和验证。 | 不是一台机器集中运行,而是许多节点复制状态并重复执行。 |
| 像计算机一样从输入与当前状态得到输出与新状态。 | 计算昂贵、吞吐有限、公开可见,不适合替代普通云计算。 |
| 开发者可部署可复用代码,用户通过交易请求执行。 | 合约不能随意访问网络、文件系统、秘密或可靠的墙上时钟。 |
| 规则精确到字节码指令与 Gas,可由不同实现复现。 | 网络升级会改变规则;“同一程序”必须连同协议版本一起讨论。 |
EVM 是“图灵完备”吗?
EVM 的指令体系足以表达通用计算,但每步执行都消耗 Gas,交易提供的 Gas 有上限; 无限循环最终会耗尽 Gas 并异常停止。因此资料常称它为“准图灵完备”: 表达能力接近通用计算模型,单次链上执行却被资源上限强制终止。[6] 这不是缺陷,而是让互不信任的代码不能无限占用全网计算资源的安全边界。
06 / EDGE CASES
协议升级、执行失败与本地模拟
“同样的字节码”还不够定义同一次计算。EVM 会随网络升级引入或调整指令、环境字段与 Gas 规则, 所以协议版本必须被视为完整输入的一部分。
如果 Node A 已启用规则 R₂,Node B 仍按旧规则 R₁,
某些交易可能得出不同 Gas 或执行结果。这不是“EVM 天生不确定”,而是两台节点没有使用相同规则集。
网络升级之所以需要跨客户端测试与协调激活,就是为了让规范链上的验证节点在同一个边界切换规则。
失败也必须是确定的
主动回滚
当前调用路径可以用 REVERT 终止并返回数据;对应状态写入被回滚,未耗完的 Gas 不会像异常耗尽那样全部烧完。
资源耗尽
执行无法继续,相关调用框架的状态变更回滚;顶层交易仍有确定的失败收据与 Gas 结算结果。
顶层交易执行失败时,合约内部预期写入通常回滚,但发送者 nonce 的消耗与已用 Gas 的费用结算不会被简单抹掉。 这保证了失败计算也有成本,并防止攻击者免费让全网反复运行昂贵代码。更精确的调用帧、异常停止与回滚语义, 会在本章第二课讲 Stack、Memory、Storage 与 Opcode 时展开。
eth_call 为什么能“运行但不上链”?
RPC 方法 eth_call 可以让某个执行客户端在指定区块状态上本地模拟一次消息调用。
它会使用 EVM 执行,却不会创建一笔由共识网络确认的交易,也不会把结果提交为规范状态。
因此“EVM 执行过”与“全网已经接受状态变化”不是同一句话。
07 / RECAP
把整课压缩成一条因果链
以后看到任何合约执行问题,都可以按下面七问排查。它们比“代码看起来一样”更接近协议真正比较的内容。
- 01起点是哪一个世界状态或区块状态?
- 02交易或消息调用的发送者、value、calldata 与 Gas 条件是什么?
- 03它在区块中的顺序是什么,前面哪些交易已改变状态?
- 04区块号、时间戳、fee recipient、prevrandao 等上下文是什么?
- 05目标地址上实际存储的字节码是什么?
- 06当时激活的是哪一套协议规则与 Gas 规则?
- 07本地重算出的状态、收据与承诺是否和区块声明一致?
EVM 不是替全网“相信某次计算”,而是让每个验证执行结果的节点, 都能用同一把尺重新计算。
六题校准
1. 下列哪句话最准确地描述 EVM?
请选择一个答案。
2. 两个节点运行同一字节码却得到不同结果,哪项最先需要核对?
请选择一个答案。
3. 谁主要负责重执行新区块中的交易?
请选择一个答案。
4. 为什么同一组交易换个顺序可能得到不同 state root?
请选择一个答案。
5. 合约需要知道纽约当前气温,哪句话正确?
请选择一个答案。
6. eth_call 模拟成功能直接推出什么?
请选择一个答案。
08 / GLOSSARY & SOURCES
术语与一手资料
这一课先建立“EVM 在哪里、为什么可验证”的定位。下一课才会打开虚拟机内部, 逐层看 Stack、Memory、Storage、Transient Storage 与 Opcode 如何协作。
核心术语
- EVM
- 以太坊执行层的虚拟机规范与运行时,执行字节码并参与状态转换。
- World state
- 执行层当前所有账户相关数据的集合,包括余额、nonce、代码与存储。
- State transition
- 从一个合法世界状态,依据交易、上下文与规则计算下一个状态的过程。
- Determinism
- 完整输入与规则相同时,合规实现必须产生相同共识可见结果。
- Execution client
- 维护执行层状态、交易池与 RPC,并包含 EVM 实现的节点软件。
- Consensus client
- 处理 PoS 区块、证明、分叉选择与最终性的节点软件。
- Execution payload
- 共识区块中与执行层有关的载荷,包含有序交易及执行承诺等数据。
- Re-execution
- 接收节点用本地执行客户端重新运行交易,以独立验证载荷结果。
- State root
- 对执行层世界状态的固定长度密码学承诺,位于执行区块头相关字段中。
- Ruleset / fork
- 某一网络升级边界下激活的执行规则集合,是确定性输入的一部分。
官方与标准原文
-
Ethereum.org · Ethereum Virtual Machine (EVM)分布式状态机、状态转换函数、EVM 指令与实现概览;页面于 2026-04-03 更新。
-
Ethereum.org · Node architecture执行客户端、共识客户端、Engine API 与交易重执行的职责边界。
-
Ethereum.org · Nodes and clients节点类型、客户端多样性、完整节点的区块与状态验证职责。
-
Ethereum.org · Transactions交易是由账户签名、用于更新以太坊状态的指令。
-
Solidity docs · The Ethereum Virtual MachineEVM 作为合约运行环境的隔离边界,以及状态、内存与调用环境的官方说明。
-
Ethereum.org · Understanding the Yellow Paper's EVM specifications从形式化符号理解 EVM 执行状态、终止条件与准图灵完备。
-
Ethereum · Execution Layer Specifications以可读 Python 代码描述各次执行层分叉的协议行为。
-
Ethereum · Execution Specification Tests由执行规范生成、供不同客户端验证一致性的测试套件。
-
Ethereum Yellow Paper以太坊执行层与 EVM 的形式化基础;阅读时应结合后续 EIP 与当前执行规范。
-
Ethereum · Execution APIsJSON-RPC 与 Engine API 的规范仓库,用于理解接口与执行运行时的边界。
08.01 · Complete
共识不是大家相信同一份答案,而是大家都能重新算一遍。
现在你已经知道 EVM 为什么存在、它在节点里的位置,以及“确定性”真正要求哪些输入。 下一课,我们进入机器内部:看 Stack、Memory、Storage 与 Opcode 如何一步一步把字节码变成状态变化。
返回上一课 · Base Fee、Priority Fee 与销毁