節點透過 --rpc(預設為 127.0.0.1:8545)以 HTTP 提供 JSON-RPC 2.0 服務,並在同一連接埠提供 WebSocket 以供訂閱。自 v0.6.8 起,節點亦可開啟第二個公開監聽器(--public-rpc,見下文)。randprotocol_client::RpcClient(Rust)封裝了下列每一個方法。本頁是 v0.6.8(c9c9bd3c,即 chain 20 所運行的版本)所提供的方法清單;凡方法存在於程式碼中但在 chain 20 上不起作用者,文中均會註明。
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-20 歸檔節點,供沒有自有節點的錢包與頁面使用(rand --rpc https://rpc.randprotocol.org …)。它只接受 HTTP POST,開放 CORS,不提供 WebSocket,而且比節點本身更為受限:
- 每次呼叫只處理一個請求。批次請求會被以
-32600拒絕。 - 方法白名單:自 2026-10-01 起,其內容與節點自身公開監聽器相同(v0.6.8 中的
rpc::PUBLIC_METHODS),因此rand program invoke所需的程式狀態讀取、rand_getAdmitted、聚合讀取及歸屬(vesting)讀取均在其中,另有rand_checkTransaction與rand_sendTransaction。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。它以 socket 位址識別呼叫者,並信任 loopback:檢視金鑰方法只回應 loopback,而 loopback 不受計量。請將其保持在127.0.0.1。反向代理或 SSH 轉發會經由 loopback 抵達,因此在其後每位訪客都等同營運者:切勿將公開端點指向此連接埠。 --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 秒內仍未返回,會回應 -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 的檢視金鑰方法加上 bearer token:取檔案的第一行(至少 32 個字元),以 Authorization: Bearer <token> 發送。啟用後,僅來自 loopback 並不足夠,任何位置的呼叫者只要出示該 token 即獲接納。
慣例
- 驗證者位址為 base58 字串(32 位元組)。雜湊值為 64 個十六進制字元,可帶或不帶
0x。屏蔽值(承諾、nullifier、anchor、樹根、見證層級)為Word8:八個小端序u32字,以 64 個小寫十六進制字元表示。 - 屏蔽位址為
rand1+ base58,共 1,667 個字元。長度超過 2,000 個字元的參數會在解析前即因長度而被拒絕。 - 每個
u64金額都是十進制字串("1500000000"= 1.5 RAND;1 RAND = 10⁹ 單位):無論是 RAND 單位或代幣單位、鏈上狀態或已解碼交易自身的欄位。JSON 數字超過 2⁵³ 後便不是精確整數,而一個 9 位小數的代幣,其供應量在數千萬單位時便已超過該值。此項改動的影響見下方附有日期的說明。 - 索引、nonce、高度、葉索引、view、長度、小數位數及日計數器(
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 個的陣列,或既非物件亦非陣列的主體,會得到單一的 -32600,id 為 null。整個主體仍受節點請求主體上限所限,該上限是按一個附帶證明的交易而設:由兩個附帶證明的 rand_sendTransaction 呼叫組成的批次會以 413 拒絕。批次適用於讀取,而非已證明的提交。
鏈與節點
rand_chainId
參數 []。結果:鏈 id(整數);testnet 上為 20。
rand_tokenInfo
參數 []。結果 { "symbol": "RAND", "decimals": 9 }。
rand_getHead
參數 []。結果 { "height": 1998, "hash": "…", "view": 2251 }。view 是節點當前的共識 view,當 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,
"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",
"binding_domain": 1,
"address": "5TAofR…", "peer_id": "12D3KooW…",
"gas_prices": { "gas_price": "100", "byte_price": "800" }
}
is_validator:此節點持有驗證者金鑰;active_validator:該金鑰屬於運行當前 epoch 的集合。reserved_peers(v0.6.8)統計在入站連線上限之外獲接納的對等節點:bootstrap 節點、任何 --reserved-peer,以及從已簽署的對等節點綁定中得知的每個驗證者身份,各計一次;在機群節點上,它應在啟動後一分鐘內達到驗證者數目。viewing_keys 是節點為節點端掃描而保存在記憶體中的檢視金鑰數目。verify_queue 是等待四個證明驗證 worker 之一處理的交易數目(最多 64 個)。hc_bundle 是本鏈證明所對應的 bundle guest,hc_auth 是其 genesis 所固定的 auth guest(自 chain 17 起的拆分授權),在沒有此項的鏈上則為 null;構建版本與任一者不符的節點會拒絕啟動。testnet 與 binding_domain 是同名的 genesis 欄位,與 rand_getLimits 所提供的相同。gas_prices 是頂端帳本當前的 gas 價格,於每次提交時更新,以十進制字串表示;在沒有 gas 部分的鏈上為 null。chain 20 的價格是動態的,每個區塊按區塊的充盈程度浮動,絕不低於 100 與 800 的下限,亦絕不高於 10,000 與 80,000 的上限,因此請在此處或 rand_getLimits 讀取,切勿寫死。此物件亦帶有 aggregation 物件(其 subsidy_base 為十進制字串,其餘為整數);在沒有 aggregation 部分的鏈上,其值全為零,chain 20 即屬此類。
此物件亦帶有 disk_free_bytes(數字)與 disk_low,以及保留期的一對欄位:prune_floor,即此節點仍保存的最低高度(歸檔節點為 0);prune_history_secs,即以 --prune-history 啟動的節點所保留的時間窗口(保留全部時為 null)。在 chain 20 上,一如 chain 19,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 是創世認證 guest(與 rand_status 中相同),或為 null。2026-10-01 公開端點在鏈 20 上的回應:
{ "version": "0.6.8", "git_sha": "c9c9bd3c1903aa4cc5833b7ab8c62fc3e6942017", "chain_id": 20,
"hc_bundle": "60af094acfe65d85fdb18fb3d06cf9085dcf28c96e59e87f1ee527226e6e3fce",
"hc_auth": "1e4e347f44cf86750b30a9a4bdf9ec9256efe353d4ff8017451eca7d195639c1",
"fri_profile": "production" }
rand_getGenesisHash
參數為 []。結果:創世哈希(十六進位);在鏈 20 上為 "6210cf071a390d7ac61d8cbea5dd9d139d1a493a862b54a45a498f36af2d5135"(鏈 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 }。disk_low 的優先級高於其他一切狀態,條件是資料目錄所在檔案系統的可用空間低於節點 --min-free-disk-mb(預設 1024,即低於 4 GB)的四倍;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):超出上限後,每 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 上為 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;對於不符合鏈 20 創世的 bundle,有 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 位元組,在鏈 20 的限制下為 17,350,656(與鏈 17 至 19 相同;鏈 13 至 15 為 34,127,872,其證明上限為 8 MiB)。4 × 2048 是 bundle 的四個信封按信封上限計算的大小。超過上限的主體返回 -32600,並註明該上限。
只有 -32000(准入拒絕)和 -32602(無法解碼)是對該交易的裁定。任何其他失敗,包括 -32603,都不能確定交易的下場:節點在回覆之前已先將交易放入池中並廣播,因此在此窗口內停止運行的節點,可能已接納了它從未答覆的交易。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 只涵蓋僅與交易自身位元組有關、且之後任何區塊都無法改變的拒絕:無效的證明、與其證明所發佈的不符的 bundle 摘要、錯誤的鑄造簽名、錯誤的鏈 id、過大的部分、交易內重複的 nullifier 或承諾、大小錯誤的信封、缺失或不匹配的認證證明、聲明了錯誤 gas 上限的 bundle 或認證證明。取決於節點當時狀態的拒絕——已花費的 nullifier、窗口以外的錨點或 time、低於下限的費用(在鏈 20 上隨 gas 價格而變動)、未知的程式、登記 nonce、過期的 invoke 讀取——不會被記住,讀作 unknown。清單為空或多於 64 個哈希時返回 -32602。
rand_mint(testnet 水龍頭)
參數為 [address] 或 [address, amount];address 為 rand1… 地址,amount 為單位數量的字串,至多 100000000000(100 RAND,即預設值)。結果:鑄造交易哈希。僅限創世設有 "faucet": true 的鏈;否則返回 -32000 faucet is disabled on this chain。觀察者節點的回應為 faucet mints are signed by validators; ask a validator node。
在創世設有 staking.faucet_recipients 的鏈上(鏈 20 即是如此,共 16 個錢包),只能向列出的錢包付款:向任何其他地址鑄造,會以 the faucet may not mint to this recipient (not in staking.faucet_recipients) 被拒絕。鏈 20 的創世還設有 staking.faucet_minters(18 個驗證者金鑰):只有列出的金鑰才可簽署鑄造。水龍頭另設每個 epoch 的預算 staking.faucet_budget_per_epoch(鏈 20 上為每 1,000 個區塊的 epoch 10,000 RAND);超出預算的鑄造會以 FaucetBudgetExhausted 被拒絕,這屬於狀態裁定,離開交易池後讀作 unknown。
香港Rand的faucet按每個節點進程限流:連續八次鑄造,每秒補充一次。超出後,該調用會回應 faucet is rate limited on this node (8 mints back to back, refilling at 1/s); try again shortly。因此,faucet 洪流無法在橋接 PauseMints 之前填滿交易池;PauseMints 與其他三項橋接治理操作一樣,不受交易池 mempool full 拒絕的限制,並在區塊中排在最前。
自 chain 14 起,鑄造是公開開啟的:Mint 操作除 cm 和 amount 外,還帶有票據的 pk、time 和 r,准入時會重新計算承諾,並拒絕無法由這些數值開啟的 cm(the mint's commitment does not open to its published note and amount),鑄造者則在域 rand-mint-2 下對全部七個欄位簽名;在 chain 20(binding_domain: 1)上則使用 rand-mint-3,並以創世哈希居首。因此,faucet 票據的擁有者和金額是公開的,正如提款的支付輸出一樣。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 即是如此。gas是調用的證明所聲明的 gas 上限,且為必填:缺少時調用會回應-32602under the gas section a call estimate needs its gas。答案為1,000,000 + gas_price × gas + byte_price × ⌈bytes / 1024⌉,按鏈頂當前價格計算,即rand_getLimits所提供的價格。以 chain 20 的底價 100 和 800 計算,一個聲明 20,479 gas、證明和信封共 1,300,000 字節的調用為"4063900"。價格逐區塊變動,因此應在接近發送時才估算。"header",即沒有該部分的鏈上的節點級 gas 政策。 調用規格接受keccak_log_height和sha256_log_height(可選,預設為 0,各在 0 至 40 之間,否則-32602),即證明標頭所聲明的哈希表高度,答案為賬本的層級底價與該標頭的 gas 底價二者中較高者。在gas部分之下,這兩個高度會被接受但不使用。null,兩者皆非。 僅按賬本的層級收費表:在免費額度(2,097,152 + 18,432 字節)或以內,調用收取其層級的費用;超出部分每 KiB(不足 1 KiB 亦按 1 KiB 計)加收 1,000 單位。
自 v0.6.8 起,{"kind":"invoke", …, "created_cells": c} 為 RPL-2 的 invoke 定價:包含調用規格的所有欄位,另加 created_cells(可選,預設為 0,至多為 max_writes,否則 -32602),即該狀態轉換將會創建的儲存格。每個儲存格加收該鏈的 cell_fee(rand_getLimits.program_state)。由調用者計數:即向 rand_getProgramCell 讀作全零的儲存格寫入非零值。在 chain 20 上,上述調用加上兩個新建儲存格為 "24063900"。在沒有 program_state 部分的鏈上,此類型為 -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_getNullifiers
參數 [from_height] 或 [from_height, limit]。結果:自該高度起發佈的每個 nullifier,同樣以 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"] } ] } ]
每個帶有 bundle 的交易在此擁有四個票據和四個 nullifier,即其四個槽位,包括虛設槽位在內,而任何讀取者都無法將虛設槽位與真實槽位區分(只顯示示例中的第一行承諾)。自 v0.6.8 起,部分交易在這四個之後擁有更多票據:invoke 為每筆支付輸出擁有一個票據,先 pays 後 mints,各帶該支付輸出自己的信封,因此收款人以試解密找到它;在設有橋接費用的鏈上(如 chain 20),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 為 1,024,至 chain 19 為止的鏈為 256。應針對鏈頂構建。
rand_getWitness
參數 [index]。結果:若超出樹的末端則為 null,否則為該葉子的默克爾路徑,葉子在前,正好 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 為每筆交易的 TxKey,以 64 個十六進位字元表示。結果:未知哈希為 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": 20,
"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 上,每個槽的 envelope_len 均為 1,860,其創世將票據信封固定為此大小(見 rand_getLimits 中的 envelope_bytes);在 chain 14 至 17 上則為 1,348。auth_commit 與 auth_proof_bytes 屬於拆分授權(自 chain 17 起):前者是 bundle 證明與授權證明均公開的公開承諾 c = H(AUTH, nk, salt),後者是授權證明的長度。在沒有 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 為推導所得,即 blake3("rand-deposit-r-1" ‖ mu),其中 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。一個 bundle 承載整筆銷毀:其 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;bundle 的 burn_asset / burn_a 重複這兩項 |
pause_mints | nonce;無 bundle、無費用,由創世暫停密鑰簽署 |
unpause_mints | nonce、pq_signers;無 bundle、無費用 |
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 集內的索引);無 bundle、無費用,僅限橋接 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(計數)。無 bundle、無費用;在創世 bridge.rotation 設定了 needs_possession 的鏈上為必需,chain 20 即如此。輪換在 delay_secs 之後生效(chain 20 上為 86,400 秒) |
cancel_rotation | v0.6.8:rotation_kind("pq_guardians" 或 "pause_key")、nonce;由當前暫停密鑰簽署,取消待生效的輪換 |
admit_validator | v0.6.8:candidate(地址)、candidate_key(十六進位)、voters(地址)。無 bundle、無費用:驗證人集投票准許新密鑰註冊,僅限設有 staking.admission_by_vote 的鏈,chain 20 即如此 |
slash_equivocation | v0.6.8:offender、view、first 與 second({ hash, height });僅限設有 staking.slashing 的鏈,chain 20 並非如此 |
invoke | v0.6.8,RPL-2:呼叫的欄位(program、proof_len、input_envelope_len)及其 transition(見下)。僅限設有 program_state 區段的鏈,chain 20 即如此 |
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 中的位置)。無 bundle;僅限創世設有 vesting 區段的鏈,chain 20 並非如此 |
代幣的註冊與鑄造是公開的,一如橋接存款:所鑄造票據的每個字都在操作之中(其 from 是鏈上固定的 MINT_FROM),因此接收方無需解密任何內容,即可由這些欄位重建票據。類型字串 bridge_attest、token_mint、register_token 與 invoke 是錢包掃描所依據的鍵,並由測試固定。
chain 20 高度 3,079 上的一筆 invoke,它讀取一個儲存格、刪除該儲存格,並從金庫支付出兩張票據:
{ "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。流入的部分屬於 bundle:burn_r 是存入程式金庫的 RAND,burn_a 個 burn_asset 則是 inflow 所指明的代幣,deposit 表示存入金庫,burn 表示銷毀(程式自身的代幣),burn_a 為 0 時則為 none。流出的部分,每筆支付對應一張由鏈計算的票據,先是從金庫 pays,然後是 mints 一種以本程式為鑄造權限的代幣。每張票據的每個字都以 token_mint 的欄位名稱列出;time 取自 bundle,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 欄位:部署由 bundle 支付。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。錢包為一次呼叫生成證明時,會把這些字組交給 prover;帳本則根據程式的 public_digest 核對證明的承諾。
rand_getProgramCell
v0.6.8,RPL-2。參數為 [program_id, key],key 為 Word8,以 64 個十六進位數字表示(可帶或不帶 0x)。結果為 { "key": "<64 hex>", "value": "<64 hex>" }。程式從未寫入的儲存格,或曾寫入零值的儲存格(寫入零值即刪除該格),讀取時為 64 個零,這是「不存在」的唯一編碼;無人部署的程式的任何 key 亦然,因為不會檢查程式是否存在。在沒有 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 }:程式的儲存格按 key 順序排列(對八個字組作無符號比較),從 after 之後開始,最多 limit 個(限制在 1 至 1,000 之間)。尚有後續內容時,next 為最後一個已回傳的 key;將它作為 after 傳回即可。最後一頁的 next 為 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_getLimits
參數為 []。結果:錢包根據鏈的創世區塊建構交易所需的資料:五項呼叫限制、note 信封大小、v0.6 開關、auth guest、gas 條款,以及自 v0.6.8 起的 audit-v6 創世欄位和程式狀態限制。在 chain 20 上:
{ "max_program_words": 65535, "max_proof_bytes": 4194304, "max_block_bytes": 20971520,
"max_call_envelope_bytes": 65536, "max_program_public_words": 32768,
"envelope_bytes": 1860, "hardening_v6": true,
"hc_auth": "1e4e347f44cf86750b30a9a4bdf9ec9256efe353d4ff8017451eca7d195639c1",
"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 } }
沒有五項限制欄位的創世(chain 12)取 4096、2097152、4194304、18432 和 0。max_proof_bytes 在 chain 13 至 15 上為 8,388,608。
| field | meaning |
|---|---|
envelope_bytes | 當創世把每個建立 note 的信封固定為恰好該長度時為 1860,即附帶備忘的格式;創世沒有此欄位時為 null(chain 14 至 17),此時錢包封裝不含備忘的 1,348 位元組信封。不存在其他值 |
hardening_v6 | 創世採用 v0.6 有效性規則時為 true。此時錢包證明一次呼叫,所依據的是程式的公開輸入加上交易的呼叫綁定,而不是只依據公開輸入:先選定費用 bundle 的 note,再證明呼叫,最後才處理 bundle。設有此旗標的鏈拒絕舊證明,沒有此旗標的鏈則拒絕新證明 |
hc_auth | 創世所固定的 auth guest,以十六進位表示,或為 null。有設定時,hc_bundle 為 bundle guest v3,每個 bundle 均帶有 auth_commit 和一個 auth 證明:錢包向 bundle guest 提供 nk 和一個全新的 salt,並針對花費金鑰證明 auth guest |
gas_metering | 創世設有 gas 區段的鏈為 "circuit"(電路內計量);沒有該區段、而節點執行自己的 gas 政策(--gas-price、--byte-price)時為 "header";兩者皆無則為 null |
gas_price, byte_price | 每單位 gas 的價格,以及每 KiB 呼叫證明和輸入信封的價格,均為十進位字串。在 gas 區段之下,它們屬於共識狀態,每個節點均相同:設有 gas.dynamic 時(如 chain 20),為鏈頂的當前價格,按每個區塊的充盈程度變動,不會低於創世下限(100 和 800),也不會高於上限;沒有 gas.dynamic 時則為該區段的固定價格。沒有區段時,它們是該節點自己的政策,兩個節點的回答可能不同 |
bundle_gas_limit | 每個 bundle 證明必須聲明的固定 gas,取自創世的 gas 區段;沒有該區段時為 null |
adjust_bps | 動態控制器單一區塊內價格最大的變動幅度,以基點計;沒有 gas.dynamic 的鏈為 null |
max_gas_price, max_byte_price | v0.6.8:控制器不會把價格推高至其上的上限,為十進位字串;chain 20 上為 "10000" 和 "80000",創世沒有設定上限時為 null(chain 18 和 19) |
byte_load | v0.6.8:僅呼叫的證明和輸入信封會推動 byte_price 時為 "paying",因此一個只有轉帳的區塊不會令其變動,如 chain 20;每筆交易的位元組均計算在內時為 null(chain 18 和 19) |
admission_by_vote | v0.6.8:登記新 validator 金鑰的 bond,是否須先經 validator 集合投票(rand_getAdmitted);chain 20 上為 true |
testnet | v0.6.8:創世的 testnet 標記,容許 faucet 與 bridge 區段並存;chain 20 上為 true,在它之前的每條鏈上為 false |
slashing | v0.6.8:{ "equivocation_bps", "jail_epochs" },即領導者雙重提案所須付出的代價,或為 null;chain 20 上為 null |
binding_domain | v0.6.8:交易的綁定和每則已簽署的操作訊息只綁定鏈 id 時為 0(chain 14 至 19),連創世雜湊也一併綁定時為 1,如此為某條鏈所作的證明或簽署,在其他鏈上均無法通過驗證(chain 20)。錢包憑鏈 id 決定要證明哪一種形式,絕不憑此回覆:v0.6.8 的 rand 錢包對鏈 id 14 至 19 採用僅綁定鏈 id 的形式,對其他所有 id 採用綁定創世的形式,而讀取此欄位只是為了及早拒絕。早於 v0.6.8 的錢包無法在 chain 20 上發送 |
proof_window_blocks | v0.6.8:bundle 的錨點最多可以有多舊(以區塊計),以及其 time 最多可以落後高度多少,兩者共用同一個窗口;chain 20 上為 1024,至 chain 19 為止則為 null(256)。使用較慢或委託 prover 的錢包據此得知一次證明可以花多長時間 |
program_state | v0.6.8,RPL-2:創世的 program_state 區段及其 invoke 限制,或為 null,此時每個 invoke 均被拒絕,亦無法登記任何程式代幣。cell_fee 是 invoke 的費用下限每建立一個儲存格所增加的 RAND 單位(十進位字串),所謂建立,是指把非零值寫入讀取時為零的儲存格;改寫、刪除或寫入零值不收費。max_reads、max_writes 和 max_payouts(pays 與 mints 合計)為硬性上限。實際上先受到的是分段規則的約束:轉換的上下文字組(11 個,加上每次讀取或寫入 16 個,每筆付款 3 個)必須能與程式的公開輸入及 8 個綁定字組並存,而不令 zkVM 的公開表增長;沒有公開輸入的程式,該表為 128 列,餘下 119 個上下文字組 |
早於某欄位的節點回答時不含該欄位。此回覆中沒有任何內容經過驗證,因此錢包不會僅憑節點一面之詞就採信 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,上限亦為 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。
Staking and supply
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)是被罰沒的金鑰可再次進入集合的第一個 epoch(18446744073709551615 表示永久),未被監禁時為 null。Chain 20 沒有 staking.slashing,因此在該鏈上它一律為 null。
rand_getAdmitted
v0.6.8。參數 []。結果 { "admission_by_vote": true, "max": 256, "admitted": ["<address>", …] }:即驗證者集合已透過 AdmitValidator 投票接納、但尚未註冊的密鑰,按地址排序。在創世區塊設定了 staking.admission_by_vote 的鏈上(如鏈 20),註冊新密鑰的 Bond 必須是其中之一。max 為賬本同一時間可容納的數目。在沒有此旗標的鏈上,admission_by_vote 為 false,列表恆為空,註冊亦無需投票。鏈 20 於 2026-10-01 回應 "admitted": []。
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": "…",
"vesting_issued": "…", "vesting_released": "…", "vesting_in_register": "…", "vesting_locked": "…",
"program_rand_out": "…", "program_rand_held": "…",
"pool_value": "…", "register_total": "…", "total_supply": "…", "invariant_holds": true }
subsidised、sealed_blocks、aggregator_bonds 和 slashed 只在聚合鏈上變動。faucet_epoch 和 faucet_minted_in_epoch 是水龍頭按每個 epoch 計算的計數器,與 staking.faucet_budget_per_epoch 對照(鏈 20 上屬共識狀態)。四個 vesting_* 欄位是創世歸屬(vesting)的計數器,在沒有 vesting 部分的鏈上一律為 "0",鏈 20 即屬此類。program_rand_out 和 program_rand_held(v0.6.8,RPL-2;沒有 program_state 部分時為 "0")分別是 invoke 以 note 形式從程式金庫支付出去的 RAND(池一側,計入 pool_value),以及金庫仍持有的 RAND(登記一側,計入 total_supply);這些 RAND 是經 invoke 的 burn_r 進入的,所以在池一側計入 burned。registration_fees_burned 是依創世 tokens.burn_registration_fee 所銷毀的代幣註冊費總和(Σ),鏈 20 已設定此項;invariant_holds 會把它連同 slashed 從鏈的發行量中扣除。Supply 說明這條恆等式。
rand_getEmission
參數 []。結果 { "inflation": "0", "subsidy": null, "faucet": true }。inflation 固定為 "0"。subsidy 是區塊聚合的補貼時間表(current、base、halving_blocks、sealed_blocks、next_halving_at),在沒有 aggregation 部分的鏈上為 null,鏈 20 即屬此類。faucet 與 rand_status 一致。
Bridge
四個方法在任何鏈上都有回應;在沒有 bridge 部分的鏈上,狀態為 { "enabled": false },登記表為 []。鏈 20 的創世區塊設有此部分:守護者集合 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,以 zUSD note 形式留在 Rand 上,歸入國庫地址)。鏈 19 的 burn_sequence 為 8,下限為 1 和 4,兩組設定均沒有。其 tokens 部分設有 1 RAND 的 registration_fee(予以銷毀)、每項支持資產 10000000000000 的 mint_cap_per_day(八位小數下為 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 | 本鏈的外發 emitter 地址,32 字節十六進制 |
emitters | 來源鏈 id → 該鏈上受信任的 emitter 地址 |
guardians | 現任集合的 20 字節地址,十六進制 |
pq_guardians | PQ 集合:Dilithium2 公鑰(1,312 字節),十六進制,與現任守護者集合按索引對應(鏈 20 為集合 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 在基本費用之外須支付的金額,以 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 起,每一行支持資產(無論在此處,還是在其他提供支持資產的地方:rand_getBridgeState.assets,以及 rand_getToken、rand_getTokens 和 rand_getTokenSupply 的 backings)都附有 minted_in_window(十進制字串)和 mint_window_secs,兩者在日計數器鏈上均為 null,另有 mint_headroom:在區塊頭的出塊時間下,各項上限容許存入該支持資產的最大金額,即每項支持資產的上限減去其已鑄造量,而在 rules v2 下,不得超過全登記表窗口所剩餘的額度。請讀取 mint_headroom,而非 mint_cap_per_day − minted_today,後者忽略了全局上限。在 rules v2 下(如鏈 20),minted_today 是滾動窗口的計數,即每項支持資產上限所核對的數字;下文有關日計數器的說明屬於鏈 14。
每一行對應一項支持資產(來源幣種),因此有七項支持資產的代幣在同一個 index 下佔七行。index 是該資產的 note 所附帶的 asset 字;索引 0 是 RAND,從不在登記表中。decimals 是該支持資產的來源小數位數。locked、mint_cap_per_day 和 minted_today 是十進制字串,以代幣本身的八位小數單位計,而非 RAND 的單位;mint_day 是普通整數,即 UTC 日序號。mint_cap_per_day 是創世 tokens.mint_cap_per_day,即每項支持資產在區塊時間的每個 UTC 日內最多可鑄造的數量。minted_today 是該支持資產在 mint_day 所鑄造的數量,而 mint_day 是區塊頭的 UTC 日(timestamp_ms / 86,400,000),因此前一日遺留的計數器,在區塊頭越過午夜後會讀作 "0"。超出上限的存款會被拒絕,訊息為 MintCapExceeded,並在翌日可獲接納。chain 和 token 是守護者所簽署的線上身份;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 則是該 bundle 所銷毀的數額,即 release_amount + fee。沒有 bridge.fees 的鏈(鏈 14 至 19)上,fee 為 "0"。鏈 20 上的序號 13,是一次 0.999 zUSD 的銷毀:"amount": "99900000"、"fee": "99900"、"release_amount": "99800100"。
Tokens (RPL)
RPL 代幣登記表:所有代幣,包括橋接及原生者。Tokens 說明該標準。
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 的欄位,每項抵押資產一列 |
program | program |
供應量、locked、mint_cap_per_day、minted_today 及 registration_fee 均為十進位字串(registration_fee 以 RAND 為單位,其餘以代幣單位計);next_index、mint_day 及 max_tokens 為數字。max_tokens 是創世時對登記冊設定的上限(chain 20 上為 4,096;無上限時為 null),超出此數的登記會被拒絕,並回傳 RegistryFull。burn_registration_fee 表示登記費是否被銷毀,而非支付予出塊者;bound_note_value 表示數額達到或超過 2⁶³ 的鑄造或存入是否屬於有效性規則(無論在哪條鏈上,准入都會拒絕這類交易)。三者在 chain 20 上均已設定。條目數少於 limit 的一頁即為最後一頁。
program 權限({ "kind": "program", "program": "<id>" })只能在設有 program_state 區段的鏈上登記,chain 20 即是如此(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 相同。
區塊聚合(chain 20 上未啟用)
這些方法存在於節點中,供創世設有 aggregation 區段的鏈使用。在 chain 20 上,登記冊為空,從不會有任何內容被解封。
| method | params | result |
|---|---|---|
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 提交。
創世鎖定釋放(chain 20 上未啟用)
這些方法存在於節點中,供創世設有 vesting 區段的鏈使用。目前尚無任何鏈設有此區段:在 chain 20 上,各方法均回應 { "enabled": false }。公開端點自 2026-10-01 起轉發這些方法。
| method | params | result |
|---|---|---|
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。此 socket 只提供 rand_subscribe 及 rand_unsubscribe,對其他任何請求回應 -32601。共有三個主題,各為獨立的串流,彼此之間不保證先後次序:
newHeads— 形狀與rand_getHead相同,每提交一個區塊發送一次,依次序發送,同步期間亦然。此處的view是該區塊本身的 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。
錯誤
| code | meaning |
|---|---|
-32601 | 未知的方法(包括已停用的帳戶方法) |
-32602 | 參數無效或缺失 |
-32000 | 被拒絕:記憶池拒絕的交易、受速率限制的水龍頭呼叫、等候逾 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、anchor、登記冊),但只保留最近 <window> 時段內的區塊、交易及收據;rand_status.prune_floor 是它仍持有的最低區塊高度。在 chain 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
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
bincode 的預設配置:定長整數、8 位元組長度前綴、按宣告次序排列的 u32 列舉標籤。五個聚合變體排在 BridgeBurn 之後、RegisterToken 之前(Transactions);chain 20 從不接納它們,也不接納四個鎖定釋放變體或 SlashEquivocation,但硬編碼標籤編號的編碼器仍須將它們計算在內。
交易包的最後兩個欄位隨 v0.6.3 及 chain 17 加入。bincode 按位置編碼,因此為 chain 16 或更早版本編寫的編碼器,所產生的交易不能被本鏈解碼,而每個交易 id 亦隨之改變:id 的域現為 rand-txid-3,綁定 auth_commit 及驗證證明的摘要。在本地重新計算 id 的客戶端必須隨之更新。在 chain 20 上,每個交易包都帶有驗證證明,無論是自行證明或委託證明皆然。v0.6.8 並無更改 Transaction 或 Bundle 的佈局;它在後面附加動作 28 至 33。
每筆交易最多攜帶一個 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 是推導而得,並非自行選擇:准入時須符合對守護者所簽署摘要 mu 計算的 blake3("rand-deposit-r-1" ‖ mu),任何其他數值一律拒絕(WrongDepositBlinding,屬永久性拒絕)。橋接代幣必須先行上架(於創世區塊,或經由 RegisterBridgedToken / ListBacking),其任何證明方可被接納;未上架代幣的證明會被拒絕,並回報 UnlistedToken。
每個 bundle 證明均針對其所附帶的交易而生成,並以該交易驗證:即將證明清空後的整筆交易,綁定至鏈 ID,而在鏈 20(binding_domain: 1)上,另綁定至創世雜湊,並使用全新的標籤。在鏈 14 至 19 上,綁定僅限於鏈 ID,因此為鏈 19 生成的證明在鏈 20 上無法通過驗證,而 v0.6.8 之前的錢包亦無法在該鏈上發送交易。在鏈 18 至 20 上,不含兩個證明的 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。