Rand Protocol
参与

运行 Rand 节点

参考全节点及其钱包均以 Rust 编写,可从源码构建。构建产出两个二进制文件:rand-node,即节点和运维工具;以及 rand,即持有屏蔽花费密钥的钱包,它通过 JSON-RPC 与任意节点通信,并在本地为每笔转账和每次机密调用运行 zkVM 证明器。实验性 testnet(链 21)已在 DigitalOcean droplet 上以 26 个验证者运行。它未经审计,不具有任何实际价值。两者的 Linux x86_64 二进制文件均附在 v0.8.0 版本发布中,该版本即车队所升级到的构建。

本地构建与运行
bash
# 1. Rust(rustup 会自动采用固定的 1.98.1 工具链)以及 RocksDB 的构建依赖
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
sudo apt install build-essential clang cmake pkg-config libssl-dev   # Linux

# 2. 克隆并构建(首次需 10–20 分钟)
git clone https://github.com/randprotocol/fullnode.git
cd fullnode
cargo build --release        # target/release/rand-node, target/release/rand

# 3. 在本机上运行双验证者链(RPC 位于 8545 和 8546)
scripts/local-testnet.sh
target/release/rand --rpc http://127.0.0.1:8545 status

# 4. 测试;使用 release 模式,因为 STARK 证明在 debug 模式下很慢(678 项测试,于 2026-09-14 实测约 43 分钟)
cargo test --workspace --release
以观察者身份加入公共 testnet
链 21
# 版本 v0.8.0(c0878c3f)运行 chain 21,此前任何版本均无法运行:chain 21 采用约束集 9,其验证密钥和证明编码是更早版本所不具备的。请从该标签构建,或在 Linux x86_64 上使用
# 使用发布的二进制文件,并对照随版本发布的 SHA256SUMS 进行校验
git checkout v0.8.0 && cargo build --release
curl -LO https://github.com/randprotocol/fullnode/releases/download/v0.8.0/rand-node -LO https://github.com/randprotocol/fullnode/releases/download/v0.8.0/rand \
     -LO https://github.com/randprotocol/fullnode/releases/download/v0.8.0/msauth-vk-production.bin# 固定的多重签名验证密钥:rand-node 从其二进制文件旁加载该密钥,缺少它则拒绝启动
sha256sum rand-node rand msauth-vk-production.bin   # 必须输出该版本的值(SHA256SUMS,以 SHA256SUMS.sig 签名):
# 324a4ab1029d39e67fc2de36b036341b0f88f13089997d7fe24c596363a58278  rand-node
# e3a38e74ee28743a960fc1c3eb1ac6c538e18dc259411e10afff7f54e268bbf4  rand
# 68facb06c7f321aaf1d4d541acf6b5c0e9d7f17788ed1c9add6c5a8a8f7acd30  msauth-vk-production.bin

# 你的节点身份:Dilithium2 验证者密钥与 p2p 对等节点 ID 合于一个文件。请自行生成
# 并保存在检出目录之外;仓库不再跟踪任何密钥
rand-node keygen --out node.key.json

# 创世文件随仓库提供;每个节点持有的文件必须完全一致。
# init 会输出其哈希,该哈希必须与下方的哈希一致
rand-node init --datadir ./data --genesis deploy/genesis-chain21.json

# 连接公共验证者(chain 21 沿用了 chain 14 的密钥,因此其对等节点 ID 和 IP 也相同)。
# 省略 --validator:你的密钥不在验证者集合中。验证者还需要 NTP
rand-node run --datadir ./data --key node.key.json \
    --listen /ip4/0.0.0.0/tcp/30303 --rpc 127.0.0.1:8545 --no-mdns \
    --bootstrap /ip4/164.90.239.200/tcp/30303/p2p/12D3KooWEQEbUwZRgqhDPXhW7vNBmcRcnhUDGUADe81VFdv3ALYe \
    --bootstrap /ip4/165.245.173.74/tcp/30303/p2p/12D3KooWJyc5oDHggAr89e9QrRFBy9Tg8TxXh18yzrb1SM6KKLYw \
    --bootstrap /ip4/188.166.235.187/tcp/30303/p2p/12D3KooWSyX84P1DAbWByLHpRBMLRWD53r3Jj4aqVt6tHoF8B2ZQ

# 钱包是一把独立的屏蔽密钥。其 rand1… 地址的文本长度约为 1.6 KB
rand keygen && rand address

# 水龙头铸币由验证者签名,因此需要验证者的 RPC:它在本地
# 双验证者链上可直接使用;观察者节点会回应 "ask a validator node"。在 chain 21 上,
# 水龙头只向其创世文件白名单中的 16 个钱包铸币,且只经由其指定的验证者
rand faucet                                  # 100 RAND 进入只有你能打开的 note
rand balance                                 # 用你的密钥扫描树;其他人无法扫描
rand send <rand1 address> 1.5              # 请求确认,生成证明(约 2 分钟),等待提交
验证者
26
法定人数
18 of 26
创世
ca76c2766ed6090ac6ba5dad86b724dd5d2b80c0edfaed287cd8b129e663ca9a
发起机密调用
rand
# 组装一个内置 guest:如果四个私有余额足以覆盖,则支付超出 1000 的盈余
rand program build --guest private_payment --arg 1000 --out pp.json
rand program deploy pp.json                  # 打印程序 id(其内容哈希)

# 在本地生成证明;只有证明、八个输出字和一份密封的输入记录会上链
rand call <program id> --input 400 --input 250 --input 300 --input 75
rand receipt <tx>                            # 输出 [1, 0, 25, 0, ...]:盈余,以数据形式发布

# 之后,打开该记录,并对照证明所发布的 H_IN 进行检查
rand open-call <tx>                          # inputs: [400, 250, 300, 75] — verdict: faithful
链能看到程序 id、gas 等级和八个输出字。它永远看不到余额;并且由于费用由屏蔽 bundle 支付,它也无从得知调用者是谁;输出是数据,任何支付都是调用者构造的 bundle。在 Apple Silicon 上的实测:tier 10 下证明约 7 秒,80 次查询 FRI 配置下证明约 1.2 MB,在验证密钥已预热的情况下验证约 16 毫秒;节点对每个等级只计算一次该密钥,并在各程序间复用。

要求

操作系统
Linux x86_64 或 macOS arm64
Rust
1.98.1,由 rust-toolchain.toml 固定;rustup 会自动安装
构建依赖
C++ 编译器、cmake、pkg-config、OpenSSL 头文件(RocksDB)
首次构建
10 至 20 分钟:从源码编译 RocksDB 和 Plonky3
端口
公共节点需开放 TCP 30303 入站;RPC 位于 127.0.0.1:8545
服务器
1 至 2 个 vCPU 的云实例即可运行 testnet 验证者
时钟
验证者上需运行 NTP(chrony):对于时间超前自身时钟超过 15 秒的区块,它会不予投票,因此时钟偏慢会导致它悄无声息地停止投票
证明
目前仅支持 CPU:在笔记本电脑上一笔屏蔽转账约需两分钟(7 秒的授权证明加上约 110 秒的 bundle 证明),并占用约 6 GB 内存;小型调用额外增加约 30 秒

选择角色

  • 观察者 向所有人开放

    同一个二进制文件,不带 --validator。同步链,验证每个证书以及每个 bundle 和调用证明,重新执行每个区块,比对回执,并提供 JSON-RPC 服务。这是新密钥在公共 testnet 上运行的方式。

  • 验证者 需质押

    在链式 HotStuff 下投票并提议区块。在 chain 21 上,与 chain 20 相同,新验证者须先经投票准入:持有超过三分之二质押的验证者为其密钥签署 AdmitValidator 操作。随后它注册节点密钥(rand-node register --v2),从钱包绑定至少 1,000 RAND,并在绑定之后的第三个 1,000 区块的纪元边界进入验证者集合(沿用 chain 18 的两个纪元的绑定延迟)。Chain 18 起始于 26 个验证者,每个质押 1,000 RAND;必须有超过三分之二的质押(26 个中的 18 个)在线并参与投票才能提交区块。请自行生成密钥:仓库中不再保留任何验证者密钥,为早期链提交的密钥文件均为已公开的种子。

  • 钱包与证明器 本地

    rand 客户端持有 256 位花费密钥,且不签署任何内容:两个证明即授权,一个是用花费密钥生成的小证明,另一个是 4 入 4 出的 bundle 证明。它扫描树以找到属于自己的 note,在你的机器上生成这两个证明,对 RAND 和任何 RPL 代币的形式相同;对于机密调用,还会为程序生成证明。只有证明、承诺、nullifier 和密封信封会到达链上。

不运行节点?同一个钱包也提供 iOS、Android、Chrome 和 Firefox 应用:钱包。

源码
randprotocol/fullnode
GPL-3.0-only · testnet 运行的是 v0.8.0,即最新版本
验证

每个节点都检查一切

同步的节点会重新验证每个证书,重新执行每个区块(包括其中的证明),并在接受之前比对回执。启动时,它检查自己的数据库,截断任何不一致的部分,同时保留其投票安全状态,并从对等节点重新获取缺失的区间。

# 节点已停止:哈希、QC、签名、证明、重放
rand-node verify --datadir ./data --mode full
rand-node verify --datadir ./data --repair

故障测试在运行中的 testnet 上进行

  • ›停止四个验证者中的一个:链继续提交,该节点恢复后数秒内即可追上。
  • ›停止四个中的两个:链因缺少法定人数而停止,它们恢复后链继续运行且不分叉。
  • ›损坏某节点的数据库:启动时被检测到,被截断,从对等节点重新同步,之后与其他节点逐字节一致。
  • ›通过不同节点发起转账:全部提交,各处余额一致,总供应量不变。
  • ›断开的对等连接会在约 30 秒内由重连逻辑重新建立。

尚未实现

列出这些,是为了让论文与节点之间的差距清晰可见,而不是靠推断。

  • ›程序的持久化独立状态与跨程序调用
  • ›钱包内置编译器:程序可以是内置的已汇编 guest,也可以是使用独立的 rand-guest 工具链构建的镜像
  • ›罚没与监禁(jailing)、区块奖励、手续费市场、哈希抽签式领导者信标
  • ›nullifier 累加器、最终确定后的证明裁剪、证明批处理
  • ›SPL Token 转账的 20 级证明,以及论文中的 GPU 证明者市场