概述

ZKEVM 是一种虚拟机,它生成 零知识证明 以验证程序的正确性。ZKEVM 被设计以支持零知识技术的方式执行智能合约。

ZKEVM 是 ZK-Rollup 的一部分,ZK-Rollup 是以太坊第二层扩展解决方案,通过将计算和状态存储转移到链下来提高吞吐量。ZK-rollup 将交易数据和验证链下交易批次有效性的零知识证明一起提交给以太坊。

早期的 ZK-Rollup 缺乏执行智能合约的能力,仅限于简单的代币交换和支付。但是,随着 EVM 兼容的零知识虚拟机的引入,ZK-Rollup 开始支持以太坊 DApps。

在这篇文章中,我们探讨了 ZKEVM 是如何运作的,为什么它重要,以及存在哪些类型的 ZKEVM。

什么是 ZKEVM?

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

我们将进一步解析这个定义,以便让您更容易理解:

EVM 兼容性

EVM 是以太坊网络上部署的智能合约执行的运行环境。EVM 充当一个“世界计算机”,为运行在以太坊区块链上的去中心化应用程序(DApps)提供动力。

如果一台虚拟机能够运行在 EVM 环境中创建的程序,那么它就被认为是“兼容 EVM”的。这样的虚拟机可以执行用 Solidity 或其他在以太坊开发中使用的高级语言编写的智能合约。ZKEVM 是兼容 EVM 的,因为它们可以执行以太坊智能合约,而无需对底层逻辑进行大量修改。

对零知识技术的支持

EVM 从未被设计用来支持零知识证明,这使得构建与 EVM 兼容、对零知识友好的虚拟机变得困难。然而,研究的进步(多项式承诺、查找表证明和自定义小组件、递归证明和硬件加速等技术发展)在一定程度上使得将 EVM 计算包裹在零知识证明中成为可能。

不同的 ZKEVM 项目采用不同的方法将 EVM 执行与零知识证明计算相结合。每种方法都有其独特的权衡,我们将在本指南的后续部分探讨这些权衡。

ZKEVM 是如何工作的?

就像 EVM 一样,ZKEVM 也是一种虚拟机,它会因程序操作而在各种状态之间转换。但 ZKEVM 更进一步,通过产生证明来证实计算的正确性。本质上,ZKEVM 使用一种机制来证明执行步骤遵循了规则。

要理解 ZKEVM 是如何运作的(以及它为何与众不同),让我们回顾一下当前 EVM 的运作方式。

EVM 如何运作

以太坊虚拟机是一种状态机,它会根据一些输入从旧状态转变为新状态。每一次智能合约的执行都会触发 EVM 状态的改变(被称为“状态转换”)。以下是在智能合约交易过程中发生的事情的高级概述:

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

  2. EVM 操作码(包含在字节码中)与 EVM 状态的不同部分(内存,存储和堆栈)进行交互。操作码执行读写操作——从状态存储中读取(获取)值并向 EVM 的存储写入(发送)新值。

  3. EVM 操作码在返回新值之前,对从状态存储中获取的值进行计算。这次更新导致 EVM 转变到一个新的状态(因此,交易被称为“状态转换”)。其他节点复制这个新状态,并保持直到执行另一笔交易。

展示程序如何在以太坊虚拟机中执行

ZKEVM 是如何运作的

ZKEVM 生成零知识证明,以验证每个计算中的各种元素:

  1. 字节码访问:是否已从正确的地址正确加载了正确的程序代码?
  2. 读写操作:
    • 计算前,程序是否从堆栈/内存/存储中获取了正确的值?
    • 执行完成后,程序是否将正确的输出值写入堆栈/内存/存储中?
  3. 计算:操作码是否正确执行(即顺序执行且没有跳过任何步骤)?

ZKEVM 的架构

ZKEVM 分为三个部分:执行环境、证明电路和验证器合约。每个组件都为 ZKEVM 的程序执行、证明生成和证明验证做出贡献。

  1. 执行环境

    正如其名,执行环境是在 ZKEVM 中运行程序(智能合约)的地方。ZKEVM 的执行环境的功能非常类似于 EVM:它接受初始状态和当前交易,以输出一个新的(最终)状态。

  2. 证明电路

    证明电路产生零知识证明,验证在执行环境中计算的交易的有效性。证明生成过程使用 pre-state、transaction inputs 和 post-state 信息作为输入来完成。之后,证明者获得了对特定状态转换有效性的简洁证明。

    ZKEVM-model

    换个角度来说,计算的本质是通过给定的输入可以得到确定的输出。交易的执行实际上就是输入经过函数处理生成输出的过程,zkp 就是为了证明函数执行的正确性。zk 电路可以理解为是对合约代码的转译,evm 将合约代码转译成字节码,zk 电路就是将合约代码转译成便于生成零知识证明的另外一种语言,然后通过相关的密码学算法就可以生成证明,验证函数执行的正确性。zk 电路类似汇编,但是更具有数学特性,称为代数电路,它只能包含加法、乘法和一些基本的门操作。

    简而言之,如果想要给一个程序(合约代码)生成证明,那么需要先将程序用 zk 这种语言重写出来,这种 encoding 的方式就叫做 zk 电路。电路只是合约代码的另外一种表现方式。所以如果将合约在 zkevm 的执行看错是普通程序加载过程的话,zk 电路的编写实际可以看作是合约程序的预处理。目前证明生成时间较长的原因并不在于 zk 电路的编写。

  3. 验证器合约

    ZK-Rollup 将有效性证明提交给部署在 L1 链(以太坊)上的智能合约进行验证。输入(pre-state 和 transaction)和输出(final state)也提交给验证器合约。然后,验证器对提供的证明进行计算,并确认提交的输出是从输入正确计算出来的。

ZKEVM 操作码是什么?

ZKEVM 操作码是用于在 EVM 兼容的 ZK-rollup 中执行程序的低级机器指令。与 EVM 一样,用高级语言编写的合约必须被编译成虚拟机可以解释的低级语言(字节码)。这个字节码指定了在虚拟机中部署程序时使用的操作码。

我们需要 ZKEVM 操作码,因为常规的 EVM 操作码在零知识证明电路中的使用效率不高。通常有两种方法来为 ZKEVM 创建操作码:

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

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

这种方法需要在算术电路中实现所有 EVM 指令集,这是一项复杂且耗时的任务。其优点是,开发人员可以使用 现有的区块链开发工具 创建智能合约,或者将现有的以太坊合约移植到 ZK-Rollup,无需进行大量修改。

为零知识证明计算创建新的语言

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

虽然这种方法通常比第一种方法更容易实施,但它也有缺点。例如,开发者可能无法访问现有的以太坊基础设施和资源。

ZKEVM-compatibility

构建 ZKEVM 有什么困难?

由于 EVM 并未考虑到 zk-proof 计算,因此它具有一些对证明电路不友好的特性。以下是四个使构建 ZKEVMs 困难的因素的简要概述:

  1. 对椭圆曲线支持有限。目前,EVM 只支持 BN254 配对。由于不直接支持循环椭圆曲线,进行证明递归变得困难。在这种设置下使用其他专用协议也很困难。验证算法必须对 EVM 友好。
  2. 特殊操作码。EVM 使用特殊的操作码进行程序执行(CALL,DELEGATECALL)和错误处理(REVERT,INVALID)等操作。这增加了为 EVM 操作设计证明电路的复杂性。
  3. 基于栈的架构。EVM 使用的是基于栈的架构,尽管比基于寄存器的结构简单,但却增加了证明计算的难度。SyncVM(zksync)和 Cario(starkware)架构在基于寄存器的模型中定义了自己的 IR/AIR。他们构建了一个专门的编译器,将智能合约代码编译成新的 zk-friendly IR。他们的方法是兼容语言,而不是原生 EVM 兼容。
  4. 存储开销。EVM 的存储布局依赖于 Keccak 哈希函数和一个巨大的 MPT(Merkle Patricia Trie),这两者都具有巨大的证明开销。例如,Keccak 哈希在电路中比 Poseidon 哈希大 1000 倍。然而,如果你用另一个哈希替换 Keccak,它将会对现有的以太坊基础设施造成一些。一些 zkEVM(如 ZkSync)试图通过替换 KECCAK256 函数来规避这个问题——但这可能会破坏与现有以太坊工具和基础设施的兼容性。
  5. 证明成本。即使上述问题得到解决,我们仍然需要面对证明生成过程。生成零知识证明需要专门的硬件,以及在时间、金钱和努力上的大量投入。

虽然这个列表并不详尽,但它列出了一些阻碍构建 EVM 兼容 ZKEVMs 的问题。然而,零知识技术的几项突破 使得缓解这些问题成为可能,从而重新激发了对 ZKEVM 解决方案的兴趣。

  • 多项式承诺的使用。在过去的几年里,大多数简洁的零知识证明协议都坚持使用 R1CS,其中 PCP 查询被编码在一个应用特定的可信设置中。电路的大小通常会膨胀,由于每个约束的度需要为 2(双线性配对 只允许在指数中进行一次乘法),所以不能做很多定制化的优化。有了 多项式承诺方案,可以在通用设置或甚至透明设置中提升你的约束到任何程度。这在选择后端时提供了极大的灵活性。
  • 查找表参数和定制小工具的出现。另一个强大的优化来自于查找表的使用。这种优化首先在 Arya 中提出,然后在 Plookup 中得到优化。这可以为 zk-unfriendly 原语(即,位运算如 AND,XOR 等)节省大量资源。定制小工具允许你以高效的方式进行高度约束。TurboPlonk 和 UltraPlonk 定义了优雅的程序语法,使使用查找表和定义定制小工具更加容易。这对于减少 EVM 电路的开销非常有帮助。
  • 递归证明越来越可行。过去,递归证明由于依赖特殊的配对友好型循环椭圆曲线(即 MNT 曲线构造)而产生了巨大的开销。这引入了大量的计算开销。然而,越来越多的技术使得这种情况在不牺牲效率的情况下成为可能。例如,Halo 可以避免需要配对友好曲线,并使用特殊的内积论证来分摊递归的成本。Aztec 表明,你可以直接为现有协议进行证明聚合(查找表可以减少非本地字段操作的开销,从而使验证电路变小)。这可以大大提高支持的电路规模的可扩展性。
  • 硬件加速正在使证明过程更加高效。Scroll 已经制造了最快的 GPU 和 ASIC/FPGA 证明器加速器。他们关于 ASIC 证明器的论文已经被今年最大的计算机会议(ISCA)接受。GPU 证明器的速度比 Filecoin 的实现快 5 倍到 10 倍。这可以大大提高证明器的计算效率。

ZKEVM 为何重要?

构建一个完全功能的 ZKEVM 将鼓励开发 EVM 兼容的 ZK-rollup 项目。这带来了几个优点:

  1. 安全可扩展性
  2. 更低的成本
  3. 更快的最终确定性和资本效率
  4. 网络效应

1. 安全可扩展性

根据协议规则,所有验证节点必须重新执行以太坊虚拟机中进行的所有计算。这种方法确保了安全性,因为以太坊节点可以独立验证程序的正确性,但它对可扩展性设定了限制(以太坊网络只能处理大约 15-20 笔交易)。

兼容 EVM 的 ZK-Rollup 可以解决以太坊的吞吐量问题,而不会破坏网络安全。与其他扩展协议一样,ZK-Rollup 不受以太坊的共识协议规则的限制,可以优化执行速度。一些估计表明,ZK-Rollup 可以每秒处理约 2000 笔交易,而不会产生以太坊的高昂费用。

然而,与其他扩容项目相比,ZK-Rollup 具有更高的安全保证;它们通过有效性证明来验证链下计算的正确性。这意味着可以在 L1(以太坊)上可靠地验证在 L2 上由智能合约执行的交易,而无需节点重新执行操作。这可以显著提高以太坊的处理速度,而不会降低安全性。

2. 更低的成本

Rollups 通过将交易数据写入以太坊主网来获取安全性,这些数据以 CALLDATA 的形式存在。然而,OP-Rollups 和 ZK-Rollup 关于哪些数据必须发布在以太坊上存在差异。

由于 optimistic rollups 并未为链下交易提供有效性证明,因此它们需要将所有与交易相关的数据发布到链上(包括签名和交易参数)。如果不将所有数据放在链上,挑战者将无法构建用于挑战无效 rollup 交易的欺诈证明。

相反,ZK-Rollup 可以在以太坊上发布最少的数据,因为有效性证明已经保证了状态转换的可信度。ZKEVM 甚至可能省略交易输入,只发布最终状态的变化,进一步减少了 CALLDATA 的需求。

这对开发者和用户都有益,因为 大部分 rollup 的成本 来自于在链上发布数据。通过将 CALLDATA 减至最低,ZK-rollup 可以降低使用去中心化应用程序的成本,如去中心化交易所、NFT 市场、预测市场等等。

3. 更快的最终确定性和资本效率

除了更好的安全性,ZK-Rollup 还有一个优势超过 optimistic rollups:更快的最终确定性。在区块链中,最终确定性是指交易变得不可逆转所需的时间;只有当网络参与者拥有其有效性的客观证据时,交易才能被最终确定。

使用 ZK-Rollup,ZKEVM 中执行的交易通常在发布到以太坊后立即完成。由于每个交易批次都附带有可以立即验证的有效性证明,主以太坊链可以快速应用状态更新。

由于 optimistic rollups 仅发布无需证明的虚拟机交易,因此必须等待挑战期过去后,交易才能最终确定。挑战期是一个为期 1-2 周的期间,在此期间任何人都可以在交易提交到以太坊后对其提出挑战。

较慢的最终性对用户体验有许多影响。例如,用户不能在延迟期满之前从 rollup 中提取资产。流动性提供者可能会解决这个问题,但如果提款涉及高价值资产甚至 NFTs,可能会无效。

ZKEVM 没有上述所描述的任何问题。更快的最终确定性对于高级用户非常有利,例如 NFT 交易者,DeFi 投资者,或者需要无缝转移资产的套利交易者(尤其是在 L1 和 L2 之间)。

4. 网络效应

构建 EVM 兼容的 zkVMs 最重要的原理是利用以太坊的网络效应。作为全球最大的智能合约平台,以太坊拥有一个大型生态系统,为开发者和项目提供价值。

例如,开发者可以访问经过严格测试和审计的代码库,广泛的工具,文档等等。创建一个与以太坊基础设施不兼容的新 zkVM 将阻止项目和开发团队利用以太坊的网络效应。

存在哪些类型的 ZKEVMs?

Vitalik 在文章 The different types of ZK-EVMs(中文翻译) 中给 zkevm 分类四类:

  • 类型 1:等效于以太坊。

    类型 1 ZK - EVM 力求完全和毫不妥协的等效于以太坊。它们不改变以太坊系统的任何部分,以使生成证明更容易。它们不会取代哈希、状态树、事务树、预编译或任何其他共识逻辑,无论它有多么外围。

  • Type 2:完全等效于 EVM。

    Type 2 通过去除一些不利于 ZK 的部分,使得证明生成更快、电路开发更容易。然而,由于这一点的后果,它可能会使得 ZK-rollup 的其他部分(例如节点软件)的开发更加复杂。这些复杂性可能是由于已经确立的最佳实践和测试工具与实施的更改(例如改变的状态树)不兼容所导致的。可能修改的不友好的零知识元素的具体示例:

    • 哈希函数:虽然以太坊使用 Keccak 哈希函数,但许多 ZK-EVM 使用 Poseidon 哈希函数,它需要的门电路数量显著较少。例如,让我们估计每种类型的哈希函数可以每秒计算多少个(即证明生成速度的比较)。Poseidon 哈希函数在证明生成方面具有显著的速度优势。

      然而,需要注意的是,相对于广泛社区认可的已建立的密码学原语,较新的密码学原语并不那么受青睐。尽管 Poseidon 可能提供速度,但 Keccak 经过实战检验的特性使其更具鲁棒性和安全,因为它被广泛采用。

      这就是为什么 Keccak 尽管更古老且被更广泛的社区采用(在其他行业,例如安全系统或智能设备中的传感器),但可以被认为比 Poseidon 更更经得起考验,毕竟 Poseidon 是在 ZK 社区内创建和使用的新哈希函数。

    • 用于数据存储的状态树:例如,虽然以太坊使用 Merkle Patricia 树(使用 Keccak 哈希),但一些 Type 2 ZK-EVM 选择稀疏 Merkle 树(使用 Poseidon 哈希)。更改状态树可能会导致一些不兼容性。例如,以太坊的 Merkle 树具有不同的节点类型,并使用 RLP 对数据进行编码,这在 ZK 中是一件困难的事情。

    • 块结构: 块包含大量信息。然而,在探索 L2 时,我们只关心 execution_payload_header(即块哈希)。

  • Type 3:几乎等效于 EVM。

    Type 3 ZK-EVM 省略了不适用于 ZK 的预编译,并可能调整内存和存储访问。依赖已删除的预编译的 DApp 需要进行重写。在不常见的情况下,Type 3 ZK-EVM 和原始 EVM 处理边缘情况的方式的差异可能需要对 DApp 进行调整。

  • Type 4:语言兼容。用高级语言(例如 Solidity,Zinc)编写的智能合约源代码被编译为中间表现形式,生成适用于 ZK 友好的虚拟机的操作码。

当前的 ZKEVM 项目主要分为两大类:支持原生 EVM 操作码的 zkVMs 和使用定制 EVM 操作码的 zkVMs。以下我们将比较不同的 ZKEVM 协议,并解释它们的工作原理:

AppliedZKP ZKEVM

Applied ZKP 是一个由以太坊基金会资助的项目,旨在开发一个与 EVM 兼容的 ZK-rollup 以及一个用于生成以太坊区块有效性证明的机制。最后一部分至关重要,因为将区块与有效性证明配对将消除节点重新执行区块的需要。

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

State proofs‍

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

EVM proofs

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

AppliedZKP ZKEVM 的 ZKEVM 利用总线映射来连接状态证明和 EVM 证明。此外,在以太坊区块被认定为有效之前,必须验证这两种证明。

Scroll ZKEVM

Scroll 是一款正在开发中的全新零知识 EVM 实现。Scroll 团队计划为每个 EVM 操作码设计零知识电路。这将允许开发者在不需要修改底层 EVM 字节码的情况下,在 Scroll 上部署以太坊原生的智能合约 EVM。

除其他事项外,Scroll ZKEVM 将使用“密码学累加器”来验证存储的正确性。这被用来证明合约字节码已从给定地址正确加载。

它还提供了一个电路,用于将字节码与执行跟踪(execution trace)进行链接。执行跟踪是一个序列,指定了执行了哪些虚拟机指令以及执行的顺序。在生成证明时,证明者将提交执行跟踪,以验证计算是否与原始字节码一致。

Polygon ZKEVM

Polygon Hermez 是一个配备了兼容 EVM 的 ZKEVM 的 Polygon ZK-rollup,旨在支持 EVM 兼容性。为了实现这一点,EVM 字节码被编译成"微操作码",并在 uVM 中执行——这是一个使用 SNARK 和 STARK 证明来验证程序执行正确性的虚拟机。

将两种证明类型结合的决定是战略性的。STARK(可扩展透明知识论证)证明的生成速度更快,但 SNARK(简洁非交互式知识论证)证明更小,且在以太坊上验证的成本更低。

Polygon Hermez ZKEVM 使用 STARK 证明电路来生成状态转换的有效性证明。SNARK 证明验证 STARK 证明的正确性(可以将其视为生成“证明的证明”),并提交给以太坊进行验证。

zkSync ZKEVM

zkSync 是由 Matter Labs 开发并由其自身的 ZKEVM 驱动的与 EVM 兼容的 ZK-rollup。zkSync 通过以下策略实现与以太坊的兼容性:

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

  2. 使用 LLVM 框架重新编译 Yul 字节码,转换为专为 zkSync 的 ZKEVM 特别设计的定制电路兼容字节码集。

就像 Polygon Hermez 一样,zkSync ZKEVM 在语言级别实现了 EVM 的兼容性,而不是字节码级别。例如,传统的乘法和加法操作码(ADDMOD,SMOD,MULMOD)不被 zkSync 的 ZKEVM 所支持。

我们在 ZKEVMs 的开发进程中处于哪个阶段?

除了 zkSync,大多数零知识 EVM 仍在生产中。然而,零知识技术的发展日益增长,意味着全功能的 ZKEVM 的前景比以往任何时候都更好。

与此同时,开发者可以利用 StarkNet 零知识虚拟机的优势,享受零知识应用的好处。StarkNet 并不与 EVM 兼容,但可以将 Solidity 源代码编译为定制的 ZK 友好字节码。您也可以选择用 Cairo(StarkNet 的语言)编写合约。

延伸阅读