撰文: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的核心模块

OP Stack + 零知识证明 = L2终局游戏?

(该图截自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)。

OP Stack + 零知识证明 = L2终局游戏?

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的一个实现,包含两个主要组件:

  • OnchainMIPS.sol: EVM implementation to verify execution of a single MIPS instruction.
  • Offchainmipsevm: 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)

OP Stack + 零知识证明 = L2终局游戏?

source: Cypher Capital
  1. 用户提交交易,可以通过L2 RPC在L2上提交,或者在L1上直接提交(可以绕过op-batcher,有更强的抗审查能力,也可作为紧急逃生装置)。
  2. op-node启动的RPC server接收到交易后,进行排序并发送给op-batcher与op-geth
  3. op-batcher对sequenced tx进行压缩,生成batch,提交到DA层(L1)。
  4. op-geth执行sequenced tx,将执行后的新状态传递给op-proposer
  5. op-proposer将L2的output root作为对于L2状态的承诺发送到L1进行存储,当挑战期结束,状态被视为finalized。
  6. 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流程

OP Stack + 零知识证明 = L2终局游戏?

source: optimism
  1. 用户开启interactive dispute game
  2. Cannon (VM)在MIPS虚拟机上运行op-program(Written in Go),以便追踪每步执行的状态变化
  3. op-program通过PreImageOracle提供的Rollup Inputs的承诺复现L2状态的计算过程,记录execution trace,无状态地验证dispute
  4. op-challenger使用二分法,将争议定位到单个指令
  5. 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方案

OP Stack + 零知识证明 = L2终局游戏?

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/