---
title: "什么是 zkEVM？"
description: "zkEVM 的类型、工作原理及其重要性"
---

# 什么是 zkEVM？

零知识以太坊虚拟机（zkEVM）是一种生成[零知识证明](https://www.alchemy.com/overviews/snarks-vs-starks)以验证程序正确性的虚拟机。zkEVM 的设计目标是以支持零知识技术的方式执行智能合约。

zkEVM 是[零知识（ZK）Rollups](https://www.alchemy.com/blog/zero-knowledge-rollups)的组成部分，后者是 Ethereum 二层扩容方案，通过将计算和状态存储转移到链下来提升吞吐量。ZK-rollup 将交易数据连同验证链下交易批次有效性的零知识证明一起提交给 Ethereum。

早期的 ZK-rollups 不具备执行智能合约的能力，只能用于简单的代币交换和支付。但随着与 EVM 兼容的零知识虚拟机的出现，ZK-rollups 开始支持 Ethereum [应用](https://www.alchemy.com/dapps/top/defi-dapps)。

本文将探讨 zkEVM 的工作原理、其重要性，以及现有的 zkEVM 类型。

## 什么是 zkEVM？

zkEVM 是一种与 EVM 兼容并支持零知识证明计算的虚拟机。与常规虚拟机不同，zkEVM 证明程序执行的正确性，包括操作中所用输入输出的有效性。

下面进一步拆解这一定义，便于理解：

### EVM 兼容性

[EVM（以太坊虚拟机）](https://www.alchemy.com/overviews/what-is-the-ethereum-virtual-machine-evm)是 Ethereum 网络上部署的智能合约的运行环境。EVM 相当于一台“世界计算机”，为运行在 Ethereum 区块链上的去中心化应用提供支持。

如果一个虚拟机能够运行为 EVM 环境编写的程序，则称其“与 EVM 兼容”。此类虚拟机能够执行用 Solidity 或其他 Ethereum 开发中使用的高级语言编写的智能合约。zkEVM 之所以与 EVM 兼容，是因为它们无需对底层逻辑进行大幅修改即可执行 Ethereum 智能合约。

### 对零知识技术的支持

EVM 在设计之初并未考虑对零知识证明的支持，这使得构建与 EVM 兼容且适合零知识技术的虚拟机颇具难度。不过，研究上的进展已使得在一定程度上将 EVM 计算包装进零知识证明成为可能。

不同的 zkEVM 项目在结合 EVM 执行与零知识证明计算方面采用了不同的方法。每种方法各有取舍，我们将在本指南后面的章节中探讨。

## zkEVM 是如何工作的？

与 EVM 类似，zkEVM 也是一种因程序操作而在不同状态间转换的虚拟机。但 zkEVM 更进一步：它会为计算的每个部分生成证明，以证实其正确性。本质上，zkEVM 使用一种机制来证明（前面所述的）执行步骤遵循了既定规则。

为了理解 zkEVM 的工作原理（以及它与众不同之处），我们先回顾一下 EVM 目前是如何工作的。

### EVM 的工作原理

以太坊虚拟机是一台状态机，根据输入从旧状态转移到新状态。每一次智能合约执行都会触发 EVM 状态的变化（称为“状态转换”）。以下是智能合约交易发生时的一个高层概览：

1. 合约字节码（由源代码编译而来）从 EVM 的存储中加载，并由 EVM 上的对等节点执行。节点使用相同的交易输入，从而保证每个节点得到相同的结果（否则它们无法达成共识）。

2. 字节码中包含的 [EVM 操作码](https://www.ethervm.io/)与 EVM 状态的不同部分（内存、存储和栈）进行交互。操作码执行读写操作——从状态存储中*读取*（获取）值，并将新值*写入*（发送）到 EVM 的存储中。

3. EVM 操作码对从状态存储中获取的值进行计算，然后返回新值。这一更新会导致 EVM 转换到新状态（因此这类交易被称为“状态转换”）。这一新状态会被其他节点复制，并保持不变，直到有另一笔交易被执行。

<ImageBlock
  src="https://media.alchemy.com/1704295117-evm-execution-model.png"
  alt="展示程序如何在以太坊虚拟机（EVM）中执行的示意图。"
  width={968}
  height={707}
  caption="展示程序如何在以太坊虚拟机（EVM）中执行的示意图。"
/>

### zkEVM 的工作原理

zkEVM 生成零知识证明，以验证每次计算中的各项元素：

1. **字节码访问**：是否从正确的地址正确加载了相应的程序代码？

2. **读写操作**：a. 程序在计算前是否从栈/内存/存储中获取了正确的值？b. 程序在完成执行后是否将正确的输出值写入了栈/内存/存储？

3. **计算**：操作码是否按正确顺序执行（即依次执行，没有跳过步骤）？

#### zkEVM 的架构

zkEVM 分为三个部分：执行环境、证明电路和验证者合约。每个组件都对 zkEVM 的程序执行、证明生成和证明验证起作用。

##### 1. 执行环境

顾名思义，执行环境是 zkEVM 中运行程序（智能合约）的地方。zkEVM 的执行环境与 EVM 的运作方式颇为相似：它以初始状态和当前交易作为输入，输出一个新的（最终）状态。

##### 2. 证明电路

证明电路生成零知识证明，验证在执行环境中计算出的交易的有效性。证明生成过程以前置状态、交易输入和后置状态信息作为输入完成。之后，证明者获得该特定状态转换有效性的简洁证明。

<ImageBlock
  src="https://media.alchemy.com/1704293216-zkevm-validity-proofs.png"
  alt="展示 zkEVM 如何为程序生成有效性证明的示意图。"
  width={902}
  height={517}
  caption="zkEVM 生成有效性证明，以验证程序执行的正确性。"
/>

##### 3. 验证者合约

ZK-rollups 将有效性证明提交给部署在 L1 链（Ethereum）上的智能合约以供验证。输入（前置状态和交易信息）与输出（最终状态）也会一并提交给验证者合约。随后，验证者对提供的证明进行计算，确认所提交的输出确实是由输入正确计算得出的。

## 什么是 zkEVM 操作码？

zkEVM 操作码是用于在与 EVM 兼容的 ZK-rollup 中执行程序的底层机器指令。与 EVM 一样，用高级语言编写的合约必须编译成虚拟机能够解释的底层语言（字节码）。该字节码指定了程序部署到虚拟机后执行时所用的操作码。

之所以需要 zkEVM 操作码，是因为常规的 EVM 操作码在零知识证明电路中使用效率低下。为 zkEVM 创建操作码通常有两种方法：

1. 为原生 EVM 操作码构建 ZK 电路
1. 为 ZK 证明计算创建新语言

#### 为原生 EVM 操作码构建零知识电路

这种方法需要在算术电路中实现所有 EVM 指令集——这是一项复杂且耗时的任务。其好处在于，开发者可以使用[现有的区块链开发工具](https://www.alchemy.com/overviews/20-blockchain-development-tools)构建智能合约，或者无需大幅修改即可将现有的 Ethereum 合约移植到 ZK-rollups 上。

#### **为 ZK 证明计算创建新语言**

这种方法需要构建一种新语言——设计用于支持有效性证明——并开发自定义操作码。开发者需要直接用新语言编写合约，或者将 Solidity 源代码编译为自定义的 zkEVM 操作码。

虽然这种方法通常比第一种方法更容易实现，但也有缺点。例如，开发者可能无法使用现有的 Ethereum 基础设施和资源。

<ImageBlock
  src="https://media.alchemy.com/1704295202-zkevm-classification.png"
  alt="按 EVM 兼容性对零知识虚拟机的分类。"
  width={937}
  height={587}
  caption="按 EVM 兼容性对零知识虚拟机的分类。"
/>

## 是什么让构建 zkEVM 变得困难？

由于 EVM 在设计时并未考虑零知识证明计算，它具有一些对证明电路不友好的特性。以下简要介绍四个使构建 zkEVM 变得困难的因素：

1. 特殊操作码
1. 基于栈的架构
1. 存储开销
1. 证明成本

### 1. 特殊操作码

与常规虚拟机不同，EVM 使用特殊的操作码来执行程序（CALL、DELEGATECALL）以及处理错误（REVERT、INVALID）等操作。这为设计 EVM 操作的证明电路增加了复杂性。

### 2. 基于栈的架构

EVM 采用基于栈的架构，虽然比基于寄存器的结构更简单，但这增加了计算证明的难度。这就是为什么诸如 [ZkSync](https://www.alchemy.com/overviews/what-is-zksync-era) 的 zkEVM 和 StarkWare 的 StarkNet 等主要的零知识虚拟机采用基于寄存器的模型。

### 3. 存储开销

EVM 的存储布局依赖于 Keccak 哈希函数和 Merkle Patricia Trie，二者都有较高的证明开销。一些 zkVM（如 ZkSync）尝试通过替换 KECCAK256 函数来规避这个问题——但这可能破坏与现有 Ethereum 工具和基础设施的兼容性。

### 4. 证明成本

即便上述问题都得到解决，仍需面对证明生成过程本身的挑战。生成零知识证明需要专用硬件，同时还需要在时间、资金和人力上投入相当大的成本。

尽管这份清单并不详尽，但它列出了阻碍构建与 EVM 兼容的 zkEVM 的一些问题。尽管如此，[零知识技术领域的多项突破](https://hackmd.io/@yezhang/S1_KMMbGt#Why-possible-now)已经使这些问题得到一定程度的缓解——这也带动了对 zkEVM 方案的新一轮关注。

## 为什么 zkEVM 很重要？

构建功能完备的 zkEVM 将推动与 EVM 兼容的 [ZK-rollup 项目](https://www.alchemy.com/overviews/zk-rollup-projects)的发展。这带来了以下几方面优势：

1. 更安全的可扩展性
1. 更低的成本
1. 更快的最终性和资金效率
1. 网络效应

### **1. 更安全的可扩展性**

根据协议规则，所有验证节点都必须重新执行以太坊虚拟机中进行过的所有计算。这种方式确保了安全性，因为 Ethereum 节点可以独立验证程序的正确性，但这也限制了可扩展性，Ethereum 网络能处理的交易量仅约为每秒 15-20 笔。

与 EVM 兼容的 ZK-rollups 可以在不损害网络安全的情况下解决 Ethereum 的吞吐量问题。与其他扩容协议一样，ZK-rollups 不受 Ethereum 共识协议规则的约束，可以针对执行速度进行优化。据估计，[ZK-rollups 每秒可处理约 2000 笔交易](https://blog.matter-labs.io/optimistic-vs-zk-rollup-deep-dive-ea141e71e075)，且无需承担 Ethereum 的高额费用。

不过，相较于其他扩容项目，ZK-rollups 具有更高的安全保障；它们通过有效性证明来验证链下计算的正确性。这意味着 L2 上智能合约执行的交易可以在 L1（Ethereum）上被可靠地验证，而无需节点重新执行这些操作。这能够在不降低安全性的前提下，显著提升 Ethereum 的处理速度。

### **2. 更低的成本**

Rollups 通过将交易数据以 CALLDATA 形式写入 [Ethereum 主网](https://www.alchemy.com/rpc/ethereum)来获得安全性保障。不过，Optimistic rollups 和 ZK-rollups 需要在 Ethereum 上发布的数据量有所不同。

由于[Optimistic rollups](https://www.alchemy.com/overviews/optimistic-rollups)不提供链下交易的有效性证明，它们需要在链上发布所有与交易相关的数据（包括签名和交易参数）。如果不将所有数据放到链上，挑战者就无法构造用于对无效 rollup 交易提出异议的欺诈证明。

相比之下，ZK-rollups 只需向 Ethereum 提交极少量的数据，因为有效性证明已经保证了状态转换的可信度。zkEVM 甚至可以省略交易输入，只发布最终的状态变化，从而进一步降低对 CALLDATA 的需求。

这对开发者和用户来说都是有利的，因为[Rollup 成本中很大一部分](https://forum.celestia.org/t/ethereum-rollup-call-data-pricing-analysis/141)来自于链上数据发布。通过将 CALLDATA 降到最低，ZK-rollups 能够降低去中心化交易所、NFT 交易市场、预测市场等各类应用的使用成本。

### 3. 更快的最终性和资金效率

除了更好的安全性外，ZK-rollups 相较于 Optimistic rollups 还有另一个优势：更快的最终性。区块链中的最终性是指交易变得不可逆所需的时间；只有当网络参与者拥有客观的有效性证明时，交易才能被最终确认。

对于 ZK-rollups 而言，在 zkEVM 中执行的交易通常在提交到 Ethereum 后立即完成最终确认。由于每个交易批次都附带即时可验证的有效性证明，Ethereum 主链可以迅速应用状态更新。

由于 Optimistic rollups 只提交虚拟机交易而不提供证明，交易必须等待挑战期结束才能达到最终性。挑战期是指提交到 Ethereum 后的 1-2 周时间，在此期间任何人都可以对交易提出质疑。

较慢的最终性对用户体验有诸多影响。例如，在延迟期结束之前，用户无法从 rollup 中提取资产。流动性提供者或许可以缓解这个问题，但如果提取的是高价值资产甚至 NFT，这种方案可能就不太有效了。

zkEVM 不存在上述任何问题。更快的最终性对于重度用户而言非常有价值，比如需要在资产（尤其是在 L1 与 L2 之间）之间顺畅转移的 NFT 交易者、DeFi 投资者或套利交易者。

### 4. 网络效应

构建与 EVM 兼容的 zkVM 最重要的原因，是要利用 Ethereum 的网络效应。作为全球最大的智能合约平台，Ethereum 拥有庞大的生态系统，为开发者和项目方都提供了价值。

例如，开发者可以使用经过实战检验和审计的代码库、丰富的工具、文档等资源。如果创建一个与 Ethereum 基础设施不兼容的新 zkVM，将使项目和开发团队无法利用 Ethereum 的网络效应。

## 现有哪些类型的 zkEVM？

目前的 zkEVM 项目主要分为两大类：支持原生 EVM 操作码的 zkVM，以及使用自定义 EVM 操作码的 zkVM。下面我们比较不同的 zkEVM 协议，并说明它们的工作原理：

### Polygon zkEVM

Polygon Hermez 是一个 [Polygon ZK-rollup](https://www.alchemy.com/overviews/polygon-zk-rollups)，其零知识虚拟机专为支持 EVM 兼容性而设计。具体做法是：将 EVM 字节码编译为“微操作码”，并在 uVM 中执行——这是一种使用 SNARK 和 STARK 证明来验证程序执行正确性的虚拟机。

将两种证明类型结合使用是一种战略性的选择。STARK（可扩展透明知识论证）证明生成速度更快，而 SNARK（简洁非交互式知识论证）证明体积更小，在 Ethereum 上验证的成本更低。

Polygon Hermez zkEVM 使用 STARK 证明电路为状态转换生成有效性证明。随后生成一个 SNARK 证明来验证该 STARK 证明的正确性（可以将其理解为生成“证明的证明”），并将其提交至 Ethereum 进行验证。

### zkSync zkEVM

zkSync 是由 Matter Labs 开发、由自研 zkEVM 驱动的与 EVM 兼容的 ZK-rollup。zkSync 通过以下策略实现与 Ethereum 的兼容：

1. 将用 Solidity 编写的合约代码编译为 Yul——一种可以为不同虚拟机编译成字节码的中间语言。

2. 使用 LLVM 框架，将 Yul 字节码重新编译为专为 zkSync 的 zkEVM 设计的、与电路兼容的自定义字节码集。

与 Polygon Hermez 类似，zkSync zkEVM 是在语言层面而非字节码层面实现与 EVM 的兼容。例如，zkSync 的 zkEVM 并不支持传统的乘法和加法操作码（ADDMOD、SMOD、MULMOD）。

### Scroll zkEVM

[Scroll](https://scroll.io/blog/zkEVM) 是一个正在开发中的新型零知识 EVM 实现。Scroll 团队计划为每个 EVM 操作码设计零知识电路。这将使开发者能够在 Scroll 上部署原生的 Ethereum 智能合约，而无需修改底层的 EVM 字节码。

除其他方面外，Scroll zkEVM 将使用一种“密码学累加器”来验证存储的正确性，用于证明合约字节码是从给定地址正确加载的。

它还提供了一个用于将字节码与执行轨迹相关联的电路。执行轨迹是一个序列，指定了执行了哪些虚拟机指令以及执行顺序。证明者将在证明生成过程中提交执行轨迹，以验证计算与原始字节码保持一致。

### AppliedZKP zkEVM

[Applied ZKP](https://github.com/privacy-scaling-explorations/zkevm-specs) 是由以太坊基金会资助的一个项目，旨在开发一个与 EVM 兼容的 ZK-rollup，以及一种为 Ethereum 区块生成有效性证明的机制。后一部分至关重要，因为将区块与有效性证明配对，可以省去节点重新执行区块的需要。

Applied ZKP 的创新之处在于将计算与存储分离开来。它使用两种有效性证明——**状态证明**和 **EVM 证明**：

#### **状态证明**‍

检查涉及存储、内存和栈的操作是否正确执行。状态证明本质上是验证读写操作的准确性。

#### **EVM 证明**

检查计算是否在正确的时间调用了正确的操作码。EVM 证明验证计算本身，同时也确认状态证明为每个操作码执行了正确的操作。

AppliedZKP zkEVM 使用一种总线映射（bus mapping）将状态证明与 EVM 证明关联起来。此外，只有当两种证明都通过验证后，Ethereum 区块才会被判定为有效。

## zkEVM 的开发进展目前处于什么阶段？

除了 zkSync 之外，大多数零知识 EVM 仍处于开发阶段。尽管如此，零知识技术的持续发展意味着，功能完备的 zkEVM 的前景比以往任何时候都更为可期。

与此同时，开发者可以借助 StarkNet 零知识虚拟机，来利用零知识应用的各项优势。StarkNet 并不与 EVM 兼容，但可以将 Solidity 源代码编译为自定义的、对 ZK 友好的字节码。你也可以选择直接用 Cairo（StarkNet 的语言）编写合约。

立即免费注册 Alchemy，开始[在 StarkNet 上构建](https://www.alchemy.com/layer2/starknet)应用。

## 常见问题

### zkEVM 代表什么？

zkEVM 代表零知识以太坊虚拟机（Zero-Knowledge Ethereum Virtual Machine），是一种在执行智能合约的同时生成零知识证明以验证正确性的虚拟机。

### zkEVM 与标准的以太坊虚拟机有何不同？

zkEVM 与 EVM 兼容，但它会生成零知识证明来验证交易的有效性，从而实现链下执行、链上验证，以提升可扩展性。

### zkEVM 的主要组成部分有哪些？

zkEVM 由三个部分组成：运行智能合约的执行环境、生成零知识证明的证明电路，以及在 Ethereum 一层上检查证明的验证者合约。

### zkEVM 的用途是什么？

zkEVM 为 ZK-rollups 提供支持，而 ZK-rollups 是一种 Ethereum 二层扩容方案，它将交易批量放到链下处理，并将有效性证明提交给一层，以实现更快、更便宜的执行。

### 为什么 zkEVM 难以构建？

构建 zkEVM 之所以具有挑战性，是因为 EVM 在设计之初并未考虑零知识证明，其特殊操作码、基于栈的架构、存储开销以及高昂的证明成本都增加了电路设计的复杂性。

### 与 Optimistic rollups 相比，zkEVM 是如何提升可扩展性的？

zkEVM 通过有效性证明实现即时最终性，省去了 Optimistic rollups 所需的 1-2 周挑战期，从而实现更快的交易处理。

### 什么是 zkEVM 操作码？

zkEVM 操作码是用于在 ZK-rollups 中执行程序的底层机器指令，其创建方式要么是为原生 EVM 操作码构建 ZK 电路，要么是开发新的对 ZK 友好的语言。

### zkEVM 实现有哪些示例？

例如 Polygon zkEVM（使用微操作码及 SNARK/STARK 证明）、zkSync（将 Solidity 编译为自定义字节码），以及 Scroll（为每个 EVM 操作码设计电路）。
