OP Stack + 零知识证明 = L2的终局游戏?
撰文:Bill Qian、Yongxin Song、Bonan Yuan,Cypher Capital
Layer2的终局游戏
如今的Layer2赛道厮杀异常激烈,前有Arbitrum, Optimism, Base 等基于optimistic的rollup,后有Scroll, zkSync, Starkenet, Scroll,Polygon zkEVM, Taiko, Linea等基于ZeroKnowledge Proof的ZKP rollup。看似Layer2的竞争百花齐放,实则都在工程原理上都是使用了,链下计算,链上证明的思路。无论是optimistic的 fraud Proof还是ZKP的电路证明,在工程实践上的核心区别,即是在链上证明方式的不同,别的原理其实大同小异。于是乎,Optimism选择了一条特殊的路径,即模块化Layer2,在逻辑上将Layer2多各个组件解藕。当OPstack实现Layer2各个模块的结偶后,一个非常看似脑洞大开时则合乎逻辑的思路打开了,即ZKP on OP Stack,把OP Stack的challenger由Optimistic Proof改成Zero Knowledge Proof,OpStack将成为支持多种证明的通用Layer2架构!
ZKP on OP Stack
一切讨论的开始来自一篇Optimism的RFP, https://github.com/ethereum-optimism/ecosystem-contributions/issues/61。
下面我来介绍下这篇RFP提出的问题和发展方向。
意图:实现零知识证明以证明Optimism’s 错误证明程序(通过Golang编译器支持的指令集)
如何实现:给OP链实现零知识证明(ZKP)是实现L2与L1之间安全和低延迟通信的前提。一种支持指令集的零知识证明,可以证明Optimism的错误证明程序,且包括任意OP Stack的区块链。在证明ISA的标准执行跟踪的基础上,支持故障证明程序还引入了额外的要求。
具体来说,故障证明程序引入了“预图预言机”的概念,它使用特殊的系统调用将外部数据加载到程序中。每个故障证明虚拟机负责实现一些机制,通过该机制,某些数据的哈希被放置在内存的特定位置,执行系统调用,然后将该哈希的原像加载到内存中供程序使用。预图预言机还用于使用初始输入引导程序。有关详细信息,请参阅故障证明程序文档中的“预图预言机”部分。
简而言之,该提案就是想利用OP Stack的高度模块化特性,将原本基于乐观证明(Opstimisic Proof)的错误证明方式,切换为利用零知识证明完成。进一步的特化,因为目前OP是将GETH通过MIPS编译为Mini Geth, 那么OP Stack的零知识证明可以理解为 ZKMips,即基于Mips虚拟机的零知识证明。
Why ZKP?
目前基于OP Stack不是跑的好好的嘛,基于乐观证明的Optimism和Arbitrum都取得极其良好的社区支持和开发者支持。OP Stack为什么还要探索零知识证明呢?笔者认为这里有几点原因
- OP Stack将layer2的模块高度抽象化,引入ZKP只是引入不同的错误证明方式,并不意味着OP会放弃乐观证明。使用OP Stack的开发者可以自由选择不同的证明方式
- 基于乐观证明(Optimistic Proof)的Optimism和Arbitrum目前依然不支持错误证明,本质上OP和ARB是两条无法证伪的单机链。
- 乐观证明7天的最终确认速度,实在是太慢了。当ZKP的Layer2占据市场后,ZKP快至30分钟的证明速度会形成显著的优势,最终用户会选择安全性更高的ZKP Layer2
因此,Optimism支持ZKP是迟早的时间。大胆的猜想,未来OP Stack会支持乐观证明和零知识证明2套错误证明系统。OP Stack是一套通用的Layer2架构,并不断迭代。为了帮助大家理解OP Stack为什么可以实现不同证明系统的切换,下文将详细的拆解OP Stack。
OP Stack的核心模块
(该图截自optimism的github)
对于OP Stack,重要的几个模块如下:
- op-node
- op-geth
- op-batcher
- op-proposer
- op-program
- Cannon
- op-challenger
这些模块均为独立的程序,并通过http的标准接口沟通,这意味着开发者如果要修改OP Stack中的一些特性,只需要修改其中的特定模块,便可以定制自己的Layer2。下面的章节,将具体的介绍每一个OP Stack的模块,和OP Stack的整体架构。
op-node
op-node是OP Stack中最重要的模块。一方面,作为Sequencer,op-node包含了区块链的共识客户端实现,可以类比以太坊中的Lighthouse, Prysm,为用户提交的交易进行排序;另一方面,作为rollup driver,op-node负责从L1区块的数据中衍生出Layer2的链。
Sequencer在收集用户交易并排序后,会由op-batcher生成一个batch,在batcher将batch提交到L1之前,为了降低Rollup网络中的延迟,Sequencer可以提前生成Layer2的block,通过P2P在Rollup网络中传播。在L2直接产生的block被认为是unsafe的,需要等待batch提交到L1后进行推导才能够视为safe,不过在正常情况下(无区块重组、欺诈等),L2直接产生的block与从L1推导出的block是相同的。Binance等交易所仅等待一定的Layer2 blocks后便认为交易是确定的,而无需等待batch被提交到L1,一定程度上说明出错的概率极低。
推导L2区块的过程由driver负责,driver持续跟踪L1 head block和L2链同步过程,从L1中获取存款交易、L2交易数据和对应收据并生成payload attributes,将payload attributes传递给执行引擎,计算L2 block。L2 blocks完全依赖于L1链的区块,每当包含L2 batch的L1 block产生,L2链进行延伸。此外,当L1 block发生重组,L2 block也会发生重组。
op-geth
op-geth是OP Stack的执行客户端实现,对go-ethereum进行了微小的修改以适应OP Stack的需求。共识客户端op-node通过Engine API来驱动执行客户端op-geth,利用payload attribute,op-geth可以计算出output信息,产生L2 block。
op-batcher
batcher即为batch submitter,主要包含两个任务。一个是对L2 sequencer数据压缩为batches;另一个是将batches提交至L1,让verifier能够利用数据进行验证。
batcher向DA层提交batcher交易,交易包含一个或多个channel frame。channel由一系列sequencer batches组成,以获得更高的压缩率,具体而言,batcher当前使用zlib进行数据压缩。由于channel的大小可能超过batcher交易所能容纳的上限,channel被分为一个或多个channel frame,一个batcher交易可以包括一个或多个channel frame(可以来自不同的channel)。
source: Optimism
该设计为batcher提供了很高的灵活性,未来OP Stack会支持batcher利用多个signer并行提交多个channel。
op-proposer
op-proposer负责将op-geth执行L2 block后产生的新状态承诺(当前以Output Merkle Root形式)提交到L1。Output Root不会立即生效,而需要等待争议期过后才能视为Finalized。
以上为OP Stack已实现的部分,下列的Fault Proof相关模块内容尚未完成,仅根据文档规范进行论述。
OP Fraud Proof由三个组件组成:
- Program: 给定Rollup Inputs(L1 Batch tx Data)的承诺和dispute,无状态地验证dispute(通过PreImageOracle提供的Inputs复现相同的计算过程)
- VM: 给定无状态的Program和Inputs,追踪任何指令(因此是stateful),在L1上证明
- Interactive Dispute Game: 二分Dispute到单个指令,用VM解决这个base case
op-program
op-program是Program的参考实现,在op-node与op-geth的基础上开发,作为无状态的中间件,验证关于L2状态转移的Claim。
为了验证L2状态的声明,program首先将L1 data应用到finalized L2状态,重建最新的L2状态,这个过程与op-node的工作类似。区别在于,op-node从RPC取数据,把状态变化应用到磁盘;而Program从Pre Image Oracle取数据,将状态变化应用到内存。Program流式地从Oracle读取数据,并进行流式的状态变更,直到读到EOF或者提前终止条件。重建L2状态后,根据状态与claim是否相同返回验证结果。
Cannon
Cannon是VM的一个实现,包含两个主要组件:
- Onchain
MIPS.sol
: EVM implementation to verify execution of a single MIPS instruction.
- Offchain
mipsevm
: Go implementation to produce a proof for any MIPS instruction to verify onchain.
链上部分,MIPS.sol实现了big-endian 32-bit MIPS指令集,模拟Linux内核的最小子集,为Go程序提供支持,但是不包含并发相关的系统调用。
链下部分,mipsevm用Go语言模拟MIPS.sol的执行过程,
- It's Go code
- …that runs an EVM
- …emulating a MIPS machine
- …running compiled Go code
- …that runs an EVM
简而言之,Cannon在链上就是在EVM用MIPS去跑MINI Geth(GETH的MIPS编译),即ETH的Golang版本。
op-challenger
op-challenger负责处理与dispute game相关的流程。
挑战是先选中一个tx执行后的state root发出质疑,之后tx将分解为多个instruction,每个instruction执行后产生新状态,形成S1, S2, … Sn的状态序列。
为了提高效率,挑战双方需要轮流执行steps,分为Attack与Defend两类。
- Attack: 争议的前一个状态作为输入,期待争议状态作为输出。DAG中需要有对前一个状态的承诺。
- Defend: 争议状态作为输入,争议后一个状态作为输出。DAG中需要有对后一个状态的承诺。
举例而言,假设有1-9999个instruction,产生S1-S10000状态序列,先检验第5000个状态,如果相同,attack step,向左二分;如果不同,defend step,向右二分。
最终通过二分法将争议锁定在单个指令的前后状态上,再交由VM处理单个指令的状态验证。
模块的工作流程
正常流程(不包含Challenge)
source: Cypher Capital
- 用户提交交易,可以通过L2 RPC在L2上提交,或者在L1上直接提交(可以绕过op-batcher,有更强的抗审查能力,也可作为紧急逃生装置)。
- op-node启动的RPC server接收到交易后,进行排序并发送给op-batcher与op-geth
- op-batcher对sequenced tx进行压缩,生成batch,提交到DA层(L1)。
- op-geth执行sequenced tx,将执行后的新状态传递给op-proposer
- op-proposer将L2的output root作为对于L2状态的承诺发送到L1进行存储,当挑战期结束,状态被视为finalized。
- op-node中的driver会从L1中获取交易数据以及其他信息,derive出canonical L2 block。在L1上finalized的block中batch tx derive出的L2 block被视为finalized,在L1上被confirmed但未finalized的batch tx derive出的L2 block被视为safe,为降低延迟直接由L2生成的L2 block可以通过P2P提前传播,被视为unsafe。
Challenge流程
source: optimism
- 用户开启interactive dispute game
- Cannon (VM)在MIPS虚拟机上运行op-program(Written in Go),以便追踪每步执行的状态变化
- op-program通过PreImageOracle提供的Rollup Inputs的承诺复现L2状态的计算过程,记录execution trace,无状态地验证dispute
- op-challenger使用二分法,将争议定位到单个指令
- Cannon为执行该指令前后的状态变化生成证明,在L1上的智能合约MIPS.sol上进行验证。
OP Stack+ZKP
根据上面的流程介绍,我们容易发现,Challenge模块与其他模块的耦合度很低,对基本交易流程的影响很低,只有在出现欺诈行为的情况下(自2021年12月OP Mainnet上线至今尚未出现)才需要Challenge模块的介入。
为了缩短当前Optimism七天的退出确认时间,也为OP Stack提供更多模块化的选择,Optimism积极拥抱ZKP技术,希望为OP Stack带来能够证明Optimism fault proof program并且支持知名ISA的ZKP,O(1) Labs与Risc-0团队的方案通过了Foundation Mission (RFP) Application。
O(1) Labs方案
source: O(1) Labs
O(1) Labs作为Mina Protocol的开发团队,计划沿用Mina Protocol采用的Kimchi作为MIPS VM的proof system,仅作了一些小的改动。
Kimchi是一个Halo2-like PLONKish system currently configured with an inner-product-argument style polynomial commitment scheme. It supports verifiable computation using traditional turing-machine-based instruction sets.
Kimchi的后端可交换,当前的实现定义在Pasta curves using an inner-product-argument-based polynomial commitment scheme (Pasta-IPA)上,与EVM所用的密码学体系不兼容,在EVM上验证成本较高。于是O(1) Labs计划将Pasta-IPA改为KZG commitment scheme using the bn128 curves (bn128-KZG),可以使用EVM现成的precompile,效率更高。
原来输入fault proof MIPS系统的输入现在输到bn128-kzg Kimchi系统,ZK-Prove执行路径。pre-image系统调用沿用OP Stack的Cannon,最终proof发送到L1上的智能合约,验证通过后在L1更新状态。
RISC Zero方案
RISC Zero团队计划沿用当前实现的Groth16后端的基于RISC-V ISA的zkVM(augmented with accelerated co-processors for common cryptographic tasks including hashing and ECDSA signature verification), 对基于Reth的Ethereum ZK Client进行修改以进一步适配Optimism,在zkVM中实现L1-L2的derivation logic以证明交易序列是由Optimism sequencer生成的。
ZK Client由zkVM guest program和host library两个部分组成,类比OP labs方案中的op-program和cannon,zkVM guest program负责计算状态转移,host library负责获取计算数据转移所需的数据,协调zkVM guest program的执行,并生成交易执行状态转移的zkp。
O(1) Labs | RISC Zero | |
Performance | 44B MIPS instruction-steps for an Optimism block | <2B zkVM cycles for an Optimism block |
Latency | 2 days for an Optimism block without paralization | 10-20min for an Optimism block with paralization |
Complexity | Kimchi: 35kloc change 5-10kloc | ZKP framework: 10kloc of Rust zkVM: 54kloc of Rust |
Robustness | Mina has been securing by Kimchi for 2 years. | Extensive automated testing |
Security | kzg-bn128-based EVM-friendly snark system require trusted setup. | The zkVM emits STARK-based proofs that require no trusted setup. On-chain verification is based on STARK->SNARK conversion. |
OP Stack Compatibility | No fundamental change | No change |
OP Stack的ZKP可能性探究
目前一家叫做ZKM的团队实现了ZKMIPs的EVM,即将EVM转译为MIPs指令集并进行零知识证明。目前反馈为,很慢,但是可用。https://ethresear.ch/t/zkmips-a-zero-knowledge-zk-vm-based-on-mips-architecture/16156
考虑到Mina和Risc0都拥有相对成熟的开发,经验,我们有理由相信,OP Stack支持ZKP只是时间问题。但是同时,考虑到OP Stack的ZKP开发启动较晚,且不是原生支持,未来的性能如何依然无法预测。
OP Stack, Layer2的通用架构
OP Stack以其优秀的代码实现、宽容的开源协议以及模块化的架构设计获得了许多知名团队的采用,唯一为人所诟病的在于所采用的Optimistic Rollup技术确定性时间过长,技术先进性不如ZK Rollup。如今,借助第三方专业团队的力量,OP Stack开始了迈向ZKP未来的尝试。考虑到当前OP Stack尚未支持Fault Proof,OP Stack有可能跳过Fault Proof阶段,直接使用ZK Proof来获取更快的确定性与更高的安全性。
对于未来的Layer2开发者而言,OP Stack将成为通用的Layer2架构,开发者可以启动自己的Layer2时,依据应用所需要的安全性和实效性,灵活的选择乐观证明,或者零知识证明。可以预见的是,乐观证明的Layer2会更加廉价,零知识证明的Layer2则会更加安全。
reference: https://blog.oplabs.co/building-a-fault-proof-system/