自从以太坊 ZK-Rollups 技术大爆发以来,各种 ZKR Layer2 方案百花齐放,有 Order-list 的去中心化交易所 Loopring,有 AMM 的去中心化交易所 ZKSwap,有支持隐私的 zk.menoy 等等。这些 ZK-Rollups 方案丰富了以太坊 Layer2 生态,安全性由 Layer1 来保证,可以称之为“最”安全的以太坊扩展方案。

但是这些方案也只能支持特定应用的场景,不能支持通用的合约开发,究其原因,是因为 ZKP 的通用电路本身就非常复杂,且受限于以太坊 Gas/ 数据等的限制,设计和实现非常复杂,可以说 zkEVM 是以太坊扩容方案这颗皇冠上的明珠。目前有多个团队在进行 zkEVM 的研究,我们本篇来看看这些 zkEVM 设计方案。

Sin7Y 团队全面分析:现阶段 zkEVM 设计方案对比

zkEVM 的基本流程:

  • 交易 tx 先在 EVM 执行器执行(执行需要交易相关的 pre_state + tx 等),得到 post_state
  • pre_state、tx、post_state 输入到 zkEVM,执行后得到 proof
  • Proof 和 Public Input (关键数据)上传到 L1 合约进行验证

本文要说的重点 zkEVM,按照 zk 证明的对象,大体分为两类:

  • 对原生 EVM 的证明,包含对原生 Opcode 的 zk 实现。这类方案的研究团队有 AppliedZKP、Sin7Y 等。
  • 对自定义 EVM 的证明,包含对自定义操作码的 zk 实现。这类方案的研究团队有 Hermez、Matter Labs 等。

zkEVM 现状

zkEVM 技术团队 进度 open source
AppliedZKP zkEVM 以太坊基金会下的 AppliedZKP 设计方案初步形成,有部分测试代码。未说明何时上主网。 设计文档和测试代码开源
Matter Labs zkEVM Matter Labs 官方称除开几个 Opcode 和 Pre-compiled 合约未实现,已上测试网,Q4 上主网,但测试网未放开。 Compiler-yul 开源,其它未开源
Hermez zkEVM Hermez 团队,被 Polygon 收购合并 基本设计方案形成,2022 年 Q2 上主网。 未开源
Sin7Y zkEVM Sin7Y 基本设计方案形成,需要继续细化方案细节。 未开源

zkEVM 方案概览

zkEVM EVM 支持 合约代码解释路径 通用电路实现 密码工具
AppliedZKP zkEVM 对 EVM 原生的 opcode 逐个做 zk 实现 Solidity/Vyper -> zkEVM Custom Constraint Halo2+KZG10+BN256
Matter Labs zkEVM 自定义 EVM,中间实现解释器,将合约代码编译为 YUL,再将 YUL 编译为 zkEVM 支持的自定义字节码 Solidity/Vyper -> YUL -> LLVM -> zkEVM TinyRAM utralPLONK
Hermez zkEVM 自定义 EVM,中间实现 uVM,将合约代码编译为 uVM 支持的微指令集 Solidity/Vyper -> micro Op -> uVM * PLONK+KZG+Groth16
Sin7Y zkEVM 对 EVM 原生的 opcode 逐个做 zk 实现,增加 specialized opcode 优化实现 Solidity/Vyper -> zkEVM custom gate/TinyRAM halo2+KZG10+RecursivePLONK

EVM 基本模型

在开始介绍各方案的 zkEVM 之前,有必要讲讲 EVM 的基本模型,主要是操作和状态的关系,如下图:

Sin7Y 团队全面分析:现阶段 zkEVM 设计方案对比

图片来自 [Ethereum EVM illustrated]

EVM 的 opcode 在执行中,需要和 Stack、Memory、Storage 进行交互,还需要一些 Context 来进行上下文环境的记录,如 Gas/Program Counter 等。其中:Stack 只用于栈式访问,Memory 可以随机访问,Storage 也可以随机访问。这些 Opcode 的定义可参见 EVM opcode 网站

AppliedZKP zkEVM

AppliedZKP 将 Proof 分为两种:

1. State Proof :用于检查 Stack/Memory/Storage 中的状态转换的正确性。
2. EVM Proof :用于检查正确的 opcode 在正确的时间被调用,检查 Opcode 本身的正确性,检查 Opcode 的有效性,还需对 Opcode 执行过程中可能遇到的所有异常情况(比如 out_of_gas)进行检查。

这两个 Proof 前者检查状态,后者检查操作,还需要 Bus Mapping 将两个 Proof 连接起来,这个 Bus Mapping 不使用 Merkle 树,而是使用 Plookup k-v Mapping。

zkEVM 架构如下:

Sin7Y 团队全面分析:现阶段 zkEVM 设计方案对比

EVM proof 则使用 Slot 的方式,将 Opcode,Opcode 的操作值,Context 分开,如下图,一个 Circuit 由多个 Slot 构成,q_op 是 Selector,o_n 是 Opcode 的值,c_n 是 Context,v_n 是操作的值。

Sin7Y 团队全面分析:现阶段 zkEVM 设计方案对比
图片来自 [ZKEVM EVM Circuit Explore]

Matter Labs zkEVM

Matter Labs 的 zkEVM 设计方案又是另外一种,它将 Solidity 和 vyper 语言编写的合约代码,编译成 Yul,再通过 LLVM 将 Yul 代码翻译成 zkEVM 支持的字节码。

Sin7Y 团队全面分析:现阶段 zkEVM 设计方案对比
图片来自 ['zkEVM' - Alex Gluchowski at ETHGlobal]

前段时间 Matter Labs 开源了其 Yul 编译器,可以将中间码 YUL 编译为自定义语法的字节码,而字节码可以运行在 zkEVM 中,源码见 此处

Sin7Y 团队全面分析:现阶段 zkEVM 设计方案对比
图片来自 ['zkEVM' - Alex Gluchowski at ETHGlobal]

Matter Labs 的电路实现,是使用 TinyRAM 来实现普通 Opcode,如 ADD,PUSH 等;对 Gas 消耗巨大的 Opcode,比如 SHA256/keccak,特殊实现该电路;最后使用递归聚合技术,将所有的 Proof 聚合成一个 Proof。

Hermez zkEVM

Hermez 的 zkEVM 方案同样令人耳目一新,他们设计了 uVM 架构,类似 Intel X86 架构,分 ROM/RAM 等模块,通过主状态机(Main State Machine)来同步模块之间的状态。uVM 架构使用 Register 而不是 Stack,这样完成同样的工作,基于 Register 的 VM 所使用的指令数比基于堆栈的 VM 所使用的指令数少,可以提高执行效率。再者,uVM 使用了大量的密码学工具,来实现 zk 完备。

Sin7Y 团队全面分析:现阶段 zkEVM 设计方案对比
图片来自 [Hermez zkEVM 介绍]

Hermez 最创新的设计是将 EVM 指令集翻译为中间指令(Micro Opcode),中间指令可以在 uVM 中执行。并且使用了大量的 Plookup 算法来提升证明及验证效率。

Sin7Y 团队全面分析:现阶段 zkEVM 设计方案对比
图片来自 [Hermez zkEVM 介绍]

Sin7Y 团队全面分析:现阶段 zkEVM 设计方案对比
图片来自 [Hermez zkEVM 介绍]

Sin7Y zkEVM

Sin7Y 团队全面分析:现阶段 zkEVM 设计方案对比
我们的 zkEVM 借鉴了上面三个的设计,将状态验证和执行验证分开,分为 State Proof 和 EVM Proof。

其中:

state proof

  • Stack Proof:验证 pop、push 等栈操作
  • Memory Proof:验证 mload、mstore 等内存操作
  • Storage Proof:sload、sstore 等 Storage 操作

EVM Proof

使用 Slot 的方式,暂定用 Custom gate 的方式,将 EVM 的 Opcode 实现:

Sin7Y 团队全面分析:现阶段 zkEVM 设计方案对比

一个 Slot 实现了所有的 Opcode,能够表达任意的 Opcode。在合约中,会有多个 Opcode,这时可以使用 Selector 来选择激活哪个 Opcode。最终的合约电路将会包含多行 Slot,全面支持 EVM Opcode。

当然,在实际的方案设计和工程实现过程中,仍然面临许多待确定和解决的 问题 ,如:

  1. EVM 到底是 Native 的好,还是 Customized 的好?

  2. 对于 Arithmetic ops,是单独设计 Lookup Table 还是设计公用的 Lookup Table?

  3. 如何约束 Variable 的 OP?

  4. 多少个 Custom Circuit 合适?数量太多则必须得用 Recursive Aggreative,这样会大大增加电路设计复杂度。

  5. 是否考虑用 Register 代替 Stack 来缩减电路规模,提升 zkEVM 执行效率?

  6. 考虑到 zkEVM 正式上线的时间,是否直接用 BLS12-381 曲线 ?

  7. Custom Slot 要处理所有的 Arithmetic OPS 的计算,包含正确计算和错误计算,op type 是由 Selector 指定,那么正确 or 错误的结果该如何指定?

  8. Tinyram 是否真的能优化 Arithmetic ops?

...

诸如以上的问题,如果我们寻找到了答案,会在后续的文章中详细展示出我们的解决方案,请持续关注我们的 官推 以及其他官方账号。也欢迎各位读者参与研究讨论。

引用

Ethereum EVM illustrated

ZKEVM EVM Circuit Explore

'zkEVM' - Alex Gluchowski at ETHGlobal

Compiler-yul

Introducing Hermez zkEVM