Rand 是开源的。全节点、浏览器、桥、证明研究以及钱包客户端,各自位于 GitHub 上独立的代码仓库中。阅读代码、运行测试、提交补丁。本页是一张地图:每个组件位于何处、用什么构建、证明系统已经走到哪一步,以及它目前止步于何处。
代码仓库
| 仓库 | 内容 | 语言 |
|---|---|---|
randprotocol/fullnode | 参考全节点与钱包:链式 HotStuff BFT、libp2p 网络、屏蔽的 RAND note 池、zkVM 证明验证器、JSON-RPC、rand 钱包命令行工具,以及 rand-prover 委托证明器。 | Rust |
randprotocol/randscan.org | randscan.org 背后的区块浏览器:基于 axum 的索引器,在 PostgreSQL 之上提供 REST 与 WebSocket API,另有 Next.js 前端。 | Rust · TypeScript |
randprotocol/bridge | 面向 Ethereum、Binance Smart Chain、Tron 和 Solana 上 USDT 与 USDC 的守护者桥:托管合约、共享的证明格式(attestation format)及其测试向量。 | Solidity · Rust |
randprotocol/zkp-circuits | 证明系统讲解(Groth16 与 STARK、屏蔽池、环签名、混币器)、research/、Rand 参考 zkVM、recursion/(递归虚拟机)、客户程序工具链与两个转换器,以及 CUDA 内核。构建全节点时,需要将本仓库作为 circuits/ 检出在其旁边。 | Rust |
randprotocol/clients | 钱包客户端:桌面端、网页端、iOS 和 Android。 | Rust · Swift · Java · JavaScript |
技术栈
从头到尾都是 Rust。Rand 是一条独立的链:HotStuff BFT 节点搭配 libp2p gossip 层,以完全屏蔽的 note 池作为账本,采用后量子签名与 note 加密,并以 Rand zkVM 承担机密计算,这一切都在全节点仓库中。证明系统本身是仍在积极研究的部分,见下文。
| 层 | 运行内容 |
|---|---|
| 共识 | 链式 HotStuff BFT、按质押加权的法定人数、三链提交 |
| 网络 | libp2p:TCP、Noise、Yamux、gossipsub、Kademlia,局域网内使用 mDNS |
| 账本 | 屏蔽 note 池:深度为 32 的 Poseidon2 树、nullifier 集合,每笔交易一个 4 入 4 出的隐藏资产捆绑包(chain 13 及之前为 2 入 2 出);自 chain 17 起,捆绑包证明之旁增加第二个 tier-10 授权证明(拆分授权);自 chain 18 起,note 信封为 1,860 字节,并带有加密备注 |
| 代币 | RPL:代币是账本注册表中的一个条目,带有 rpl1… id,而非合约;它以 note 的形式在同一个池中流转 |
| 质押 | 公开的验证者注册表:从捆绑包中质押保证金,两个 epoch 的解绑期,每个 epoch 1,000 个区块;自 chain 20 起,新验证者须经验证者集合投票准入 |
| 机密计算 | Rand zkVM:Plonky3 批量 STARK 下的 RV32IM,零知识隐藏的 FRI,约束集 8;自 chain 18 起,调用会声明由电路强制执行的 gas 上限,并按 gas 和按 KiB 付费;自 chain 20 起,程序在单元(cell)中保存状态,并在金库(vault)中持有价值(RPL-2) |
| 密码学 | Dilithium2 · ML-KEM-768 · Poseidon2 · BLAKE3 · ChaCha20-Poly1305 |
| 存储 | 每个节点一个 RocksDB,提交经 fsync,启动时进行完整性检查;可选的历史裁剪(--prune-history 24h),归档节点则保留全部数据 |
| 桥 | 四条链上由守护者证明的锁定,每次铸造都有 Dilithium2 联合签名法定人数;桥接资产是同一个池中的 note |
| 语言 | 全程使用 Rust;桥使用 Solidity,浏览器使用 TypeScript |
适用于所有程序的统一关系
白皮书中的通用执行关系 R_exec 已经以代码形式存在:rand_zkvm,一台在 Goldilocks 域上、基于 Plonky3、由单个批量 STARK 证明的 RV32IM 机器。它证明的是:某个踪迹(trace)在由加盐的 H_IN 所承诺的输入上运行了程序 hc,得到这些公开输出;而程序本身从不作为验证器的参数。发布一个机密程序,意味着登记一个哈希,而不是生成一个定制电路。
该证明系统是透明的,无需可信设置,也不需要配对曲线,其安全假设是抗碰撞哈希。其他所有涉及证明的组件,预期都将收敛到这个 crate 上,而不是各自另起炉灶。该 crate 位于 zkp-circuits/research,并以约束集 8 内置于全节点(circuits aeacf31,fullnode v0.6.7 与 v0.6.8)。除非某一行指明了更晚的约束集,下文的表格与测量均描述约束集 5(里程碑 M4.2);数据取自 fullnode 的 docs/zkvm.md、docs/zkvm-milestones.md 和 docs/confidential.md,截至 2026-09-13,测量值均为在 Apple Silicon 笔记本上的实测值,而非目标值。
八张表挂在具名总线上,第九张按需出现
一次承诺,一次 FRI 开启。各表之间从不相互调用;它们通过具名的 LogUp 总线(PROGRAM、PROGRAM_WORD、MEMORY、ALU、POSEIDON2、INPUT_DIGEST、INPUT_READ、KECCAK,以及范围查找和半字节查找)交换事实,验证器检查每条总线在全局上是否平衡。每张表的最大约束度数都由测试固定在 FRI 膨胀系数所允许的上限 8 之下。
| 表 | 类型 | 作用 |
|---|---|---|
program | witness | 原始指令字,自 M3.4 起在电路内解码,由 cpu 汇总为 hc 的摘要 |
cpu | witness | 每个周期一行,另有摘要行,将程序吸收进 hc、将加盐输入吸收进 H_IN |
memory | witness | 寄存器与 RAM 合在一张表中,按 (space, addr, ts) 排序;自 M2.5 起支持子字访问 |
alu | witness | 字节分段算术、移位、比较;自 M2.6 起支持 RV32M 乘法与除法 |
range | 预处理 · 256 行 | 范围检查与 2 的幂查找 |
nibble | 预处理 · 256 行 | 4 位 AND、OR、XOR;命中本身就是对两个操作数的范围检查 |
poseidon2 | witness | 每个置换轮一行,以 32 行为一块;服务于 POSEIDON2 总线和两个摘要 |
input | witness · 自 M4.1 起 | 每个私有输入字一行;服务于 INPUT_DIGEST 和 INPUT_READ,因此读取无法逃离承诺 |
keccak | witness · 可选 | 以 32 行为一块的 Keccak-f[1600],仅出现在其客户程序调用过 KECCAK 的证明中(M4.2) |
此后又落地了三个约束集。约束集 6 新增了一张必选的 public 表,用于程序部署时的公开输入,绑定到未加盐的摘要 H_PUB,并在 keccak 旁新增了可选的 sha256 表。约束集 7(chain 16)在新的 BLIND 总线上对每个 LogUp 终值加盲,并将每张已声明的表的行数下限定为 2⁷,同时新增了绑定长度的 POSEIDON2_LEN 系统调用。约束集 8(chain 18)在 cpu 表中新增了 GAS 列,以及一个公开值,即声明的 GAS_LIMIT。
证明会揭示什么
公开: 代码哈希 hc(八个电路内摘要字)、加盐的输入承诺 H_IN(八个字)、gas 层级(tier),以及八个输出字。自约束集 6 起还有 H_PUB,即公开输入的摘要;自约束集 8 起还有声明的 gas 上限。证明头部声明了 Keccak 和 SHA-256 表的高度,因此它会显示一次调用是否做过哈希,以及在 2⁷ 下限之上大致做了多少。
隐藏: 私有输入(H_IN 是加盐的,因此既隐藏又绑定);每一个指令字,因为验证器检查的是 hc 而从不检查程序;每一个寄存器和内存值;每一次所走的分支;确切的周期数和确切的 gas 消耗;以及运行过哪些系统调用,但两张哈希表的高度所显示的部分除外。
每个证明的层级(tier)是公开的,因为 STARK 的大小本身就会暴露其踪迹高度;隐藏索引不会带来任何好处。hc 是绑定的,而不是隐藏的:见目前止步于何处。
实测,约束集 5
| FRI | 80 次查询 · 20 位 PoW · 膨胀系数 8 · arity 8 · 开启 ZK;260 位推测安全性,约 86 位已证明。M2 的 27 次查询调优已在 2026-09-12 的审计中撤销 |
| 调用 | tier 10 的 private_payment:证明约 7 秒,80 次查询下证明约 1.2 MB(27 次查询时为 435 KB),相比 M1 的 21.6 秒和 892 KB 有所下降 |
| 转账 | chain 13 及之前的 2 入 2 出捆绑包客户程序:3,811 个字,约 9,160 个周期,tier 14;证明约 100 秒,证明约 1.3 MB。chain 14 的 4 入 4 出隐藏资产客户程序固定在同一 tier:约 100 秒,约 1.42 MB |
| 验证 | 密钥已预热时约 16 毫秒;在新的 (tier, heights) 密钥下首次验证约 230 毫秒 |
| 区块 | 4 MiB 预算和 2 MiB 证明上限:80 次查询下每个区块约三笔屏蔽转账 |
Apple Silicon 笔记本,release 构建。M2.3 中的字节表拆分改变了证明时间;80 次查询的配置则使证明大小重新上升。验证器密钥与程序内容无关,由 tier 以及证明所声明的程序、输入和 keccak 高度作为键,因此节点只需预热一个密钥并反复复用。
后续的约束集调整了证明大小。在约束集 7 下,生产配置中层级 10 的证明为 1,367,688 字节,携带 Keccak 的层级 10 证明为 3,283,898 字节(2026-09-28 实测)。自 chain 17 起,一笔转账携带两个证明:层级 14 的打包证明,约 1.49 MB;以及层级 10 的授权证明,约 1.37 MB,证明耗时约 7 秒。Chain 20 的创世配置将区块上限设为 20 MiB,证明上限设为 4 MiB,且单次调用不得超过层级 14。
三个目标,一个电路
只有 RISC-V 原生执行。Solidity 和 Solana 程序有两种方式:一是在同一关系内的解释器 guest 上运行,以其字节码作为输入;二是在链下翻译为 RISC-V 程序,其输出与解释器的输出逐字一致。开销大的操作码需要专用的协处理器表,而不是逐位模拟。
| 目标 | 路径 | 协处理器 |
|---|---|---|
| RISC-V | 原生。RV32IM,可通过 asm.rs 手工汇编,也可使用面向 riscv32im-unknown-none-elf 编译的 no_std Rust,自 M4.1 起以扁平二进制加载,或由 rand-guest 从 Rust 或 C 构建为镜像容器(部署 Rust 程序) | Poseidon2(自集合 7 起含 POSEIDON2_LEN);自 M4.2 起含 Keccak-f[1600];自集合 6 起含 SHA-256 |
| Solidity | 用 solc --bin-runtime 生成 EVM 字节码,然后交给 evm.bin 解释器 guest(字节码作为输入),或交给 evm2rv:它将字节码翻译为 C,再由 rand-guest 构建为输出相同的 RV32IM 镜像(Ethereum 转译器) | Keccak-256(表已随附)、256 位模运算、ECRECOVER、用于存储的 Merkle 见证系统调用 |
| Solana / SVM | sBPF ELF,由 sbpf.bin 解释器 guest 运行,或由 sbpf2rv 翻译为输出相同的 RV32IM 镜像(Solana 转译器) | SHA-256、Ed25519 验证、64 位乘法 |
里程碑
里程碑 1 证明了通用机器。里程碑 3 将其变为屏蔽池:带电路内成员资格证明的转账在 R_exec 下完成证明,验证者在不接触任何程序字的情况下检查 hc。里程碑 4 是兼容性:其加载器、输入承诺和 Keccak 表作为约束集 4 和 5 发布,SHA-256 表随集合 6 发布。EVM 和 sBPF 解释器 guest、rand-guest 工具链以及两个翻译器均已构建完成。ERC-20 转账已在一台 128 GB 的机器上完成证明;层级 20 的 SPL Token 证明尚未完成。里程碑 5 是区块聚合背后的递归虚拟机,已构建完成,在所有链上均处于关闭状态。约束集 7 和 8 紧随 9 月的评审和 gas 模型之后。
| 编号 | 范围 | 退出标准 | 状态 |
|---|---|---|---|
| M1 | 五张表、RV32I 基础指令集、HALT/WRITE_OUTPUT/READ_INPUT、启用零知识、层级填充、汇编器、模拟器 | fib、memcpy、bubble_sort、alu_mix 和 balance_check 完成证明并通过验证;每个作弊测试均被拒绝 | 已完成。 44 项测试;后续一次评审一轮修复了五处可靠性缺口 |
| M1.5 | 查看密钥:一进一出的屏蔽转账 guest,基于 ML-KEM-768 和 ChaCha20-Poly1305 的票据信封,按参与方和按交易划分范围的披露,模拟账本 | 转账在层级 12 完成证明且账本接受;每种披露范围恰好打开其自身的行;查看密钥不能花费 | 已完成。 未并入节点 |
| M2 | 验证密钥缓存,FRI 重新调整为 100 位推测目标,字节表拆分为范围表和半字节表,子字加载与存储,RV32M 扩展 | 交付范围小于原定范围:扁平二进制加载器和更牢固的 READ_INPUT 绑定顺延至 M4.1 | 已完成。 层级 10 的 fib:证明从 892 KB 降至 268 KB,证明耗时从 21.6 秒降至 3.1 秒,首次验证从 2.17 秒降至 16 毫秒。约束集 3,硬分叉 |
| M3 | Poseidon2 芯片和系统调用;以其为基础、作为 guest 例程实现的 NOTE_COMMIT、NULLIFY 和 MERKLE_VERIFY;已花费的承诺移出公开输出;程序表作为见证,hc 在电路内摘要 | 转账关系在 R_exec 下完成证明,成员资格在电路内,且 verify(hc, proof) 从不接触任何程序字 | 已完成。 转账 guest:4,554 条指令,4,903 个周期,层级 14。Merkle 路径遍历现为计数循环,因此程序大小不再随树深度增长 |
| CUDA | GPU 证明者后端:NTT 和 Poseidon2 Merkle 承诺作为 CUDA 内核,置于 Plonky3 的 Dft 和 Mmcs trait 之后;rand send、call 和 deploy 接受 --cuda | 每个 guest 都通过纯 Rust 参考孪生实现和模拟驱动完成证明并通过验证;CPU 验证者无法区分各后端 | 已完成;2026-09-28 首次在硬件上运行。 在 NVIDIA H100 上,内核针对 sm_80 和 sm_90 构建为 PTX,并与 CPU 及 Plonky3 参考实现一致。在集群 GPU 节点上的生产环境重新测量仍待完成。CUDA 调用无法封装输入信封,因为盐值从不离开证明者 |
| M4.1 | 扁平二进制加载器和首批面向 riscv32im-unknown-none-elf 编译的 no_std Rust guest;带盐的输入承诺 H_IN 及其专属输入表,使 READ_INPUT 成为对已承诺向量的查找 | 由标准工具链构建的 guest 可加载、证明并通过验证;对同一输入索引的两次读取一致,且输入绑定到 H_IN | 已完成。 2026-09-11 作为约束集 4 上线:26 个公开值,八张表,硬分叉 |
| M4.2 | 手写的 Keccak-f[1600] 协处理器表和 KECCAK 系统调用,仅当 guest 使用时才出现在证明中;证明声明的内存高度;以四个分量为键的验证密钥;2026-09-12 审计后 FRI 恢复为 80 次查询 | keccak256 作为已编译的 guest 完成证明,且不含该表的证明在形状上与 M4.1 的证明字节级一致 | 已完成。 2026-09-12 作为约束集 5 上线,硬分叉。携带 Keccak 的证明约大 1.9 MB,超过默认的 2 MiB 上限。创世配置调高上限的链可接纳此类证明:chain 13(8 MiB)于 2026-09-19 接纳了一次 3.41 MB 的携带 Keccak 的调用,chain 20 的上限为 4 MiB |
| M4.3 · M4.4 | 编译为 RV32IM 的 EVM 和 sBPF guest 解释器,外来字节码作为输入;与 Keccak 并列的 SHA-256 协处理器表;随后是 rand-guest 工具链以及 evm2rv 和 sbpf2rv 翻译器(2026-09-18) | ERC-20 转账和 SPL Transfer 各自在 R_exec 下完成证明 | 已构建;已完成一次退出证明。 evm.bin(18,009 个字)和 sbpf.bin(8,317 个)可运行 ERC-20 和 SPL Token 测试向量,翻译后的镜像与之逐字一致。ERC-20 的 transfer 于 2026-09-19 在一台 128 GB 的 droplet 上以层级 18 完成证明(峰值 85.0 GB,53.8 分钟);层级 20 的 SPL Token 证明据推算约需 330 GB,尚未完成(证明内存)。两者均无法在链上调用:调用上限为层级 14 |
| M5 | 递归虚拟机(rVM):一台 24 条指令、原生基于 Goldilocks 的机器,其程序用于验证 Rand zkVM 证明,每种内部证明形状对应一个 N 通用的聚合程序,CPU 与 CUDA 后端分离,并带有自验证器(M5.1 至 M5.4,2026-09-13 至 2026-09-16) | 50 个真实的生产打包证明被接受,50 个被篡改的证明在指定步骤被拒绝;对一个真实打包证明的验证程序所作的 rVM 证明在本机验证通过(测试配置) | 已构建;生产证明需要大型机器。 以 crates/randprotocol-rvm 引入。链端聚合已合并,在所有链上均处于关闭状态(见下文) |
| set 7 | 每个 LogUp 终值均加盲;每张已声明的表至少 2⁷ 行;对输入、公开和盐值字做 32 位范围检查;POSEIDON2_LEN 系统调用;JALR 修复;验证密钥由 key_derivation_v2 加盐 | 2026-09-27 和 28 日 zkVM 评审中会改变验证密钥的修复,一次性合入 | 已完成。 Fullnode v0.6.1,chain 16(2026-09-28),硬分叉 |
| set 8 | gas 计量器:cpu 表中的 GAS 列和公开的 GAS_LIMIT,在电路内证明 GAS ≤ GAS_LIMIT;该次运行的确切 gas 保持私密 | 调用按其声明的上限付费,且每个打包证明都声明同一个固定的上限 | 已完成。 Fullnode v0.6.7-rc1,chain 18(2026-09-29),硬分叉。bundle_gas_limit 为 20,479 |
屏蔽池阶段
fullnode 的账本分三个阶段落地,每个阶段都是一次硬分叉(docs/shielded.md §7)。S1 用票据池取代了账户账本;S3 将桥以票据的形式带回,并率先落地;S2 在其上加入了质押。三者均已在 main 上,并在当前链上运行。
下表 S2 以下各行是 v0.5 的工作。每一行都是一次硬分叉;它们合在一起作为一条全新的链,即 chain 14,于 2026-09-20 基于构建 b3c594c 切出,并在通过已部署源端点完成一次 zUSD 实网往返之后,于同日标记为 v0.5。Chain 15 自 2026-09-26 起在 v0.5.8 及之后版本上运行,承载了全部这些内容,并启用了审计 v4 与 v5 中以创世区块为开关的修复:带白名单且每个 epoch 有额度的水龙头、延迟生效的质押激活、质押权重上限、与创世绑定的注册、consensus_domain 1、桥规则 v2,以及代币注册表的数量上限、被销毁的注册费和 2⁶³ 的票据上限。Chain 20 自 2026-10-01 06:17 UTC 起在 v0.6.8(c9c9bd3c)上运行,是 chain 19 的一次硬分叉,保留以上全部内容,并加入 v0.6 各版本的工作,见下文。
| 编号 | 范围 | 验收标准 | 状态 |
|---|---|---|---|
| S1 | 资金池本身:票据、2 进 2 出的已证明捆绑包、深度为 32 的 Poseidon2 承诺树与作废符集合、带本地证明者的 rand 钱包、经过脱敏的 RPC | 钱包之间的屏蔽转账、两个验证节点之间的双花竞争,以及由捆绑包支付的部署并调用,均在集群测试套件中通过 | 已完成。 自 chain 6(2026-09-12)起在公共节点集群上运行 |
| S3 | 作为票据的桥:桥接持有物带有注册表的资产索引,一份证明存入一张由链自行计算的票据,BridgeBurn 是唯一的双捆绑包交易;用于调用输入的密封信封,可由调用者、每次调用的密钥或指定的审计者打开 | 桥接资产作为票据被铸造、花费和销毁;调用者可以在不公开的前提下披露程序运行所用的输入,且 rand open-call 会对照 H_IN 检查开启结果 | 已完成。 最先落地。Chain 9 至 13 的创世区块不含桥部分;自 chain 14 起的每条链都包含。自 chain 14 起,一次销毁是一个捆绑包,而不是两个 |
| S2 | 屏蔽链上的质押:公开的验证节点登记簿、从捆绑包销毁额中扣出的 Bond、历时两个 epoch 的 Unbond、提入收款地址上一张票据的 Withdraw、每 1,000 个区块一个并重新推导验证节点集合的 epoch,以及对登记簿与资金池的供应量审计 | 第五个验证节点完成登记、质押,并自下一个 epoch 起出块;另一个验证节点退出集合并提现为一张票据,其收款钱包可以花费该票据;两者均在集群测试套件中通过 | 已完成。 钱包的本地承诺树于 2026-09-21 随后完成:钱包自行计算见证,不再告知其节点所花费的是哪个叶子 |
| RPL | 代币标准(docs/tokens.md):代币是账本中的一条注册表条目,带有 62 个字符的 rpl1… bech32m id;创建无需许可,只需支付以 RAND 计的注册费;铸造权限在注册时固定为无、某个密钥或桥;代币符号不要求唯一;rand token create、mint、set-authority、burn、info、list,以及 rand_getTokens、rand_getToken、rand_getTokenSupply | 一种代币被注册、铸造、通过 rand send --asset 发送,并在同一资金池中作为票据被销毁 | 自 chain 14(v0.5)起运行。 在 chain 20 上,注册费为 1 RAND 且被销毁,注册表最多容纳 4,096 种代币,创世区块把 zUSD 列在索引 1 |
| RPL-2 | 程序状态(docs/program-state.md):每个程序的单元(8 个字的键对应 8 个字的值,纳入状态根)、每种资产一个公开金库、只能由其程序铸造的代币,以及 Invoke 动作(Action 33),即一次声明其读写单元和支付票据的调用;rand program invoke、state、vault,以及 rand_getProgramCell、rand_getProgramCells、rand_getProgramVault | 仅当所声明的每次读取仍然成立且金库足以覆盖每笔支付时,账本才应用该状态转换;过期的读取会被拒绝并重新证明 | 自 chain 20(v0.6.8)起运行。 cell_fee 为每创建一个单元 0.01 RAND;每次 invoke 最多 8 次读取、8 次写入和 4 笔支付。参见程序 |
| 隐藏资产捆绑包 | 每笔交易恰好携带一个 4 进 4 出的捆绑包,取代 2 进 2 出的捆绑包:槽位 0–1 存放私有资产(仅转 RAND 时为占位项),槽位 2–3 始终为 RAND 并支付费用。双捆绑包的代币转账和双捆绑包的桥销毁已取消 | RAND 的转账与任何 RPL 代币的转账发布完全相同的形态,因而所转移的资产被隐藏 | 自 chain 14(v0.5)起运行。 14 档,证明约需 100 s,在 chain 14 和 15 上证明约 1.42 MB;其 hc_bundle 为 83d3a370…。Chain 18 至 20 固定使用捆绑包 guest v3,hc_bundle 为 60af094a…,约 1.49 MB |
| 交易绑定 | 每个捆绑包证明都针对 H("rand-tx-bind-1", chain_id ‖ tx with proofs blanked) 生成并据此验证,该值置于公开输入段中 | 一份被复制且未经修改的证明,在目的地、验证节点或备注被更改后重新提交,会被拒绝 | 自 chain 14(v0.5)起运行。 自 chain 20(binding_domain 1)起,原像为 H("rand-tx-bind-2", genesis hash ‖ chain_id ‖ …),且每条已签名的动作消息也带有创世哈希,因此为某一条链证明或签名的内容无法在另一条链上通过验证 |
| B1–B4 | 桥加固(docs/bridge.md §§14–20)。B1:每个支撑资产的每日铸造上限,以及一把只能暂停的暂停密钥(恢复需要 PQ 法定人数)。B2:区块时间戳比其父块晚出 60 s 以上即为无效,且验证节点不会为超前自身时钟 15 s 以上的区块投票,因此验证节点需要 NTP。B3:每次铸造都需要 Dilithium2 联合签名的法定人数。B4:在创世之后、在 PQ 守护者法定人数之下上架桥接代币或支撑资产,无需切换新链 | zUSD 是拥有七个支撑资产的一种代币(Ethereum、Binance Smart Chain、Tron 和 Solana 上的 USDT 与 USDC),通过交易注册,且 total_supply == Σ backings.locked 由构造保证成立。本地九阶段关卡(zusd_e2e.rs:四个验证节点、真实证明,从水龙头到注册、存入、转账、销毁再到审计)9 项全部通过 | 自 chain 14(v0.5)起运行。 在 chain 20 上:每个支撑资产每日铸造上限 100,000 zUSD,另加每滚动 24 小时全局 4,000 zUSD(桥规则 v2),守护者集合 1 含八位 PQ 守护者,每次铸造和每次销毁收取 10 bps 的 zUSD 费用(bridge.fees),守护者轮换需要持有证明并等待 86,400 s(bridge.rotation)。zUSD 在 chain 20 的创世区块中列出,带有其七个支撑资产以及切换时锁定的 99 zUSD |
| 审计 v3 | 由一位联合创始人主导的第三轮内部审计的修复(2026-09-19;尚未进行独立审计)。POOL-1:水龙头的 Mint 携带其票据开启信息(pk、time、r),准入时重新计算承诺,铸造者签署 rand-mint-2;创世分配的票据同样带有开启信息。RPC-1:rand_getWitness(es) 同时最多运行两次树重建,并在 10 s 后返回 -32000 busy。OPS-1:全部十八个验证节点密钥已轮换,在仓库之外生成,仓库中不跟踪任何密钥 | 承诺所开启的数额超过其金额的铸造会被拒绝;chain 14 的任何密钥从未出现在仓库中 | 自 chain 14(v0.5)起运行。 PRIV-1,即点名叶子的见证请求,已于 2026-09-21 由钱包自带的树关闭 |
v0.5 之后的版本
每个版本都是一个 git 标签,并在 fullnode 的 CHANGELOG.md 中有一条记录。改变共识、线路格式或验证密钥的版本会随一条新链发布;其余版本则逐节点滚动上线到运行中的链上。
| 版本 | 内容 | 链 |
|---|---|---|
| v0.5 至 v0.5.8 | RPL 代币、zUSD 与加固后的跨链桥(见上文);审计修复;历史修剪;共识与同步加固 | 14、15 |
| v0.5.9 | 重新扫描修复:水龙头仅由创世验证者铸币,同步退避,gossip 预检 | 15 |
| v0.5.10 | 地址分享:指纹、randpay: 链接和二维码;加密备注,由链 18 首次启用 | 15 |
| v0.5.11 | 面向团队、投资者和合作伙伴分配的带时间锁的创世归属(vesting)。受创世配置控制,在任何链上均未启用 | 无 |
| v0.6 | 来自 9 月评审的 zkVM、rVM 和聚合修复 | 15 |
| v0.6.1 | 约束集 7:LogUp 盲化、2⁷ 的表下限、32 位范围检查、POSEIDON2_LEN、JALR 修复。链 16 以 hardening_v6 和 bundle guest v2 切出 | 16 |
| v0.6.2 | 委托证明,第一阶段:rand-prover 二进制文件和钱包的 --prover。第一阶段的 prover 会收到花费密钥 | 16 |
| v0.6.3、v0.6.4 | 委托证明,第二阶段:拆分授权。bundle 证明不再需要花费密钥,改由第 10 层的授权证明使用,交易 id 域变为 rand-txid-3 | 17 |
| v0.6.6、v0.6.7-rc1 | Gas:约束集 8、每个证明声明的 gas 上限、动态 gas 与字节价格;备注已启用。v0.6.6 从未以标签形式切出 | 18 |
| v0.6.7 | 链 18 上不改变任何共识规则的修复:封存证明修剪(休眠)、信封格式固定、viewing key 卫生、rVM 分配器、GPU 内核别名、ALU 测试覆盖。在完整工作区测试套件跑完之前即已打标签 | 18、19 |
| v0.6.8 | RPL-2:程序单元、程序金库和 Invoke 操作。zUSD 跨链桥费用,双向。最后的 audit-v6 修复:不再自动释放锁(CON-4)和超时证书 pacemaker(CH-1);--public-rpc 监听器、读取限制、保留的验证者对等节点、同步与 gossip 预算、交易池的字节上限、对证明头所声明度数的限制(ZKV-4);以及链 20 启用的受创世配置控制的规则:创世哈希绑定、testnet、1,024 个区块的证明窗口、gas 价格上限与付费字节负载、按投票准入、质押准入上限改为比例、跨链桥轮换的持有证明与延迟。钱包需要此版本才能在链 20 上发送交易 | 20 |
目前的局限
与白皮书的偏差,如实陈述而不粉饰。每一项都在相应 crate 自己的文档中跟踪,并标明了弥补它的里程碑。
hc是绑定的但不是隐藏的:它不带盐,因此可以确认对某个程序的猜测,同一程序的两次部署也可以相互关联。M3.4 消除的是验证者以明文持有整个程序这一点。- 2026-09-21 之前构建的钱包会向其节点请求见证,而见证请求会指明即将花费的叶子。当前的
rand自己保存一份树的副本,从不发出请求;节点仍为旧钱包提供rand_getWitness。 - 存款在边界处是公开的:水龙头铸币、创世 note 和跨链桥存款都以明文携带其金额(自链 14 起,铸币和创世 note 还携带其 opening,因此所有者密钥也是公开的),这与任何地方从透明地址到 shielded 地址的存款所具有的单跳可见性相同。
- 零知识是统计意义上的,而非完美的。这正是 Plonky3 0.7 的隐藏式 FRI 实际提供的性质,crate 中也如此说明。
- 转录哈希是带开发用轮常数的 Poseidon2,而不是论文中的 SHA3-384 / BLAKE3-384。只需更换配置,无需重写。
- 在 80 次 FRI 查询下,bundle 证明在链 14 和 15 上约为 1.42 MB(截至链 13 约为 1.3 MB)。自链 17 起,一笔转账携带约 2.85 MB 的证明:bundle 证明约 1.49 MB,授权证明约 1.37 MB。在默认链上,区块为 4 MiB、证明上限为 2 MiB 时,含 Keccak 的证明会直接超出证明上限;链 20 的创世设置了 20 MiB 的区块和 4 MiB 的证明上限(链 13 至 16 设置为 8 MiB)。
- 调用证明的头部不是隐藏的。它声明了层级以及 Keccak 和 SHA-256 表的高度,因此可以看出一次调用是否进行了哈希。在 v0.6 prover 下限之前于链 15 上提交的调用暴露得更多:行数少于 2⁷ 的私有表可以从证明中读出。v0.6 prover 下限对新的调用堵住了这一点,而约束集 7 连同
hardening_v6自链 16 起将其变为链的规则。 - 一次调用的上限为第 14 层,最多 2¹² 行 Keccak(128 次置换)和 2¹³ 行 SHA-256(128 次压缩);在
hardening_v6下,超过 8,180 个字的程序无法部署。EVM 和 sBPF 解释器 guest 以及翻译后的 ERC-20 和 SPL Token 镜像都超过了这个大小。 - 持有见证的一方能看到一切。零知识保护的是验证者的视野,而不是 prover 的。自链 17 起,钱包可以把 bundle 证明交给配对的
rand-prover,而无需交出花费密钥,但该 prover 仍持有 viewing key,能看到这些 note。CUDA 后端于 2026-09-28 首次在硬件上运行,目前尚无生产环境的测量数据。
仓库结构
fullnode 的 Cargo 工作区,按其 README 和 crates/ 目录所示。
| 路径 | 内容 |
|---|---|
crates/randprotocol-core/ | 纯逻辑,无 I/O:密码学、note 与承诺树、账本规则、gas、创世、HotStuff 状态机 |
crates/randprotocol-zkvm/ | Rand zkVM,从 zkp-circuits/research 以约束集 8 引入(circuits aeacf31;用 deploy/sync-zkvm.sh 重新同步),外加链上的证明验证器及其验证密钥缓存 |
crates/randprotocol-rvm/ | 递归虚拟机,从 zkp-circuits/recursion 引入:一种原生域上的机器,其程序用于验证 Rand zkVM 证明 |
crates/bridge-codec/ | guardian 跨链桥的线路格式和法定人数规则,与 Solidity 合约和 Solana 程序逐字节共享 |
crates/randprotocol-node/ | RocksDB 存储、libp2p 网络、交易池、区块同步、JSON-RPC 服务器和 rand-node 二进制文件 |
crates/randprotocol-client/ | rand 钱包二进制文件和 RpcClient 库,不依赖 RocksDB 或 libp2p |
crates/randprotocol-prover/ | rand-prover 二进制文件:为配对钱包证明 bundle 的委托 prover |
deploy/ | 测试网创世文件、nodes.env、运行脚本、云端配置、切换和重建脚本。自链 14 的筹备起,此处不再跟踪任何密钥 |
docs/ | 参考文档和设计规范 |
scripts/ | 本地双验证者测试网 |
已规范但尚未交付
这些组件在论文或 fullnode 的文档中有所描述,但并未运行:要么不在仓库中,要么已构建但未在任何链上启用。列出它们,是为了让规范与代码之间的差距一目了然,而不必靠推断。
| 组件 | 状态 |
|---|---|
| bridge · guardian | 端到端运行证明格式的 guardian 和 relayer 守护进程;合约、编解码器和 fullnode 的接收端已交付,守护进程尚未交付 |
| fullnode · aggregation | 使用递归虚拟机的区块聚合:封存、修剪和封存形式的同步。已构建,在所有链上均关闭;rand-node 会拒绝带有 aggregation 部分的创世。它仍需要端到端的伪造聚合演练,并且它只移除 bundle 证明,不移除授权证明。生产环境的 rVM 证明需要大型机器:在约束集 7 下,两个证明的聚合耗用 133 GB,三个耗用 221 GB,退出证明则超过 256 GB(2026-09-28 和 29 日测得;未在约束集 8 下重新测量) |
| fullnode · vesting | 面向团队、投资者和合作伙伴的带时间锁的创世分配(v0.5.11,docs/vesting.md)。受创世配置控制:没有 vesting 部分时,四种 vesting 操作会被拒绝,而目前没有任何链带有该部分。链 20 的供应审计将每个 vesting 计数器都报告为零。自 v0.6.8 起,可撤销条目由其撤销者中达到阈值的一方撤销,且只能撤销到其创世条目所指定的金库 |
| fullnode · slashing | 针对领导者双重签名的罚没与监禁已在 v0.6.8 中构建,位于 staking.slashing 之后,在链 20 上关闭(其创世中没有该配置,而全部 26 个验证者密钥属于同一运营者)。区块奖励、哈希抽签的领导者信标、nullifier 累加器和跨程序调用尚未构建。持久化的每程序状态已作为 RPL-2 交付(见上文) |
prover/ | GPU 证明守护进程:从队列中领取批次,竞争提交。CUDA 内核位于 zkp-circuits 中,于 2026-09-28 首次在 NVIDIA H100 上运行;市场守护进程不存在。随附交付的 rand-prover 为与其配对的钱包提供证明,并不是一个市场 |
| zkp-circuits · M4.4 exit proof | 一次 SPL Token 转账的证明(第 20 层),外推约为 330 GB。ERC-20 转账(第 18 层)于 2026-09-19 在一台 128 GB 的 droplet 上完成证明。两者都无法在链 20 上调用,因为链 20 将调用上限设为第 14 层 |
构建与测试
Rust 标准工作流,每个仓库都适用。fullnode 是一个 Cargo workspace,工具链版本固定,并带有一套会通过 TCP 启动真实节点的集群测试。构建时需要将 circuits 仓库检出到其旁边、目录名为 circuits,并且要位于 vendored crate 所同步的那个提交(v0.6.7 和 v0.6.8 为 aeacf31)。zkVM 是 zkp-circuits 中的一个独立 crate,有自己的工具链版本锁定,并附带一个演示,说明机密调用会泄露什么、不会泄露什么。
fullnode:
git clone https://github.com/randprotocol/fullnode.git
git clone https://github.com/randprotocol/zkp-circuits.git circuits # the sibling directory must be named circuits
git -C circuits checkout "$(sed -n 's/^circuits: //p' fullnode/crates/randprotocol-zkvm/guests-compiled/PROVENANCE.md)"
cd fullnode
# Rust 1.98.1 is pinned by rust-toolchain.toml; first build pulls RocksDB and Plonky3, 10 to 20 minutes
cargo build --release # target/release/rand-node, target/release/rand, target/release/rand-prover
# All crates; release because STARK proving is slow in debug. One to two hours, mostly proving
cargo test --release
# One machine, two validators
scripts/local-testnet.sh
target/release/rand --rpc http://127.0.0.1:8545 status
位于 zkp-circuits/research 中的研究用 zkVM:
# Toolchain is pinned by rust-toolchain.toml; the first build pulls Plonky3
cargo build --release
# Narrated demo: thirteen proofs, one at production FRI parameters (~6-7 min)
cargo run --release
# Emulator, per-table constraints, cheating provers, ZK, end-to-end, viewing keys, compiled guests (395 tests, ~17 min)
cargo test
fullnode 测试套件在 v0.6.1、16 vCPU 机器上的实测数据:core 521 项测试,node 373 项,client 117 项,作弊证明者(cheating-prover)套件 116 项,隐藏 bundle 作弊测试 21 项(75 分钟),钱包流程 6 项(53 分钟),集群 26 项(44 分钟),zUSD 端到端关卡 2 项(51 分钟)。递归 VM 的生产证明不在该套件之内,所需内存见上文。
运行节点介绍了如何用该构建加入公共 testnet;testnet 创世文件、引导节点(bootstrap peers)和运行脚本随 fullnode 的 deploy/ 目录一并发布,下载页面提供了简要说明。
参与贡献
fullnode 采用 GNU General Public License v3.0(GPL-3.0-only)授权;此前为 Apache-2.0。缺陷和设计提案请在变更所涉及的仓库中提交 issue。欢迎提交 pull request:提交前请运行 cargo fmt && cargo clippy,并保持改动范围集中。可从 fullnode issues 入手。
架构、隐私电路、手续费代币证明以及后量子权衡,均记录在论文页面上的白皮书中。fullnode 仓库自带的 docs/ 目录是本文档中每一页内容的核对依据。