节点在 --rpc(默认 127.0.0.1:8545)上提供基于 HTTP 的 JSON-RPC 2.0,并在同一端口上提供用于订阅的 WebSocket。自 v0.6.8 起,它还可以开启第二个公共监听器(--public-rpc,见下文)。randprotocol_client::RpcClient(Rust)封装了下列每个方法。本页是 v0.8.0(c0878c3f)所提供的方法列表,即 chain 21 自 2026-10-12 起运行的版本;若某个方法存在于代码中但在 chain 21 上不起作用,页面会注明。v0.8.0 相对 v0.6.8(chain 20 的方法列表)新增的内容汇总在末尾的chain 21 与 v0.8.0 的新增内容。
curl -s http://127.0.0.1:8545 -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"rand_getHead","params":[]}'
公共端点
https://rpc.randprotocol.org(同一代理也位于 https://randprotocol.org/api/rpc)转发到一个保留全部区块的 chain-21 归档节点,供没有自有节点的钱包和页面使用(rand --rpc https://rpc.randprotocol.org …)。它仅支持 HTTP POST,开放 CORS,不提供 WebSocket,并且比节点本身更受限:
- 每次调用只接受一个请求。批量请求会以
-32600拒绝。 - 方法白名单:自 2026-10-01 起,与节点自身公共监听器的集合相同(
rpc::PUBLIC_METHODS),因此rand program invoke所需的程序状态读取、rand_getAdmitted、聚合读取和归属(vesting)读取都在其中,另有rand_checkTransaction和rand_sendTransaction;自 2026-10-12 起,它遵循 v0.8.0 的集合,新增了rand_getScanLeaves(钱包按信封头扫描)、rand_getRandPrice、rand_getMultisig以及四个永续合约读取方法(rand_getPerps、rand_getPerpAccount、rand_getPerpAccounts、rand_getPerpInputs)。rand_mint、rand_importViewingKey、rand_getViewingNotes、rand_removeViewingKey和rand_getPeers不在其中,调用时会在到达节点之前以-32601method not allowed here应答:公共水龙头是滥用面,而查看密钥只应交给你自己运行的节点。 - 请求体最大为 12 MiB,足以容纳任何转账、代币操作或部署,以及证明最大约 3.4 MB 的调用(交易以十六进制编码,其 bundle 证明和 auth 证明在计入调用证明之前约占 2.85 MB)。更大的调用应发往你自己的节点。超出上限时:HTTP 413 和
-32600。 - 每个地址每分钟 1,200 次请求,
rand_sendTransaction每分钟 6 次。超出时:HTTP 429 和-32005。读取配额是按钱包首次同步的规模确定的,即一次突发中的数百个请求(chain 18 高度 99,000 时为 645 个)。 - 当其后的节点不应答时,返回
-32000upstream unavailable。
本页其余内容描述的均是节点本身。
节点的两个监听器
自 v0.6.8(audit v6)起,节点有两个 JSON-RPC 监听器。
--rpc <ADDR>,运营者监听器。 提供所有方法、批量请求和 WebSocket。它按套接字地址识别调用方并信任环回地址:查看密钥方法只对环回地址应答,环回地址不计量。请将其保持在127.0.0.1上。反向代理或 SSH 转发是经由环回地址到达的,因此在其后每个访问者都等同于运营者:切勿把公共端点指向此端口。--public-rpc <ADDR>,公共监听器,专为这一跳而设。它提供固定的方法集合:钱包、浏览器或页面所需的读取方法以及rand_sendTransaction(rpc::PUBLIC_METHODS)。rand_importViewingKey、rand_getViewingNotes、rand_removeViewingKey、rand_mint和rand_getPeers永远不在此提供,日后新增的方法在列入之前也不提供;此类调用会以-32000<method> is not served on this node's public listener应答。批量请求为-32600,也没有 WebSocket 路由。所有调用方共用一个计量,突发 600 个请求,每秒 150 个;超出后返回 HTTP 429 和带有-32000的响应体。按访问者的限制属于代理,因为只有代理能看到访问者。其调用方最多占用节点阻塞读取槽位的一半,因此运营者监听器永远不会被饿死。
两个监听器共用两项读取限制。阻塞读取若在 30 s 内未返回,则以 -32000 this read took longer than 30 s on this node; retry with a smaller range 应答。rand_getBlocks 在读取到 64 MiB 区块后结束其分页。
--rpc-viewing-token-file <PATH> 为 --rpc 的查看密钥方法加上持有者令牌:取文件的第一行,至少 32 个字符,以 Authorization: Bearer <token> 发送。启用后,仅凭环回地址不再足够,任何位置的调用方只要出示该令牌即可获得服务。
约定
- 验证者地址是 base58 字符串(32 字节)。哈希为 64 个十六进制字符,可带或不带
0x。屏蔽值——承诺、作废符、锚点、树根、见证层级——为Word8:八个小端序u32字,表示为 64 个小写十六进制字符。 - 屏蔽地址为
rand1+ base58,共 1,667 个字符。长度超过 2,000 个字符的参数在解析之前即因长度被拒绝。 - 每个
u64金额都是十进制字符串("1500000000"= 1.5 RAND;1 RAND = 10⁹ 单位):RAND 单位或代币单位,链上状态或已解码交易自身的字段均如此。JSON 数字在超过 2⁵³ 之后无法精确表示整数,而一个 9 位小数代币的供应量在几千万单位时就会超过这一值。此变更带来的影响见下文带日期的说明。 - 索引、nonce、高度、叶索引、视图、长度、小数位数和日计数器(
mint_day)从不是金额,全程为 JSON 整数。 - 每个请求都必须带有
id成员。 没有id的对象是通知,会以-32600拒绝;显式的"id": null是正常请求。 - 没有余额方法,也没有账户方法。 钱包通过用其查看密钥扫描
rand_getCommitments和rand_getNullifiers来计算余额。rand_getBalance、rand_getAccount和rand_getAssetBalance以-32601应答。
破坏性变更,2026-09-20(chain 14):每个金额都是十进制字符串
在 chain 14 之前,已解码交易中的金额是 JSON 整数。这一例外已不复存在。下列字段从 JSON 数字改为十进制字符串,其含义和位置均无其他变化:
bundle.fee,位于rand_getTransaction的tx中,以及rand_getBlockByHeight/rand_getBlockByHash的transactions[]中;kind=mint、bond、unbond、withdraw、bridge_attest时的action.amount(同上述三个方法);kind=bridge_burn时的action.amount和action.relayer_fee(同上述三个方法);rand_getAssets各行以及rand_getBridgeState.assets[]各行中的locked。
任何把这些字段当作数字读取的客户端,都必须改为解析字符串。rand_status 的 aggregation.subsidy_base(仅聚合链)在同一变更中也改为字符串。其余所有金额原本就是字符串:rand_getSupply、rand_getEmission、rand_getValidators、查看票据,以及随 chain 14 引入的每个字段——bundle 的 burn_a 和 burn_r、代币供应量、各抵押资产的 locked、mint_cap_per_day 和 minted_today、registration_fee,以及 token_mint、token_burn 和 register_token 的 amount(initial_amount、initial.amount)。
批量请求
POST 请求体可以是最多 20 个请求对象的数组,以同样长度的数组按请求顺序应答,错误也包括在内。请求依次执行。空数组、超过 20 个的数组,或既非对象也非数组的请求体,均为一个 id 为 null 的 -32600。整个请求体仍受节点请求体上限约束,该上限是按一笔携带证明的交易确定的:包含两个携带证明的 rand_sendTransaction 调用的批量请求会以 413 拒绝。批量请求用于读取,而不是已证明的提交。
链与节点
rand_chainId
参数 []。结果:链 id(整数);自 2026-10-12 起测试网上为 21(2026-10-01 至该日为 20)。
rand_tokenInfo
参数 []。结果 { "symbol": "RAND", "decimals": 9 }。
rand_getHead
参数 []。结果 { "height": 1998, "hash": "…", "view": 2251 }。view 是节点当前的共识视图,在视图超时时会领先于高度。
rand_status(别名 rand_syncStatus)
参数 []。结果:
{
"height": 1998, "head_hash": "…", "view": 2251, "high_qc_view": 2250,
"syncing": false, "sync_target": 1998,
"sync_inflight_age_ms": null, "sync_failures": 0, "sync_late_batches": 0, "compact_fetched": 0,
"peer_count": 26, "connected_peers": 26, "reserved_peers": 25, "ws_clients": 0, "refused_cache": 0,
"verify_queue": 0, "mempool_size": 0,
"is_validator": true, "active_validator": true, "faucet": true, "confidential": true,
"testnet": true, "fri_profile": "production", "programs": 10, "viewing_keys": 0,
"notes": 197, "nullifiers": 160, "tree_root": "72b9…1197", "hc_bundle": "60af…3fce", "hc_auth": "1e4e…39c1",
"hc_auth_multisig": "9705…8247", "msauth_key": "loaded", "binding_domain": 1,
"address": "5TAofR…", "peer_id": "12D3KooW…",
"gas_prices": { "gas_price": "100", "byte_price": "800" }
}
is_validator:该节点持有验证者密钥;active_validator:该密钥属于运行当前纪元的验证者集合。reserved_peers(v0.6.8)统计越过入站连接上限而被接纳的对等节点:引导节点、所有 --reserved-peer,以及从签名的对等节点绑定中获知的每个验证者身份,各计一次;在集群节点上,它应在启动后一分钟内达到验证者数量。viewing_keys 是节点在内存中持有、用于节点侧扫描的查看密钥数量。verify_queue 是等待四个证明验证工作线程之一的交易数量(最多 64 笔)。hc_bundle 是本链证明所对应的 bundle guest,hc_auth 是其创世区块所固定的 auth guest(自链 17 起为拆分授权),在没有该项的链上为 null;构建与其中任一项不一致的节点会拒绝启动。hc_auth_multisig(v0.8.0)是第二个 auth guest,即私密多签策略(链 21 上为 9705f8e2…8247,层级 18),或为 null;msauth_key 说明节点用于它的验证密钥的来源:"loaded"(二进制文件旁固定的 msauth-vk-production.bin,每个链 21 验证者都必须具备)、"built"(开发构建)或 "absent"(没有该 guest 的链)。compact_fetched(v0.8.0,紧凑区块)统计本节点按哈希获取的交易体数量,原因是领导者的紧凑提案引用了其内存池中没有的交易;若该计数随每个区块不断增长,说明该节点缺少 gossip 广播的数据。testnet 与 binding_domain 是同名的创世字段,与 rand_getLimits 所返回的一致。gas_prices 是链头账本当前的 gas 价格,每次提交时刷新,以十进制字符串表示;在没有 gas 部分的链上为 null。链 21 的价格与链 20 一样是动态的,每个区块按满载程度浮动,从不低于 100 和 800 的下限,也从不高于 10,000 和 80,000 的上限,因此请从这里或 rand_getLimits 读取,不要硬编码。该对象还包含一个 aggregation 对象(其 subsidy_base 为十进制字符串,其余为整数);在没有 aggregation 部分的链上(如链 21),其值全部为零。
该对象还包含 disk_free_bytes(数值)和 disk_low,以及一组保留策略字段:prune_floor,即本节点仍保存的最低高度(归档节点为 0);prune_history_secs,即以 --prune-history 启动的节点所保留的时间窗口(保留全部数据时为 null)。在链 21 上,与链 19 和链 20 一样,26 个验证者中有 24 个保留 24 小时的区块;两个归档节点保留全部区块。参见裁剪节点。
rand_getPeers
参数 []。结果:由 { "peer_id": "12D3KooW…", "addrs": ["/ip4/…/tcp/30303"], "connected_secs": 1241 } 组成的数组。
rand_getBlockByHeight / rand_getBlockByHash
参数 [height] 或 [hash]。若未知则结果为 null,否则为:
{
"hash": "647b…", "height": 50, "view": 92, "parent": "2d41…",
"proposer": "3v3VBJ…", "timestamp_ms": 1788000123456,
"tx_root": "0000…", "state_root": "a1b2…", "justify_view": 91,
"tx_count": 0, "transactions": [ ]
}
仅提供已提交的区块。transactions 的结构与 rand_getTransaction 的 tx 相同。区块还带有 sealed,其中每笔交易带有 sealed_by;在没有聚合的链上,它们分别为 false 和 null。
rand_getBlocks
参数 [from_height, to_height]。结果:区块头,按从旧到新排序,自 from_height 起最多 1,024 个(2026-09-24 之前的节点为 128 个):即 rand_getBlockByHeight 的字段去掉 transactions。超出上限或越过链头的范围会被截断而不是被拒绝;自 v0.6.8 起,一页在读取了 64 MiB 的区块后也会结束;请从返回的最后一个高度继续。若 to_height 小于 from_height,返回 -32602。
自 v0.6.8 起,每个区块头还带有 public_notes:该区块的 bridge_attest、token_mint 和 register_token 交易,以及在有桥接费用的链上的 bridge_burn 交易,形式为 [{ "hash", "raw" }](即 rand_getRawTransaction 所返回的编码);其他区块则为空。销毁交易返回时其证明被清空,并带有 "proofs_stripped": true;其 hash 是真实的交易 id。钱包首次同步读取这些页面,无需其他任何内容即可重建公开票据。
rand_getFinality
参数 [height] 或 [hash]。结果为以下之一:{ "status": "committed", "height", "hash" }、{ "status": "certified", "height", "hash", "qc_view" }、{ "status": "proposed", "height", "hash" }、{ "status": "unknown" }。高度只会与已提交的链比对,因此只会返回 committed 或 unknown;哈希还可能返回 certified(位于副本的未提交树中,且带有法定人数证书)或 proposed(位于树中,但没有证书)。
rand_getProposer
参数 [view] 或 [from_view, to_view],最多 64 个视图。结果 { "epoch": 3, "proposers": [ { "view": 2251, "proposer": "2nRdFC…" } ] }:即在当前验证者集合下每个视图的领导者,而不是该视图当时历史上运行的集合。若范围反向或超过 64 个视图,返回 -32602。
rand_getVersion
参数 []。结果 { "version", "git_sha", "chain_id", "hc_bundle", "hc_auth", "fri_profile" }。version 是工作区 crate 的版本;git_sha 是构建时记录的提交哈希,若受跟踪文件有差异则附加 -dirty,否则为 "unknown"。hc_auth 是创世 auth guest,与 rand_status 中相同,或为 null。2026-10-12 公共端点在链 21 上的返回:
{ "version": "0.8.0", "git_sha": "c0878c3fbe5659cf91415d27b0e74d1282f0efef", "chain_id": 21,
"hc_bundle": "60af094acfe65d85fdb18fb3d06cf9085dcf28c96e59e87f1ee527226e6e3fce",
"hc_auth": "1e4e347f44cf86750b30a9a4bdf9ec9256efe353d4ff8017451eca7d195639c1",
"fri_profile": "production" }
rand_getGenesisHash
参数 []。结果:十六进制的创世哈希;链 21 上为 "ca76c2766ed6090ac6ba5dad86b724dd5d2b80c0edfaed287cd8b129e663ca9a"(链 20 的为 6210cf07…5135,链 19 的为 a3defc93…228a)。仅凭链 id 无法区分两次链切换;这个哈希可以。自链 20 起,它还是每笔交易绑定和每条签名操作消息的一部分(binding_domain: 1,参见 rand_getLimits)。
rand_getHealth
参数 []。结果为以下之一:{ "status": "disk_low", "free_bytes": "3221225472" }、{ "status": "ok" }、{ "status": "syncing", "behind": 412 }、{ "status": "behind", "behind": 30 }。当数据目录所在文件系统的可用空间低于节点 --min-free-disk-mb(默认 1024,即低于 4 GB)的四倍时,disk_low 优先于其他所有状态;free_bytes 为十进制字符串。当 sync_target - height 至多为 2 且没有未完成的同步批次请求时为 ok;存在未完成请求时为 syncing;节点未在同步而滞后仍大于 2 时为 behind。
rand_getMempoolInfo
参数 []。结果 { "count": 2, "bytes": 2611200, "oldest_ms": 1450, "max_count": 10000 }。bytes 是池中每笔交易编码长度之和;池为空时 oldest_ms 为 null。自 v0.6.8 起,内存池还有字节数上限,为创世 max_block_bytes 的八倍(链 20 上为 160 MiB,链 21 上为 152 MiB):超出后,每 KiB 高于其下限支付更多的交易会取代最便宜的交易,而支付更少或相同的交易会被以 mempool full 拒绝。治理操作可越过这两项上限。
提交
rand_sendTransaction
参数 [hex],其中 hex 为 bincode(Transaction)。结果:交易哈希。节点按准入顺序(交易)进行验证,放入内存池并广播。错误为 -32000 并附原因:nullifier already spent、anchor is not one of the last 1024 roots、time 12 is outside [1500, 2524](两个窗口均为创世 proof_window_blocks,链 20 和 21 上为 1,024;至链 19 为 256)、fee 1000000 below minimum 2000000、the bundle's digest is not what its proof published、invalid bundle proof: …、unknown program …、already in mempool、conflicts with a pending transaction over <nullifier>、faucet is disabled on this chain;对于 invoke,有 cell <key> is no longer what this transition read(状态裁决:重新读取该 cell 并再次证明)或 the vault holds … of asset … and the transition pays …;对于在投票准入下注册的 Bond,有 validator … has not been admitted by the validator set's vote (staking.admission_by_vote); ask the validators for an AdmitValidator first;对于不符合创世要求的 bundle(链 20 和 21),有 envelope is 1348 bytes, this chain requires exactly 1860、this chain requires an auth proof on every bundle (genesis hc_auth)、the auth proof publishes a different commitment than the bundle's auth_commit、auth proof: …、bundle proof declares gas limit …, this chain requires exactly 20479、non-canonical proof: … — re-prove with an up-to-date wallet;对于桥接操作,有 bridge: attestation already consumed、the attestation names a different recipient、the attestation deposits under asset 2, and the transaction names 1、the bundle burns 399, not the 400 the action declares;对于携带了其操作不允许的销毁的 bundle,有 the bundle burns asset 2 on an action that burns no token、a burn of 5 is not allowed on this action 或 RAND burned through burn_a (5); a RAND burn goes through burn_r;对于桥接状态,有 bridge minting is paused、mint cap … per backing per day、already paused、not paused、wrong pause nonce、wrong list nonce、chain N has no registered emitter;对于代币注册表,有 wrong mint nonce 和 wrong token index。被接受不等于已提交:请轮询 rand_getTransaction 或 rand_getTransactionStatus。
一条交易若大于该链的区块上限(取自 rand_getLimits 的 max_block_bytes),会在进入内存池之前被以 -32000 拒绝,并写明两个大小。请求体上限为 2 × (2 × max_proof_bytes + 4 × 2048 + max_call_envelope_bytes + 16,384 + 64 KiB) + 256 KiB,由创世配置在启动时计算得出:默认链为 8,867,840 字节,按 chain 20 的限制为 17,350,656 字节,与 chain 17 至 19 相同(chain 13 至 15 为 34,127,872 字节,其证明上限为 8 MiB)。在带有 hc_auth_multisig 的创世配置上,如 chain 21,第一项按上限计入三个证明(捆绑证明、授权证明和更大的多签授权证明),因此在 chain 21 的 max_proof_bytes 为 6 MiB 时,请求体上限会更宽。4 × 2048 是捆绑包的四个信封按信封上限计算的大小。超出该上限的请求体返回 -32600,并写明该上限。
只有 -32000(准入被拒绝)和 -32602(无法解码)是对该交易的裁决。其他任何失败,包括 -32603,都不能确定该交易的去向:节点在答复之前就已将交易放入池中并进行 gossip 传播,因此在这段间隙中停止运行的节点,可能已经接纳了它从未答复过的交易。randprotocol_client 仅在这两个错误码上将发送视为被拒绝。
rand_getTransactionStatus
参数 [[hash, …]],1 至 64 个哈希。结果:每个哈希对应一项,按顺序排列:
[ { "hash": "…", "status": "committed", "height": 1998, "index": 0 },
{ "hash": "…", "status": "pending" },
{ "hash": "…", "status": "rejected", "reason": "bad mint signature" },
{ "hash": "…", "status": "unknown" } ]
每个哈希的查找顺序:已提交(存储),待处理(内存池),已拒绝(由 rand_status 的 refused_cache 计数的拒绝缓存),否则为 unknown。rejected 仅涵盖针对交易自身字节的拒绝,这类拒绝不会因之后的任何区块而改变:无效的证明、与其证明所公布的不一致的捆绑摘要、错误的 mint 签名、错误的链 id、过大的部分、交易内重复的作废符或承诺、大小错误的信封、缺失或不匹配的授权证明、声明了错误 gas 限额的捆绑包或授权证明。取决于节点当时状态的拒绝则不会被记住,读取为 unknown:已花费的作废符、超出窗口的锚点或 time、低于下限的费用(自 chain 20 起随 gas 价格变动)、未知的程序、寄存器 nonce、过期的 invoke 读取。空列表或超过 64 个哈希时返回 -32602。
rand_mint(testnet 水龙头)
参数 [address] 或 [address, amount];address 为 rand1… 地址,amount 为以单位计的字符串,最大 100000000000(100 RAND,默认值)。结果:mint 交易哈希。仅在创世配置含 "faucet": true 的链上可用;否则返回 -32000 faucet is disabled on this chain。观察者节点答复 faucet mints are signed by validators; ask a validator node。
在创世配置设置了 staking.faucet_recipients 的链上(chain 20 如此,chain 21 亦然,共 16 个钱包),只有列出的钱包可以收款:向任何其他地址的 mint 都会被拒绝,答复 the faucet may not mint to this recipient (not in staking.faucet_recipients)。该创世配置(chain 20 与 chain 21 均如此)还设置了 staking.faucet_minters(18 个验证者密钥):只有列出的密钥可以签署 mint。水龙头还有每个 epoch 的额度 staking.faucet_budget_per_epoch(chain 20 和 21 上为每个 1,000 区块的 epoch 10,000 RAND);超出额度的 mint 会被以 FaucetBudgetExhausted 拒绝,这是一个状态裁决,一旦离开池后读取为 unknown。
水龙头按节点进程限速:连续八次 mint,之后以每秒一次的速度恢复。超出后调用答复 faucet is rate limited on this node (8 mints back to back, refilling at 1/s); try again shortly。因此,水龙头的洪泛无法在桥的 PauseMints 之前填满池;PauseMints 与其他三种桥治理操作一样,同样不受池的 mempool full 拒绝约束,并在区块中排在最前。
自 chain 14 起,mint 是可打开的:Mint 操作在 cm 和 amount 之外,还携带票据的 pk、time 和 r,准入时会重新计算承诺,并拒绝无法由它们打开的 cm(the mint's commitment does not open to its published note and amount),minter 在域 rand-mint-2 下对全部七个字段签名;在 chain 20(binding_domain: 1)上则在 rand-mint-3 下签名,创世哈希置于最前。因此,水龙头票据的所有者和金额是公开的,正如提现的支付是公开的一样。rand_mint 的参数不变。
rand_estimateFee
参数 [spec],取以下之一:{"kind":"bundle"}、{"kind":"deploy","words":n,"public_words":m}、{"kind":"call","tier":t,"bytes":b,"gas":g},其中 t 取 10、12、14、16、18、20。结果:以单位计的最低费用,为字符串。{"kind":"bundle"} 为 "1000000"。public_words(可选,默认 0)与代码一样按字计费,因此费用为 n + m 个字的部署费用。bytes(可选,默认 0)为调用的证明长度加上其输入信封的长度。
调用如何计价取决于 rand_getLimits 的 gas_metering:
"circuit",即带有自身gas配置段的链,如 chain 20 和 21。gas是调用的证明所声明的 gas 限额,且为必填:缺少时调用答复-32602under the gas section a call estimate needs its gas。答案为1,000,000 + gas_price × gas + byte_price × ⌈bytes / 1024⌉,按链顶当前的价格计算,即rand_getLimits所提供的价格。在 100 和 800 的下限价格下(chain 20 和 21),一次声明 20,479 gas、证明与信封共 1,300,000 字节的调用为"4063900"。价格逐块变动,因此应在临近发送时估算。"header",即在没有该配置段的链上由节点层面的 gas 策略决定。 调用 spec 接受keccak_log_height和sha256_log_height(可选,默认 0,各在 0 至 40 之间,否则-32602),即证明头所声明的哈希表高度,答案为账本的档位下限与该证明头的 gas 下限中的较大者。在gas配置段之下,这两个高度会被接受但不使用。null,两者皆非。 仅按账本的档位费率表:不超过免费额度(2,097,152 + 18,432 字节)时,调用按其档位的费用计;超出部分每 KiB 加收 1,000 单位,不足 1 KiB 按 1 KiB 计。
自 v0.6.8 起,{"kind":"invoke", …, "created_cells": c} 为 RPL-2 的 invoke 计价:包含调用 spec 的所有字段,另加 created_cells(可选,默认 0,至多为 max_writes,否则 -32602),即该状态转换将创建的单元数。每个单元加收该链的 cell_fee(rand_getLimits.program_state)。单元数由调用方计数:向 rand_getProgramCell 读取为零的单元写入非零值,即算一个。在 chain 20 上,上述调用若创建两个单元则为 "24063900"。在没有 program_state 配置段的链上,该 kind 返回 -32602。
费用中有完整的费率表。
池
rand_getTreeInfo
参数 []。结果 { "next_index": 41, "root": "6b1d…c4", "nullifiers": 12 }:叶子数量、当前根、已花费的票据数量。
rand_getCommitments
参数 [from_index] 或 [from_index, limit]。结果:从 from_index 起的一页叶子,最旧的在前,无论 limit 多大,最多 1,000 行。
[ { "index": 40, "cm": "2a9f…07", "height": 37,
"envelope": { "kem_ct": "b41c…", "to_receiver": "77e0…", "to_sender": "0c31…", "body": "9dd2…" } } ]
rand_getScanLeaves
v0.8.0。参数 [from_index] 或 [from_index, limit]。结果:与 rand_getCommitments 相同的一页,顺序相同,同样有 1,000 行上限,但每个信封被裁剪为其头部:scan 为 kem_ct ‖ to_receiver ‖ to_sender,标准 base64 并带填充,钱包封装的每个信封为 1,208 字节,链自身生成的、信封为空的票据则为空。
[ { "index": 40, "cm": "2a9f…07", "height": 37, "scan": "tBzc…" } ]
判断所有权只需要这个头部:对 kem_ct 解封装并打开 to_receiver(或在出站查看密钥下打开 to_sender),只有密钥正确才会成功。v0.8.0 的 rand 钱包先分页读取头部,然后仅用 rand_getCommitments 读取其某个密钥已打开的叶子,以及头部不是 1,208 字节的叶子:在 chain 20 的前 1,000 个叶子上,头部行的 JSON 为 1,718 字节,而完整行为 3,876 字节。过旧而没有该方法的节点答复 -32601,此时钱包照旧分页读取 rand_getCommitments。该方法在公共监听端口上可用,公共端点自 2026-10-12 起转发。
rand_getNullifiers
参数 [from_height] 或 [from_height, limit]。结果:从该高度起发布的每个作废符,同样有 1,000 行上限。一页可能在某个高度的中间截止;请回退到所见的最高高度再分页。
[ { "height": 37, "nullifier": "8c04…d1" }, { "height": 41, "nullifier": "12be…9a" } ]
rand_getCompactBlocks
参数 [from_height, to_height],两者均必填。结果:每个区块一行,最旧的在前,仅包含轻钱包所需的内容:
[ { "height": 192, "hash": "63f6…08", "timestamp_ms": 1788000123456,
"commitments": [],
"transactions": [
{ "hash": "4f2c…e7",
"commitments": [ { "index": 40, "cm": "2a9f…07", "envelope": { "kem_ct": "…", "to_receiver": "…", "to_sender": "…", "body": "…" } } ],
"nullifiers": ["8c04…d1", "5e77…20", "03aa…6f", "e19b…42"] } ] } ]
每个携带捆绑包的交易在此拥有四个票据和四个作废符,即其四个槽位,包括无人能与真实槽位区分的虚设槽位(示例中仅显示第一个承诺行)。自 v0.6.8 起,有些交易在这四个之后拥有更多票据:invoke 为每笔支付拥有一个票据,先是 pays 再是 mints,各带该支付自己的信封,因此收款方通过试解密找到它;在设有桥费用的链上,如 chain 20 和 21,bridge_burn 拥有其金库费用票据,bridge_attest 在其存款之后拥有其费用票据。费用票据的信封为空,不封装给任何人:金库钱包由交易的公开字段重建该票据。
至多 128 个区块每次调用(更宽的范围会被截断),并且除第一个区块(始终完整返回)之外,至多 1,000 个票据;从最后返回的 height 加一处继续。区块级的 commitments 数组在高度 0 处存放创世存款,其余高度为空;Withdraw 与 BridgeAttest 派生出的票据出现在各自的交易之下。范围倒置或缺少边界时返回 -32602。
rand_getAnchor
参数为 [](取链头)或 [height]。结果为 { "height": 192, "root": "6b1d…c4" };若该高度没有记录的锚点,则返回 -32001。只有区块末尾的根才是锚点。节点可以回答旧高度的查询,但一个 bundle 的锚点只有在属于最近 proof_window_blocks 个根之一时才被接受:chain 20 和 21 为 1,024,chain 19 及之前为 256。请基于链头构建。
rand_getWitness
参数为 [index]。结果在超出树末端时为 null,否则为该叶子的 Merkle 路径,自叶子起排列,恰好 32 层,并附带树的当前根:
{ "index": 40, "root": "6b1d…c4", "path": ["0000…00", "f2a1…3b", "…"] }
这是节点提供的开销最大的读取操作(它要重建完整的深度为 32 的树),也是唯一会向节点披露调用方某些信息的请求。一个节点同时最多进行两次树重建,rand_getWitness 与 rand_getWitnesses 合计;等待槽位超过 10 秒的请求会被拒绝,返回 -32000 witness builds are busy on this node; retry shortly。
rand_getWitnesses
参数为 [[index, …]],即 1 到 32 个叶子索引。结果为 { "root": "…", "witnesses": [ { "index": 7, "path": ["…"] }, { "index": 9, "path": null } ] }:即 rand_getWitness 在一次建树中对多个叶子的折叠,因此需要证明多个票据的钱包只需支付一次重建的开销。超出树末端的索引,其对应条目读作 path: null。列表为空或索引多于 32 个时返回 -32602。
查看密钥与披露
rand_importViewingKey
参数为 [viewing_key] 或 [viewing_key, rescan_from_height],密钥为 64 个十六进制字符。结果为 { "imported": true, "rescan_from_height": 0, "viewing_keys": 3 }。节点仅在内存中保存该密钥:每个节点至多 64 个,重启时清除;已持有的密钥再次导入为空操作("imported": false)。导入本身从不扫描;扫描由下一个方法驱动。密钥格式错误时返回 -32602;导入第 65 个密钥时返回 -32000。
这三个查看密钥方法只应答环回调用方,并以 -32000 拒绝其他任何人,除非节点以 --rpc-viewing-open 运行且前面有负责认证的组件。rand_removeViewingKey([viewing_key] → { "removed": bool, "viewing_keys": n })释放一个槽位并将密钥清零。注册表以密钥的单向标识 blake3("rand-viewing-registry-id-1" ‖ nk) 为键,而不是以密钥本身为键,因此导入时的那一份是唯一的长期副本,移除时会将其抹除。请求本身的 JSON 文本以及试解密产生的临时副本不会被抹除。
rand_getViewingNotes
参数为 [viewing_key] 或 [viewing_key, from_index, limit](limit 默认值与最大值均为 1,000)。每次调用先将该密钥的扫描推进至多 10,000 个叶子,然后返回该页:
{ "scanned_index": 10041, "next_index": 10041, "complete": true,
"notes": [
{ "index": 40, "cm": "2a9f…07", "height": 37, "role": "received",
"note": { "pk": "…", "from": "…", "amount": "1500000000", "asset": 0, "time": 5, "memo": "coffee" },
"nullifier": "8c04…d1", "spent": false },
{ "index": 43, "cm": "b310…88", "height": 39, "role": "sent",
"note": { "pk": "…", "from": "…", "amount": "25000000", "asset": 0, "time": 9, "memo": null },
"nullifier": null, "spent": null } ] }
role 为 received(信封以接收方身份打开,且票据指向该密钥的 pk)或 sent(通过出站查看密钥打开)。票据的 memo 是发送方加密的备注,为至多 510 字节的 UTF-8 文本;若没有备注,或其字段打开后格式错误,则为 null;格式错误的备注绝不会使收款方丢失该票据。备注是任何人都可以写的文本:请将其视为不可信内容显示。对于此节点未导入的密钥,返回 -32001。
rand_checkTransaction
参数为 [hash, key],key 是 64 个十六进制字符的单笔交易 TxKey。哈希未知时结果为 null,否则为该密钥所披露的内容:
{ "tx": "4f2c…e7", "height": 192,
"disclosed": [ { "output": "bundle:0", "cm": "2a9f…07", "index": 40,
"note": { "pk": "…", "from": "…", "amount": "1500000000", "asset": 0, "time": 5, "memo": "invoice 7" } } ] }
无状态:密钥随调用结束而丢弃。output 为 bundle:0 … bundle:3(对应 bundle 的四个输出槽位,槽位 0–1 为私有资产输出,槽位 2–3 为 RAND 输出,含占位项),deposit(桥接证明的存款信封),token_mint(TokenMint 的票据),initial_mint(RegisterToken 的初始铸造),mint:0(水龙头铸造的唯一信封),或(v0.6.8)payout:0 … payout:3(invoke 所支付的票据,按其在转换中的位置编号,先 pays 后 mints);asset_bundle:* 已随第二个 bundle 一并移除。在收取桥接费用的链上,deposit 打开的是净存款,即总额减去费用。所披露的 note 带有其 asset:使用发送方封装时所用的密钥进行此调用,是 RPC 唯一会揭示一笔转账移动了哪种资产的地方。它同样带有 memo,与 rand_getViewingNotes 一致:能打开票据的密钥也能打开备注,二者出自同一个封装体。错误的密钥返回 { "disclosed": [] },与不披露任何内容的交易无从区分。提现和创世分配的信封不会被尝试:它们在节点内部以立即丢弃的密钥封装,因此不存在对应的 TxKey。水龙头铸造的信封会被尝试:其接收方通过信封的 KEM 部分恢复密钥(rand tx-key)。
交易
rand_getTransaction
参数为 [hash]。在提交之前结果为 null,提交之后为:
{
"height": 192, "index": 0, "block_hash": "63f6…08",
"tx": {
"hash": "4f2c…e7", "chain_id": 21,
"bundle": { "anchor": "6b1d…c4",
"nullifiers": ["8c04…d1", "5e77…20", "03aa…6f", "e19b…42"],
"commitments": ["2a9f…07", "b310…88", "77c1…0e", "5d20…b3"],
"fee": "1000000", "burn_a": "0", "burn_r": "0", "burn_asset": 0, "time": 5,
"proof_len": 1490435, "envelope_len": [1860, 1860, 1860, 1860],
"auth_commit": "9217…ee9e", "auth_proof_bytes": 1361161 },
"action": { "kind": "none" }
}
}
对于不含 bundle 的操作,bundle 为 null。证明和信封仅报告长度。在 chain 20 和 21 上,每个槽位的 envelope_len 为 1,860,其创世将票据信封固定为该大小(见 rand_getLimits 中的 envelope_bytes);在 chain 14 至 17 上为 1,348。auth_commit 与 auth_proof_bytes 属于拆分授权(自 chain 17 起):前者是公开承诺 c = H(AUTH, nk, salt),bundle 证明与授权证明都会公布它,后者是授权证明的长度。在没有 hc_auth 的链上,二者分别为零和 0。
bundle 是隐藏资产 bundle(自 chain 14 起):四个输入槽位和四个输出槽位,因此始终有四个 nullifiers、四个 commitments 和四个 envelope_len,含占位项。每笔交易至多携带一个;不存在第二个 bundle。它没有 asset 字段:槽位 0–1 承载私有资产,槽位 2–3 承载 RAND,公开信息中没有任何内容表明槽位 0–1 移动了哪种资产。RAND 的转账与任何 RPL 代币的转账都是 "kind": "none",且 burn_a、burn_r 和 burn_asset 全为 0,形态完全相同,字段逐一一致。不存在 token_transfer 这一类型。这三个销毁字段是 bundle 对价值离开资金池所作的唯一公开声明:
burn_a/burn_asset:被销毁的私有资产数量,以及是哪种资产。在token_burn或bridge_burn上非零,此时它们等于该操作的amount与asset;在inflow为deposit或burn的invoke上也非零。burn_r:被销毁的 RAND。在bond(等于其amount)、register_aggregator,以及将 RAND 存入程序金库的invoke上非零。fee:RAND 费用,始终来自槽位 2–3。
各操作的呈现形式(每个 amount、relayer_fee 和 initial_amount 均为十进制字符串;代币的数量以其自身单位计,而非 RAND 的单位):
| 类型 | 字段 |
|---|---|
none | — |
mint | cm、amount、minter(验证者的 base58) |
deploy | program、words、public_words_len |
call | program、proof_len、input_envelope_len(调用不携带时为 null) |
bond | validator、amount、registered |
unbond | validator、amount、nonce |
withdraw | validator、amount、nonce、time |
bridge_attest | attestation_len、recipient、asset、asset_index、amount、time、r、commitment、pq_signers(共同签名的守护者在 pq_guardians 中的索引;2,420 字节的签名不予渲染)。守护者集合轮换时,asset_index、amount 和 commitment 为 null。r 为派生值,即对守护者所签摘要 mu 计算的 blake3("rand-deposit-r-1" ‖ mu)。自 v0.6.8 起另有 deposit_amount(存款人的票据:amount,即守护者所签的总额,减去桥接费用)和 fee_note({ amount, asset, time, r, commitment },即国库的票据,不含所有者;无桥接费用时为 null);commitment 是净存款的叶子 |
bridge_burn | asset、amount、relayer_fee、to_chain、token(被赎回的底层资产)、to。一个捆绑包承载整笔销毁:其 burn_asset 和 burn_a 即该操作的 asset 和 amount。自 v0.6.8 起另有 release_amount(已签名主体所释放的数额,即 amount 减去桥接费用)和 fee_note,与 attest 相同 |
register_token | name、symbol、decimals、authority("none"、"key"、"bridge" 或 "program")、index、initial_amount、initial({ amount, recipient, time, r } 或 null) |
token_mint | asset、amount、recipient、time、r、nonce |
set_authority | asset、nonce、new_authority(base58;放弃权限时为 null) |
token_burn | asset、amount;捆绑包的 burn_asset / burn_a 重复这两项 |
pause_mints | nonce;无捆绑包、无费用,由创世暂停密钥签名 |
unpause_mints | nonce、pq_signers;无捆绑包、无费用 |
register_bridged_token | name、symbol、salt、chain、token、decimals(首个底层资产的源链小数位数)、nonce、asset_id、pq_signers |
list_backing | token_index、chain、token、decimals、nonce、pq_signers |
rotate_pq_guardians | new_pq_guardians、nonce(已消耗的 rotation_nonce)、pq_signers(轮换前 PQ 集合中的索引);无捆绑包、无费用,仅限桥接 rules_v2 链 |
rotate_pause_key | new_pause_key、nonce、pq_signers;同上 |
rotate_pq_guardians_v2、rotate_pause_key_v2 | v0.6.8:v1 的字段,PQ 形式另加 possession_signatures(一个计数)。无捆绑包、无费用;在创世 bridge.rotation 设置了 needs_possession 的链上为必需,链 20 如此,链 21 亦然。轮换在 delay_secs 之后生效(两条链均为 86,400 s) |
cancel_rotation | v0.6.8:rotation_kind("pq_guardians" 或 "pause_key")、nonce;由当前暂停密钥签名,撤销一次待生效的轮换 |
admit_validator | v0.6.8:candidate(地址)、candidate_key(十六进制)、voters(地址)。无捆绑包、无费用:验证者集合投票允许一个新密钥注册,仅限设有 staking.admission_by_vote 的链,链 20 和链 21 即是 |
slash_equivocation | v0.6.8:offender、view、first 和 second({ hash, height });仅限设有 staking.slashing 的链,链 20 和链 21 均未设置 |
invoke | v0.6.8,RPL-2:调用的字段(program、proof_len、input_envelope_len)及其 transition(见下文)。仅限有 program_state 部分的链,链 20 和链 21 即是 |
perp_deposit、perp_order、perp_cancel、perp_withdraw、perp_oracle、perp_state_proof | v0.8.0,RPL-3(链 21,其创世含有 perps 部分;没有该部分时以 UnsupportedAction 拒绝)。perp_deposit:trading_key、account(捆绑包的 burn_r,或 burn_asset 的 burn_a,即为抵押品——链 21 上为 zUSD)。perp_order:account 和嵌套的 body(nonce、market、side 0 买 / 1 卖、kind 0 限价 / 1 市价、tif 0 GTC / 1 IOC、reduce_only、price、size)。perp_cancel:account、nonce、target。perp_withdraw:account、nonce、amount、recipient、time。perp_oracle:validator、prices({ market, price })、nonce。perp_state_proof:from_height、to_height、new_root、payouts({ request, amount })、fees、proof_bytes。订单、撤单、提款和预言机价格均经签名,无捆绑包、无费用;状态证明不签名,因此任何人都可以生成证明。每个字段按设计均为公开:引擎的输入正是其证明者所重放的内容 |
create_multisig、multisig_deposit、multisig_pay、multisig_rotate | v0.8.0,多签账户(链 21,其创世含有 multisig 部分;没有该部分时以 UnsupportedAction("multisig") 拒绝)。create_multisig:salt、threshold、signer_count(由捆绑包携带;其 burn_r 为 1 RAND 的 create_fee 加上首次存入的款项)。multisig_deposit:account(捆绑包的销毁即为存款)。multisig_pay:account、nonce、time、pays(每张票据的 cm,与 invoke 相同)、signers(已签名者的索引);无捆绑包,从该账户的 RAND 行支付 0.001 RAND 的基础费用。multisig_rotate:account、nonce、threshold、signer_count、signed_by;无捆绑包、无费用。区块头在 public_notes 中携带 multisig_pay 的票据 |
set_rand_price | v0.8.0:price_micros_per_rand(十进制字符串)、nonce、voters(地址,按列出顺序)。验证者集合为美元计价的封存补贴所投的 RAND/USD 价格票,无捆绑包、无费用;仅限设有 fees.usd_subsidy 的链,链 21 未设置,因此在该链上以 UnsupportedAction 拒绝 |
register_aggregator、unbond_aggregator、withdraw_aggregator、slash_aggregator、aggregate | 其公开字段;仅限聚合链 |
claim_vested、revoke_vesting、bond_vested、unbond_vested | entry(十六进制)、amount(撤销时为 unvested)、nonce;领取或撤销时另有 time;质押时另有 validator 和 registers;自 v0.6.8 起撤销时另有 signers(其签名者在该条目 revokers 中的位置)。无捆绑包;仅限创世含有 vesting 部分的链,链 20 和链 21 均无 |
代币的注册和铸造是公开的,桥接存款亦然:已铸造票据的每个字都在该操作之中(其 from 是链上固定的 MINT_FROM),因此接收方无需任何解密,即可凭这些字段重建该票据。类型字符串 bridge_attest、token_mint、register_token 和 invoke 是钱包扫描所依据的键,并由测试固定。
链 20 高度 3,079 处的一笔 invoke(链 20 的示例程序尚未在链 21 上重新部署),它读取了一个单元,删除了它,并从金库中支付出两张票据:
{ "kind": "invoke", "program": "aaaf…4b21", "proof_len": 1433874, "input_envelope_len": null,
"transition": {
"reads": [{ "key": "0100…fa98", "value": "0000000004000000…00000000" }],
"writes": [{ "key": "0100…fa98", "value": "0000000000000000000000000000000000000000000000000000000000000000" }],
"inflow": "none",
"pays": [{ "asset": 0, "amount": "1000000000", "recipient": "rand1…", "time": 3027, "r": "87e6…9a67", "cm": "2555…6487" },
{ "asset": 4, "amount": "2000000000", "recipient": "rand1…", "time": 3027, "r": "b833…f390", "cm": "2b70…f204" }],
"mints": [] } }
这一切按设计均为公开。reads 是程序读取的单元及其读到的值:证明基于它们生成,若它们不再成立,账本便拒绝该交易。writes 是程序写入的单元;写入值为 64 个零即删除该单元。单元的键或值是一个 Word8。流入的部分来自捆绑包:burn_r 是存入程序金库的 RAND,burn_asset 的 burn_a 是 inflow 所指明的代币,即 deposit(存入金库)或 burn(程序自身的代币);burn_a 为 0 时为 none。流出的部分是链计算出的票据,每笔支付一张:先是从金库支付的 pays,然后是铸造权限属于该程序的代币的 mints。每张票据的每个字都以 token_mint 的字段名列于此;time 来自捆绑包,cm 是链所追加的叶子,票据的 from 是链上固定的 PROGRAM_FROM。程序的八个输出字位于回执中,与调用相同。
任何转账回复都不携带发送方、接收方、nonce、数额或资产:已存储的转账中不存在这类字段。
rand_getRawTransaction
参数 [hash]。结果:完整的已提交交易,为 bincode 十六进制,含证明字节——这是聚合者所需要的,而 rand_getTransaction 从不渲染。
程序与回执
rand_getProgram
参数 [program_id]。结果为 null 或 { "id", "base_pc", "words_len", "code_hash", "deployed_at", "public_words_len", "public_digest" }。没有 deployer 字段:部署由捆绑包支付。public_words_len 是程序部署时公开输入的长度(没有则为 0);public_digest 是其摘要,即每次调用的证明所校验的值,没有则为 null。
rand_getProgramCode
参数 [program_id]。结果为 null 或 { "base_pc": 0, "words": [ … ] }。
rand_getProgramPublic
参数 [program_id]。结果:程序部署时的公开字,为一个十六进制字符串,每个字以其 4 个小端字节表示(每字 8 个十六进制数字):[1, 2, 0xdeadbeef] 即 "0100000002000000efbeadde"。部署时没有公开输入的程序返回 "",没有任何程序拥有的 id 返回 null。为调用生成证明的钱包把这些字传给证明者;账本则依据程序的 public_digest 校验证明的承诺。
rand_getProgramCell
v0.6.8,RPL-2。参数 [program_id, key],其中键是以 64 个十六进制数字表示的 Word8(可带或不带 0x)。结果为 { "key": "<64 hex>", "value": "<64 hex>" }。程序从未写入的单元,或写入了零的单元(这会删除它),读取为 64 个零,这是“不存在”的唯一编码;无人部署的程序的任何键同样如此,因为不检查程序是否存在。在没有 program_state 部分的链上返回 { "enabled": false }。单元按设计为公开:钱包正是读取它来构造 invoke 的 reads。
rand_getProgramCells
v0.6.8。参数 [program_id, { "after": "<64 hex>" | null, "limit": n }],对象可省略。结果为 { "cells": [{ "key", "value" }, …], "next": "<64 hex>" | null }:程序的单元按键的顺序排列(对八个字做无符号比较),从 after 之后开始,至多 limit 个(限定在 1 到 1,000 之间)。还有后续内容时,next 是所返回的最后一个键;将它作为 after 传回。最后一页上它为 null。没有任何单元的程序返回 { "cells": [], "next": null };没有该部分时返回 { "enabled": false }。
rand_getProgramVault
v0.6.8。参数 [program_id]。结果 [{ "asset": 0, "amount": "123" }, …],按资产索引升序排列(0 为 RAND,其余索引均为代币注册表中的索引),金额为以该资产自身单位表示的十进制字符串。余额为零的行不存在,因此空金库以及无人部署的程序均为 []。没有该配置段时返回 { "enabled": false }。价值通过 invoke 的 bundle 进入金库(burn_r,以及 inflow 为 deposit 时 burn_asset 的 burn_a),并以该转换的 pays 所指明的 note 形式流出。
rand_getPerps
v0.8.0,RPL-3(永续合约)。参数 []。结果:交易所截至链头的公开状态;在没有 perps 配置段的链上,则仅返回 { "enabled": false },不含其他内容。在链 21 上(2026-10-12,尚无任何账户时):
{ "enabled": true,
"collateral_asset": 1, "max_tier": 18, "max_window_blocks": 64,
"max_block_inputs": 24, "min_deposit": "100000000",
"engine_hc": "f286a61171e274278ec8d18d7853e5f36799ed8dc5a3e31e0077ad89ef1d1573",
"genesis_root": "da0e3a53d93e50ec03fa40c6d2bd3dad8b9c7b4f542175e86a1dea567cbb9846",
"markets": [{ "id": 0, "symbol": "BTC-PERP", "lot": 100000, "tick": 100000000,
"max_leverage": 20, "maintenance_bps": 250, "taker_fee_bps": 5, "maker_fee_bps": 2 }],
"proved_root": "…", "proved_height": 0, "head_height": 2178,
"pending_heights": [1, 2, …, 2178],
"medians": [{ "market": 0, "price": "0" }],
"accounts": 0, "pending_withdrawals": 0 }
engine_hc 是状态证明所运行的撮合引擎的摘要,genesis_root 是切换时得出的状态根,三个承诺均为 64 个小写十六进制字符。pending_heights 是尚未被任何状态证明覆盖的已关闭区块高度,按升序排列:即下一个证明所取的窗口。中位数是以抵押品单位表示的十进制字符串(zUSD,八位小数:100,000,000 的 tick 即一美元一个 BTC),当上一次收盘时没有足够的新鲜预言机质押量为价格提供法定人数支持时,为 "0"。永续合约证明者和交易场所会轮询此接口。适用于公共监听端口和公共端点。
rand_getPerpAccount
v0.8.0。参数 [account],即 64 位十六进制的 id。结果为一个交易账户 { "account", "trading_key" (the Dilithium2 public key, hex), "nonce_high", "used" (the 64-bit nonce bitmap, a decimal string), "withdrawals": [{ "request", "amount", "height" }] }:钱包的下一个 nonce 为 nonce_high + 1,withdrawals 是按请求顺序排列的待处理请求,并附有各自被接纳时的区块高度。账户的抵押品和仓位属于引擎状态,而非账本状态,不对外提供。对于交易所不持有的 id,以及在没有该配置段的链上,返回 null。
rand_getPerpAccounts
v0.8.0。参数 [{ "after": "<64 hex>" | null, "limit": n }],该对象可选。结果 { "accounts": [<如 rand_getPerpAccount>, …], "next": "<64 hex>" | null },账户按 id 顺序,从 after 之后开始,至多 limit 个(上限为 1,000)。交易所至多持有 15 个账户,因此一页即为全部;没有该配置段时为 { "accounts": [], "next": null }。
rand_getPerpInputs
v0.8.0。参数 [height]。结果 { "height", "digest", "words": [<u32>, …] },即已关闭区块的永续合约输入字(证明者据此运行引擎),以及账本为该高度记录的摘要;证明者会拒绝摘要与自身不一致的窗口。对于本节点没有对应行的高度返回 null:状态证明已覆盖该高度(该行随证明一同被清除)、该高度高于链头,或该链没有 perps 配置段。
rand_getLimits
参数 []。结果:钱包根据链的创世配置构建交易所需的内容:五项调用限制、note 信封大小、v0.6 开关、认证 guest、gas 条款,自 v0.6.8 起还有 audit-v6 创世字段和程序状态限制,自 v0.8.0 起还有多签认证 guest、费用规则、永续合约限制和多签限制。在链 21 上(2026-10-12):
{ "max_program_words": 65535, "max_proof_bytes": 6291456, "max_block_bytes": 19922944,
"max_call_envelope_bytes": 65536, "max_program_public_words": 32768,
"envelope_bytes": 1860, "hardening_v6": true,
"hc_auth": "1e4e347f44cf86750b30a9a4bdf9ec9256efe353d4ff8017451eca7d195639c1",
"hc_auth_multisig": "9705f8e2f1bc8561848b29cb8efd57c37e3e39788fa58a5f03304d8019668247",
"gas_metering": "circuit", "gas_price": "100", "byte_price": "800",
"bundle_gas_limit": 20479, "adjust_bps": 1250,
"max_gas_price": "10000", "max_byte_price": "80000", "byte_load": "paying",
"admission_by_vote": true, "testnet": true, "slashing": null, "binding_domain": 1,
"proof_window_blocks": 1024,
"program_state": { "cell_fee": "10000000", "max_reads": 8, "max_writes": 8, "max_payouts": 4 },
"fee_rules": { "burn_base": true, "burn_floor": true, "subsidy_net_of_fees": false,
"proposer_share_bps": null, "prove_base": null, "usd_subsidy": null },
"perps": { "collateral_asset": 1, "max_tier": 18, "max_window_blocks": 64,
"max_payouts": 8, "max_block_inputs": 24, "min_deposit": "100000000" },
"multisig": { "create_fee": "1000000000", "max_signers": 10, "max_payouts": 4 } }
没有这五项限制字段的创世配置(链 12)取 4096、2097152、4194304、18432 和 0。max_proof_bytes 在链 13 至 15 上为 8,388,608,在链 16 至 20 上为 4,194,304;链 21 将其提高到 6,291,456(6 MiB),以容纳多签认证证明,并将 max_block_bytes 从 20,971,520 降至 19,922,944(19 MiB)。
| 字段 | 含义 |
|---|---|
envelope_bytes | 当创世文件将每个创建票据的信封固定为恰好该长度(即携带备注的格式)时为 1860;创世文件没有此字段时为 null(链 14 至 17),此时钱包封装不含备注的 1,348 字节信封。不存在其他取值 |
hardening_v6 | 当创世文件运行 v0.6 有效性规则时为 true。此时钱包证明一次调用,所依据的是程序的公开输入再加上交易的调用绑定,而不是仅依据公开输入:先选定费用捆绑包中的票据,再证明调用,最后生成捆绑包。带此标志的链拒绝旧证明,不带此标志的链拒绝新证明 |
hc_auth | 创世文件固定的认证客户程序,十六进制,或 null。已设置时,hc_bundle 为捆绑包客户程序 v3,每个捆绑包都携带 auth_commit 和一个认证证明:钱包向捆绑包客户程序提供 nk 和一个新的盐,并针对花费密钥证明认证客户程序 |
hc_auth_multisig | v0.8.0:创世文件固定的第二个认证客户程序,即私密多重签名策略(由 Dilithium2 密钥组成的 M-of-N,在层级 18 上证明),十六进制,或 null。已设置时(如链 21),该链还接受该客户程序形态的认证证明,并对照此摘要进行检查;钱包仅在其已设置时才提供 rand multisig-private。在没有该字段的链上,多重签名形态的认证证明会被以 InvalidAuthProof 拒绝 |
gas_metering | 创世文件含 gas 部分的链上为 "circuit"(电路内计量);没有该部分、而节点运行自己的 gas 策略(--gas-price、--byte-price)时为 "header";两者皆无时为 null |
gas_price, byte_price | 每单位 gas 的价格,以及每 KiB 调用证明与输入信封的价格,均为十进制字符串。在 gas 部分之下,它们是共识状态,在每个节点上都相同:带 gas.dynamic 时(如链 20 和 21),为链顶当前的价格,按区块的充满程度逐块变动,永不低于创世下限(100 和 800),也永不高于上限;不带时为该部分的固定价格。没有该部分时,它们是此节点自己的策略,两个节点的回答可能不同 |
bundle_gas_limit | 每个捆绑包证明必须声明的固定 gas,来自创世文件的 gas 部分;没有该部分时为 null |
adjust_bps | 动态控制器单个区块内价格的最大变动幅度,以基点计;没有 gas.dynamic 的链上为 null |
max_gas_price, max_byte_price | v0.6.8:控制器永不将价格抬升到其上的上限,十进制字符串;链 20 和 21 上为 "10000" 和 "80000",创世文件未设置时为 null(链 18 和 19) |
byte_load | v0.6.8:当只有调用的证明与输入信封会推动 byte_price 时为 "paying",因此一个由转账组成的区块不会使其变动,如链 20 和 21;每笔交易的字节都计入时为 null(链 18 和 19) |
admission_by_vote | v0.6.8:登记新验证者密钥的质押是否需要先经验证者集合投票(rand_getAdmitted);链 20 和 21 上为 true |
testnet | v0.6.8:创世文件的 testnet 标记,它允许水龙头与桥接部分并存;链 20 和 21 上为 true,此前的每条链上为 false |
slashing | v0.6.8:{ "equivocation_bps", "jail_epochs" },即领导者双重提议所付出的代价,或 null;链 20 和 21 上为 null |
binding_domain | v0.6.8:0 表示交易的绑定与每条已签名的操作消息只绑定链 id(链 14 至 19),1 表示它们还带有创世哈希,因此为一条链生成的证明或签名在其他任何链上都无法通过验证(链 20 和 21)。钱包依据链 id 决定证明哪种形式,绝不依据此回复:v0.6.8 的 rand 钱包对链 id 14 至 19 使用链 id 形式,对其他每个 id 使用与创世绑定的形式,并仅为提前拒绝而读取此字段。早于 v0.6.8 的钱包无法在链 20 上发送交易,早于 v0.8.0 的钱包无法在链 21 上发送交易(约束集 9) |
proof_window_blocks | v0.6.8:捆绑包的锚点至多可以多旧、其 time 至多可以落后高度多少,以区块计,两者共用一个窗口;链 20 和 21 上为 1024,至链 19 为止的各链上为 null(256)。证明者较慢或由他人代理的钱包据此判断一次证明可以花多长时间 |
program_state | v0.6.8,RPL-2:创世文件的 program_state 部分及其 invoke 限制,或 null,此时每个 invoke 都被拒绝,也无法注册任何程序代币。cell_fee 是 invoke 的费用下限为其创建的每个单元所增加的 RAND 单位数(十进制字符串),即向读出为零的单元写入非零值;重写、删除或写入零不收费。max_reads、max_writes 和 max_payouts(支付与铸造合计)是硬性上限。实际上首先起约束作用的是分段规则:转换的上下文字数(11 + 每次读或写 16 + 每笔支付 3)必须能与程序的公开输入和 8 个绑定字一并容纳,而不使 zkVM 的公开表增长;对于没有公开输入的程序,该表为 128 行,留下 119 个上下文字 |
fee_rules | v0.8.0:创世文件的 fees 部分,或在没有该部分的链上为 null(至链 20 为止)。在链 21 上,burn_base 和 burn_floor 为 true:捆绑包全部已结算的下限(0.001 RAND 的基础费;部署的基础费加按字计的部分;调用按层级精确计算的 gas 与字节部分;桥接销毁的费用;invoke 的单元费)被销毁,而不是支付给提议者,提议者只保留小费,rand_getSupply.base_fees_burned 对其计数。发送者所付的费用不变。subsidy_net_of_fees、proposer_share_bps、prove_base 和 usd_subsidy 属于聚合型链,在链 21 上为 false 或 null;prove_base 一旦设置,会抬高每个捆绑包的下限,rand_estimateFee 已将其计入 |
perps | v0.8.0,RPL-3:创世文件 perps 部分的限制,或在没有该部分的链上为 null,此时每个永续合约操作都被拒绝。在链 21 上,抵押品为资产 1(zUSD),状态证明上限为层级 18、至多覆盖 64 个区块,一个区块至多记录 24 个永续合约输入,一个状态证明至多支付 8 笔提款,一笔存款至少为 1 zUSD(以其八位小数单位计为 "100000000")。市场列表见 rand_getPerps |
multisig | v0.8.0:创世文件 multisig 部分的限制,或在没有该部分的链上为 null,此时全部四种多重签名操作都被拒绝。在链 21 上:create_fee 为 "1000000000"(1 RAND,经由创建它的捆绑包销毁),每个账户至多 10 个签名者,每笔支付至多 4 个支付票据 |
早于某字段的节点在回答中不含该字段。此回复中的任何内容都未经认证,因此钱包不会仅凭节点的一面之词采信 envelope_bytes:无论节点如何回答,rand 钱包在链 id 14 至 17 上都封装旧版信封,其他客户端也应如此。
rand_getReceipt
参数 [tx_hash]。结果在调用被提交之前为 null,之后为 { "tx", "program", "tier": 14, "outputs": [1, 0, 25, 0, 0, 0, 0, 0], "height": 17, "index": 0, "h_in": "9c0e…7f", "h_pub": null }。没有 effect 字段。h_pub 是程序部署时公开输入的摘要,调用的证明即对照它检查,对于没有公开输入的程序为 null。invoke(v0.6.8)有一份与调用相同的回执,rand_getReceipts 和 receipts 主题原样携带它。
rand_getReceipts
参数 [program_id, from_height, to_height, limit?]。结果 { "receipts": [ … ], "next_height": 2051 }:program_id 中满足 from_height <= height <= to_height 的回执,先按高度、再按索引排序,每一项都恰好是 rand_getReceipt 的对象。limit 默认且上限为 256,并且从不拆分同一高度:一页一旦容纳了 limit 份回执,仍会提供该高度的其余回执。next_height 是第一个未提供的高度,当 to_height 结束了该页时为 null。to_height 低于 from_height 时返回 -32602。
rand_getCallEnvelope
参数 [tx_hash]。结果为 null,或十六进制的 { "tx", "h_in", "kem_ct", "to_sender", "to_auditor", "body" },即该调用已封装的输入记录,原样提供;节点不持有可以打开它的密钥。当调用未发布任何信封(--no-envelope)、该交易不是调用,或没有回执时为 null。
质押与供应量
rand_getValidators
参数 []。结果:登记簿中每个条目一行,按地址顺序排列,金额为十进制字符串:
[{ "address": "…", "stake": "1000000000000",
"pending": [{ "release_epoch": 41, "amount": "5000000000" }],
"rewards": "4000000", "payout": "rand1…", "nonce": 3, "active": true, "jailed_until": null }]
jailed_until(v0.6.8)是被罚没的密钥可以再次进入集合的第一个纪元(18446744073709551615 表示永久),未被监禁时为 null。链 20 和 21 没有 staking.slashing,因此在那里它始终为 null。
rand_getAdmitted
v0.6.8。参数 []。结果 { "admission_by_vote": true, "max": 256, "admitted": ["<address>", …] }:验证者集合已通过 AdmitValidator 投票接纳、但尚未注册的密钥,按地址顺序排列。在创世配置设置了 staking.admission_by_vote 的链上(链 20 如此,链 21 亦如此),注册新密钥的 Bond 必须位于其中。max 是账本一次最多容纳的数量。在没有该标志的链上,admission_by_vote 为 false,列表恒为空,注册无需投票。链 20 于 2026-10-01 返回 "admitted": []。
rand_getMultisig
v0.8.0。参数 [id],即账户的 64 位十六进制 id。结果 { "enabled": true, "id", "signers": ["<Dilithium2 public key, hex>", …], "threshold", "nonce", "vault": [{ "asset", "amount" }, …] }:signers 按账户内的顺序排列(签名按位置指明其签名者),nonce 是支付与轮换共用的唯一计数器,vault 按资产升序排列(0 为 RAND,其余每个索引属于代币注册表),金额为以资产自身单位表示的十进制字符串,余额为零的资产不列出。对于登记簿中不存在的 id,返回 null;在没有 multisig 部分的链上,返回 { "enabled": false }。在链 21 上,创世时唯一的账户是基金会国库 d5fd188308af5322b234b199ae6193fa686ae1453e6af39720638b1f441b1958:3 个签名者中需 2 个,持有 100,000 RAND。自 2026-10-12 起由公共端点转发。
rand_getRandPrice
v0.8.0。参数 []。结果 { "price_micros_per_rand", "set_at_height", "nonce", "fresh", "max_age_blocks" },即验证者集合为美元计价的封存补贴所投票确定的 RAND/USD 价格(每 RAND 的微美元数,十进制字符串;fresh 按下一个区块判定);若链的创世配置没有 fees.usd_subsidy,则为 null,链 21 即是如此:它在该处返回 null,且 SetRandPrice(tag 44)会被拒绝。自 2026-10-12 起由公共端点转发。
rand_getEpoch
参数 []。结果 { "epoch": 41, "epoch_blocks": 1000, "next_set": ["…", "…"] };next_set 是一个预测值。
rand_getSupply
参数 []。结果:
{ "height": 1998,
"genesis_deposited": "…", "genesis_staked": "…", "faucet_minted": "…",
"faucet_epoch": "…", "faucet_minted_in_epoch": "…",
"withdraw_deposited": "…", "fees_paid": "…", "burned": "…",
"subsidised": "…", "sealed_blocks": "…", "aggregator_bonds": "…", "slashed": "…",
"registration_fees_burned": "…", "base_fees_burned": "…",
"vesting_issued": "…", "vesting_released": "…", "vesting_in_register": "…", "vesting_locked": "…",
"program_rand_out": "…", "program_rand_held": "…",
"perps_rand_out": "…", "perps_rand_held": "…",
"multisig_issued": "…", "multisig_rand_in": "…", "multisig_rand_out": "…",
"multisig_base_out": "…", "multisig_rand_held": "…",
"pool_value": "…", "register_total": "…", "total_supply": "…", "invariant_holds": true }
subsidised、sealed_blocks、aggregator_bonds 和 slashed 仅在聚合链上变动。faucet_epoch 和 faucet_minted_in_epoch 是水龙头按纪元计的计数器,对照 staking.faucet_budget_per_epoch(自链 20 起为共识状态)。四个 vesting_* 字段是创世归属(vesting)的计数器,在没有 vesting 部分的链上均为 "0",链 20 和链 21 即是如此。program_rand_out 和 program_rand_held(v0.6.8,RPL-2;没有 program_state 部分时为 "0")分别是调用(invoke)从程序金库中以 note 形式支付出去的 RAND(池侧,计入 pool_value),以及金库仍持有的 RAND(登记簿侧,计入 total_supply);它是通过调用的 burn_r 进入的,因此在池侧计入 burned。registration_fees_burned 是在创世配置 tokens.burn_registration_fee 下被销毁的代币注册费之和,链 20 和链 21 均设置了该项;invariant_holds 将它与 slashed 一并从链所发行的数量中扣除。Supply 解释了该恒等式。
有三组字段属于 v0.8.0,在创世配置缺少相应部分的链上均为 "0"。base_fees_burned 是在 fees.burn_base / fees.burn_floor 下被销毁的每个打包交易(bundle)的底价总和(链 21):在池侧计入 burned,并与 registration_fees_burned 一同从恒等式右侧扣除;在这些标志下,fees_paid 只统计提议者保留的小费。perps_rand_out 和 perps_rand_held 分别是永续合约状态证明以 note 形式从交易所支付出去的 RAND,以及交易所仍持有的 RAND;在链 21 上,抵押品是 zUSD,即一种代币,其供应量在进出时不变动,因此两者在此处均保持为 "0"。multisig_issued 是创世时为多重签名账户注入的数量(链 21 上为 100,000 RAND,即基金会国库,与 genesis_staked 并列),multisig_rand_in 是创建或存入所投入的每一笔 bundle 销毁,multisig_rand_out 是 RAND 支付 note,multisig_base_out 是支付时计入提议者奖励的 bundle 底价,multisig_rand_held 是这些账户仍持有的数量,计入 total_supply。invariant_holds 涵盖以上全部。在链 21 的创世切割点,genesis_staked 为 26,000 RAND,genesis_deposited 为 3,938.879078887 RAND,multisig_issued 为 100,000 RAND:在水龙头铸造之前共计 129,938.879078887 RAND。
rand_getEmission
参数 []。结果 { "inflation": "0", "subsidy": null, "faucet": true }。inflation 固定为 "0"。subsidy 是区块聚合的补贴计划(current、base、halving_blocks、sealed_blocks、next_halving_at),在没有 aggregation 部分的链上为 null,链 20 和链 21 即是如此。faucet 与 rand_status 一致。
Bridge
四个方法在任何链上都会应答;在没有 bridge 部分的链上,状态为 { "enabled": false },注册表为 []。链 21 的创世配置包含该部分,承接自链 20 在高度 814,702 处的状态:守护者集合 1(guardian_set_index 为 1),含八名守护者、八名 PQ 守护者、一把暂停密钥,创世时 burn_sequence 为 13,另有重放下限(来源链 2、3 和 4 的 min_inbound_sequence 为 3,来源链 5 为 7)、桥的 rules_v2(在所有抵押资产合计范围内,每 24 小时窗口的全局铸造上限为 4,000 zUSD),以及 v0.6.8 新增的两组:rotation(PQ 守护者或暂停密钥的轮换需要新密钥的持有证明,并在提交后 86,400 秒生效)和 fees(每笔存入的 10 bps 与每笔销毁的 10 bps,在 Rand 上以 zUSD note 的形式存入国库地址)。链 19 的 burn_sequence 为 8,下限为 1 和 4,且两组均无。其 tokens 部分含 1 RAND 的 registration_fee(被销毁)、按抵押资产计的 mint_cap_per_day 为 10000000000000(8 位小数下为 100,000 zUSD),并列出 zUSD 本身:创世时承接自链 14,资产 id 相同,索引为 1,共七种抵押资产。
rand_getBridgeState
参数 []。结果 { "enabled": false },或:
{
"enabled": true,
"emitter": "01…",
"emitters": { "2": "02…" },
"guardian_set_index": 0,
"guardians": ["aabb…"],
"pq_guardians": ["…"],
"mint_paused": false,
"pause_nonce": 0,
"list_nonce": 0,
"pause_key": "…",
"registration_fee": "1000000000",
"burn_sequence": 1,
"rotation_nonce": 0,
"rules_v2": { "global_mint_cap_per_window": "…", "cap_window_secs": 86400,
"global_minted_in_window": "…", "global_mint_headroom": "…" },
"min_inbound_sequence": { "2": 2, "3": 2, "4": 2, "5": 2 },
"rotation_rules": { "delay_secs": 86400, "needs_possession": true },
"pending_rotations": [],
"fees": { "mint_bps": 10, "burn_bps": 10, "recipient": "rand1…" },
"assets": [ … ]
}
| field | meaning |
|---|---|
emitter | 本链的出站发射者地址,32 字节十六进制 |
emitters | 来源链 id → 在该链上受信任的发射者地址 |
guardians | 当前集合的 20 字节地址,十六进制 |
pq_guardians | PQ 集合:Dilithium2 公钥(1,312 字节),十六进制,与当前守护者集合按索引对齐(链 20 和链 21 上为集合 1)。每个 BridgeAttest 都带有该集合的法定人数联署签名。守护者集合的轮换不会改变它;只有 rules_v2 链上的 rotate_pq_guardians 才会 |
mint_paused | 为 true 期间,每个转账 attest 都会被拒绝并返回 bridge minting is paused;销毁和轮换保持开放 |
pause_nonce | 下一次暂停或取消暂停必须携带的值;两者都会使其递增 |
list_nonce | 下一次 register_bridged_token 或 list_backing 必须携带的值;两者都会使其递增 |
pause_key | 唯一可暂停铸造的 Dilithium2 密钥,十六进制。它只能暂停:取消暂停需要 PQ 守护者法定人数 |
registration_fee | RegisterBridgedToken 在 bundle 底价之外所需支付的费用,以 RAND 单位计,十进制字符串 |
burn_sequence | 迄今已发出的出站消息数 |
rotation_nonce | 下一次 rotate_pq_guardians / rotate_pause_key 必须携带的值 |
rules_v2 | 全局铸造上限及其滚动窗口,在没有桥规则 v2 的链上为 null。在该规则下,按抵押资产计的上限同样是滚动窗口,且铸造被暂停时拒绝上架。自 v0.6.8 起,它还带有 global_minted_in_window 和 global_mint_headroom,均为十进制字符串 |
min_inbound_sequence | 创世重放下限:来源链 id → 来自该链的转账可携带的最小序列号,为普通数字;在没有该下限的链上为 null(链 15 及更早)。低于该值的 bridge_attest 会被拒绝并返回 BelowReplayFloor,这是永久性的裁决。中继者读取它,以丢弃本链所切自的那条链已经铸造过的锁定 |
rotation_rules | v0.6.8:来自创世配置 bridge.rotation 的 { "delay_secs", "needs_possession" },或 null。在该规则下,轮换是 _v2 动作,携带新密钥的持有证明签名,并在生效前等待 delay_secs |
pending_rotations | v0.6.8:已提交但尚未生效的轮换,每项为 { "kind": "pq_guardians", "new_pq_guardians", "effective_at_secs" } 或 { "kind": "pause_key", "new_pause_key", "effective_at_secs" };没有 rotation_rules 时为 null。由当前暂停密钥签名的 cancel_rotation 可撤销其中一项 |
fees | v0.6.8:来自创世配置 bridge.fees 的 { "mint_bps", "burn_bps", "recipient" },或 null(链 14 至 19)。链会保留每笔存入和每笔销毁的该比例份额,向下取整至抵押资产的整数释放单位,并以 zUSD note 的形式发给 recipient。存入按总额扣除费用后入账;销毁的签名正文所释放的数额为其金额减去费用。钱包读取它来估算自身存入的价值,当钱包即 recipient 时,据此重建其费用 note |
assets | rand_getAssets 的各行 |
没有余额:被桥接的价值就是 note。不再有 next_index:被桥接的代币在可存入之前就已上架,其索引已由注册时确定,因此没有需要预测的索引。请从 assets 或 rand_getTokens 中读取已上架代币的索引。
rand_getAssets
参数 []。结果:桥的资产注册表,按索引升序排列,或为 []:
[{ "index": 1, "chain": 2, "token": "aaaa…", "asset_id": "…", "decimals": 6, "locked": "600",
"mint_cap_per_day": "10000000000000", "minted_today": "1000", "mint_day": 20350,
"minted_in_window": "1000", "mint_window_secs": 86400, "mint_headroom": "390000000000" }]
自 v0.6.8 起,此处以及所有提供 backing 的位置(rand_getBridgeState.assets、rand_getToken、rand_getTokens 和 rand_getTokenSupply 的 backings)中的每一行 backing 都带有 minted_in_window(十进制字符串)和 mint_window_secs,在按日计数器的链上二者均为 null;另有 mint_headroom:在区块头的出块时间下,各项上限允许对该 backing 存入的最大金额,即单 backing 上限减去其已铸造量,且在规则 v2 下不超过全注册表窗口所剩的额度。请读取 mint_headroom,而不要用 mint_cap_per_day − minted_today,后者忽略了全局上限。在规则 v2 下(如链 20 和 21),minted_today 是滚动窗口内的计数,即单 backing 上限所检查的数值;下文关于按日计数器的描述适用于链 14。
每个 backing(源币种)一行,因此有七个 backing 的代币在同一个 index 下占七行。index 是该资产的 note 所携带的 asset 字;索引 0 为 RAND,且从不出现在注册表中。decimals 是该 backing 的源币种小数位数。locked、mint_cap_per_day 和 minted_today 是以代币自身八位小数为单位的十进制字符串,绝不以 RAND 为单位;mint_day 是普通整数,即 UTC 日序号。mint_cap_per_day 是创世配置 tokens.mint_cap_per_day,即一个 backing 在区块时间的每个 UTC 日内最多可铸造的数量。minted_today 是该 backing 在 mint_day 上已铸造的数量,mint_day 是区块头的 UTC 日(timestamp_ms / 86,400,000),因此一旦区块头越过午夜,来自前一日的计数器读作 "0"。超出上限的存入会被以 MintCapExceeded 拒绝,并于次日起可被接纳。chain 和 token 是守护者(guardian)签名所针对的链上标识;asset_id 是这二者的 blake3,即 rand_bridgeAssetId 所计算的结果。
rand_bridgeAssetId
参数 [token_chain, token_address](整数,32 字节十六进制)。结果:资产 id,64 个十六进制字符。纯算术运算。
rand_getBridgeBurn
参数 [sequence]。结果为 null 或 { "sequence": 0, "body_hex": "…", "digest": "…", "tx": "…", "height": 2, "amount": "…", "release_amount": "…", "fee": "…" }。
后三个字段自 v0.6.8 起在所有链上提供,为以代币八位小数为单位的十进制字符串。release_amount 是已签名主体所携带的金额,直接从 body_hex 本身读出:即源合约释放的金额,中继者费用从中支付。fee 是链以国库 note 形式留存的桥接费用,amount 是该捆绑包销毁的数量,即 release_amount + fee。没有 bridge.fees 时(链 14 至 19),fee 为 "0"。链 20 上的序号 13(链 21 沿用链 20 的 burn_sequence,即 14,因此其第一笔销毁的序号为 14),一笔 0.999 zUSD 的销毁:"amount": "99900000"、"fee": "99900"、"release_amount": "99800100"。
代币(RPL)
RPL 代币注册表:所有代币,包括桥接代币和原生代币。代币说明了该标准。
rand_getTokens
参数 [from_index, limit],均为可选(默认 0 和 1000;limit 被限制在 1,000 以内)。结果:注册表按索引升序,自 from_index 起按范围读取:
{ "enabled": true, "registration_fee": "1000000000", "next_index": 3, "max_tokens": 4096,
"burn_registration_fee": true, "bound_note_value": true,
"tokens": [
{ "index": 2, "id": "<64 hex>", "id_text": "rpl1…", "name": "Test Coin", "symbol": "TST",
"decimals": 6,
"authority": { "kind": "key", "key": "<Dilithium2 key, hex>", "address": "<base58>" },
"mint_nonce": 1, "total_supply": "5700", "registered_at": 3 }
] }
在没有 tokens 部分的链上:{ "enabled": false, "tokens": [] }。index 是该代币的 note 所携带的 asset 字(0 为 RAND,从不列出)。id 是代币的资产 id,id_text 是其带校验和的文本形式:bech32m,HRP 为 rpl,作用于 32 个 id 字节,共 62 个字符。authority 为以下之一:
kind | 其他字段 |
|---|---|
none | —(固定供应量,或已放弃权限) |
key | key、address |
bridge | backings:[{ "chain", "token", "decimals", "locked", "mint_cap_per_day", "minted_today", "mint_day" }],即 rand_getAssets 的字段,每个 backing 一行 |
program | program |
供应量、locked、mint_cap_per_day、minted_today 和 registration_fee 为十进制字符串(registration_fee 以 RAND 为单位,其余以代币单位计);next_index、mint_day 和 max_tokens 为数字。max_tokens 是创世时对注册表规模设定的上限(链 20 和 21 上为 4,096;无上限时为 null),超过此上限的注册会被以 RegistryFull 拒绝。burn_registration_fee 表示注册费用是被销毁而非支付给提议者;bound_note_value 表示等于或高于 2⁶³ 的铸造或存入是否属于有效性规则(无论在哪条链上,准入都会拒绝此类交易)。这三项在链 20 和 21 上均已设置。短于 limit 的一页即为最后一页。
program 权限({ "kind": "program", "program": "<id>" })仅可在带有 program_state 部分的链上注册,链 20 和 21 即如此(v0.6.8):该代币的初始供应量为零,且只有该程序的调用才能铸造或销毁它。
钱包应通过此列表解析代币 id,而绝不通过 rand_getToken:转账的资产在链上是私密的,而读取整个注册表的开销与指定哪个代币无关。
rand_getToken
参数 [token]:注册表索引(数字或十进制字符串)、64 位十六进制 id(带或不带 0x,大小写均可)或 rpl1… 文本形式(全小写或全大写)。结果:该代币在 rand_getTokens 中的行,或 null。格式错误的 id(校验和错误、HRP 不同、长度错误、大小写混用、非十六进制)返回 -32602,因此笔误绝不会指向另一个代币。按代币查询会告知节点调用方关心哪个代币;它用于区块浏览器和一次性读取。
rand_getTokenSupply
参数 [token],形式相同。结果为 null 或:
{ "total_supply": "600",
"backings": [{ "chain": 2, "token": "<32 bytes hex>", "decimals": 6, "locked": "600",
"mint_cap_per_day": "10000000000000", "minted_today": "1000", "mint_day": 20350 }] }
原生代币的 backings 为空;对于桥接代币,locked 数额之和等于 total_supply。隐私方面的说明与 rand_getToken 相同。
区块聚合(在链 21 上未启用)
这些功能存在于节点中,适用于创世配置带有 aggregation 部分的链。在链 21 上,与链 20 一样,注册表为空,从未有任何内容被解封。v0.8.0 在所有链上更改了 Aggregate 操作的线上格式(新增了 payout_total 和 layout,见下文),尽管没有任何链承载过该操作。
| 方法 | 参数 | 结果 |
|---|---|---|
rand_getAggregate | [hash] | 封存该交易的聚合的 covers、aggregator、subsidy、proving_share、n、height;对任何其他交易为 null |
rand_getAggregators | [] | 聚合者注册表:每行包含 address、bond、payout、nonce、unbonding |
rand_getUnsealed | [from, limit] | { "bundles": [{ "hash", "height", "excess" }], "next_from" },即聚合者仍可覆盖的捆绑包 |
Aggregate 与其他交易一样通过 rand_sendTransaction 提交。
创世归属(在链 21 上未启用)
这些功能存在于节点中,适用于创世配置带有 vesting 部分的链。目前尚无链带有该部分:在链 21 上,与链 20 一样,每个方法都返回 { "enabled": false }。公共端点自 2026-10-01 起转发这些方法。
| 方法 | 参数 | 结果 |
|---|---|---|
rand_getVesting | [id] 或 [id, at_ms],条目的 64 位十六进制 id | 该条目:其类别、受益人、归属计划(amount、start_ms、cliff_ms、linear_ms、step_ms)、已领取、已撤销和已质押的数量,以及 as_of_ms(默认为区块头的时间)时的 vested_now、claimable_now、unvested_now;未知 id 为 null。自 v0.6.8 起,可撤销条目会列出 revokers、撤销所需的这些撤销者的 threshold,以及撤销所支付的 treasury(它们取代了单一的 revoker),且条目带有 revoke_nonce 和 locked_now |
rand_getVestingSummary | [] | { "enabled": true, "height", "as_of_ms", "entries", "issued", "released", "locked", "classes": [ … ] }:按类别的合计,不含密钥或所有者 |
rand_getVestingSchedule | [from_ms, to_ms, step_ms],最多 1,000 个点 | { "enabled": true, "issued", "points": [{ "t_ms", "locked" }] }:注册表锁定总额随时间的变化 |
金额为十进制字符串。四个归属操作通过 rand_sendTransaction 提交。
订阅(WebSocket)
ws://127.0.0.1:8545/ 或 /ws。该套接字仅提供 rand_subscribe 和 rand_unsubscribe,对其他任何请求返回 -32601。三个主题,是相互独立的流,彼此之间不保证顺序:
newHeads—rand_getHead的格式,每提交一个区块发送一次,按顺序发送,同步期间亦然。此处的view是该区块自身的视图。receipts或receipts <program_id>— 每个至少带有一条匹配调用回执的已提交区块发送一条通知:{ "height", "hash", "receipts": [ … ] },每个回执采用rand_getReceipt的格式。transaction <hash>— 发送一条通知,随后节点移除该订阅:{ "status": "committed", "height", "index" },或针对交易自身字节的拒绝{ "status": "rejected", "reason" }(rand_getTransactionStatus具有同样的限制)。与状态相关的拒绝从不会被通知,因此请配合超时使用。
{ "jsonrpc": "2.0", "id": 1, "method": "rand_subscribe", "params": ["newHeads"] }
{ "jsonrpc": "2.0", "id": 2, "method": "rand_unsubscribe", "params": ["1"] }
{ "jsonrpc": "2.0", "id": 3, "method": "rand_subscribe", "params": ["receipts", "<program_id>"] }
{ "jsonrpc": "2.0", "id": 4, "method": "rand_subscribe", "params": ["transaction", "<hash>"] }
{ "jsonrpc": "2.0", "id": 1, "result": "1" }
{ "jsonrpc": "2.0", "id": 2, "result": true }
{ "jsonrpc": "2.0", "method": "rand_subscription",
"params": { "subscription": "1", "result": { "height": 1998, "hash": "…", "view": 2251 } } }
边界:每个节点 64 个连接(第 65 个在升级时被以 503 拒绝)、每个连接 8 个订阅、每个客户端帧 64 KiB、每 30 秒一次 ping 且须在 5 秒内应答,以及每个流 256 条积压条目——在其所监听的流上落后过多的订阅者将以代码 1008 关闭,而不是被缓冲;请重新连接,并通过 rand_getCompactBlocks(区块头)、rand_getReceipts(回执)或 rand_getTransactionStatus(交易)填补缺口。对于不带升级头的普通 GET /,返回 400。
错误
| 代码 | 含义 |
|---|---|
-32601 | 未知方法(包括已停用的账户方法) |
-32602 | 参数无效或缺失 |
-32000 | 被拒绝:内存池拒绝的交易、受速率限制的 faucet 调用、等待超过 10 秒的见证构建、超过 30 秒的读取、公共监听器不提供的方法,或超出上限的订阅 |
-32001 | 所引用的对象未找到 |
-32010 | 已裁剪:高度低于此节点的保留下限;data.floor 给出该下限(见下文) |
-32603 | 内部错误 |
-32600 | 请求无效:请求体超过大小限制、不是 JSON、批请求格式错误,或为通知 |
{ "jsonrpc": "2.0", "id": 1, "error": { "code": -32000, "message": "…" } }
对于 rand_sendTransaction,只有 -32000 和 -32602 是对该交易的裁决;出现任何其他代码时,其结局未知(见 rand_sendTransaction)。
已裁剪节点:错误 -32010
以 --prune-history <window> 启动的节点保留整个账本(note、nullifier、锚点、注册表),但只保留最近 <window> 的区块、交易和回执;rand_status.prune_floor 是它仍持有的最低高度。在链 21 上,与链 20 一样,26 个验证者中有 24 个以 --prune-history 24h 运行;两个存档节点不带该标志运行,保留每个区块,公共端点转发到其中一个。
- 按高度,低于下限(创世块除外):
rand_getBlockByHeight、按高度的rand_getFinality,以及触及下限以下的rand_getBlocks、rand_getCompactBlocks或rand_getReceipts范围,均返回-32010pruned: height h is below this node's retention floor f,并附带data: { "floor": f }。请向存档节点查询。[0, 0]仍可返回创世块。 - 按哈希:对于已裁剪的哈希,
rand_getBlockByHash、rand_getReceipt、rand_getRawTransaction、rand_getCallEnvelope和rand_getAggregate返回null,与从未存在过的哈希相同;只有存档节点能区分两者。rand_getTransaction和rand_checkTransaction同样返回null,仅当残留的位置行指向低于下限的高度时才返回-32010。在已裁剪节点上,rand_getTransactionStatus会为每个unknown条目添加floor。 - 钱包扫描不受影响:
rand_getCommitments、rand_getNullifiers、rand_getAnchor以及见证方法读取的是从不裁剪的数据族。
链上传输的交易
Transaction { chain_id: u64, bundle: Option<Bundle>, action: Action }
Bundle { // the hidden-asset bundle (since chain 14)
anchor: Word8, nullifiers: [Word8; 4], commitments: [Word8; 4],
fee: u64, burn_a: u64, burn_r: u64, burn_asset: u32, time: u32,
envelopes: [Envelope; 4], proof: Vec<u8>,
auth_commit: Word8, auth_proof: Vec<u8>, // since chain 17 (v0.6.3): split authorisation's c and
} // its proof; zeros and empty without hc_auth
Envelope { kem_ct: Vec<u8>, to_receiver: Vec<u8>, to_sender: Vec<u8>, body: Vec<u8> }
Action::None
Action::Mint { cm: Word8, pk: Word8, time: u32, r: Word8, envelope: Envelope, amount: u64,
minter: PublicKey, signature: Signature }
Action::Deploy { base_pc: u32, words: Vec<u32>, public: Vec<u32> }
Action::Call { program: Hash, proof: Vec<u8>, input_envelope: Option<CallEnvelope> }
Action::Bond { validator: Address, amount: u64, registration: Option<Registration> }
Action::Unbond { validator: Address, amount: u64, nonce: u64, signature: Signature }
Action::Withdraw { validator: Address, amount: u64, nonce: u64, time: u32, r: Word8,
envelope: Envelope, signature: Signature }
Action::BridgeAttest { attestation: Vec<u8>, recipient: ShieldedAddress, r: Word8, time: u32,
asset: u32, envelope: Envelope, pq_signatures: Vec<PqSignature> }
Action::BridgeBurn { asset: u32, amount: u64, relayer_fee: u64, to_chain: u16,
token: [u8; 32], to: [u8; 32] }
// the five aggregation variants sit here in the enum's declared order
Action::RegisterToken { name: String, symbol: String, decimals: u8, authority: MintAuthority,
initial: Option<InitialMint>, salt: [u8; 32], index: u32 }
Action::TokenMint { asset: u32, amount: u64, recipient: ShieldedAddress, r: Word8, time: u32,
envelope: Envelope, nonce: u64, signature: Signature }
Action::SetAuthority { asset: u32, new: Option<PublicKey>, nonce: u64, signature: Signature }
Action::TokenBurn { asset: u32, amount: u64 }
Action::PauseMints { nonce: u64, signature: Signature } // bundle-less, fee-less
Action::UnpauseMints { nonce: u64, pq_signatures: Vec<PqSignature> } // bundle-less
Action::RegisterBridgedToken { name: String, symbol: String, salt: [u8; 32], chain: u16,
token: [u8; 32], decimals: u8, nonce: u64,
pq_signatures: Vec<PqSignature> }
Action::ListBacking { token_index: u32, chain: u16, token: [u8; 32], decimals: u8, nonce: u64,
pq_signatures: Vec<PqSignature> }
Action::RotatePqGuardians { new_pq_guardians: Vec<PublicKey>, nonce: u64,
pq_signatures: Vec<PqSignature> } // bundle-less, fee-less
Action::RotatePauseKey { new_pause_key: PublicKey, nonce: u64,
pq_signatures: Vec<PqSignature> } // bundle-less, fee-less
// the four vesting variants (ClaimVested, RevokeVesting, BondVested, UnbondVested) follow, tags 24 to 27;
// since v0.6.8 RevokeVesting carries `signatures: Vec<RevokerSignature>` in place of one `signature`
Action::AdmitValidator { candidate: PublicKey, signatures: Vec<(PublicKey, Signature)> } // tag 28, v0.6.8
Action::SlashEquivocation { first: Box<SignedHeader>, second: Box<SignedHeader> } // tag 29
Action::RotatePqGuardiansV2 { new_pq_guardians: Vec<PublicKey>, possession: Vec<Vec<u8>>,
nonce: u64, pq_signatures: Vec<PqSignature> } // tag 30
Action::RotatePauseKeyV2 { new_pause_key: PublicKey, possession: Vec<u8>, nonce: u64,
pq_signatures: Vec<PqSignature> } // tag 31
Action::CancelRotation { kind: u8, nonce: u64, signature: Signature } // tag 32
Action::Invoke { program: Hash, proof: Vec<u8>, input_envelope: Option<CallEnvelope>,
transition: Transition } // tag 33, RPL-2
Action::PerpDeposit { trading_key: PublicKey } // tag 34, RPL-3 (v0.8.0, chain 21): rides a bundle
Action::PerpOrder { account: Word8, body: PerpOrderBody, signature: Signature } // tag 35, bundle-less, fee-less
Action::PerpCancel { account: Word8, nonce: u64, target: u64, signature: Signature } // tag 36
Action::PerpWithdraw { account: Word8, nonce: u64, amount: u64, recipient: ShieldedAddress,
r: Word8, time: u32, envelope: Envelope, signature: Signature } // tag 37
Action::PerpOracle { validator: PublicKey, prices: Vec<PerpPrice>, nonce: u64,
signature: Signature } // tag 38
Action::PerpStateProof { from_height: u64, to_height: u64, new_root: Word8,
payouts: Vec<PerpPayout>, fees: u64, proof: Vec<u8> } // tag 39, unsigned
Action::CreateMultisig { salt: [u8; 32], signers: Vec<PublicKey>, threshold: u8 } // tag 40 (v0.8.0, chain 21): rides a bundle
Action::MultisigDeposit { account: [u8; 32] } // tag 41, rides a bundle
Action::MultisigPay { account: [u8; 32], nonce: u64, time: u32, pays: Vec<Payout>,
signatures: Vec<SignerSignature> } // tag 42, bundle-less
Action::MultisigRotate { account: [u8; 32], nonce: u64, signers: Vec<PublicKey>, threshold: u8,
signatures: Vec<SignerSignature> } // tag 43, bundle-less, fee-less
Action::SetRandPrice { … } // tag 44 (v0.8.0): the validators' RAND/USD vote; chains with fees.usd_subsidy only
MintAuthority = None | Key(PublicKey) | Bridge { backings: Vec<Backing> } | Program(Hash)
InitialMint { amount: u64, recipient: ShieldedAddress, r: Word8, time: u32, envelope: Envelope }
Transition { reads: Vec<Cell>, writes: Vec<Cell>, inflow: Inflow, pays: Vec<Payout>, mints: Vec<Payout> }
Cell { key: Word8, value: Word8 } // keys strictly ascending in each list
Inflow = None | Deposit | Burn // what the bundle's burn_a of burn_asset is to the program
Payout { asset: u32, amount: u64, recipient: ShieldedAddress, r: Word8, envelope: Envelope }
Registration { public_key: PublicKey, payout: ShieldedAddress, signature: Signature }
CallEnvelope { kem_ct: Vec<u8>, to_sender: Vec<u8>, to_auditor: Vec<u8>, body: Vec<u8> }
PqSignature { index: u8, signature: Vec<u8> } // one guardian's Dilithium2 co-signature, by set index
PerpOrderBody { nonce: u64, market: u32, side: u8, kind: u8, tif: u8, reduce_only: bool, price: u64, size: u64 }
PerpPrice { market: u32, price: u64 }
PerpPayout { request: Word8, amount: u64 }
SignerSignature { index: u8, signature: Signature } // a multisig signer, by position in the account's signers
bincode 的默认配置:定长整数、8 字节长度前缀、按声明顺序排列的 u32 枚举标签。五个聚合变体位于枚举中 BridgeBurn 之后、RegisterToken 之前(交易);链 21 与链 20 一样,从不接纳它们,也不接纳四个归属(vesting)变体、SlashEquivocation 或 SetRandPrice,但硬编码标签编号的编码器仍须将它们计入。
bundle 的最后两个字段随 v0.6.3 和链 17 一同出现。bincode 按位置编码,因此为链 16 或更早版本编写的编码器所生成的交易,本链无法解码,并且每个交易 id 都随之改变:id 的域现为 rand-txid-3,它绑定 auth_commit 和授权证明的摘要。在本地重新计算 id 的客户端必须随之更新。自链 20 起,每个 bundle 都携带授权证明,无论是自证明还是委托证明。v0.6.8 未改动 Transaction 或 Bundle 的布局;它追加了动作 28 至 33。v0.8.0 同样保持 Transaction 和 Bundle 不变——多签授权的 bundle 与其他 bundle 具有相同的字段,只有其授权证明所声明的形态不同——并追加动作 34 至 44:六个永续合约动作(34–39,v0.7.x 的 RPL-3,在链 21 上处于未启用状态)、四个多签动作(40–43)以及 SetRandPrice(44)。两个既有变体在每条链上都发生了变化:Action::Aggregate 在末尾新增了 payout_total: u64(在 rand-aggregate-4 下签名,绑定创世块的为 -5)以及末尾的 layout(Flat 或 Tree,4 字节枚举索引),因此其编码和 txid 随之改变;没有任何链曾承载过此类交易。约束集 9(v0.8.0,链 21)改变了每个证明的编码和每个验证者密钥,而不是交易布局:由 v0.8.0 之前的构建生成的 bundle、授权或调用证明无法在链 21 上解码,这就是 v0.8.0 拒绝链 18 至 20、而 v0.8.0 之前的钱包无法在链 21 上发送交易的原因。
每笔交易至多携带一个 bundle。Bond 携带的 bundle 其 burn_r 等于其 amount,且 burn_a 与 burn_asset 为 0。BridgeBurn 或 TokenBurn 通过 bundle 销毁:burn_asset 必须是该动作的 asset(绝不为 0),burn_a 为该动作的 amount,burn_r 为 0,而 fee 则从槽位 2–3 以 RAND 支付。其他每个动作都不销毁代币,RAND 只能通过 burn_r 销毁:burn_asset 为 0 而 burn_a 非零的 bundle 在任何地方都会被拒绝。BridgeAttest 的 r 是推导出来的,而非选取的:准入要求 blake3("rand-deposit-r-1" ‖ mu),其中 mu 为守护者所签名的摘要,其他任何值都会被拒绝(WrongDepositBlinding,永久性拒绝)。桥接代币必须先被列入——在创世块中,或通过 RegisterBridgedToken / ListBacking——才可接纳对它的任何证明;对未列入代币的证明会被以 UnlistedToken 拒绝。
每个 bundle 证明都是针对其所在交易生成并据以验证的:即证明被清空后的整笔交易,绑定到链 id,并且自链 20 起(binding_domain: 1)绑定到创世哈希,使用全新的标签。在链 14 至 19 上,绑定仅为链 id,因此为链 19 生成的证明无法在链 20 上通过验证,早于 v0.6.8 的钱包无法在那里发送交易;为链 20 生成的证明绑定到链 20 的创世块,并且无论如何属于约束集 8,因此同样无法在链 21 上通过验证,早于 v0.8.0 的钱包无法在那里发送交易。在链 18 至 21 上,不含两个证明的 bundle 编码为 7,936 字节,不含证明的转账交易为 7,949 字节(链 14 至 16 上为 5,848 和 5,861,信封为 1,348 字节且没有授权字段)。在生产配置下,链上传输的一笔转账约为 2.85 MB,几乎全是证明:bundle 证明约 1.49 MB,授权证明约 1.36 MB。在拆分授权之前约为 1.43 MB。
链 21 与 v0.8.0 的新增内容
链 21 于 2026-10-12 上线(创世块切换于 10:22 UTC,全部 26 个验证者于 10:31 UTC 完成切换),运行 fullnode v0.8.0(c0878c3f),是链 20 的一次硬分叉。与链 20 的方法列表(即本页在 v0.6.8 时给出的列表)相比:
- 约束集 9。 每个证明的编码和每个验证者密钥都已改变(rVM 第 4 阶段的 Merkle 跨度与 MODQ 芯片);v0.8.0 在启动时拒绝链 18 至 20,由较旧构建生成的证明在链 21 上会被拒绝。没有
Transaction或Bundle字段发生移动。 rand_getLimits:max_proof_bytes为 6,291,456,max_block_bytes为 19,922,944;新增hc_auth_multisig、fee_rules、perps和multisig。rand_status:hc_auth_multisig、msauth_key、compact_fetched。rand_getSupply:base_fees_burned、perps_rand_out、perps_rand_held以及五个multisig_*计数器。rand_sendTransaction: 在带有多签 guest 的链上,请求体上限按三个证明计算。- 新方法,均为公开:
rand_getScanLeaves、rand_getPerps、rand_getPerpAccount、rand_getPerpAccounts、rand_getPerpInputs、rand_getMultisig、rand_getRandPrice。公共端点自 2026-10-12 起转发这些方法。 - 新动作: 标签 34 至 39(RPL-3 永续合约)、40 至 43(多签账户)和 44(
SetRandPrice,在链 21 上未启用),由rand_getTransaction按上文所述呈现;Aggregate新增了payout_total和layout。 - 费用: 在链 21 的
fees.burn_base和fees.burn_floor下,每个 bundle 的结算下限均被销毁,提议者保留小费(费用)。发送方的支付金额不变。 - 仅节点侧,适用于每条链: 紧凑区块(领导者广播区块头和交易哈希;
compact_fetched)、启动检查点、验证缓存(聚合的 STARK 每个节点只验证一次)、跟随者在共识循环之外应用提案、rand_getBlocks的分页以 16 MiB 回复为界(v0.7.0,审计 v7),以及用于证明的--threads/--cpu(v0.7.1)。 - 私有多签: 在第 18 层的第二个授权 guest 内证明的 M-of-N 策略,由
rand multisig-private生成(命令行);链上或本页的数据形态中,没有任何内容可将此类 bundle 区分出来。迄今尚无链 21 的交易承载过此类 bundle。
fullnode 在 c0878c3f 处自带的 docs/rpc.md 保存了逐方法的变更记录,本页即以其为对照阅读。