2021-08-25 00:42 | 出处: ZKSwap
自从以太坊 ZK-Rollups 技术大爆发以来,各种 ZKR Layer2 方案百花齐放,有 Order-list 的去中心化交易所 Loopring,有 AMM 的去中心化交易所 ZKSwap,有支持隐私的 zk.menoy 等等。这些 ZK-Rollups 方案丰富了以太坊 Layer2 生态,安全性由 Layer1 来保证,可以称之为“最”安全的以太坊扩展方案。
但是这些方案也只能支持特定应用的场景,不能支持通用的合约开发,究其原因,是因为 ZKP 的通用电路本身就非常复杂,且受限于以太坊 Gas/数据等的限制,设计和实现非常复杂,可以说 zkEVM 是以太坊扩容方案这颗皇冠上的明珠。目前有多个团队在进行 zkEVM 的研究,本篇将对这些 zkEVM 设计方案进行详解。
本文要说的重点 zkEVM,按照 zk 证明的对象,大体分为两类:
| 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 | 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 |
在开始介绍各方案的 zkEVM 之前,有必要讲讲 EVM 的基本模型,主要是操作和状态的关系,如下图:
EVM 的opcode在执行中,需要和 Stack、Memory、Storage 进行交互,还需要一些 Context 来进行上下文环境的记录,如 Gas/Program Counter 等。其中:Stack 只用于栈式访问,Memory 可以随机访问,Storage 也可以随机访问。这些 Opcode 的定义可参见 EVM opcode 网站。
AppliedZKP 将 Proof 分为两种:
这两个 Proof 前者检查状态,后者检查操作,还需要 Bus Mapping 将两个 Proof 连接起来,这个 Bus Mapping不使用 Merkle 树,而是使用 Plookup k-v Mapping。
zkEVM 架构如下:
EVM proof 则使用 Slot 的方式,将 Opcode,Opcode 的操作值,Context 分开,如下图,一个 Circuit 由多个 Slot 构成,q_op 是Selector,o_n 是 Opcode 的值,c_n 是 Context,v_n 是操作的值。
Matter Labs 的 zkEVM 设计方案又是另外一种,它将 Solidity 和vyper 语言编写的合约代码,编译成 Yul,再通过 LLVM 将 Yul 代码翻译成 zkEVM 支持的字节码。
前段时间 Matter Labs 开源了其 Yul 编译器,可以将中间码 YUL 编译为自定义语法的字节码,而字节码可以运行在 zkEVM 中,源码见此处。
Matter Labs 的电路实现,是使用 TinyRAM 来实现普通 Opcode,如 ADD,PUSH 等;对 Gas 消耗巨大的 Opcode,比如 SHA256/keccak,特殊实现该电路;最后使用递归聚合技术,将所有的 Proof 聚合成一个 Proof。
Hermez 的 zkEVM 方案同样令人耳目一新,他们设计了 uVM 架构,类似 Intel X86 架构,分 ROM/RAM 等模块,通过主状态机(Main State Machine)来同步模块之间的状态。uVM 架构使用 Register 而不是 Stack,这样完成同样的工作,基于 Register 的 VM 所使用的指令数比基于堆栈的 VM 所使用的指令数少,可以提高执行效率。再者,uVM 使用了大量的密码学工具,来实现 zk 完备。
Hermez 最创新的设计是将 EVM 指令集翻译为中间指令(Micro Opcode),中间指令可以在 uVM 中执行。并且使用了大量的 Plookup 算法来提升证明及验证效率。
我们的 zkEVM 借鉴了上面三个的设计,将状态验证和执行验证分开,分为 State Proof 和 EVM Proof。
其中:
state proof:
EVM Proof:
使用 Slot 的方式,暂定用 Custom gate 的方式,将 EVM 的 Opcode 实现:
一个 Slot 实现了所有的 Opcode,能够表达任意的 Opcode。在合约中,会有多个 Opcode,这时可以使用 Selector 来选择激活哪个 Opcode。最终的合约电路将会包含多行 Slot,全面支持 EVM Opcode。
当然,在实际的方案设计和工程实现过程中,仍然面临许多待确定和解决的问题,如:
EVM 到底是 Native 的好,还是 Customized 的好?
对于 Arithmetic ops,是单独设计 Lookup Table 还是设计公用的 Lookup Table?
如何约束 Variable 的 OP?
多少个 Custom Circuit 合适?数量太多则必须得用 Recursive Aggreative,这样会大大增加电路设计复杂度。
是否考虑用 Register 代替 Stack 来缩减电路规模,提升 zkEVM 执行效率?
考虑到 zkEVM 正式上线的时间,是否直接用 BLS12-381 曲线?
Custom Slot 要处理所有的 Arithmetic OPS 的计算,包含正确计算和错误计算,op type 是由 Selector 指定,那么正确 or 错误的结果该如何指定?
Tinyram 是否真的能优化 Arithmetic ops?
...
诸如以上的问题,如果我们寻找到了答案,会在后续的文章中详细展示出我们的解决方案,请持续关注我们的官推以及其他官方账号。也欢迎各位读者参与研究讨论。