Genesis 部署 — 设计

概述

用全部 44 个系统合约(含 OracleHub 0x8016 + DID 0x8017-0x8019)重新部署 genesis,验证 Oracle operator tx 注入和 DID 系统合约功能的端到端流程。

核心变更:

  1. 清理旧环境(Docker 容器 + PostgreSQL 数据库)

  2. 重新编译系统合约 + bootloader(含 OracleHub onlyOperator 变更 + bootloader Oracle 代码移除)

  3. zkstack ecosystem init(L1 合约部署 + genesis 创建)

  4. 启动 zksync_server + Oracle 后台服务

  5. 通过 cast 交易初始化 OracleHub + DID 合约

  6. E2E 验证:Oracle 价格注入、DID 创建查询、L1→L2 deposit


架构

部署流程

1. 环境清理
   ├─ 停止 Docker 容器 (reth, postgres, blockscout)
   └─ 清理 PostgreSQL 数据库 (DROP + CREATE)

2. 编译
   ├─ system-contracts: yarn preprocess + hardhat compile
   ├─ bootloader: yarn preprocess:bootloader (新 hash, 无 Oracle memory slot)
   └─ L1 contracts: forge build

3. zkstack ecosystem init
   ├─ 部署 L1 合约到本地 Reth (chain_id=9)
   ├─ 生成 genesis block (44 系统合约)
   ├─ 初始化 PostgreSQL
   └─ 生成 contracts.toml (新 GENESIS_ROOT, bootloader_hash 等)

4. 启动节点
   ├─ zksync_server (State Keeper + API + eth_watch + eth_sender)
   └─ Oracle 后台 (baby-chain.toml: 31 pairs, mock source)

5. 合约初始化 (cast 交易)
   ├─ OracleHub.initialize(symbols, 60, 500, 1)
   ├─ OracleHub.setOperator(operator_address)
   └─ (DID 合约无需初始化 — 默认状态即可使用)

6. E2E 验证
   ├─ eth_chainId = 271
   ├─ Oracle: getLatestPrice() 返回价格
   ├─ DID: createDID() + getDocument()
   └─ Bridge: L1→L2 deposit + 余额验证

系统合约清单 (44 个)

地址
合约
状态

0x8001-0x800F

标准 zkSync 系统合约 (15 个)

无变更

0x8010-0x8015

预编译 + 工具合约 (6 个)

无变更

0x8016

OracleHub

已修改: onlyOperator + setOperator

0x8017

DIDRegistry

已注册, L1Messenger 集成

0x8018

CredentialRegistry

已注册, L1Messenger 集成

0x8019

IdentityVerifier

已注册, L1Messenger 集成

+ 19 个

Precompile 合约

无变更

Bootloader 变更

  • 移除: ORACLE_CALLDATA_BEGIN_SLOT(), updateOraclePrices(), ORACLE_HUB_ADDR()

  • 恢复: SCRATCH_SPACE_BEGIN_SLOT = 8 (从 32 恢复)

  • 结果: 新的 bootloader_hash 需要在 genesis config 中更新


环境要求

组件
版本/要求

Rust

nightly-2025-03-19

Node.js

v20 (nvm use 20, v24 会导致 hardhat-zksync-solc 错误)

Docker

运行中 (reth + postgres)

Foundry

foundry-zksync (支持 --zksync)

CUDA

ZKSYNC_USE_CUDA_STUBS=true (无 GPU)

PostgreSQL

localhost:5432

Reth

localhost:8545 (L1, chain_id=9)


OracleHub 初始化

Genesis 后通过 cast 交易初始化:

注意: initialize() 使用 onlyCallFromBootloader 修饰符,genesis 后无法通过普通交易调用。解决方案:

  • 方案 A: 修改 initialize()onlySystemCall,允许 admin 调用

  • 方案 B: 在 genesis 的 custom_genesis_state 中预设存储值

  • 方案 C: 使用 ForceDeployUpgrader 在 genesis 时调用

推荐方案 A(最简单)— 将 initialize() 改为 onlySystemCall


E2E 验证清单

#
验证项
命令
期望结果

1

链 ID

cast rpc eth_chainId --rpc-url localhost:3050

0x10f (271)

2

OracleHub 初始化

cast call 0x8016 "stalenessThreshold()" --rpc-url localhost:3050

60

3

Oracle 价格查询

cast call 0x8016 "getLatestPrice(bytes32)" $ETH_HASH --rpc-url localhost:3050

非零价格

4

DID 创建

cast send 0x8017 "createDID(bytes32[],bytes32)" ... --rpc-url localhost:3050

交易成功

5

DID 查询

cast call 0x8017 "getDocument(address)" $ADDR --rpc-url localhost:3050

返回 DID 文档

6

L1 Deposit

cast send <bridge> "deposit{value: 1 ether}" --rpc-url localhost:8545

L2 余额增加

7

L2 余额

cast balance $ADDR --rpc-url localhost:3050

> 0

8

Batch 提交

检查 L1 上的 commit 交易

batch 包含 Oracle tx


文件清单

可能修改的文件

文件
改动

era-contracts-l1/system-contracts/contracts/OracleHub.sol

initialize() 改为 onlySystemCall (如方案 A)

era-core/etc/env/base/contracts.toml

genesis 参数自动更新 (zkstack)

config/baby-chain.toml

确认 oracle 配置正确

无需修改的文件

系统合约代码 + bootloader + keeper.rs + oracle_tx.rs — 均已在之前的 Phase 中完成


交付计划

任务
内容

Task 1

OracleHub.initialize() 修饰符修改 + 编译验证

Task 2

环境清理 (Docker + PostgreSQL)

Task 3

编译系统合约 + bootloader

Task 4

zkstack ecosystem init (L1 + genesis)

Task 5

启动 zksync_server + 验证 API

Task 6

合约初始化 (OracleHub + setOperator)

Task 7

E2E 验证 (Oracle + DID + Bridge)

Task 8

dev-log 更新

Last updated