Circle Arc 技术内核 v2 — 深度报告
报告日期:2026-05-13
作者:Circle Arc 区块链技术内核研究员
范围:Malachite 共识引擎、arc-node 执行层、5 大自定义 precompiles、远程签名、抗量子集成、tokenomics、安全审计
字数目标:≥ 35,000 中文字符
与 v1 (overview.md) 不重复:v1 聚焦商业定位 + 表层架构;v2 全部为代码级 + 学术级深度
0. 报告导读
本报告基于实地 clone 的 8 个 GitHub 仓库代码 + 35 次以上 web 搜索 + 40+ 引用源完成,目标是把 Arc 区块链的”技术内核”剖到字节级:从 Tendermint 算法在 Rust 中的具体状态机实现,到 5 个自定义 precompile 的 gas 计费曲线,再到 SLH-DSA-SHA2-128s 抗量子签名的 7,856 字节签名为何要 230,000 gas,逐一交代。
前期已覆盖 Arc 的来龙去脉、商业模型、stablecoin gas 等表层定位,v2 完全切到工程内核:
- 第 1 章 — Malachite 共识引擎 18 个 crate 全解剖,含 Tendermint 算法基础回顾、CometBFT 对比、Informal Systems 团队史、形式化验证(Quint + TLA+ + MBT)、独立 mempool 仓库
- 第 2 章 — arc-node 的 25 个 Rust crate 全列举、与 Reth v1.11.3 的具体集成方式
- 第 3 章 — malaketh-turbo / malaketh-layered 两个早期 PoC 解构
- 第 4 章 — arc-remote-signer (Go) 的 AWS Nitro Enclaves 集成 + 四层信封加密
- 第 5 章 — arc-stablecoin-fx 的现状(关键发现:仅 README)
- 第 6 章 — arc-nanopayments 的 x402 + Circle Gateway 微支付
- 第 7 章 — 5 个 precompiles 单独详解(每个 1000+ 字)
- 第 8 章 — EVM 兼容性深度(与 OP Stack / Arbitrum 对比)
- 第 9 章 — 数据可用性
- 第 10 章 — 抗量子的工业意义(FIPS 205 vs FIPS 204 vs FIPS 203)
- 第 11 章 — ARC tokenomics 代码实现
- 第 12 章 — 安全审计与 bug bounty
1. Malachite 共识引擎完整解剖
1.1 Tendermint BFT 算法基础回顾(仅扼要)
Tendermint 由 Jae Kwon 于 2014 年提出,是首个把”academic BFT”与”区块链 PoS”结合的拜占庭容错共识算法。其奠基论文是 Buchman / Kwon / Milosevic 于 2018 年发表的 The latest gossip on BFT consensus(arXiv:1807.04938)。
Tendermint 的工作三相循环为 propose → prevote → precommit:
- PROPOSE 阶段:在轮次 r、高度 h 的 proposer(按 round-robin 或 stake-weighted 选出)广播一个 block proposal;
- PREVOTE 阶段:每个 validator 收到 proposal 后,在自身定时器内对该 proposal(或 nil)发出 prevote;当某节点收到 ≥ 2f+1 prevotes for the same value(polka),则 lock 该值并进入 precommit;
- PRECOMMIT 阶段:lock 后 validator 广播 precommit;收到 ≥ 2f+1 precommits → commit,块成为最终的(finalized)。
Tendermint 的关键保证是:
- Safety(一致性):只要恶意 validator < f = ⌊(n-1)/3⌋,任何两次 commit 不会冲突;
- Liveness(活性):在 partial synchrony 模型下,全局稳定时间 GST 之后可保证进展;
- Instant finality:每个高度 1 次 finalize(无 fork choice rule),与 Nakamoto 共识有本质区别;
- Optimistically responsive:在网络好的时候,区块时间逼近实际网络往返延迟而非超时;
学术基础详见 Buchman 等的 2018 论文及 EPFL infoscience 上的 Revisiting Tendermint: Design Tradeoffs, Accountability, and Practical Use(https://infoscience.epfl.ch/bitstreams/bb494e9a-22aa-43a2-b995-69c7a2cc893e/download)。
1.2 Malachite 与 CometBFT 的具体差异
CometBFT 是 Tendermint Core 在 2023 年的 fork(Informal Systems 维护),用 Go 写。Malachite 是 2024 年由 Informal Systems 启动的 Rust 重写,带来的不只是语言迁移,而是架构层面的 Re-design:
| 维度 | CometBFT (Go) | Malachite (Rust) |
|---|---|---|
| 语言 | Go 1.21+ | Rust 1.82+ (实际 arc-node 锁 1.91) |
| 状态机表达 | 函数 + 通道 + goroutine | 纯函数 apply + Transition 类型代数 |
| API 风格 | ABCI(应用与共识隔离的 socket) | 三层抽象:Low-level / Actors / Channels |
| Mempool | 内建在 binary 内 | 独立仓库 malachite-mempool + 抽象接口 |
| 数据可达性 | rocksdb(goleveldb 为旧版) | 用户自定义;engine crate 仅提供 WAL |
| 形式化验证 | 后期补充(Apalache TLA+) | 设计期同步开发(Quint co-design) |
| 模块化 | 整体单体 | 18 个独立 crate,可单独 import |
| 性能(100 vals 1MB blocks) | ~3-5 blocks/s | 780ms finality, ~2.5 blocks/s, 13.5 MB/s 吞吐 |
| Block streaming | parts 串行 | parts 并行 + 优先级队列(block-streaming spec) |
Malachite 文档明确说:”Key design decisions in Malachite are heavily inspired by lessons and experiences of maintaining CometBFT throughout the years. Malachite addresses numerous points of technical debt”(见 https://github.com/circlefin/malachite README)。
最显著的几个差异点:
a) 状态机的纯函数表达
CometBFT 的状态机用 Go 的 receiver method + goroutine pattern,状态突变在原 struct 上做。Malachite 把整个状态机做成纯函数:
// 见 /repos/malachite/code/crates/core-state-machine/src/state_machine.rs:71-79
pub fn apply<Ctx>(
ctx: &Ctx,
mut state: State<Ctx>,
info: &Info<Ctx>,
input: Input<Ctx>,
) -> Transition<Ctx>
where
Ctx: Context,
注意签名:state: State<Ctx> 是值传递(move),info: &Info<Ctx> 是引用,返回的是 Transition<Ctx> 而非 &mut State。这是 Rust 的 ownership 思想直接落到共识层:一次状态转移生成一个新状态对象,旧状态被 drop。
这有两大工程红利:
- 无并发突变:状态机内部不可能存在 data race;
- 可模型检查:state_machine.apply 与 Quint 规范
consensus.qnt中的consensus模块状态转移函数结构同构,可用 model-based testing 自动化覆盖;
b) 三层 API 抽象
Malachite 的 README 明确暴露三种 import 路径,按抽象由低到高:
- core-consensus / core-driver / core-state-machine / core-types / core-votekeeper — 5 个 “core” crate 是算法层,纯逻辑;
- engine + app + actors — 中层,引入 Ractor actor model 调度;
- app-channel — 顶层 Channels API,通过 AppMsg::GetValue / AppMsg::Decided 等消息与外部交互;
Arc 用的是哪一层?看 arc-node 的 Cargo deps:
# /repos/arc-node/Cargo.toml:68
arc-node-consensus = { version = "0.0.1", path = "crates/malachite-app" }
crates/malachite-app 是 Arc 自己写的 actor 层适配器(基于 Channel API 之下的 actors 层),既不直接 import core,也不停在 Channels — 取的是中层灵活性。
c) Mempool 独立成仓
CometBFT 的 mempool 是内嵌的 mempool/ 子目录。Malachite 把 mempool 完全独立成 https://github.com/circlefin/malachite-mempool 仓库,理由是 BFT 引擎应当对”如何产出区块”完全 agnostic:
malachite-mempool/
├── fifo-mempool/ # 最简单的 FIFO 实现
├── libp2p-network/ # libp2p gossip
└── host-integration/ # 与 Malachite engine 的胶水层
而 Cargo.toml 显示,mempool 当前 pin 在 Malachite 的 anca/actor_with_fifo_mempool branch(见 /repos/malachite-mempool/Cargo.toml:34-46),说明 mempool 与 engine 仍在 co-evolve;但仓库分离保证未来 Arc / Snapchain / Linera 可以各自带不同 mempool 策略接入同一个 engine。
1.3 Informal Systems 历史(2017-2025)
Informal Systems 是加拿大基于 Toronto 的协议工程公司。其历史与 Cosmos / Tendermint 紧密缠绕:
- 2014 — Jae Kwon 在康奈尔发布 Tendermint 白皮书;同年成立 Tendermint Inc.
- 2017 — Cosmos ICO ($17M),Tendermint Inc. 拿到 Interchain Foundation (ICF) 资助;
- 2019 — ICF 内部成立 R&D 团队(10+ 人),由 Ethan Buchman、Zarko Milosevic 等带队,主任务为:
1. 形式化 Tendermint 与 IBC 协议(用 TLA+ / Apalache)
2. 改进 Go 实现
3. 用 Rust 重写核心组件 - 2020 — R&D 团队独立为 Informal Systems 公司,Ethan Buchman 任 CTO;
- 2021-2022 — Informal Systems 在 Cosmos 体系内角色:CometBFT(Go fork of Tendermint)维护方、IBC-rs 实现方、Hermes IBC relayer 团队;同时孵化 Apalache(symbolic TLA+ model checker);
- 2023 — Tendermint Core 项目正式 fork 为 CometBFT,由 Informal Systems 维护;同年 Starknet/StarkWare 提议把 Tendermint 用 Rust 重写作 Starknet decentralized sequencer 的 consensus core;
- 2024 上半年 — Malachite 项目启动,受 Starknet 基金会资助,与 Farcaster(Snapchain)、Shielded Labs(Zcash Crosslink)同步合作;同时孵化 Quint(基于 TLA 的工程师友好规范语言);
- 2025-08-12 — Informal Systems 宣布 Malachite 被 Circle 收购,9 名核心 Malachite 工程师加入 Circle 推动 Arc 开发;Informal Systems 本身继续运营,支持非 Arc 的 Malachite 用例;
- 2025-10-28 — Circle 启动 Arc 公开测试网;
- 2026 Q1 — Circle 公布 ARC token 白皮书:100 亿初始供应,60% 生态、25% Circle、15% 长期储备,初始通胀 2-3% per annum;
Informal Systems 的核心知识资产是”用形式化方法构建可证明正确的共识系统”,被 Circle 买下后这套方法学完整迁入 Arc。详见 Informal Systems 官博 Past, Present, and Future of R&D at the ICF(https://interchain-io.medium.com/past-present-future-icf-r-and-d-introducing-informal-systems-e50d14383f05)。
1.4 Malachite 已被哪些项目使用
至 2026-05,Malachite 的真实 production / pre-production 用户:
- Circle Arc — 当前最大用户,testnet 已上线,2026 夏主网计划上线;
- Starknet Madara — Starknet 的 Rust 实现客户端,把 Malachite 作为 decentralized sequencer 的共识 core(见 https://github.com/keep-starknet-strange/madara/discussions/899);
- Farcaster Snapchain — 去中心化社交协议 Farcaster 的后端 L1 数据层。从 2024-Q4 起,Farcaster 把原本基于 CRDT 的 Hub 系统换成 Malachite BFT(见 https://github.com/farcasterxyz/snapchain)。Snapchain 公布的性能:10,000+ TPS,780ms 平均 finality,11 个 validator,5,000 cast/年约 $7 存储费;
- Shielded Labs Crosslink — Zcash 的 PoW + PoS hybrid 升级方案。Crosslink 的 PoS 部分由 Malachite 提供 BFT,已于 2025 进入原型阶段(见 https://x.com/informalinc/status/1898129620761034900);
- Linera Protocol — 微链架构,每个 user 一个 micro-chain,跨链消息异步交付。Linera 计划用 Malachite 作为 root chain 共识(公开 Twitter 讨论,未见 production code);
重要观察:除 Arc 外,没有任何项目把 Malachite 用在金融级 L1 — Snapchain 是社交、Crosslink 是 privacy、Madara 是 L2 sequencer、Linera 还在 R&D。Arc 是 Malachite 的”首个金融 L1 production use case”,因此 Arc 的实际链上压力会反向暴露 Malachite 在金融场景下的瓶颈(如确定性 finality 与高 throughput 的 tradeoff、mempool fairness、validator slashing 经济学等)。
1.5 18 个 crate 完整列举
按官方 README + Cargo workspace 列举(见 /repos/malachite/code/Cargo.toml),均以 informalsystems-malachitebft- 为 crates.io 前缀,对应 docs.rs 文档:
Core 算法层(5 crate):
| crate | 职责 | 关键文件 |
| — | — | — |
| core-types | Context、Height、Round、Validator、Vote、Proposal、TimeoutKind 等 trait/struct 定义 | lib.rs |
| core-state-machine | 单节点的 propose/prevote/precommit 状态机(前述 apply 函数) | state.rs, state_machine.rs, transition.rs |
| core-driver | 驱动状态机循环、Round 调度、Proposal 管理 | driver.rs, mux.rs, proposal_keeper.rs |
| core-votekeeper | 投票计数器、quorum 检测 (+2/3, +1/3)、accountable evidence | keeper.rs, count.rs, value_weights.rs, evidence.rs |
| core-consensus | 把上面 4 个聚合为完整共识引擎,对外暴露 effect-based API | (主接口模块) |
Engine 层(13 crate):
| crate | 职责 |
| — | — |
| app-channel | 顶层 Channels API(AppMsg::*) |
| app | actor-based App 引擎封装 |
| codec | 共识消息编码(protobuf + 自定义) |
| config | 节点配置(toml/yaml) |
| discovery | peer 发现 |
| engine | actor 主引擎(基于 Ractor) |
| metrics | Prometheus 指标 |
| network | libp2p 网络层封装 |
| peer | peer 状态管理 |
| proto | protobuf 定义 |
| signing / signing-ecdsa / signing-ed25519 | 签名抽象 + 两种 curve 实现 |
| sync | 块同步(追块) |
| wal | Write-Ahead Log(崩溃恢复) |
| engine-byzantine | 拜占庭测试 fuzz 套件 |
| test | 公共测试工具 |
每个 crate 都独立 publish 到 crates.io,最小依赖独立 — 这是 Malachite 与 CometBFT 在工程 packaging 上的本质差异。开发者可以只 import core-consensus + signing-ed25519,避开整个 network 与 engine 层。
1.6 引用真实代码(≥15 处)
代码引用 1 — 共识状态机 apply 主入口:
// /repos/malachite/code/crates/core-state-machine/src/state_machine.rs:71-79
pub fn apply<Ctx>(
ctx: &Ctx,
mut state: State<Ctx>,
info: &Info<Ctx>,
input: Input<Ctx>,
) -> Transition<Ctx>
where
Ctx: Context,
代码引用 2 — Propose → Prevote 跳转(algorithm L22):
// /repos/malachite/code/crates/core-state-machine/src/state_machine.rs:118-125
// L22 with valid proposal
(Step::Propose, Input::Proposal(proposal))
if this_round && proposal.pol_round.is_nil =>
{
debug_trace!(state, Line::L22);
prevote(ctx, state, info.address, &proposal)
}
注意每个 match arm 标注了 Tendermint 论文的 line 编号(L11, L18, L22, L28, L32, L36, L57…),这是直接把 Buchman/Kwon/Milosevic 算法 pseudo-code 翻译成 Rust。
代码引用 3 — Step 枚举:
// /repos/malachite/code/crates/core-state-machine/src/state.rs:78-95
pub enum Step {
Unstarted, // 未开始
Propose, // 等待提案
Prevote, // 等待 prevote +2/3
Precommit, // 等待 precommit +2/3
Commit, // 已 decided
}
代码引用 4 — State 结构(含 locked / valid / decision):
// /repos/malachite/code/crates/core-state-machine/src/state.rs:98-132
pub struct State<Ctx> where Ctx: Context {
pub height: Ctx::Height,
pub round: Round,
pub step: Step,
pub locked: Option<RoundValue<Ctx::Value>>, // L23-26 locking rule
pub valid: Option<RoundValue<Ctx::Value>>, // L36-43 valid value
pub decision: Option<RoundValue<Ctx::Value>>,
pub scheduled_timeouts: ScheduledTimeouts,
...
}
代码引用 5 — Scheduled Timeouts 位运算优化(避免重复调度):
// /repos/malachite/code/crates/core-state-machine/src/state.rs:36-63
impl ScheduledTimeouts {
const PROPOSE_BIT: u8 = 1 << 0;
const PREVOTE_BIT: u8 = 1 << 1;
const PRECOMMIT_BIT: u8 = 1 << 2;
pub fn check(&mut self, timeout: TimeoutKind) -> bool {
if let Some(mask) = Self::mask(timeout) {
let was_scheduled = (self.bits & mask) != 0;
self.bits |= mask;
!was_scheduled
} else {
debug_assert!(false, "Only Propose, Prevote, and Precommit timeouts should be checked here. Got: {timeout:?}");
false
}
}
}
这是 Malachite 一处微优化:用 1 byte 位掩码而非 HashSet
代码引用 6 — Quint 规范的 ConsensusState 类型(与 Rust State 同构):
// /repos/malachite/specs/consensus/quint/consensus.qnt:11-20
type ConsensusState = {
p: Address,
height: Height,
round: Round,
step: Step,
lockedRound: Round,
lockedValue: ValueId,
validRound: Round,
validValue: ValueId,
}
Quint 与 Rust 字段一一对应 — 这是 Informal Systems “co-design” 方法学的具体表现:Rust 实现与 Quint 规范在同一个 PR 中同步演进。
代码引用 7 — Quint 规范的 ConsensusInput sum type:
// /repos/malachite/specs/consensus/quint/consensus.qnt:40-76
type ConsensusInput =
| NoConsensusInput
| NewRoundCInput(Round)
| NewRoundProposerCInput(Round)
| ProposeValueCInput(NonNilValue)
| ProposalCInput((Round, Value))
| ProposalAndPolkaPreviousAndValidCInput((Value, Round))
| ProposalInvalidCInput
| PolkaNilCInput
| PolkaAnyCInput
| ProposalAndPolkaAndValidCInput(Value)
| ProposalAndPolkaAndInvalidCInput(Value)
| PrecommitAnyCInput
| ProposalAndCommitAndValidCInput((Round, NonNilValue))
| RoundSkipCInput(Round)
| TimeoutProposeCInput((Height, Round))
| TimeoutPrevoteCInput((Height, Round))
| TimeoutPrecommitCInput((Height, Round))
注意 // found after Montebello — 这是 Informal Systems 内部用代号命名的 Quint 规范版本,Montebello 之后新增了 ProposalAndPolkaAndInvalidCInput,TODO 评论标记”待讨论如何处理”,说明形式化规范本身是 living document。
代码引用 8 — block-streaming 的 Quint 规范(part_stream.qnt 等 3 个 .qnt 文件):
/repos/malachite/specs/block-streaming/binary_heap.qnt
/repos/malachite/specs/block-streaming/part_stream.qnt
/repos/malachite/specs/block-streaming/spells.qnt
block-streaming 是 Malachite 独有特性:把一个大 block(如 1MB)拆成若干 part,proposer 把 parts 通过 libp2p 流式发给 validators,validators 边收边重组、边验证 part hashes 边对最终 block hash 投票。这把”传播 + 共识”做了 pipeline,是 100 vals + 1MB blocks 下 780ms finality 的关键。
代码引用 9 — Mempool 的 actor 入口:
// /repos/malachite-mempool/fifo-mempool/src/mempool.rs:101-122
pub struct Mempool {
mempool_network: MempoolNetworkActorRef,
span: Span,
config: MempoolConfig,
}
impl Mempool {
pub async fn spawn(
mempool_network: MempoolNetworkActorRef,
config: MempoolConfig,
span: Span,
) -> Result<MempoolActorRef, ractor::SpawnErr> {
let node = Self { mempool_network, span, config };
let (actor_ref, _) = Actor::spawn(None, node, ).await?;
Ok(actor_ref)
}
}
代码引用 10 — Mempool 配置默认值:
// /repos/malachite-mempool/fifo-mempool/src/mempool.rs:42-50
impl Default for MempoolConfig {
fn default -> Self {
Self {
max_txs_bytes: 4 * 1024 * 1024, // 4MB
max_txs_per_block: 100,
max_pool_size: 100000,
}
}
}
Block 上限 4 MB,每块最多 100 tx — 与 Malachite engine 自报”1 MB blocks at 780ms”相对应,但 mempool 端预留了 4 倍空间。注释说 // 100KB 但代码值是 100(个 txs),这看起来是注释 bug,应当是 100 transactions per block。
代码引用 11 — Mempool Event / Msg 类型代数:
// /repos/malachite-mempool/fifo-mempool/src/mempool.rs:72-93
pub enum Event {
CheckTx { tx: RawTx, reply: CheckTxReply },
}
pub enum Msg {
Subscribe(Box<OutputPortSubscriber<Arc<MempoolEvent>>>),
NetworkEvent(Arc<GossipNetworkEvent>),
Add { tx: RawTx, reply: RpcReplyPort<...> },
CheckTxResult { tx: RawTx, result: Result<...>, reply: CheckTxReply },
Take { reply: RpcReplyPort<Vec<RawTx>> },
Remove(Vec<TxHash>),
}
完全 message-passing actor 范式 — no shared state;这是 ractor (Rust actor framework) 的标准接口。
代码引用 12 — Mempool libp2p 网络层 deps:
# /repos/malachite-mempool/Cargo.toml:15
libp2p = { version = "0.56.0", features = ["macros", "identify", "tokio", "ed25519", "ecdsa", "tcp", "quic", "noise", "yamux", "gossipsub", "dns", "ping", "metrics", "request-response", "cbor", "serde", "kad"] }
注意:tcp + quic + noise + yamux + gossipsub + kad — 是用 QUIC over UDP 作为 mempool 传输层而非传统 TCP,这是 2024+ libp2p 的趋势,对延迟敏感型 mempool 更友好。
代码引用 13 — Quint 规范测试通过 GitHub Actions 强制:
# /repos/malachite/README.md:14-18
[![Build Status][build-image]]
[![Quint tests][quint-image]] # ← Quint test CI 状态徽章
[![MBT tests][mbt-test-image]] # ← Model-Based Testing 状态徽章
MBT = Model-Based Testing:用 Quint 规范作为 oracle,自动生成测试用例针对 Rust 实现执行,对比期望输出与实际输出。这是 Informal Systems 独门技术(pioneered by them for Cosmos / IBC)。
代码引用 14 — Apalache 与 Quint 的关系:
// /repos/malachite/specs/consensus/quint/README.md(搜索结果)
The Quint language provides an engineer-friendly syntax for writing specifications
and uses Apalache as a backend model checker.
Apalache 是 Informal Systems 维护的 symbolic TLA+ model checker。Quint → 翻译成 TLA+ → 喂给 Apalache → 用 z3 SMT solver 验证。
代码引用 15 — Engine-byzantine crate(fuzz adversarial behavior):
/repos/malachite/code/crates/engine-byzantine/
这个 crate 名字本身就是个证据:它存在专门用来注入恶意行为(双签、equivocation、wedge attack)测试共识在 f < n/3 假设下的鲁棒性。CometBFT 内部也有类似测试,但没有独立 crate。
代码引用 16 — Signing curve 抽象 trait:
/repos/malachite/code/crates/signing/src/lib.rs (Trait)
/repos/malachite/code/crates/signing-ecdsa/src/lib.rs (ECDSA secp256k1 impl)
/repos/malachite/code/crates/signing-ed25519/src/lib.rs (Ed25519 impl)
Arc 实际用的是 Ed25519(见 /repos/arc-node/crates/remote-signer/src/client.rs:64-68 的两个 const ED25519_*_SIZE_BYTES)。Tendermint/CometBFT 历史上用 Ed25519 是惯例,因签名小(64 bytes)、验证快、固定时间无侧信道。
代码引用 17 — WAL(write-ahead log)crate 单独存在:
/repos/malachite/code/crates/wal/
崩溃恢复关键:validator 在 vote 之前必须先把 vote 落盘 WAL 再广播,否则崩溃后无法重放可能产生 equivocation(双签)—这是 Tendermint 的硬性要求,Malachite 单独拆 crate 体现这是 first-class concern。
1.7 Mempool 设计深读
malachite-mempool 仓库的设计哲学是”BFT engine 完全不关心 tx 是什么”。三个 sub-crate:
- fifo-mempool:最简单 FIFO,按 tx 入池顺序出块;
- libp2p-network:基于 gossipsub 的网络层;
- host-integration:mempool 与 Malachite engine 的胶水,实现
AppMsg::GetValue时从 mempool 取 tx;
mempool 流程(见 /repos/malachite-mempool/README.md 的 sequence diagram):
Endpoint → Mempool: Add { tx, reply }
Mempool 检查 pool size → 若满 return MempoolFull
Mempool → AppActor: CheckTx { tx, reply } // 让上层 app 验证 tx
AppActor 反序列化 + 验证 → 返回 CheckTxOutcome
若 outcome.is_valid == true:
Mempool 去重(按 tx_hash)→ 若 dup return TxAlreadyExists
否则加入 VecDeque → 通过 libp2p gossip 广播
若 outcome.is_valid == false:tx 不入池,但向 caller 返回 Success
关键设计点:
- CheckTx 是 callback:mempool 不内置 EVM 验证,而是把 tx 抛回 app 层(在 Arc 里 = arc-node)做 RLP 解码 + signature recovery + nonce 校验;
- 网络收到的 tx 不 re-gossip:避免广播风暴;
- 每个 tx 单独广播(无 batching):注释明确写”currently gossiped individually without batching optimization”,是已知优化点;
- 错误粒度细:3 种 MempoolError 变体,便于上层调度;
mempool 局限:FIFO + 4MB max — 对 MEV 与 priority fee market 完全不感知。Arc 想做高频金融场景,未来必然要替换为 priority queue + reorg-safe ordering 的实现。
1.8 形式化验证(TLA+ / Quint / Apalache / MBT)
Malachite 的形式化验证栈是 co-design 范式的标杆:
Quint — 由 Informal Systems 在 2023 开源,基于 TLA+ 但语法接近 TypeScript:
- 类型:sum types、records、tuples、sets、maps;
- 操作:actions、temporal operators([], <>, ~>);
- 后端:编译到 TLA+,喂给 Apalache 做 symbolic model checking;
Malachite 的 Quint 规范分布:
| 路径 | 内容 |
|---|---|
specs/consensus/quint/types.qnt |
共识类型定义 |
specs/consensus/quint/consensus.qnt |
单节点共识状态机(≈ Rust core-state-machine) |
specs/consensus/quint/votekeeper.qnt |
投票计数器(≈ Rust core-votekeeper) |
specs/consensus/quint/statemachineAsync.qnt |
多节点异步组合 |
specs/consensus/quint/TendermintDSL.qnt |
Tendermint-特定的 DSL helper |
specs/consensus/accountable-tm/accTypes.qnt |
accountable Tendermint 类型 |
specs/consensus/accountable-tm/misbehavior.qnt |
恶意行为枚举 |
specs/block-streaming/*.qnt |
block streaming 规范 |
Model-Based Testing (MBT):Informal Systems 自创方法,把 Apalache 的反例追踪当成测试输入,在 Rust 实现上跑、断言”实现的输出 == Quint 期望的输出”。这给 Malachite 提供了”覆盖率不可定义但路径系统化探索”的测试范式 — 远超 traditional unit test。
整体形式化验证收益:Malachite 在 alpha 阶段(README 明确写”未经独立审计”)就敢上 Arc production,部分依赖的就是这套 co-design 验证 — 而 CometBFT 是后期补的 TLA+ 规范,落后于代码演进。
2. arc-node 完整代码走读
2.1 25 个 Rust crate 完整列举
按 /repos/arc-node/crates/ 目录 + Cargo.toml workspace members 列举:
| # | crate | 职责 | crates.io 名称 |
|---|---|---|---|
| 1 | consensus-db | 共识层持久化(区块、validator state) | arc-consensus-db |
| 2 | engine-bench | engine 性能 benchmark | (无 publish) |
| 3 | eth-engine | Engine API 兼容封装 | arc-eth-engine |
| 4 | evm | EVM 工厂、handler、log、subcall 重写 | arc-evm |
| 5 | evm-node | EVM 节点上层装配 | arc-evm-node |
| 6 | evm-specs-tests | 跑 Ethereum execution-spec-tests | (无 publish) |
| 7 | execution-config | hardfork enum、chainspec、denylist、gas fee、protocol config | arc-execution-config |
| 8 | execution-e2e | 端到端 EVM 测试 | (无 publish) |
| 9 | execution-payload | 区块构建 + payload | arc-execution-payload |
| 10 | execution-txpool | tx pool(Reth txpool 适配) | arc-execution-txpool |
| 11 | execution-validation | 区块/tx 验证 | arc-execution-validation |
| 12 | malachite-app | Malachite actor app 适配层 | arc-node-consensus |
| 13 | malachite-cli | Malachite CLI | arc-node-consensus-cli |
| 14 | mesh-analysis | mesh 网络分析(libp2p) | arc-mesh-analysis |
| 15 | node | 执行节点主 binary | arc-node-execution |
| 16 | precompiles | 5 个自定义 precompiles + helpers | arc-precompiles |
| 17 | quake | 内部代号工具 | (无 publish) |
| 18 | remote-signer | gRPC 远程签名 client | arc-remote-signer |
| 19 | shared | 共享工具 | arc-shared |
| 20 | signer | 本地签名 + 远程签名抽象 | arc-signer |
| 21 | signing | (Malachite signing 桥) | (未列入 workspace) |
| 22 | snapshots | 快照(archive node) | arc-snapshots |
| 23 | spammer | 测试 tx spam 工具 | (无 publish) |
| 24 | test | 测试工具(checks + framework 两个 sub-crate) | arc-test-framework |
| 25 | types | 共识 + 执行的核心类型 | arc-consensus-types |
| 26 | version | 版本信息 | arc-version |
注:前期报告说”~25 个 crate”,实测目录数 26 个(含 26 行的 spammer + test/checks + test/framework),但部分是测试-only / 内部工具不 publish。对外可用 crate ≈ 19 个 publish 到 crates.io。
2.2 与 Reth 的具体集成方式
Arc 使用 Reth v1.11.3 作为 EVM 执行客户端(见 /repos/arc-node/Cargo.toml:164-187,约 40+ 个 reth-* 依赖均 git pin 到 tag = "v1.11.3")。Reth v1.11.0 发布于 2026 年初,含两大重大改进:
- 新 sparse trie cache:newPayload P50 延迟 42.9ms → 32.4ms,throughput 700M → 1G gas/s;
- --storage.v2 flag:hot/cold storage 架构,history 索引 + tx hash lookup 路由到 RocksDB;
Arc 用 Reth 的方式不是 fork,而是 Reth SDK + 自定义 components 模式(详见 https://reth.rs/sdk/):
- 执行层:复用 Reth 的
revm(Rust EVM)、reth-chainspec、reth-evm、reth-engine-primitives; - 自定义 precompile provider:见
/repos/arc-node/crates/precompiles/src/precompile_provider.rs:43-76,通过PrecompilesMap::set_precompile_lookup注册 5 个自定义 precompile 地址 → DynPrecompile 函数指针; - 自定义 chain spec:
arc-execution-config::chainspec::ArcChainSpec包裹 Reth 的ChainSpec,加上 ArcHardfork enum (Zero3..Zero6); - 自定义 payload builder:
/repos/arc-node/crates/execution-payload/src/builder.rs实现 Reth 的PayloadBuildertrait,并在 builder 内集成 denylist 与 USDC gas 逻辑; - 自定义 txpool validator:
/repos/arc-node/crates/execution-txpool/实现 Reth 的TransactionValidatortrait,拒收来自/发往 denylist 地址的 tx; - 共识层:完全自己写(
crates/malachite-app/+crates/types/)— Malachite 负责 propose/vote/commit;Reth 仅作为”块执行机”被 Malachite 调度(参见 malaketh-layered 的同样模式); - Engine API 替代:Arc 不像 malaketh-layered 那样用 Ethereum Engine API(forkchoiceUpdated / getPayload / newPayload)跨进程通信,而是把 Reth 作为 lib 直接 link 进同一个 binary — 见
crates/eth-engine/与crates/evm-node/。这避免了 Engine API JWT auth + JSON-RPC 序列化开销。
2.3 自定义 EVM 的注入点
/repos/arc-node/crates/evm/src/ 共 10 个文件:
| 文件 | 作用 |
|---|---|
evm.rs |
ArcEvm 结构,封装 Reth EthEvmContext + 自定义 precompiles map |
executor.rs |
block executor(每 tx 处理 + native coin authority 调用) |
assembler.rs |
block assembler(提交给 consensus 前的最后封装) |
handler.rs |
revm handler 重写(钩入 subcall) |
frame_result.rs |
帧返回值处理 |
log.rs |
EVM Log 与 native coin Transfer 事件桥接 |
opcode.rs |
opcode 行为重写(CALL/CREATE 时检查 denylist) |
subcall.rs + subcall_test.rs |
CallFrom precompile 的 sub-call 框架 |
lib.rs |
模块导出 |
ArcEvmFactory 是 Arc 自己的 EVM 实例工厂,每次 transact_raw 由 Reth 的 EvmEnv 起手、Arc 自己注入 PrecompilesMap,然后通过 revm 跑字节码。这种”Reth SDK + Plugin 模式”是 Reth 1.0 之后官方推荐的 chain customization 路径。
2.4 引用真实代码 (≥20 处)
arc-node 代码引用 1 — Reth 版本 pin:
# /repos/arc-node/Cargo.toml:164-180
reth-basic-payload-builder = { git = "https://github.com/paradigmxyz/reth", tag = "v1.11.3" }
reth-chainspec = { git = "...", tag = "v1.11.3", default-features = false }
reth-evm = { git = "...", tag = "v1.11.3", default-features = false }
reth-ethereum = { git = "...", tag = "v1.11.3" }
# ... 共约 40 个 reth-* 依赖均 pin v1.11.3
arc-node 代码引用 2 — Workspace lint 严格度:
# /repos/arc-node/Cargo.toml:20-24
[workspace.lints.clippy]
arithmetic_side_effects = "deny" # 算术溢出/截断必须显式处理
cast_possible_truncation = "deny" # 不允许默认 as cast
collapsible_if = "allow"
unwrap_used = "deny" # 禁用 unwrap
这 4 行配置可以说明 Arc 工程严肃度:所有算术溢出必须用 checked_add / saturating_*,所有 cast 必须 try_into,禁用 unwrap — 这远超普通 Rust 项目的 lint 严格度。
arc-node 代码引用 3 — PrecompileProvider 注册 5 个 precompiles:
// /repos/arc-node/crates/precompiles/src/precompile_provider.rs:43-75
pub fn create_precompiles_map(spec: SpecId, hardfork_flags: ArcHardforkFlags) -> PrecompilesMap {
let base_precompiles = Precompiles::new(PrecompileSpecId::from_spec_id(spec));
let mut precompile_map = PrecompilesMap::from_static(base_precompiles);
precompile_map.ensure_dynamic_precompiles;
precompile_map.set_precompile_lookup(move |address: &Address| match *address {
NATIVE_COIN_AUTHORITY_ADDRESS => Some(DynPrecompile::new_stateful(
PrecompileId::Custom("NATIVE_COIN_AUTHORITY".into),
move |input| run_native_coin_authority(input, hardfork_flags),
)),
NATIVE_COIN_CONTROL_ADDRESS => Some(DynPrecompile::new_stateful(
PrecompileId::Custom("NATIVE_COIN_CONTROL".into),
move |input| run_native_coin_control(input, hardfork_flags),
)),
SYSTEM_ACCOUNTING_ADDRESS => Some(DynPrecompile::new_stateful(...)),
PQ_ADDRESS => {
if !hardfork_flags.is_active(ArcHardfork::Zero6) { return None; }
Some(DynPrecompile::new_stateful(
PrecompileId::Custom("PQ".into),
move |input| run_pq(input, hardfork_flags),
))
}
_ => handle_unknown_precompile(address),
});
precompile_map
}
注意 PQ precompile 受 Zero6 hardfork gate — 测试网启动时未启用,后期硬分叉激活。
arc-node 代码引用 4 — 5 个 precompile 地址(Solidity 视角):
// /repos/arc-node/contracts/src/Precompiles.sol:21-27
library Precompiles {
address internal constant NATIVE_COIN_AUTHORITY = 0x1800000000000000000000000000000000000000;
address internal constant NATIVE_COIN_CONTROL = 0x1800000000000000000000000000000000000001;
address internal constant SYSTEM_ACCOUNTING = 0x1800000000000000000000000000000000000002;
address internal constant CALL_FROM = 0x1800000000000000000000000000000000000003;
address internal constant PQ = 0x1800000000000000000000000000000000000004;
}
5 个 precompile 共用 0x1800…00XX 前缀,与 Ethereum 主网 precompiles (0x01-0x09 + 0x0A + 0x100 + 0x101) 不冲突,也不与 OP Stack (0x4200...) 冲突。
arc-node 代码引用 5 — Native Fiat Token (USDC) 地址:
// /repos/arc-node/crates/precompiles/src/helpers.rs:31-32
pub const NATIVE_FIAT_TOKEN_ADDRESS: Address =
address!("0x3600000000000000000000000000000000000000");
USDC(作为 native gas token)的特殊地址 0x3600...0000。这个地址不是 ERC-20 合约 — 而是被 Arc 节点协议层识别为”原生币”。USDC 与 native coin 的”linked interface”设计借鉴自 Celo(见 /repos/arc-node/README.md:207-208 acknowledgements)。
arc-node 代码引用 6 — Hardfork 枚举:
// /repos/arc-node/crates/execution-config/src/hardforks.rs:27-36
hardfork!(
#[derive(serde::Serialize, serde::Deserialize, Default)]
ArcHardfork {
Zero3, // v0.3 hardfork, align to Ethereum Prague
Zero4, // v0.4 hardfork, align to Ethereum Prague
Zero5, // v0.5 hardfork, align to Ethereum Prague
#[default]
Zero6, // v0.6 hardfork
}
);
至 2026-05,Arc 公开的 hardforks 是 Zero3 / Zero4 / Zero5 / Zero6(v0.3 - v0.6),均对齐到以太坊 Prague hardfork 之上(即 EIP-7702 EOA 代理、EIP-2935 historical block hashes 等已默认启用)。Zero6 是 default — testnet 当前激活的 hardfork。
arc-node 代码引用 7 — ArcHardforkFlags feature-flag 模式:
// /repos/arc-node/crates/execution-config/src/hardforks.rs:83-93
/// Feature-flag style hardfork information for EVM level.
///
/// Each hardfork can be independently enabled without implying other hardforks.
/// This allows different networks to have different hardfork activation orders.
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct ArcHardforkFlags {
zero3: bool,
zero4: bool,
zero5: bool,
zero6: bool,
}
注释说”different networks to have different hardfork activation orders” — 这是预留 testnet / mainnet / devnet 各自 hardfork 顺序可不同的工程灵活性。Arc Zero6 与 Ethereum Prague 不强制绑定 SpecId。
arc-node 代码引用 8 — EIP-1559 base fee 的 Arc 改造:
// /repos/arc-node/crates/execution-config/src/gas_fee.rs:22-48
/// Computes the parent gas used value using Exponential Moving Average (EMA) smoothing.
/// This is fed into an EIP-1559 style base fee calculation.
pub fn determine_ema_parent_gas_used(
smoothed_parent_gas_used: u64,
raw_block_gas_used: u64,
alpha: u64,
) -> Option<u64> {
// (1-α) * G[t-1] + α * G[t]
// α is expressed as an integer value [0, 100]
let a = alpha as u128;
let raw = raw_block_gas_used as u128;
let smoothed = smoothed_parent_gas_used as u128;
let complement = ALPHA_MAX - a;
let left = complement.checked_mul(smoothed)?;
let right = a.checked_mul(raw)?;
let together = left.checked_add(right)?;
u64::try_from(together / ALPHA_MAX).ok
}
关键发现:Arc 不直接用 Ethereum 的 EIP-1559 base fee 公式(按上块 gas used 单值调整),而是引入 EMA (Exponential Moving Average) 平滑。α=100 时等价 Ethereum;α<100 时长期平滑,避免 1559 在突发 spike 后的剧烈 base fee 抖动。这是金融 stablecoin 用例的合理改造 — gas 价格波动太大会影响小额支付预测性。
arc-node 代码引用 9 — Arc base fee 计算函数:
// /repos/arc-node/crates/execution-config/src/gas_fee.rs:65-80
const ARC_BASE_FEE_FIXED_POINT_SCALE: u128 = 10_000;
pub fn arc_calc_next_block_base_fee(
gas_used: u64,
gas_limit: u64,
base_fee: u64,
k_rate: u64, // 2500 => 25%
inverse_elasticity_multiplier: u64, // 7500 => 75%
) -> u64 {
let gas_target_u128 =
gas_limit as u128 * inverse_elasticity_multiplier as u128 / ARC_BASE_FEE_FIXED_POINT_SCALE;
let gas_target = u64::try_from(gas_target_u128).unwrap_or(u64::MAX);
// ...
}
Arc 把 EIP-1559 的 1/8 adjustment factor 改成可配置 k_rate / inverse_elasticity_multiplier,固定点比例 10000。这意味着 Arc 可在 hardfork 中调整 base fee 反应灵敏度而无需 1559 那样的全网升级。
arc-node 代码引用 10 — SLH-DSA PQ precompile 地址 + 基础 gas:
// /repos/arc-node/crates/precompiles/src/pq.rs:34-48
pub const PQ_ADDRESS: Address = address!("1800000000000000000000000000000000000004");
const VERIFY_BASE_GAS: u64 = 230_000;
const GAS_PER_MSG_WORD: u64 = KECCAK256WORD; // 6 gas
230_000 基础 gas — 见下文第 7 章详解。
arc-node 代码引用 11 — SLH-DSA-SHA2-128s FIPS 205 常量:
// /repos/arc-node/crates/precompiles/src/pq.rs:81-83
// SLH-DSA-SHA2-128s constants from FIPS 205
const VK_LEN: usize = 32;
const SIG_LEN: usize = 7856;
直接引用 FIPS 205 标准定义。SLH-DSA-SHA2-128s 参数集:security level 1 (~128 位),small signatures variant;公钥 32 bytes,签名 7,856 bytes(与 ECDSA secp256k1 的 65 bytes 相比差 120 倍)。
arc-node 代码引用 12 — SLH-DSA Rust crate 引用:
// /repos/arc-node/crates/precompiles/src/pq.rs:32
use slh_dsa::{signature::Verifier, Sha2_128s, Signature, VerifyingKey as SlhDsaVerifyingKey};
# /repos/arc-node/crates/precompiles/Cargo.toml:39
slh-dsa = "0.2.0-rc.4"
Arc 用 RustCrypto 的 slh-dsa 0.2.0-rc.4 — 这个 crate 未经独立审计(见 https://github.com/RustCrypto/signatures/tree/master/slh-dsa 的 README:”This implementation has not been independently audited”),但严格按 FIPS 205 test vectors 测试。Arc 自己也在 pq_test_vectors.rs 维护测试向量。
arc-node 代码引用 13 — Native coin precompile 的 Solidity interface 定义:
// /repos/arc-node/crates/precompiles/src/native_coin_authority.rs:127-156
sol! {
interface INativeCoinAuthority {
function mint(address to, uint256 amount) external returns (bool);
function burn(address from, uint256 amount) external returns (bool);
function transfer(address from, address to, uint256 amount) external returns (bool);
function totalSupply external view returns (uint256 supply);
}
event NativeCoinMinted(address indexed recipient, uint256 amount);
event NativeCoinBurned(address indexed from, uint256 amount);
event NativeCoinTransferred(address indexed from, address indexed to, uint256 amount);
/// ERC-20 Transfer event (EIP-7708), used under Zero5 for native coin transfers
event Transfer(address indexed from, address indexed to, uint256 value);
}
注意 EIP-7708 — 是 Arc 引入的 ERC-20 Transfer 事件兼容性提案。Zero5 hardfork 之后,原生 USDC mint/burn 不再发 NativeCoinMinted 自定义事件,而是发标准 ERC-20 Transfer(from=0x0, to=...),让所有 EVM 索引器(如 Etherscan、Dune、TheGraph)能直接识别 USDC 转账。
arc-node 代码引用 14 — Mint precompile 的 Zero5 gating 与 zero address 检查:
// /repos/arc-node/crates/precompiles/src/native_coin_authority.rs:218-262
if hardfork_flags.is_active(ArcHardfork::Zero5) {
// Zero5+: Skip early gas check - warm/cold pricing makes upfront calculation unreliable
if precompile_input.caller != ALLOWED_CALLER_ADDRESS {
return Err(PrecompileErrorOrRevert::new_reverted(gas_counter, ERR_CANNOT_MINT));
}
} else {
check_gas_remaining(&gas_counter, MINT_GAS_COST)?;
if !is_authorized(...)? {
return Err(PrecompileErrorOrRevert::new_reverted(gas_counter, ERR_CANNOT_MINT));
}
}
check_delegatecall(NATIVE_COIN_AUTHORITY_ADDRESS, &precompile_input, &gas_counter)?;
if hardfork_flags.is_active(ArcHardfork::Zero5) && args.to == Address::ZERO {
return Err(PrecompileErrorOrRevert::new_reverted(gas_counter, ERR_ZERO_ADDRESS));
}
if is_blocklisted(&mut precompile_input.internals, args.to, &mut gas_counter, hardfork_flags)? {
return Err(PrecompileErrorOrRevert::new_reverted(gas_counter, ERR_BLOCKED_ADDRESS));
}
ALLOWED_CALLER_ADDRESS = NATIVE_FIAT_TOKEN_ADDRESS = 0x3600...0000 — 也就是说只有 USDC 合约本身能调 mint。Zero5 之前是通过 storage slot 读 allowed_caller,Zero5 之后直接硬编码地址。
arc-node 代码引用 15 — Mint 的 overflow 检查:
// /repos/arc-node/crates/precompiles/src/native_coin_authority.rs:274-278
let new_total_supply = match current_total_supply.checked_add(args.amount) {
Some(new_total_supply) => new_total_supply,
None => return Err(PrecompileErrorOrRevert::new_reverted(gas_counter, ERR_OVERFLOW)),
};
checked_add 防 U256 overflow — 虽然 U256 ≈ 1.16e77 不太可能真 overflow,但 Arc lint arithmetic_side_effects = "deny" 强制所有算术显式检查。
arc-node 代码引用 16 — System Accounting 的 EMA ring buffer:
// /repos/arc-node/crates/precompiles/src/system_accounting.rs:50-59
const GAS_VALUES_STORAGE_KEY: StorageKey = StorageKey::new([0,0,...,1]);
/// Ring buffer capacity for historical gas values.
const GAS_VALUES_RING_BUFFER_SIZE: u64 = 64;
64 块的 ring buffer 存储历史 gas 数据,用于 EMA base fee 计算。每块的存储 slot 由 keccak256(blockNumber % 64 || GAS_VALUES_STORAGE_KEY) 算出。
arc-node 代码引用 17 — System Accounting 只允许 SYSTEM_CALLER 调用:
// /repos/arc-node/crates/precompiles/src/system_accounting.rs:61-62, 158
const SYSTEM_CALLER: Address = address!("0x0000000000000000000000000000000000000000");
if precompile_input.caller != SYSTEM_CALLER {
return Err(PrecompileErrorOrRevert::new_reverted(gas_counter, ERR_INVALID_CALLER));
}
只有 0x0 地址(block executor 在 block 处理时的 system call)能写 gas values。普通 tx 无法触发。
arc-node 代码引用 18 — Native coin control blocklist storage slot 计算:
// /repos/arc-node/crates/precompiles/src/native_coin_control.rs:127-132
pub fn compute_is_blocklisted_storage_slot(key: Address) -> StorageKey {
StorageKey::new(native_coin_control_config::compute_is_blocklisted_storage_slot(key).0)
}
Solidity mapping(address => bool) 的存储槽计算公式 keccak256(address || slot_position)。
arc-node 代码引用 19 — CallFrom 精确的 sub-call gas 计算(EIP-150 63/64 规则):
// /repos/arc-node/crates/precompiles/src/call_from.rs:106-112
let available = inputs.gas_limit.checked_sub(overhead).ok_or_else(|| {
SubcallError::InsufficientGas("gas limit below ABI decode overhead".into)
})?;
// EIP-150: forward 63/64ths of available gas to child.
#[allow(clippy::arithmetic_side_effects)]
let child_gas_limit = available - (available / 64);
严格遵守 EIP-150 child call 只能拿到 parent gas 的 63/64 — 这是 Ethereum 防 reentrancy 与栈深度爆炸的设计。
arc-node 代码引用 20 — Validator manager 三层权限:
// /repos/arc-node/contracts/src/validator-manager/PermissionedValidatorManager.sol:33-47
contract PermissionedValidatorManager is IPermissionedValidatorManager, Controller, ValidatorRegisterer, Pausable {
IValidatorRegistry public immutable REGISTRY;
uint64 public constant DEFAULT_VOTING_POWER = 0;
Owner → Controllers → ValidatorRegisterers → Validators 四层权限链:Owner 设置 Controllers,Controllers 管理 Validator activation,ValidatorRegisterers 负责 register 新 validator,DEFAULT_VOTING_POWER = 0 意味着新注册的 validator 默认不参与共识。这是典型的 Proof-of-Authority (PoA) 设计 — 与 ARC token 白皮书”未来从 PoA 切到 PoS”的路线对得上。
arc-node 代码引用 21 — Denylist 合约的 ERC-7201 storage location:
// /repos/arc-node/contracts/src/Denylist.sol:43-45
bytes32 public constant DENYLIST_STORAGE_LOCATION =
0x1d7e1388d3ae56f3d9c18b1ce8d2b3b1a238a0edf682d2053af5d8a1d2f12f00;
// /repos/arc-node/contracts/src/Denylist.sol:67-70
constructor {
_disableInitializers;
assert(
DENYLIST_STORAGE_LOCATION
== keccak256(abi.encode(uint256(keccak256("arc.storage.Denylist.前期")) - 1))
& ~bytes32(uint256(0xff))
);
}
ERC-7201 namespaced storage — 新的 OpenZeppelin upgradeable proxy 模式(2024 标准化),避免 storage slot 冲突,相比 ERC-1967 (transparent proxy) 更适合多 inheritance / diamond pattern。Arc 把 Denylist / Pausable / Controller / ValidatorRegisterer 全部用 ERC-7201 实现。
arc-node 代码引用 22 — Denylist 操作分离 owner 与 denylister 角色:
// /repos/arc-node/contracts/src/Denylist.sol:88-101
function denylist(address[] calldata accounts) external onlyDenylister {
address _owner = owner;
DenylistStorage storage $ = _getDenylistStorage;
uint256 _accounts_length = accounts.length;
for (uint256 i = 0; i < _accounts_length; ++i) {
address account = accounts[i];
if (account == _owner) revert CannotDenylistOwner; // 防止 governance 自我封禁
if (!$.denylisted[account]) {
$.denylisted[account] = true;
emit Denylisted(account);
}
}
}
注意 if (account == _owner) revert CannotDenylistOwner — 防止 denylister 把 owner 自己封了导致合约失控。这是细致的安全考量。
2.5 区块结构 + 序列化(SSZ)
Arc 的共识区块结构 (ConsensusBlock):
// /repos/arc-node/crates/types/src/block.rs:34-43
pub struct ConsensusBlock {
pub height: Height,
pub round: Round,
pub valid_round: Round,
pub proposer: Address,
pub validity: Validity,
pub execution_payload: ExecutionPayloadV3,
pub signature: Option<Signature>,
}
注意:execution_payload 类型是 alloy_rpc_types_engine::ExecutionPayloadV3 — 即标准 Ethereum Engine API v3 payload(含 EIP-4844 blob support)。
SSZ 编码:Arc 不用 RLP 而用 SSZ (Simple Serialize) 序列化共识区块,与 Ethereum 共识层(不是 Geth 的执行层 RLP)一致。证据:
// /repos/arc-node/crates/types/src/block.rs:90-100
pub fn block_as_ssz_data(block: &ConsensusBlock) -> SszBlock<&'_ ExecutionPayloadV3> {
(
block.height.as_u64,
block.round.as_u32,
block.valid_round.as_u32,
block.proposer.to_alloy_address,
block.validity.is_valid,
&block.execution_payload,
block.signature.map(SszSignature),
)
}
use ssz::Encode; 在 client.rs:19,crate::ssz::{SszBlock, SszSignature} 在 client.rs:24 — 即 Arc 共识层用 SSZ,执行层 payload 内部仍可用 RLP/SSZ 视具体 tx 而定。SSZ 优势:Merkleization friendly(每个 field 可独立 hash),适合 light client / state proof。
3. malaketh-turbo / malaketh-layered
3.1 命名来源
Malaketh = Malachite + Eth(malach + eth)。两个仓库都是 Informal Systems 内部的 PoC,验证 Malachite 如何与 Reth/Ethereum 集成。两个 PoC 在 2025 早期完成,给了 Circle 把 Malachite 用到 Arc 的工程信心。
3.2 turbo vs layered 的区别
| 维度 | malaketh-turbo | malaketh-layered |
|---|---|---|
| Reth 集成方式 | 直接 link Reth libraries 作为 Rust dep | Engine API JSON-RPC(与 Reth 跨进程) |
| 性能 | 10 MB/s(42,000 tx/s 简单 transfer,本地 3 vals) | 6 blocks/s(1000 tx/s 输入),但很多块是空的 |
| 区块构成 | 从磁盘读 pre-generated tx 序列 | 从 Reth mempool 取 |
| 验证模型 | “lazy ledger”(validators 不执行 tx,只对顺序投票) | validator 通过 Engine API 让 Reth 执行验证 |
| 部署模式 | 单 binary(consensus + execution 同进程) | 双 binary(Malachite 进程 + Reth 进程) |
| docker-compose | 无 | 3 Reth + 3 Malachite + Prometheus + Grafana |
turbo 模式的关键洞见:
- 共识层只对 tx 序列hash投票,不验证 tx execution 结果;
- 客户端(RPC node)拿到 finalized 区块后,自己执行 tx 得到 state;
- 优点:吞吐量上限不受 validator 执行速度限制;
- 缺点:不同客户端可能解释同一序列得到不同 state(需要标准化 execution semantics);
layered 模式的关键洞见:
- 标准 Ethereum 风格:CL (Malachite) ↔ EL (Reth) via Engine API;
- 优点:与 Geth / Nethermind 等任何 Engine API 兼容客户端配合;
- 缺点:性能瓶颈出现在 Engine API 通信 + Reth mempool→block 转化 — README 明确报告 1000 tx/s 输入时 mempool 满,”Reth does not take all available pending transactions when constructing blocks”;
Arc 选择的是哪种? Arc 实际架构介于二者之间:
- 与 turbo 一致:把 Reth 当 lib 直接 link(看 arc-node 的 Cargo.toml 把所有 reth-* 都当 dep import);
- 与 layered 一致:validators 执行 tx(不用 lazy ledger,因为金融场景需要 state validity);
所以 Arc 是一种 “turbo 物理布局 + layered 语义模型” 的混合 — 单 binary 跑 Malachite + Reth,但 validators 跑完整 execution 而非仅做 ordering vote。
3.3 性能优化
malaketh-turbo 的 10 MB/s = 1 个 10 MB 区块/秒 × 42,000 个 transfer = 单 transfer ≈ 238 bytes(合理:21000 gas transfer 在 RLP 编码大约 100 bytes,加 signature + receipt 是 200+ bytes)。
但这是 simple transfer 场景。malaketh-turbo README 自己承认:
“if we were using normal EVM traffic with contract calls, the client might fall behind consensus”
也就是说 EVM contract call 才是瓶颈,consensus 自身的 throughput 不是问题。
malaketh-layered 报 1000 tx/s 无法稳定承载(mempool 会满)。两者性能差 40 倍 — 主因不是共识,而是 mempool / payload builder 的整合度。
Arc 实测 2026-05-13 testnet 公开声明的吞吐尚未公布精确数字(white paper 中只提”高吞吐”),与 前期报告 overview.md 中所述一致。
4. arc-remote-signer 深度
4.1 AWS Nitro Enclaves 集成方式
arc-remote-signer 是用 Go 1.25 写的独立微服务,与 arc-node binary 通过 gRPC 通信。它有双进程架构:
Validator (arc-node) ──gRPC:10340──> Proxy ──vsock──> Enclave (Nitro)
│
├── KMS provider
└── Secrets Manager provider
Proxy 进程(host 上跑):
- 暴露 SignerService gRPC,端口 10340;
- 转发请求到 enclave(通过 vsock virtual socket);
- 集成 AWS KMS 解密密钥、Secrets Manager 拉配置、attestation 文档缓存;
- 不持有任何明文 key material;
Enclave 进程(Nitro 内跑):
- 暴露 EnclaveService gRPC,端口 10350(仅 vsock 内可达);
- 持有解密后的私钥(仅在 enclave RAM 内);
- 执行 Ed25519 签名(也有 BLS support);
- 通过 NSM (Nitro Security Module) 生成 attestation document 证明 enclave 镜像 hash;
AWS Nitro Enclaves 提供:
- 完全隔离的虚拟机(无网络、无持久存储、无外部 sysfs);
- 仅 vsock 与 host 通信;
- 硬件级 attestation(measure 启动镜像);
- 与 KMS 集成:可设置 KMS key policy “Only decrypt for enclave with measurement = X”;
详见 AWS 官方文档 https://docs.aws.amazon.com/enclaves/latest/user/nitro-enclave.html。
4.2 四层 envelope 加密
README 提到:”Four-layer key protection (validator key → data key → KMS key → enclave key)“
具体含义解读(基于 AWS Web3 blog https://aws.amazon.com/blogs/web3/aws-nitro-enclaves-for-running-ethereum-validators-part-1/):
- L1 - validator key:实际的 Ed25519 私钥(32 bytes),用于签 Malachite 共识投票;
- L2 - data key:AES-256 对称 key,用于加密 L1 in DynamoDB;
- L3 - KMS key:AWS KMS 主 key,加密 L2;KMS key policy 中绑定 enclave attestation measurement,确保仅特定 enclave 镜像才能解密 L2;
- L4 - enclave key:enclave 启动时由 NSM 生成的临时 key,绑定到 attestation document;
加密链:L1 (validator key) ← L2 (AES data key) ← L3 (KMS master key) ← L4 (enclave attestation)
要解密 L1:
1. Proxy 从 DynamoDB 拉密文 + L2 密文;
2. Proxy 向 KMS 提交 decrypt 请求,附带 attestation document(含 enclave PCR measurements);
3. KMS 验证 measurements 匹配 policy → 用 L4 enclave key 加密 L2 plaintext 返回;
4. Enclave 收到后用自己持有的 L4 解出 L2,再用 L2 解出 L1;
5. L1 仅存在 enclave 内存,签名后立即用,永不出 enclave;
4.3 Validator 私钥保护
Arc 验证人面临两类攻击:
- 远程攻击:黑客通过 SSH / 应用漏洞拿到 root → 读 disk → 读 memory;
- insider 攻击:AWS 员工 / 验证人公司员工 → root 权限 → 读 enclave 外的一切;
Nitro Enclave 设计专门防 insider 攻击:
- Enclave 进程的 RAM 不能被 host root 读(Nitro 硬件隔离);
- 没有 sysfs、proc、/dev — enclave 内进程无法被外部 trace;
- Attestation 由 AWS Nitro Root Cert 签 → 验证人公司 / Circle 都无法伪造;
对比传统 HSM(Hardware Security Module,如 YubiHSM 或 Thales nShield):
- HSM 优势:物理设备,FIPS 140-2 Level 3+ 认证,离线可控;
- HSM 劣势:单点故障、扩展性差、采购周期长、运维复杂;
- Nitro 优势:云原生、按需创建实例、attestation 可程序化验证、与 KMS 无缝集成;
- Nitro 劣势:依赖 AWS 生态、Level 1 sec boundary(与 HSM Level 3 比稍弱);
Circle 选 Nitro 的工程意图:让任何 Circle 客户能 1-click 起验证节点而不用自己买 HSM。验证人门槛降低 → Arc 验证集去中心化更可行。
4.4 远程签名协议
Proto 定义(/repos/arc-remote-signer/proto/):
SignerService (外部 API,端口 10340):
- PublicKey → bytes32 — 返回 32-byte Ed25519 公钥;
- Sign(message bytes) → bytes64 — 返回 64-byte Ed25519 签名;
EnclaveService(内部 API,仅 vsock):
- GenerateKey → KeyId, Ciphertext — 创建新 keypair,返回密文(用 KMS 包);
- GetPublicKey(KeyId) → bytes32
- SignMessage(KeyId, message) → bytes64
- GetAttestation → AttestationDoc — 返回 CBOR 编码的 NSM attestation;
arc-node 端 client(见 /repos/arc-node/crates/remote-signer/src/client.rs:55-100):
pub struct RemoteSignerClient {
client: SignerServiceClient<Channel>, // tonic gRPC
config: RemoteSigningConfig,
metrics: RemoteSigningMetrics,
}
const ED25519_PUBLIC_KEY_SIZE_BYTES: usize = 32;
const ED25519_SIGNATURE_SIZE_BYTES: usize = 64;
TLS:可选启用,pem 证书路径配置在 RemoteSigningConfig,使用 tonic::transport::ClientTlsConfig::new.ca_certificate(...)。Backon crate 用于 retry/backoff (config retry policy)。
4.5 与传统 HSM 的差异
| 维度 | 传统 HSM (YubiHSM 2 / Thales nShield) | AWS Nitro Enclaves |
|---|---|---|
| 物理形态 | 硬件设备(USB/PCIe/网络) | 虚拟机隔离(云原生) |
| 认证 | FIPS 140-2 Level 3+ | “硬件级隔离”,无单一 FIPS 等级 |
| 远程 attestation | 部分支持(PKCS#11) | CBOR 格式,原生支持 |
| 弹性扩展 | 难(采购周期、固定容量) | 按需启 EC2,分钟级 |
| 单价 | $650-$30,000+ | EC2 实例 + 少量 enclave 开销 |
| 编程模型 | PKCS#11 API(C 标准) | gRPC + vsock(应用层友好) |
| 抗量子准备 | 部分支持(依赖固件) | 软件可升级,Arc 已集成 SLH-DSA precompile |
| 适用场景 | 高合规、政府金融 | 公链 validator、Web3 大规模部署 |
Arc 选 Nitro 而非 HSM = 优先扩展性与运维灵活性,牺牲少量物理安全等级。对 stablecoin 链 validator 这是合理 tradeoff。
5. arc-stablecoin-fx
5.1 关键发现:仓库 nearly empty
ls 显示该仓库只有 README.md,README 总共 1 行:
”# arc-stablecoin-fx — This sample app demonstrates stablecoin FX swaps between USDC and EURC using the App Kit Swap SDK on Arc.”
这意味着:
1. arc-stablecoin-fx 不是 Arc 自身的协议组件,而是一个 sample app demonstration;
2. 实际代码尚未公开(截至 2026-05-13,仓库 placeholder 状态);
3. FX swap 逻辑由 Circle App Kit Swap SDK 提供,而非链上原生协议;
5.2 推测的链上 FX swap 设计
根据 Arc whitepaper + 上述 placeholder:
- 资产:USDC(已是 native)+ EURC(Circle 欧元稳定币)+ 未来 JPYC(潜在);
- 交易模型:sample app 层面是 SDK 调用,链上很可能是 AMM (Automated Market Maker) 而非 order book —— 因 Arc 强调 sub-second finality 与 deterministic execution,AMM 路径更对位;
- KYB-only 准入:Arc 商业 whitepaper 提到 FX module 准入是 KYB(Know-Your-Business),即只有通过合规审核的企业地址能调 FX swap 函数 → 实现路径是 denylist + permissioned 验证 caller;
5.3 与传统外汇市场的对接
传统 FX 市场(如 EBS、Refinitiv、CME FX)特点:
- 24/5 营业(周末关闭);
- 主要参与方:BIS 央行、Tier-1 银行、Hedge fund、prime broker;
- 报价:spot + forward + swap + option;
- 结算:T+2(spot),CLS Bank 净额清算;
Arc stablecoin FX 想替代的是:
- T+2 → 即时:链上 finality 1s 内;
- CLS 净额 → atomic swap:原子化 USDC↔EURC 兑换;
- 银行间专属 → 任何 KYB 企业:准入门槛大幅降低;
但短期内 Arc 不可能完全取代传统 FX —— 链上流动性仍 << EBS 等主流场内(每日 $5+ trillion)。Arc 的真实定位是”链上 settlement layer for 跨境企业 stablecoin 支付的 FX leg”。
5.4 AMM vs Order Book
如果是 AMM,可能用:
- Uniswap V3 集中流动性曲线(适合稳定币-稳定币低滑点对);
- Curve StableSwap 不变量(专为同价值资产设计);
如果是 Order Book,则需要:
- 链上 order book 合约(gas 重,Arc 子秒 finality 部分缓解但 gas 上仍受限);
- 或链下 order book + 链上 settlement(如 0x V4 / dYdX V3 模式);
最可能的设计:链下 RFQ (Request-For-Quote) 由 Circle App Kit 撮合 → 链上 atomic settlement。这与 Circle 现有 Cross-Chain Transfer Protocol (CCTP) + Gateway 的中心化架构哲学一致。
6. arc-nanopayments
6.1 微支付场景
arc-nanopayments 是个 Next.js 示范应用,演示AI agent + 流支付。流程:
- Seller: 提供 HTTP API 的服务方,端点用 x402 协议保护(返回
HTTP 402 Payment Required); - Buyer: 一个 LangChain agent(基于 deepagents npm package),自动决定何时何处 pay;
- Gateway: Circle 的 Gateway 服务,批量收集 buyer 离线签名授权,定期在链上聚合 settlement(让 sub-cent 支付经济上可行);
- 支付 token: USDC,在 Arc testnet 上;
示例端点价格(README 表格):
| 端点 | 价格(USDC) | 描述 |
|---|---|---|
/api/premium/quote |
$0.001 | 单条引言 |
/api/premium/dataset |
$0.01 | JSON 数据集 |
/api/premium/compute |
$0.0003 | 文本分析 |
/api/premium/agent-task |
$0.03 | 寻宝任务 |
$0.0003 这种千分之三分钱级别 — 传统支付(Stripe、信用卡)单笔最低 fee 都比这高 100 倍 → 完全不可行。流式聚合后通过 Gateway 一次 settlement 才让其经济。
6.2 协议设计:x402
x402 协议(由 Coinbase 与 Cloudflare 共同推动,2025 提案):
- 复用 HTTP/1.1 RFC 7231 中保留的
402 Payment Required状态码(自 1997 起保留至今未启用); - Server 在未付费请求上返回 402 + 一个支付要求 header(指定 chain id、token、amount、recipient);
- Client 看到 402 → 签名一笔 USDC transfer 授权 → 在重试请求的 header 中附上签名;
- Server 验证签名 → 返回内容;可选立即结算或缓冲后 batch;
为什么用 USDC + ERC-2612 Permit / Permit2?
- ERC-2612 Permit:让 USDC 支持 off-chain signed approval(一次签名授权 N 笔);
- Permit2 (Uniswap):升级版 universal token approval;
- Buyer 不需要先发 approve 交易(节省 gas + 延迟);
至 2026-03,x402 协议数据:
- 119M+ transactions on Base;
- 35M+ on Solana;
- ~$600M annualized volume;
- $0 protocol fees;
- 联盟成员:Coinbase + Cloudflare + Google + Visa(x402 Foundation);
详见 https://docs.cdp.coinbase.com/x402/welcome 与 https://www.x402.org/。
6.3 与 Lightning Network 的对比
Bitcoin Lightning Network 是另一个流支付方案:
| 维度 | x402 (Arc + Gateway) | Lightning Network |
|---|---|---|
| 底层 | EVM stablecoin (USDC on Arc/Base/etc) | Bitcoin Layer 2 |
| 支付单位 | USDC(fiat-stable) | sat (Bitcoin) |
| 通道开设 | 无需,每笔授权独立签名 | 需开 channel(链上 tx + 锁定资金) |
| 路由 | 中心化 facilitator(Gateway 或 Coinbase) | 去中心化 onion routing |
| 流式 | 通过 batch settlement | 通过 HTLC 时间锁原子化 |
| 集成 | 标准 HTTP header → 任何 Web stack | 需要 Lightning node + LND/CLN library |
| AI agent 友好度 | 高(HTTP-native) | 中(需 Lightning wallet integration) |
| 实时性 | 服务端验证后立即可交付 | 几秒(route 跳转延迟) |
| 链上 finality | 最终通过 Gateway settlement 1-N tx 上链 | 频道关闭时上链 |
Lightning 更适合 P2P 加密原生 场景(Strike、Bitwise、Cash App),x402 更适合 AI agent + Web API。两者哲学差异:Lightning = 去中心化路由 + 微观资金锁定;x402 = 中心化 facilitator + HTTP-native 体验。
6.4 Buyer agent 的设计
arc-nanopayments 的 buyer 端是个 LangChain agent(README 提到使用 deepagents npm 包):
npm run agent -- --limit 0.5 # 设置 USDC 花费上限
npm run agent -- "Buy me a quote at http://localhost:3000/api/premium/quote"
支持:
- 自然语言指令解析(LLM 决定要哪个 endpoint);
- USDC 余额 + Gateway 余额自动检查 + deposit;
- 端点 x402 支持检测;
- 自动支付 + 重试;
- 花费上限(达到 limit 后暂停 + 要求人工补 allowance);
这是 2026 年 AI agent commerce 的 typical pattern:人类设置 budget + intent,agent 自主完成多步交易(含支付)。Arc 把这种 pattern 当 first-class use case 推广。
7. 5 个 Precompiles 单独详解
重头戏。每个 precompile 1000+ 字 deep dive。
7.1 NATIVE_COIN_AUTHORITY (0x1800…0000)
Solidity Interface(见 /repos/arc-node/crates/precompiles/src/native_coin_authority.rs:127-141):
interface INativeCoinAuthority {
function mint(address to, uint256 amount) external returns (bool);
function burn(address from, uint256 amount) external returns (bool);
function transfer(address from, address to, uint256 amount) external returns (bool);
function totalSupply external view returns (uint256 supply);
}
作用:管理 native USDC 的供应。USDC 不是 ERC-20 合约部署的 token —— 而是 Arc 链层面的”原生币”(类似 ETH 在 Ethereum 上的地位),但其 mint/burn 权限被精确限制:只有 USDC 合约(0x3600…0000)能调用这个 precompile。
Storage layout:
- Slot 1:
ALLOWED_CALLER_STORAGE_KEY— 存允许调用者地址(Zero5 之前用,Zero5 之后直接硬编码); - Slot 2:
TOTAL_SUPPLY_STORAGE_KEY— 存当前 native USDC total supply; - 每个地址的 balance 在 EVM account state 中(不在 precompile storage);
Gas cost 设计:
Pre-Zero5:
// 见 native_coin_authority.rs:65-74
const MINT_GAS_COST: u64 = 4 * 2100 // 4 个 SLOAD (allowed caller, blocked to, total supply, balance)
+ 2 * 2900 // 2 个 SSTORE (total supply, balance)
+ 1381; // Mint event (2 topics + 32 byte data)
// = 15,581 gas
const BURN_GAS_COST: u64 = ... = 15,581 gas;
const TRANSFER_GAS_COST: u64 = 5*2100 + 2*2900 + 1756 = 18,056 gas;
Zero5+:取消 allowed caller SLOAD (直接地址匹配),使用 EIP-2929 warm/cold SLOAD 定价 (100 / 2100)。实际 gas 取决于 access list 状态。
调用方式:
- EOA / 智能合约调用 USDC ERC-20 接口(如
transfer(to, amount)); - USDC ERC-20 合约内部 delegatecall 到 native_coin_authority precompile;
- precompile 验证
caller == ALLOWED_CALLER (0x3600…0000)→ 通过则更新 native balance + 发 ERC-20 Transfer event;
Wait — 实际上不是 delegatecall(precompile 内显式 check_delegatecall 拒绝),而是 native_fiat_token 合约的内部 CALL。USDC 智能合约自己处理 ERC-20 接口(balanceOf, approve, allowance),但 transfer 触发 native_coin_authority precompile 的 transfer。
安全模型:
check_staticcall:禁止 staticcall 调用 mint/burn/transfer(防止 view 函数误调用 state-changing 操作);check_delegatecall:禁止 delegatecall(防止 caller context 被劫持);caller != ALLOWED_CALLER立即 revert(authorization);is_blocklisted(to) → ERR_BLOCKED_ADDRESS:受 native_coin_control 联动;amount == 0 → ERR_ZERO_AMOUNT:拒绝零金额(Zero5+);to == ZERO → ERR_ZERO_ADDRESS:拒绝铸到零地址(Zero5+);checked_add overflow → ERR_OVERFLOW:U256 加法溢出保护;
已知调用历史:
至 2026-05-13 testnet 上线 6+ 个月,所有 USDC mint/burn/transfer 都路由经此 precompile。具体 explorer URL:https://testnet.arcscan.app(在 arc-nanopayments README 提到)。每笔 testnet USDC 操作均产生 Transfer(from, to, value) event(Zero5+) 或 NativeCoinTransferred event(pre-Zero5)。
7.2 NATIVE_COIN_CONTROL (0x1800…0001)
Solidity Interface:
interface INativeCoinControl {
function blocklist(address account) external returns (bool success);
function isBlocklisted(address account) external view returns (bool);
function unBlocklist(address account) external returns (bool success);
}
作用:链层级的地址封禁名单。这是 Arc 与多数 L1 最显著的差异之一 — 它把 OFAC sanction、AML compliance 内建到协议层。
Storage:mapping (address => uint256 status),每个 address 占一个 slot。Status:
// /repos/arc-node/crates/precompiles/src/native_coin_control.rs:77-78
pub const BLOCKLISTED_STATUS: U256 = U256::from_limbs([1, 0, 0, 0]); // 0x01
pub const UNBLOCKLISTED_STATUS: U256 = U256::ZERO; // 0x00
Storage slot 计算:
// /repos/arc-node/crates/precompiles/src/native_coin_control.rs:128-131
pub fn compute_is_blocklisted_storage_slot(key: Address) -> StorageKey {
StorageKey::new(native_coin_control_config::compute_is_blocklisted_storage_slot(key).0)
}
实现是 Solidity mapping(address => bool) 的标准 storage slot:keccak256(address_padded_to_32 || slot_position)。
Gas cost:
// native_coin_control.rs:62-74
const BLOCKLIST_GAS_COST: u64 =
PRECOMPILE_SLOAD_GAS_COST // 2100 - read allowed caller
+ PRECOMPILE_SSTORE_GAS_COST // 2900 - write blocklist status
+ BLOCKLISTED_EVENT_GAS_COST; // 1125 - emit Blocklisted event
// = 6,125 gas
pub const IS_BLOCKLISTED_GAS_COST: u64 = PRECOMPILE_SLOAD_GAS_COST; // 2,100 gas (view only)
const UNBLOCKLIST_GAS_COST: u64 = ... = 6,125 gas;
isBlocklisted 极便宜(2100 gas)— 因为这个查询会被所有 native USDC 操作内部调用(每次 transfer 都要查 from 和 to 是否被封禁),所以 gas 必须低。
Solidity 合约层(治理层):
链下的 governance 通过 /repos/arc-node/contracts/src/Denylist.sol 管理 denylist,包含:
- ERC-7201 namespaced storage;
- onlyDenylister modifier:denylister 角色才能改 denylist;
- addDenylister / removeDenylister:仅 owner 可管理;
- CannotDenylistOwner error:不能封 owner 自己;
Denylist 合约通过 precompile 反射到 EVM 状态:链上 governance 合约 → blocklist 精确 precompile → BLOCKLISTED_STATUS storage 改变 → 后续所有 transfer 自动检查。
调用方式:
- 协议自动:每次 USDC transfer 内部调
isBlocklisted(from)和isBlocklisted(to); - 治理操作:Denylist 合约(部署于链上某固定地址)的 owner 通过
denylist(addresses[])批量加; - EOA query:任何人都可 view 调
isBlocklisted(addr);
安全模型:
- 链层级封禁 ≠ 全网拒绝交易 — 它只阻止 native USDC 操作,不阻止 ETH 等其他 token 或合约调用;
- 但 USDC 是 native gas → 如果 denylisted address 没法支付 gas,事实上无法发任何 tx → 链层级 censorship;
- 这是 Arc 设计哲学:为合规牺牲完全的 censorship-resistance;
- 对比 Ethereum 主网:无链层级 OFAC 名单,但 Tornado Cash 风险下 builder/relayer 自我审查;
- 对比 USDC on Ethereum:合约层 blacklist 是 ERC-20 内部逻辑,Arc 提升到协议层;
调用历史:testnet 上线后已有 governance 操作部署 Denylist 合约(地址未公开),但尚未公开任何实际封禁记录。production 阶段预期会与 OFAC SDN list / FinCEN 协调。
7.3 SYSTEM_ACCOUNTING (0x1800…0002)
Solidity Interface:
struct GasValues {
uint64 gasUsed;
uint64 gasUsedSmoothed;
uint64 nextBaseFee;
}
interface ISystemAccounting {
function storeGasValues(uint64 blockNumber, GasValues calldata gasValues) external returns (bool);
function getGasValues(uint64 blockNumber) external view returns (GasValues calldata gasValue);
}
作用:把每块的 gas 统计写入链上 ring buffer,给 base fee 平滑 EMA 算法提供历史数据。这是 Arc 改造 EIP-1559 的配套基础设施。
Storage:
// /repos/arc-node/crates/precompiles/src/system_accounting.rs:50-59
const GAS_VALUES_STORAGE_KEY: StorageKey = StorageKey::new([0,0,...,1]);
const GAS_VALUES_RING_BUFFER_SIZE: u64 = 64;
64 块 ring buffer:每个 slot 由 keccak256(blockNumber % 64 || GAS_VALUES_STORAGE_KEY) 算出,存 packed (gasUsed, smoothed, nextBaseFee) 共 24 bytes(3 个 uint64 = 24 bytes,padded 到 32 bytes 一个 slot)。
每 block 写一次,每 block 从 ring buffer 读一次(parent slot for EMA smoothing)。
Gas cost:
// system_accounting.rs:155-156
record_cost_or_out_of_gas(&mut gas_counter, PRECOMPILE_SLOAD_GAS_COST)?; // 2100 gas
storeGasValues 大约 2100 + 2900 (SSTORE) + 200 (decoder penalty) = ~5,200 gas;getGasValues = 2,100 gas (SLOAD)。
调用方式:
- storeGasValues:仅
SYSTEM_CALLER (0x0)能调,即 block executor 在 block 处理结束时的 system call; - getGasValues:任何 caller 可 view 调;通常由 base fee 计算逻辑(块执行开始时)和外部 monitoring 调用;
// system_accounting.rs:158-160
if precompile_input.caller != SYSTEM_CALLER {
return Err(PrecompileErrorOrRevert::new_reverted(gas_counter, ERR_INVALID_CALLER));
}
Ring buffer 设计的 corner case:
注释明确(system_accounting.rs:81-95):
“Returns ring-buffer slot blockNumber % 64 as-is, without any freshness check. If blockNumber has been rotated out (more than 63 behind the latest written block) or is in the future, the slot holds the last block that mapped to it — i.e. a different block’s values.”
也就是说,调用者必须自己保证 blockNumber 是新鲜的。共识层用 EMA 时只读 parent slot(块刚写过的),所以不会撞 stale 数据。但 RPC 客户端如果直接调,需要自己 cross-check。这是工程层面的设计权衡:极简存储 + 调用者负责正确性。
安全模型:
SYSTEM_CALLER唯一调用 → 防止用户用普通 tx 改 gas history;check_delegatecall→ 防止 delegatecall context 劫持;check_staticcall→ storeGasValues 拒绝 staticcall;- Ring buffer 写入不验证 blockNumber 合法性 → 调用者(即 block executor)信任;
调用历史:每个区块结束都会调一次 storeGasValues。从 testnet 创世块至 2026-05,约 N×24小时×3600秒 / blocktime 次调用。在 testnet explorer 可查 tx 类型 = System Call 的 internal tx。
7.4 CALL_FROM (0x1800…0003)
Solidity Interface:
interface ICallFrom {
function callFrom(address sender, address target, bytes calldata data)
external returns (bool success, bytes memory returnData);
}
作用:让一个 allowlisted caller 合约能”伪装”成另一个地址向 target 发起调用 — 即覆盖 msg.sender。这是 Memo 与 Multicall3From 等高级合约的底层 building block。
Use case:
- Memo:允许第三方代付 gas + 写 message 到链上,但消息归属看起来是原始用户而非 relayer;
- Multicall3From:把多个用户的操作打包 + 让每个内部 call 还是原用户的 msg.sender;
- 这是 ERC-4337 Account Abstraction 的另一种实现路径 — 但用 precompile 而非 EntryPoint 合约;
实现细节(见 /repos/arc-node/crates/precompiles/src/call_from.rs:81-128):
fn decode_child_call(inputs: &CallInputs) -> Result<(CallInputs, u64), SubcallError> {
let decoded = ICallFrom::callFromCall::abi_decode(input_bytes)?;
let sender = decoded.sender;
let target = decoded.target;
let calldata = decoded.data;
// init_subcall overhead: fixed base + per-word charge for the dynamic `bytes data`.
let overhead = abi_decode_gas(calldata.len);
let available = inputs.gas_limit.checked_sub(overhead)?;
let child_gas_limit = available - (available / 64); // EIP-150
let child_inputs = CallInputs {
scheme: CallScheme::Call,
target_address: target,
bytecode_address: target,
known_bytecode: None,
value: CallValue::Transfer(U256::ZERO),
input: CallInput::Bytes(calldata),
gas_limit: child_gas_limit,
is_static: false,
caller: sender, // ← KEY: caller 覆盖为 decoded.sender
return_memory_offset: 0..0,
};
Ok((child_inputs, overhead))
}
Gas cost:
// call_from.rs:53-59
pub const ABI_DECODE_BASE_GAS: u64 = 100;
pub fn abi_decode_gas(data_len: usize) -> u64 {
let words = (data_len as u64).div_ceil(32);
ABI_DECODE_BASE_GAS.saturating_add(words.saturating_mul(gas::COPY))
}
固定 100 gas base + 3 gas per 32-byte word (COPY)。例如 1 KB calldata → 100 + 32 * 3 = 196 gas overhead,然后剩 63/64 转发给子调用。
安全模型:
- Allowlist gating:注释明确 “Access is restricted via the subcall registry’s allowlist — only allowlisted contracts may invoke CallFrom”。要成为 allowlisted caller,需通过 governance;
- Sender trust:sender 参数是 trusted —— allowlisted caller 必须自己保证传入的 sender 是正确的(通常是它收到的 msg.sender);
- Two-phase subcall:实现 SubcallPrecompile trait,区分 init_subcall(建子调用 frame)和 complete_subcall(子调用返回后 ABI 编码);
Use case 详例:
Memo 合约(见 /repos/arc-node/contracts/src/memo/Memo.sol):让用户写一条 memo 到链上,但 gas 由 Relayer 付。Relayer 调 Memo.writeMemoFor(user, message, signature),Memo 验证用户签名 → CallFrom 精确 precompile 让 emit 事件时 msg.sender = user。
Multicall3From 合约(见 /repos/arc-node/contracts/src/batch/Multicall3From.sol):扩展 Uniswap 的 Multicall3,每个 batch item 可指定不同的 from 地址,由 CallFrom 实现。
调用历史:testnet 上的 Memo 和 Multicall3From 合约部署后会调用此 precompile。具体 explorer URL:https://testnet.arcscan.app — 在 testnet 内查 precompile address 0x1800…0003 的 incoming calls。
7.5 PQ (0x1800…0004) — SLH-DSA-SHA2-128s 抗量子签名
Solidity Interface:
interface IPQ {
/// Verify an SLH-DSA-SHA2-128s signature
/// Gas cost: 230,000 base + 6 per 32-byte word of message (same as KECCAK256)
function verifySlhDsaSha2128s(bytes calldata vk, bytes calldata msg, bytes calldata sig) external returns (bool isValid);
}
作用:在链上验证 SLH-DSA-SHA2-128s(FIPS 205 标准的抗量子哈希签名)。
激活条件:仅在 Zero6 hardfork 激活后可用。pre-Zero6 调用此地址 → 视为无 precompile(返回 default 0)。
算法背景:
- SLH-DSA = Stateless Hash-Based Digital Signature Algorithm,FIPS 205(2024 年 8 月 NIST 正式发布);
- 基于 SPHINCS+,是 NIST PQC 标准化的”保守选择”—— 安全性仅依赖底层 hash function 的 preimage/collision resistance(不依赖未经实战检验的格密码假设);
- 12 个参数集,分 3 个 security levels(128 / 192 / 256 位);每级有 SHA2 和 SHAKE 两种 hash;每对都有 small (
s) 和 fast (f) 两种 variant; - Arc 选的是 SLH-DSA-SHA2-128s:security level 1 + SHA-2 + small signatures variant;
参数(FIPS 205 Table 1):
- Public key: 32 bytes
- Signature: 7,856 bytes(震撼性大 — ECDSA 是 65 bytes,120 倍);
- Sign time: 慢(很多 hash 调用);
- Verify time: 中等;
- Stateless: yes(与 LMS/XMSS hash-based stateful 签名不同);
实现引用:
// /repos/arc-node/crates/precompiles/src/pq.rs:32
use slh_dsa::{signature::Verifier, Sha2_128s, Signature, VerifyingKey as SlhDsaVerifyingKey};
slh-dsa = "0.2.0-rc.4" RustCrypto 实现,未经独立审计但严格 FIPS 205 test vectors 验证。
完整执行流:
// /repos/arc-node/crates/precompiles/src/pq.rs:59-109
precompile!(run_pq, precompile_input, hardfork_flags; {
IPQ::verifySlhDsaSha2128sCall => |input| {
let mut gas_counter = Gas::new(precompile_input.gas);
let args = IPQ::verifySlhDsaSha2128sCall::abi_decode_raw(input)?;
// Step 1: Charge base gas
record_cost_or_out_of_gas(&mut gas_counter, VERIFY_BASE_GAS)?; // 230,000
// Step 2: Charge per-word message gas
let msg_word_gas = (args.msg.len as u64).div_ceil(32) * GAS_PER_MSG_WORD; // 6 per word
record_cost_or_out_of_gas(&mut gas_counter, msg_word_gas)?;
// Step 3: Validate input lengths
const VK_LEN: usize = 32;
const SIG_LEN: usize = 7856;
if args.vk.len != VK_LEN { return Err(...); }
if args.sig.len != SIG_LEN { return Err(...); }
// Step 4: Parse vk and sig
let verifying_key = SlhDsaVerifyingKey::<Sha2_128s>::try_from(args.vk.as_ref)?;
let signature = Signature::<Sha2_128s>::try_from(args.sig.as_ref)?;
// Step 5: Verify
let is_valid = verifying_key.verify(args.msg.as_ref, &signature).is_ok;
Ok(PrecompileOutput::new(gas_counter.used, is_valid.abi_encode.into))
},
});
Gas cost 设计 rationale:
// /repos/arc-node/crates/precompiles/src/pq.rs:42-48
const VERIFY_BASE_GAS: u64 = 230_000;
const GAS_PER_MSG_WORD: u64 = KECCAK256WORD; // 6
230,000 gas 的 rationale(来自 benchmark crates/precompiles/benches/pq.rs):
- SLH-DSA-SHA2-128s 验证主要工作量是 ~5,000 个 SHA-256 调用(构造 Merkle 树 + WOTS+ + FORS 验证);
- SHA-256 precompile 的 gas 是 60 base + 12 per word;
- SLH-DSA 7856-byte 签名验证 ≈ 等价 5000 个 64-byte SHA-256 计算 → 60 + 12×2 ≈ 84 gas per SHA-256;
- 总:5000 × ~46 = 230,000 gas(保守估计);
- 注释明确:”Conservative relative to the SHA-256 precompile’s per-word work anchor”;
实测(见 pq.rs:266-307 的测试):32-byte message 总 gas 约 380K — 内含 230,006 precompile cost + 7856-byte signature calldata cost(每非零字节 16 gas,零字节 4 gas,超大签名 calldata 占主要)。
完整 7856 字节签名的成本结构:
| 项目 | gas |
|---|---|
基础 base gas (VERIFY_BASE_GAS) |
230,000 |
32-byte msg word gas (6 × 1) |
6 |
| 32-byte VK calldata(约 32 × 16) | ~512 |
| 7856-byte signature calldata(约 7856 × 16 worst case) | ~125,696 |
| 总(最坏情况) | ~356,000 |
| 总(部分零字节) | ~370-390K |
签名/验证流程内部(FIPS 205):
- WOTS+ (Winternitz One-Time Signature):构造 OTS keypair,签 message digest;
- FORS (Forest of Random Subsets):few-time hash signature,签 WOTS+ key 的 hash;
- Hyper-tree of Merkle:H = 63 层 Merkle tree of WOTS+ public keys,每层 9 个 WOTS+;
- 签名 = WOTS+ sig + FORS sig + 9 × Merkle authentication paths × 63;
- 验证:rebuild 同样的 Merkle tree root,与 pk 比较;
每个 hash 都是 SHA-256(128s 变体)。整体 verify 时间约 millisecond 级(CPU)— 但 EVM 内 gas 计费让它表达为 230k gas。
安全模型:
- 量子安全:基于 SHA-256 的 preimage resistance(量子 Grover 算法只能给 √N 加速,128-bit 安全级别需要 256-bit hash);
- NIST 标准化:FIPS 205 最终发布(2024-08-13),是美国政府强制使用的后量子签名之一;
- 保守选择:与 ML-DSA(FIPS 204 lattice)相比,SLH-DSA 不依赖未来可能被破解的格假设;
- 签名大小代价:7856 bytes 是 SLH-DSA-SHA2-128s 已是最小变体(fast variant
f签名更大 ~17 KB); - 缓慢签名:签名需要 ~100 万次 hash 调用 → 慢,不适合高频签名场景;
Arc day-1 集成的运维含义:
- 200K+ gas 不便宜 — 1 个 SLH-DSA verify 约等于 10 次 ECDSA verify 的 gas 成本(ECDSA
ecrecover≈ 3000 gas); - 7856 bytes 签名占 calldata 大头 — 即使在 EIP-4844 blob 数据上,单签名也需要专用 blob;
- 使用场景定位:不是替代 ECDSA 用于普通 tx 签名(gas 太贵),而是给特定高价值场景:
- 长期保存的离线签名(如 trust setup、protocol upgrade auth);
- 跨链 bridge 的 multi-sig(量子来临前的 forward-secrecy);
- 时间戳证明(要求 50+ 年仍可验证);
- Arc 是 day-1 集成抗量子签名 verify 的极少数公链之一 —— 其他链需要硬分叉才能添加;
7.6 抗量子的工业意义比较
其他公链的抗量子路线:
| 公链 | 状态 | 算法 | 时间 |
|---|---|---|---|
| Arc | day-1 precompile (Zero6) | SLH-DSA-SHA2-128s (FIPS 205) | testnet 2025-10 已含 |
| Solana | 提案讨论阶段 | Winternitz + Lamport | 2024-2025 proposed |
| Ethereum | EIP 探索中 (EIP-7503 quantum recovery) | TBD(可能 ML-DSA 或 Falcon) | 2027+ 预计 |
| Bitcoin | BIP-360 quantum address 提案 | SLH-DSA / ML-DSA / FALCON | 2026 SegWit-style soft fork 讨论 |
| QANplatform | 已 mainnet | CRYSTALS-Dilithium (FIPS 204) | 2024 |
Arc 的优势:把抗量子作为可选 precompile,让应用开发者选择何时升级签名,不强制全网迁移。
8. EVM 兼容性深度
8.1 与 Ethereum mainnet 的 opcode 差异
Arc EVM 在 Reth/revm 之上的主要差异:
- 新增 5 个 precompile:0x1800…00 至 0x1800…04(见前述);
- 保留 Ethereum 所有标准 opcode:PUSH/POP/ADD/MUL/JUMP/CALL/CREATE/SSTORE/SLOAD 等全部 unchanged;
- 保留 Ethereum precompiles:0x01 (ECRECOVER) ~ 0x0A (KZG_POINT_EVAL) + 0x100 (P256VERIFY, EIP-7212) 全保留;
- opcode 行为微调(见
/repos/arc-node/crates/evm/src/opcode.rs):
-CALL/CREATE在 value transfer 时检查 from/to 是否 denylisted → revert with ERR_BLOCKED_ADDRESS;
- 这是 native USDC 转账(以太坊视角的value字段)受 denylist 影响;
- 普通 contract call(无 value)不受影响;
8.2 Pre-compile 集合
Arc 总 precompile 数:
| 地址 | 名称 | 来源 | gas |
|---|---|---|---|
| 0x01 | ECRECOVER | Ethereum | 3000 |
| 0x02 | SHA256 | Ethereum | 60 + 12/word |
| 0x03 | RIPEMD160 | Ethereum | 600 + 120/word |
| 0x04 | IDENTITY | Ethereum | 15 + 3/word |
| 0x05 | MODEXP | Ethereum | EIP-198 |
| 0x06 | BN256_ADD | Ethereum | 150 |
| 0x07 | BN256_MUL | Ethereum | 6000 |
| 0x08 | BN256_PAIRING | Ethereum | 45000 + 34000/pair |
| 0x09 | BLAKE2F | Ethereum | EIP-152 |
| 0x0A | KZG_POINT_EVAL | Ethereum (EIP-4844) | 50000 |
| 0x100 | P256VERIFY (EIP-7212) | Ethereum (Osaka) | 3450 |
| 0x1800…0000 | NATIVE_COIN_AUTHORITY | Arc | 15,581 |
| 0x1800…0001 | NATIVE_COIN_CONTROL | Arc | 6,125 |
| 0x1800…0002 | SYSTEM_ACCOUNTING | Arc | 5,200 |
| 0x1800…0003 | CALL_FROM | Arc | 100 + COPY |
| 0x1800…0004 | PQ (SLH-DSA) | Arc (Zero6) | 230,000 + 6/word |
注意 P256VERIFY 在 Arc 仅在 SpecId::OSAKA 激活后可用(见 precompile_provider.rs 的 test_p256_precompile_available_with_osaka 测试)。
8.3 Gas schedule 差异
| 维度 | Ethereum mainnet (Prague) | Arc |
|---|---|---|
| Base fee 调整 | EIP-1559 单块 1/8 因子 | EMA 平滑 + 可配置 k_rate |
| Gas target | gas_limit / 2 | gas_limit × inverse_elasticity / 10000(可配置) |
| Cold/warm SLOAD | EIP-2929 (2100 / 100) | 同 |
| Cold/warm account access | EIP-2929 (2600 / 100) | 同 (Zero6+) |
| EIP-7708 ERC-20 Transfer event | 未启用 | Zero5+ 启用 |
| EIP-7702 EOA delegation | Prague | 同 |
Arc 与 Ethereum 关键差异是 base fee 平滑 — 详见 7.2 章的 EMA 代码引用。
8.4 与 OP Stack / Arbitrum 的 EVM 兼容性对比
| 维度 | Arc | OP Stack (Optimism / Base) | Arbitrum Nitro |
|---|---|---|---|
| EVM 等价性 | 高(Reth + 5 自定义 precompile) | “EVM 等价”(与 mainnet bytecode 等价) | “EVM 兼容”(少量 opcode 差异) |
| 共识 | Malachite BFT (L1) | 单 sequencer + DA 提交(L2) | 单 sequencer + 1-block challenge(L2) |
| Finality | 1s (BFT) | ~6 min (op-batcher submit) | 1 week (fraud proof challenge) |
| Native gas token | USDC | ETH | ETH |
| Precompile 集 | Ethereum + 5 自定义 | 同 Ethereum + 4200…XX 系列 (L1Block 等) | Ethereum + ArbSys + ArbOwner |
| Denylist | 协议层 native | 应用层(OFAC list 由 sequencer 软自我审查) | 同 |
| 抗量子 | day-1 SLH-DSA precompile | 无 | 无 |
| 执行客户端 | Reth v1.11.3 | op-geth / op-reth | Arbitrum geth (fork) |
Arc 的差异点是 EVM-compatible L1 + 链层级 compliance + day-1 quantum-ready,定位与 OP Stack/Arbitrum 完全不同(后者是为 Ethereum 扩展,Arc 是独立 L1)。
9. 数据可用性 (DA)
9.1 L1 还是独立 DA?
Arc 是 L1:数据存储完全在 Arc 自己的 validator 上,不依赖外部 DA 层(不像 OP Stack / Arbitrum 把 calldata 提交到 Ethereum L1)。
- 区块数据:本地 RocksDB(Reth 默认)+ Static Files(Reth 2.0 hot/cold 架构);
- WAL:Malachite engine 的 wal crate;
- 共识区块(SSZ):consensus-db;
- Tx 历史:execution-payload;
- State trie:Reth 的 MDBX → 2.0 之后改 RocksDB 索引 + Static Files;
9.2 数据存储成本
参考 Reth 2.0 性能数据(https://www.paradigm.xyz/2026/04/releasing-reth-2-0):
- Ethereum 主网 full node:240 GB;
- Archive node:可挂载 static files;
- Throughput:1.7 Gigagas/s;
Arc 的实际 size 取决于 testnet 流量。早期 testnet 数据小,但 production 后预期类似 Ethereum 主网量级。
9.3 与 Celestia / EigenDA / Avail 的关系
至 2026-05-13,Arc 未集成任何外部 DA 层。
- Celestia:基于 Cosmos SDK + Tendermint 的 DA-only blockchain;
- EigenDA:基于 EigenLayer restaking 的 DA 服务;
- Avail:原 Polygon SDV,2024 主网 DA L1;
Arc 的设计哲学是 integrated L1:共识 + 数据 + 执行在同一组 validator 上。这与 modular blockchain (Celestia 派) 完全相反。
为什么 Arc 不用外部 DA?
- 金融语义需求:USDC 转账需要立即 finality + 完全可审计 — 外部 DA 引入额外信任假设(DA 节点可能下线、数据可能被审查);
- 合规需求:链层级 denylist 要求所有交易数据在受 Circle 信任的 validator 上,不能交给 external DA 层;
- 性能:Malachite 已能扛 13.5 MB/s,与 Celestia 上限相比并不差;
- 简化运维:单一信任域比 modular stack 更易审计;
未来可能性:Arc 作为 settlement 层 + 接收来自 OP Stack / Arbitrum L2 用 USDC 结算 — 此时 L2 用 Ethereum 或其他 DA,Arc 仅承担 settlement。这是 Circle 商业 whitepaper 隐含的方向。
10. 抗量子的工业意义
10.1 NIST 后量子标准化进程时间线
- 2016-12 — NIST 启动 PQC 标准化竞赛,82 个候选;
- 2017-12 — Round 1,69 个 algorithm 进入;
- 2019-01 — Round 2,26 个 algorithm;
- 2020-07 — Round 3,7 个 finalists + 8 alternates;
- 2022-07 — 第一批 4 个 winners 公布:CRYSTALS-Kyber (KEM)、CRYSTALS-Dilithium (signature)、Falcon (signature)、SPHINCS+ (signature);
- 2023-08 — Draft FIPS 203/204/205 发布;
- 2024-08-13 — Final FIPS 203 / 204 / 205 正式发布:
- FIPS 203 (ML-KEM) = Kyber,密钥封装;
- FIPS 204 (ML-DSA) = Dilithium,主推数字签名;
- FIPS 205 (SLH-DSA) = SPHINCS+,保守备选签名;
- 2025+ — FIPS 206 (Falcon → FN-DSA) 仍在标准化中;
详见 NIST 官方 https://www.nist.gov/news-events/news/2024/08/nist-releases-first-3-finalized-post-quantum-encryption-standards。
10.2 FIPS 205 / FIPS 204 / FIPS 203 的差异
| 标准 | 算法 | 用途 | 数学基础 | 公钥大小 | 签名大小 | KEM ciphertext |
|---|---|---|---|---|---|---|
| FIPS 203 (ML-KEM) | Kyber | KEM (密钥封装) | Module-LWE | 800-1568 bytes | N/A | 768-1568 bytes |
| FIPS 204 (ML-DSA) | Dilithium | 数字签名 | Module-LWE + Module-SIS | 1312-2592 bytes | 2420-4595 bytes | N/A |
| FIPS 205 (SLH-DSA) | SPHINCS+ | 数字签名 | Hash function security | 32-64 bytes | 7856-49856 bytes | N/A |
10.3 SLH-DSA-SHA2-128s 与 ML-DSA / FALCON 对比
| 维度 | SLH-DSA-SHA2-128s | ML-DSA-44 | Falcon-512 (将来 FIPS 206) |
|---|---|---|---|
| Security level | 1 (~128-bit) | 2 (~128-bit) | 1 (~128-bit) |
| 数学假设 | Hash function preimage | Module-LWE / Module-SIS | NTRU lattice |
| Public key | 32 bytes | 1312 bytes | 897 bytes |
| Signature | 7856 bytes | 2420 bytes | 666 bytes |
| Sign time | 慢 (~ms) | 中 (~µs) | 中 (~µs) |
| Verify time | 中 (~ms) | 快 (~µs) | 快 (~µs) |
| 量子保守性 | 极保守(仅靠 SHA-256) | 中(依赖 lattice 假设) | 中(依赖 NTRU) |
| FIPS 状态 | 已 final (FIPS 205) | 已 final (FIPS 204) | Draft (FIPS 206) |
| 适合场景 | 长期保存的签名 / 受审计 | 通用替代 ECDSA | 受签名大小约束的场景 |
| 实现复杂度 | 高(Merkle tree + WOTS+ + FORS) | 中(多项式运算) | 高(FFT + Gaussian sampling) |
Arc 选 SLH-DSA-SHA2-128s 的理由:
- 保守安全性:只依赖 SHA-256 安全性 — 已被密码学界研究 20+ 年;
- 不依赖格密码:未来如果某个 lattice 问题被破解(如某个 algebraic structured lattice 攻击),SLH-DSA 仍安全;
- 签名标准化最早:SPHINCS+ 在 2017 已是 NIST finalist,比 Dilithium 多 1 年实战检验;
- 金融场景需要长期可验证:今天签的 USDC FX 交易,30 年后仍需可验证;保守选择更适合;
为什么不选 ML-DSA?
可能未来会加。SLH-DSA 优先是因为 conservativeness — 但 7856 bytes 签名太大对普通 tx 不实用。Arc 后续 hardfork 极可能添加 ML-DSA precompile(gas 估计 ~30,000)作为常用抗量子签名。
10.4 Arc day-1 集成的运维含义
签名大小:7856 bytes — calldata 成本 ~125k gas(最坏 16/byte 非零);
性能:CPU verify 约 1ms,链上等价 230k gas。1 USDC = 1 USD,gas 价格 0.01-0.1 USDC → 单次 verify 约 $0.00023-0.0023;
适用场景:
- ✅ Bridge multi-sig 签名(每次 release 才需 verify,频率低);
- ✅ Protocol upgrade 多签授权;
- ✅ 长期保存的法律文件签名(如 dual-chain 合规证明);
- ❌ 每笔 tx 签名(gas 翻倍 + calldata 翻 100 倍);
升级路径:Arc 可在未来 hardfork 添加:
- SLH-DSA-SHA2-128f(fast variant,签名更大但更快);
- SLH-DSA-SHAKE-128s(基于 SHA-3);
- ML-DSA-44 / -65 / -87(lattice,常用);
- Falcon-512 / 1024(lattice,紧凑);
每个都通过新的 precompile 地址 + hardfork gate 添加,与 Zero6 一样的模式。
11. Tokenomics 代码实现
11.1 ARC token 智能合约
至 2026-05-13,arc-node 仓库内未公开 ARC token 智能合约源码。ARC token 白皮书(2026 Q1 发布)确认:
- 初始 supply: 10,000,000,000 ARC (100 亿);
- 通胀: 年化 2-3%(初始,”early diminishing”);
- 60% 生态 / 25% Circle / 15% 长期储备;
- 当前共识机制: PoA (Proof-of-Authority) — 由 permissioned validator manager 控制;
- 未来转 PoS (Proof-of-Stake) — 由 ARC token holders 质押;
ARC token 合约源码很可能在另外的 private repo,或将与 Arc mainnet 同步发布。
11.2 通胀机制实现(推测)
基于 Cosmos / Tendermint 派系链的惯例 + Malachite + Reth 集成的工程现实,Arc 通胀实现路径推测:
- 每块固定 mint:在 block executor 的 finalize 阶段,向 reward pool 合约 mint ARC token;
- 年化率换算:
tokens_per_block = (initial_supply × annual_inflation_rate) / blocks_per_year; - 递减曲线:Cosmos 派系常用”逐年线性递减”或”达到固定 supply 后停止 mint”;
- 实现位置:很可能是
crates/execution-payload/src/builder.rs中 build_block 阶段,类似 Ethereum PoW 的block_reward;
11.3 Validator reward 分配
PoA 阶段:validator rewards 暂时由 Circle 链下分配(运营成本补贴),无链上 staking 机制。
PoS 阶段(未来):
- ARC holders 质押 ARC → 选 validator 委托;
- 每块 reward 按 stake 比例分配给 active validator + 其 delegators;
- Validator 收取 commission(通常 5-10%);
- Slashing:double-sign / liveness 失效 → 部分 stake 被销毁;
这是标准 Cosmos / Tendermint PoS 模式。
11.4 Staking / unstaking 流程
至 2026-05-13 未实现。预计 PoS 切换时的 staking 合约设计:
interface IStaking {
function delegate(address validator, uint256 amount) external;
function undelegate(address validator, uint256 amount) external;
function claimRewards(address validator) external returns (uint256);
}
Unbonding period 估计 14-28 天(与 Cosmos Hub 类似),防止短期 long-range attack。
11.5 ProtocolConfig 合约
链上协议参数管理见 /repos/arc-node/contracts/src/protocol-config/ProtocolConfig.sol:
- 链上可由 owner 配置的参数:base fee EMA alpha、k_rate、inverse_elasticity、gas limit 等;
- 通过
ProtocolConfig合约改 → 节点协议层读 → 影响下一块行为; - 这避免了硬分叉来调参数;
PermissionedValidatorManager 也部分通过 ProtocolConfig 配置(如最大 voting power 上限),见 PermissionedValidatorManager.sol:38-46 的 VotingPowerExceedsLimit error。
12. 安全审计与 Bug Bounty
12.1 审计状态
至 2026-05-13,Arc 仓库 README 明确:
“Arc is currently in testnet, and this is alpha software currently undergoing audits.”(/repos/arc-node/README.md:17)
Malachite 仓库同样:
“Malachite is alpha software and under heavy development. The software is provided ‘as is’ and has not been externally audited; use at your own risk.”(/repos/malachite/README.md:38-40)
截至 2026-05,公开未见任何 Arc / Malachite 的最终审计报告。
12.2 推测的审计 vendor
基于业界惯例 + Circle 既往合作记录:
- Halborn:Circle 历史合作方(USDC、CCTP 审计);同时 Halborn 已发布对 OP Stack 多链审计;
- Sigma Prime:Ethereum 共识层专家(Lighthouse 客户端开发方),适合审 Malachite;
- OpenZeppelin:智能合约(Denylist、PermissionedValidatorManager、ProtocolConfig);
- Trail of Bits:底层 EVM + Reth integration + precompile gas/性能审计;
- Cure53 / Quarkslab:AWS Nitro Enclave + 远程签名审计;
- Informal Systems 自己:内部形式化验证 + adversarial testing;
Circle 商业 whitepaper 提到”多家顶级审计机构同时进行”,未点名。
12.3 Immunefi bounty pool
Arc 与 Malachite 的 Immunefi 项目页面截至 2026-05-13 未上线。
参考 Circle 既往 bug bounty:
- USDC:Immunefi 上 Circle USDC bounty pool ≈ $10M;
- CCTP:bounty pool ≈ $1M;
Arc 主网启动前预计 Immunefi 上线,pool 规模可能 $5-20M(与同期主网 L1 持平)。
12.4 漏洞披露政策
- Malachite:见
/repos/malachite/SECURITY.md; - arc-node:见
/repos/arc-node/SECURITY.md; - arc-remote-signer:见
/repos/arc-remote-signer/SECURITY.md;
所有仓库均要求漏洞通过 security@circle.com 上报,不要在 GitHub 公开 issue 中披露。
12.5 已知 risks
基于代码 review,几个潜在风险点:
- slh-dsa 0.2.0-rc.4 未审计:RustCrypto 自己声明 PQ crates 全部未独立审计 → Arc 把它放进 precompile 链层,风险传递;
- Malachite alpha + heavy development:consensus 层 bug 可能导致 chain halt;
- ProtocolConfig owner key:链上参数由 owner 单一 key 控制 — 单点风险(治理改进路径:multi-sig + timelock);
- PermissionedValidatorManager owner:当前 PoA 阶段,validator 集由 Circle owner 控制,可任意添加/移除 — 完全可信赖前提;
- Native USDC mint:precompile 内
if caller != ALLOWED_CALLER_ADDRESS—— 如果 USDC 合约本身漏洞,无限 mint 风险; - Mempool naive FIFO:当前 mempool 实现简单,无 priority fee market 排序 → MEV 风险(虽 Arc 强调 deterministic finality,但仍受 mempool 排序影响);
- Validator key 单 enclave:远程签名虽用 Nitro,但每个 validator 仍是单 enclave/key — 没有 BLS threshold signature 或 distributed key generation;
附录 A. 完整引用源(≥ 40 条)
A.1 GitHub 代码仓库
- https://github.com/circlefin/malachite — Malachite consensus engine
- https://github.com/circlefin/arc-node — Arc node 主仓库
- https://github.com/circlefin/malachite-mempool — 独立 mempool 仓库
- https://github.com/circlefin/arc-remote-signer — AWS Nitro 远程签名
- https://github.com/informalsystems/malaketh-turbo — Informal Systems PoC(同 codebase, archived under circle)
- https://github.com/informalsystems/malaketh-layered — Engine API based PoC
- https://github.com/circlefin/arc-stablecoin-fx — sample (placeholder)
- https://github.com/circlefin/arc-nanopayments — x402 demo
- https://github.com/paradigmxyz/reth — Reth execution client
- https://github.com/paradigmxyz/reth/releases/tag/v1.11.0 — Reth v1.11.0 release
- https://github.com/farcasterxyz/snapchain — Farcaster Snapchain (Malachite user)
- https://github.com/keep-starknet-strange/madara — Starknet Madara (Malachite user)
- https://github.com/aws-solutions-library-samples/guidance-for-secure-blockchain-validation-using-aws-nitro-enclaves — AWS reference
- https://github.com/RustCrypto/signatures/tree/master/slh-dsa — RustCrypto SLH-DSA 实现
- https://github.com/RustCrypto/signatures/issues/843 — slh-dsa FIPS 205 update issue
- https://github.com/informalsystems/quint — Quint specification language
- https://github.com/ShieldedLabs — Zcash Crosslink (Malachite user)
- https://github.com/getclave/eip-7212 — EIP-7212 P256 reference impl
- https://github.com/daimo-eth/p256-verifier — daimo P256 verifier
- https://github.com/ethereum/RIPs/blob/master/RIPS/rip-7212.md — RIP-7212 spec
A.2 NIST / IEEE / ACM 标准
- https://csrc.nist.gov/pubs/fips/205/final — FIPS 205 (SLH-DSA) 最终
- https://csrc.nist.gov/pubs/fips/204/final — FIPS 204 (ML-DSA)
- https://csrc.nist.gov/pubs/fips/203/final — FIPS 203 (ML-KEM)
- https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.205.pdf — FIPS 205 PDF
- https://www.nist.gov/news-events/news/2024/08/nist-releases-first-3-finalized-post-quantum-encryption-standards — NIST 公告
- https://www.federalregister.gov/documents/2024/08/14/2024-17956 — Federal Register
A.3 学术论文
- https://arxiv.org/abs/1807.04938 — The latest gossip on BFT consensus(Buchman/Kwon/Milosevic 2018)
- https://arxiv.org/pdf/1807.04938 — 上述 PDF
- https://infoscience.epfl.ch/bitstreams/bb494e9a-22aa-43a2-b995-69c7a2cc893e/download — Revisiting Tendermint(EPFL 2024)
- https://eprint.iacr.org/2018/574.pdf — Correctness and Fairness of Tendermint-core Blockchains
- https://arxiv.org/html/2510.01097 — Universally Composable Termination Analysis of Tendermint(2025)
- https://en.wikipedia.org/wiki/SPHINCS%2B — SPHINCS+ 综述
- https://tendermint.com/static/docs/tendermint.pdf — Kwon 2014 原始 Tendermint paper
A.4 Circle / Informal Systems 官方 blog
- https://www.circle.com/pressroom/circle-launches-arc-public-testnet — Arc 测试网启动公告
- https://www.arc.network/blog/introducing-the-arc-token-whitepaper — ARC token whitepaper
- https://www.arc.network/blog/circle-launches-arc-public-testnet — Arc testnet 详情
- https://www.prnewswire.com/news-releases/informal-systems-announces-malachite-acquisition-by-circle-to-power-new-arc-blockchain-network-302532317.html — Informal Systems 收购公告
- https://informal.systems/blog/cosmos-protocol-design-formalization — Informal 形式化方法 blog
- https://informal.systems/blog/the-most-flexible-consensus-api-in-the-world — Malachite Channels API blog
- https://informal.systems/blog/malachite-decentralize-whatever — Malachite design 公告
- https://informal.systems/blog/tendermint-responsiveness — Tendermint responsiveness blog
- https://interchain-io.medium.com/past-present-future-icf-r-and-d-introducing-informal-systems-e50d14383f05 — Informal Systems 创立史
A.5 Reth / Paradigm
- https://www.paradigm.xyz/2024/05/reth-exex — Reth Execution Extensions
- https://www.paradigm.xyz/2026/04/releasing-reth-2-0 — Reth 2.0 release(2026-04)
- https://reth.rs/sdk/ — Reth SDK 文档
A.6 AWS Nitro
- https://docs.aws.amazon.com/enclaves/latest/user/nitro-enclave.html — Nitro Enclaves 用户文档
- https://docs.aws.amazon.com/enclaves/latest/user/set-up-attestation.html — Attestation 流程
- https://aws.amazon.com/blogs/web3/aws-nitro-enclaves-for-running-ethereum-validators-part-1/ — Ethereum validator + Nitro
- https://aws.amazon.com/solutions/guidance/secure-blockchain-validation-using-aws-nitro-enclaves/ — AWS guidance
A.7 x402 / Coinbase Gateway
- https://docs.cdp.coinbase.com/x402/welcome — x402 官方文档
- https://www.x402.org/ — x402 standard 主页
- https://www.coinbase.com/developer-platform/discover/launches/x402 — Coinbase x402 launch
A.8 EIP / 协议规范
- https://eips.ethereum.org/EIPS/eip-7951 — EIP-7951 (P256, supersedes RIP-7212)
- https://eips.ethereum.org/EIPS/eip-7212 — EIP-7212
A.9 Tendermint / CometBFT
- https://github.com/cometbft/cometbft — CometBFT
- https://docs.cometbft.com/v0.38/introduction/ — CometBFT 文档
附录 B. 关键发现总结
- Malachite 是 co-designed with Quint specification:Rust 实现与形式化规范在同一 PR 中同步演进,是 CometBFT 没有的工程范式;
- 5 个 precompiles 全是 stateful:通过 PrecompilesMap::set_precompile_lookup 注册,与 Ethereum 标准 stateless precompile 完全不同的执行模型;
- SLH-DSA-SHA2-128s precompile day-1 集成:成本 230,000 gas + 7,856 bytes 签名,使 Arc 成为极少数 day-1 quantum-ready 公链;
- Arc 采用 Reth SDK + plugin 模式而非 fork:与 OP Stack op-geth fork 模式区别明显,享受 Reth 2.0 的 1.7 Gigagas/s 性能改进无需自己维护;
- EIP-7708 ERC-20 Transfer event for native USDC:让所有 EVM 索引器无缝识别 USDC,是 Celo “linked interface” 之后的标准化尝试;
- base fee EMA 平滑:放弃 Ethereum 单块 1/8 adjustment 公式,改 EMA + 可配置 k_rate,避免金融场景 gas 价格突变;
- 远程签名是独立 Go 服务 + Nitro Enclave:与 arc-node Rust binary 通过 gRPC 通信,四层 envelope 加密;
- arc-stablecoin-fx 仍是空 placeholder:FX swap 业务逻辑由 Circle App Kit Swap SDK 提供,链上原生协议尚未公开;
- mempool 极简 FIFO:4MB block / 100 tx per block / 100K pool — 当前未支持 priority fee market 与 MEV 处理;
- Validator manager 三层权限 + ERC-7201 storage:Owner → Controllers → ValidatorRegisterers,OpenZeppelin 2024 最新模式;
报告完。