返回 Expert 笔记
Expert Day 241

ZK Co-processor — Axiom / Risc Zero / Brevis

ZK Coprocessor 概念、Axiom 历史数据 / Brevis SQL / Risc Zero zkVM

2026-12-28
Phase 4 - ZK电路开发实战 (Day 223-243)
ZKcoprocessorAxiomRiscZeroBrevisBonsai

日期: 2026-12-28 方向: ZK工程 / 电路开发 阶段: Phase 4 - ZK电路开发实战 (Day 223-243) 标签: #ZK #coprocessor #Axiom #RiscZero #Brevis #Bonsai


今日目标

类型内容
学习ZK Coprocessor 概念、Axiom 历史数据 / Brevis SQL / Risc Zero zkVM
实操部署一个 Risc Zero "hello world" zkVM 程序,提交到 EVM verify
产出risc0_demo/(含 Cargo + host + guest + verifier deployment)

背景与定位

ZK Coprocessor 是什么?/ What is ZK Coprocessor?

类比 GPU 是 CPU 的 coprocessor —— ZK coprocessor 是 EVM 智能合约的 "外挂":

  • EVM 合约能力受限(gas 上限、计算简单、无法访问历史数据)
  • 把复杂计算外包到 off-chain ZK prover
  • ZK prover 输出 (result, proof),合约只 verify proof

核心 use case:

  1. 历史数据查询:链上合约访问任意历史 block 的 state(如「Alice 过去 6 个月平均余额」)
  2. 重计算:链上 simulate 多次 swap、复杂金融建模
  3. 大规模数据聚合:on-chain index、leaderboard、空投资格批量验证
  4. 私有计算:不暴露中间数据但证明结果

为什么不是 The Graph / Subgraph?

  • Subgraph 是 trusted indexer
  • ZK Coprocessor 是 cryptographically verified

三大 ZK Coprocessor

1. Axiom

定位: 历史数据 + 复杂计算的 ZK 查询引擎

架构:

1. dApp call Axiom contract: query(blockNumber, slotKey, ...)
2. Axiom indexer fetches data
3. ZK proof: "this data was at block N, slot S"
4. Result + proof submitted to L1
5. dApp callback receives verified result

API 模式(伪代码):

contract MyDApp is AxiomV2Client {
    function _validateAxiomV2Call(...) internal override {
        // verify query template
    }

    function _axiomV2Callback(
        uint64 sourceChainId,
        address callerAddr,
        bytes32 querySchema,
        uint256 queryId,
        bytes32[] calldata axiomResults,
        bytes calldata extraData
    ) internal override {
        // 处理 ZK 验证后的数据
        uint256 balance = uint256(axiomResults[0]);
        // ...
    }
}

Axiom V2 主网合约 (Ethereum):

  • AxiomV2Core: 0x69963768F8407dE501029680dE46945F838Fc98B
  • AxiomV2Query: 0xf15cc7B983748686Cd1eCca656C3D3E46407DC1f

真实 use case:

  • Pirate Nation NFT — 用 Axiom 查 holder 的历史 holding 时长
  • DeFi yield protocols — 验证用户长期 LP behavior 后给奖励
  • Snapshot voting — 加 ZK 验证 voter 在某 block 持有 token

2. Risc Zero(Bonsai)

定位: 通用 zkVM coprocessor — 把任何 Rust 程序变 ZK proof

架构:

[Guest Rust program]
       ↓ cargo risczero build
[ELF binary (RISC-V)]
       ↓ Risc Zero zkVM exec
[receipt = (journal, seal/proof)]
       ↓ Bonsai 服务(云端 prover)
[proof in 5-30 min]
       ↓ on-chain verify
[Solidity verifier confirms]

Bonsai 是 Risc Zero 的 SaaS prover(GPU 集群),用户付费换 prove 时间。

关键合约:

  • RiscZeroVerifier (Sepolia): 0xBC6DB...(见 risczero docs)
  • 主网部署多个版本

3. Brevis

定位: ZK SQL — 让 dApp 用 SQL 查询历史链上数据

API:

SELECT SUM(amount) FROM erc20_transfers
WHERE token = 'USDC' AND from = '0xAlice'
  AND block_number BETWEEN 19_000_000 AND 19_100_000

→ Brevis 后端跑查询 + 生成 ZK proof → 合约接收 (sum_amount, proof) 验证

真实 use case:

  • 链上 DEX 给「忠实 LP」奖励:SQL 查询过去 30 天 LP 时长
  • 借贷协议给「长期还款好用户」降息

完整 RISC Zero "Hello World" 实现

项目结构

risc0_demo/
├── Cargo.toml
├── host/
│   ├── Cargo.toml
│   └── src/main.rs       # off-chain runner
├── methods/
│   ├── Cargo.toml
│   ├── build.rs
│   ├── guest/            # ZK guest code
│   │   ├── Cargo.toml
│   │   └── src/main.rs
│   └── src/lib.rs
└── contracts/
    └── HelloVerifier.sol

Cargo.toml (root)

[workspace]
members = ["host", "methods"]
resolver = "2"

[workspace.dependencies]
risc0-zkvm = "1.0"
risc0-build = "1.0"
serde = "1.0"

methods/guest/src/main.rs (the ZK program)

#![no_main]
use risc0_zkvm::guest::env;

risc0_zkvm::guest::entry!(main);

// proves: I know x such that fibonacci(x) = result
fn fib(n: u32) -> u64 {
    let mut a: u64 = 0;
    let mut b: u64 = 1;
    for _ in 0..n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn main() {
    // 1. read input from host
    let n: u32 = env::read();

    // 2. compute fib
    let result = fib(n);

    // 3. commit to public journal (becomes "public output")
    env::commit(&n);
    env::commit(&result);
}

methods/build.rs

fn main() {
    risc0_build::embed_methods();
}

methods/src/lib.rs

include!(concat!(env!("OUT_DIR"), "/methods.rs"));

host/src/main.rs (off-chain runner)

use methods::{HELLO_GUEST_ELF, HELLO_GUEST_ID};
use risc0_zkvm::{default_prover, ExecutorEnv};

fn main() {
    let n: u32 = 30;

    // 1. setup executor env with input
    let env = ExecutorEnv::builder()
        .write(&n).unwrap()
        .build().unwrap();

    // 2. produce receipt (proof + journal)
    let prover = default_prover();
    let receipt = prover.prove(env, HELLO_GUEST_ELF).unwrap().receipt;

    // 3. extract committed values
    let (n_committed, result): (u32, u64) = receipt.journal.decode().unwrap();
    println!("n = {}, fib = {}", n_committed, result);

    // 4. verify (offline)
    receipt.verify(HELLO_GUEST_ID).expect("invalid proof");
    println!("proof verified ✓");

    // 5. for on-chain: serialize seal
    let seal_bytes = bincode::serialize(&receipt.inner.composite().unwrap()).unwrap();
    std::fs::write("proof.bin", &seal_bytes).unwrap();
    println!("proof saved: {} bytes", seal_bytes.len());
}

contracts/HelloVerifier.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {IRiscZeroVerifier} from "risc0/IRiscZeroVerifier.sol";

contract HelloVerifier {
    IRiscZeroVerifier public immutable verifier;
    bytes32 public immutable imageId;   // = HELLO_GUEST_ID

    event FibVerified(uint32 n, uint64 result);

    constructor(IRiscZeroVerifier _verifier, bytes32 _imageId) {
        verifier = _verifier;
        imageId = _imageId;
    }

    function submit(
        bytes calldata seal,
        uint32 n,
        uint64 result
    ) external {
        bytes memory journal = abi.encode(n, result);
        verifier.verify(seal, imageId, sha256(journal));
        emit FibVerified(n, result);
    }
}

运行

# build
cargo build --release

# run host (generates proof)
cd host && cargo run --release
# Output:
# n = 30, fib = 832040
# proof verified ✓
# proof saved: 215423 bytes

# deploy verifier on Sepolia
forge create HelloVerifier --constructor-args $RISCZERO_VERIFIER $IMAGE_ID

# call submit() with proof
cast send $CONTRACT "submit(bytes,uint32,uint64)" \
     "$(xxd -p proof.bin | tr -d '\n')" 30 832040

真实数据 / Real Data

Risc Zero (fib(30))

  • Guest ELF: ~50 KB
  • Prove time (local CPU): ~30 sec
  • Prove time (Bonsai GPU): ~5 sec
  • Receipt size: ~200 KB (raw STARK)
  • After Groth16 wrap: ~1 KB
  • Verify gas (Solidity): ~250k

Axiom V2 history query

  • Query a single storage slot at past block: ~$1 in gas + Axiom fee
  • Query 1000 events aggregated: ~$5
  • Latency: ~30 min (prover cycle)

Brevis SQL

  • Simple SELECT-WHERE: ~1 min, ~$0.5
  • Complex AGGREGATE: ~10 min, ~$5

三大 Coprocessor 对比

维度AxiomRisc ZeroBrevis
Programming model模板化(schema)自定义 RustSQL
通用性中(限于历史查询)高(任意 Rust)高(数据查询)
Latency~30 min~5-30 min (Bonsai)~1-10 min
Cost$1-10 / query$0.01-1 / proof$0.5-5
生态EVM EIP-tag-friendly多链EVM
主要 use case历史 state proof通用计算data analytics

工程经验

1. 选 SP1 还是 Risc Zero?

维度Risc ZeroSP1
成熟度早 (2022 公开)后起 (2024)
Backend自研 STARKPlonky3 (community)
Prover serviceBonsai (paid)开源 + community
生态较大增长快
价格$$$ Bonsai自部署/开源

许多团队最终都试两个,选适合的。

2. 何时用 Coprocessor 何时不用?

用 Coprocessor

  • 一次性大计算(年度统计、空投快照)
  • 历史数据查询
  • 用户级数据聚合(不能 indexer 完成)

不用

  • 高频/小计算(直接合约就行)
  • 需要 < 1 sec 响应
  • 简单查询(用 oracle / The Graph 就够)

3. cost 优化

prove 是按计算量 (cycles) 收费:

  • 减少 hash / 序列化(这些很贵)
  • 用 specialized circuit(如 ZK SQL)而非通用 zkVM
  • batch 多个 query 共享 setup

关键合约 (mainnet)

Risc Zero Verifier (Ethereum mainnet)

  • BonsaiRelay: 0x59B7...(具体见 dev.risczero.com)

Axiom V2 (Ethereum mainnet)

  • AxiomV2Core: 0x69963768F8407dE501029680dE46945F838Fc98B
  • AxiomV2Query: 0xf15cc7B983748686Cd1eCca656C3D3E46407DC1f

Brevis on-chain

  • BrevisRequest: 0x9Bb6E...(见 brevis.network docs)

关键速查

RISC0 commands:
  cargo risczero new <name>       # scaffold
  cargo risczero build            # build guest
  cargo run --release             # generate proof (host)
  receipt.verify(IMAGE_ID)        # offline verify

Risc Zero proof type:
  composite (full STARK):  ~200 KB, gas-prohibitive
  succinct (recursion):    ~50 KB, still expensive
  groth16 (final wrap):    ~1 KB, ~250k gas ✓

面试题

  1. Q: 为什么 ZK Coprocessor 是 ZK 的「下一个杀手应用」? A: zk-Rollup 解决「scale Ethereum」,coprocessor 解决「extend Ethereum」。让任何合约能访问历史数据 + 重计算 + 大规模查询,而不需要 trusted indexer。可解锁:长尾激励(基于历史 behavior)、复杂金融衍生品定价、链上 AI、社交图谱。

  2. Q: Risc Zero 的 zkVM 与 SP1 / Cairo 的差别? A: Risc Zero 用自研 STARK + RISC-V,封装较好(Bonsai SaaS prover)。SP1 是开源 RISC-V + Plonky3,社区驱动。Cairo 是自研 ISA + STARK,主要服务 StarkNet。三者都是「跑任意程序输出 ZK proof」,但 Risc Zero 最易上手,SP1 最透明,Cairo 最优化。

  3. Q: Axiom 怎么验证「过去 X 区块 Alice 的 USDC 余额」? A: (1) 链上有 history accumulator (block hash chain);(2) Axiom prover 取 USDC 合约的 storage proof + block 的 state root;(3) ZK 电路验证:(a) state root @ block N 是 chain history 的一部分;(b) MPT path 从 state root → Alice's USDC slot;(c) slot value 即 balance。最终 proof 链上 verify。

  4. Q: ZK Coprocessor 和 The Graph 的差别? A: The Graph 是 trusted indexer:subgraph 节点跑查询,需相信节点诚实(虽 decentralized 但 economic 安全)。Coprocessor 是 cryptographically verified:proof 数学正确。代价:The Graph 几毫秒响应,Coprocessor 几分钟到几小时。互补关系,不是替代。


明日预告

Day 242 — ZK 安全审计。读 3 份真实 ZK 审计报告,学习常见漏洞模式(underconstrained, missing range check, soundness gaps)。