第 08 课:EVM 究竟是如何工作的?
踏上构建生产级应用的旅程。
你已经把一个智能合约部署到了 Monad,也亲眼看着一笔交易被确认。但中间到底发生了什么?这一课就来打开引擎盖。
在上一课中,你把一个 dapp 发布到了 Monad —— 合约上链,交易被确认,状态对所有人都发生了变化。但总得有什么东西真正在每个网络节点上以完全相同的方式运行那段智能合约代码。这个东西就是 EVM。
EVM 是你的智能合约能够每次都在网络中每一台计算机上准确按你所写执行的原因,而且没有任何人去协调它。理解它是什么 —— 哪怕只是从高层概念上理解 —— 都会让你成为一个更好的构建者。
什么是 EVM?
EVM 是 Ethereum Virtual Machine(以太坊虚拟机) 的缩写。它是在以太坊兼容区块链(包括 Monad)上执行智能合约代码的引擎。
当你部署一个智能合约时,你并不是把人类可读的代码放到链上,而是放上一组 EVM 知道如何执行的极其简单的指令。网络中的每个节点都运行同样的 EVM、执行同样的指令,并得到同样的结果。这就是网络在没有中央服务器告诉每个人该做什么的情况下保持一致的方式。
可以把 EVM 想象成整个网络共享的一台计算器。当一笔交易进来时,每个节点都做同样的运算。如果它们都得到相同的答案,这笔交易就是有效的;只要有一个结果不一样,就说明出了问题。
EVM 的作用是什么?
以太坊是一个状态机
要理解 EVM,先理解以太坊到底是什么样的系统会很有帮助。
以太坊是一个状态机(state machine)。意思是它有一个当前状态 —— 所有账户、所有余额,以及每个智能合约中存储的所有数据的快照 —— 每当一个新区块被处理时,它就从一个状态过渡到下一个状态。
打个简单的比方:想象一场篮球比赛的记分牌。记分牌有一个当前状态(比分)。每进一球,状态就发生变化。篮球规则定义了状态被允许如何变化 —— 你不能随便往板上写一个数字。
以太坊的工作方式是一样的。当前状态是网络此刻发生的一切。每一笔交易就像一次进球 —— 它按照规则改变状态。EVM 就是负责执行这些规则并计算新状态的东西。
这也是为什么以太坊常被称为分布式状态机(distributed state machine),而不仅仅是分布式账本。Bitcoin 主要是一个账本 —— 它记录谁向谁转了多少钱。以太坊则跟踪网络上每一个智能合约的完整状态。
以太坊的「状态」是什么?
作为一个系统,以太坊与 Bitcoin 的区别是什么?
当你的合约运行时会发生什么
当有人与你的智能合约交互 —— 比如在你的应用里点击「Update Message」 —— 实际发生的事情是这样的:
-
一笔交易被创建。 你的钱包对一笔交易进行签名,内容是「用这些输入调用这个合约上的这个函数」。
-
交易被广播到网络。 每个节点都会收到它。
-
EVM 执行合约代码。 每个节点都对当前状态运行同样的指令。没有任何节点比其他节点更被信任 —— 它们都必须独立地得到同样的结果。
-
状态更新。 如果交易有效,新的状态 —— 包括你的合约存储的任何东西 —— 就会被记录到区块链上。
-
区块最终敲定。 新状态成为网络的官方状态。
关键洞察:没有任何一台计算机在单独运行你的合约。是成千上万台计算机在同时运行它,并相互校验对方的结果。这就是它之所以无需信任的原因。
为什么每个节点都要执行同样的智能合约代码?
从 Solidity 到 Opcode
当你(或者你的 AI 智能体)写一个智能合约时,它是用 Solidity 写的 —— 一种人类可读的语言。但区块链并不理解 Solidity。在你的合约能够运行之前,它会被编译成 EVM 真正能理解的东西:opcode(操作码)。
Opcode 是极其简单的指令。比如 ADD、SUB、MUL、DIV —— 基础数学运算;STORE、LOAD —— 读写数据。每个 opcode 只做一件事。无论多么复杂,你的整个智能合约最终都会归结为一长串这些微小操作的序列。
这和你的笔记本电脑工作原理是同一个思路。你用 Python 或 JavaScript 写代码。计算机并不直接理解这些语言 —— 它会把它们编译为 CPU 能执行的低级指令。Opcode 就是 EVM 版本的低级指令。
你永远不会直接看到这些 opcode。你的智能体写 Solidity,Hardhat 编译它,EVM 运行编译结果。但每次你的合约执行时,引擎盖下发生的就是这些。
什么是 opcode?
EVM 如何记住东西
EVM 有两种类型的内存,理解它们的区别对智能合约的工作方式很重要。
Memory(内存) 是临时的。它只在一笔交易期间存在。交易一结束,它就被擦除。可以把它想象成一张草稿纸 —— 工作时你可以在上面写东西,但完事之后就会被丢掉。
Storage(存储) 是永久的。它存在于区块链上,跨交易持久存在。当你的 MessageBoard 合约保存一条新消息时,它就被写进了 storage。下一次有人调用合约时它还在,第二天还在,明年也还在。
Storage 才是让智能合约真正可以作为后端使用的东西。任何你的合约需要记住的数据 —— 余额、所有权、消息、投票 —— 都会被写入 storage,永久保存在区块链上。
这也是为什么与 storage 交互比使用 memory 消耗更多 gas。把永久数据写入分布在世界各地的成千上万个节点是昂贵的;临时草稿纸上的运算则是廉价的。
EVM 的 memory 和 storage 有什么区别?
状态转换
每次有交易运行时,EVM 都会拿到网络当前的状态,应用这笔交易,并产生一个新状态。这被称为状态转换(state transition)。
状态转换的关键在于它们是确定性的(deterministic) —— 也就是说,相同的输入总是产生相同的输出。如果你给 EVM 同样的当前状态和同样的交易,它每次都会得到完全一样的新状态,在每个节点上都是如此。没有随机性,没有歧义。
这就是网络无需信任的原因。每个节点都独立运行同样的状态转换,并检查结果是否与其他人一致。如果某个节点试图作弊 —— 产生不一样的结果 —— 其他节点会立即拒绝它。
在 EVM 的语境下,「确定性」是什么意思?
为什么 Monad 运行 EVM
Monad 是 EVM 兼容的(EVM-compatible)。意思是它运行的就是以太坊运行的那个 EVM。任何能在以太坊上运行的智能合约,不需要任何改动就能在 Monad 上运行。
这对构建者来说意义重大。它意味着:
- 你学过的所有关于 Solidity 的知识都适用于 Monad
- 你用过的每一个工具(Hardhat、wagmi、RainbowKit)都能在 Monad 上工作
- 部署在以太坊上的智能合约可以零修改地重新部署到 Monad 上
区别在于 Monad 运行 EVM 的速度要快得多。以太坊每秒大约能处理 15 到 30 笔交易,Monad 的设计目标是处理数千笔。同样的规则,更高得多的吞吐量。这正是 Monad 架构 —— 流水线(pipelining)、并行执行(parallel execution)和 MonadDB —— 所要实现的核心目标。
所以当你把 MessageBoard 合约部署到 Monad 时,你用的并不是另一个系统。你用的是同一个 EVM,只是跑在快得多的轨道上。
EVM 兼容是什么意思?
EVM 作为一台共享的计算机
再换一个角度来理解。
你的笔记本电脑有一颗 CPU —— 一块运行指令的芯片。当你打开一个应用时,CPU 执行该应用的代码。EVM 本质上是整个以太坊网络共享的一颗虚拟 CPU。
它不是跑在你机器里的某块芯片上,而是同时跑在成千上万台机器上。它不是被一个操作系统所控制,而是由协议本身的规则所约束。它也不是被用来在本地跑你的应用,而是被用来运行任何人都可以与之交互的智能合约。
这就是它被叫作虚拟机的原因。它的行为像一台计算机 —— 执行指令、读写内存、产生输出 —— 但它并不存在于任何一台单独的物理设备上。它存在于整个网络之中。
为什么 EVM 被称为「虚拟」机?
这对作为构建者的你意味着什么
理解 EVM 是什么会改变你思考自己在构建什么的方式。当你部署一个合约时:
- 你不是在租一台服务器 —— 你是在向一台被成千上万节点运行的共享计算机发布代码
- 你不是在信任一家公司去执行你的逻辑 —— 是网络在强制执行它
- 你不是在把数据存进别人拥有的数据库 —— 状态存在于一台去中心化的机器上
这就是其他一切的基础。智能合约之所以能以那种方式工作,是因为 EVM 以那种方式工作。
关于用 Vibecoding 写智能合约的一个严肃警告
你已经在大一课程里 vibecode 过一个智能合约,在后续课程中还会写更多。在你继续之前,你需要理解一件重要的事:智能合约和前端代码不一样。
当你 vibecode 一个 UI、出了问题时,你修一下、再部署一次。犯错的成本很低。智能合约在几个关键方面是不同的:
- 错误可能是永久的。 智能合约一旦部署就是不可变的。如果逻辑里有 bug,你往往无法打补丁 —— 那段有缺陷的代码会永远留在那里。
- 错误可能代价高昂。 智能合约可能持有真实的资金。处理资金的合约里一个逻辑错误,可能导致这些资金被丢失或被盗。这种事在经验丰富的开发者身上多次发生过 —— 不只是新手才会遇到。
- AI 模型在这里更不可靠。 模型在前端代码上的训练数据远远多于 Solidity。它们在智能合约上犯的错误更多,而且这些错误更难被发现。
- 上下文会迅速变得复杂。 一旦你的合约开始与其他协议交互,智能体就可能丢失重要细节,进而引发隐蔽但严重的 bug。
大一 dapp 课程中的留言板合约是有意做得简单的 —— 没有任何金融逻辑。这是经过设计的。出于学习目的,小而简单总是更安全。
经验法则:在没有经验丰富的 Solidity 开发者审计之前,绝不要部署任何持有真实资金的智能合约。 Vibecoding 是一种用来学习和原型设计的强大方式。当涉及真金白银时,它不能替代专业评审。
接下来是什么
现在你已经理解了运行你智能合约的是什么,下一课是 Monskills——如何把一个通用的 AI 编程助手变成懂你技术栈、地址和部署流程的 Monad 专家,让它不再靠猜。
0/9 正确
0% — 全部答对即可完成