Rand Protocol
Dokumentation
Referenz

JSON-RPC

Alle rand_*-Methoden, die der Node bereitstellt – Parameter, Ergebnisformate und Fehler – sowie Batches, die WebSocket-Subscriptions und das Wire-Format von Transaktionen.

Der Knoten stellt JSON-RPC 2.0 über HTTP auf --rpc bereit (Standard 127.0.0.1:8545) und auf demselben Port einen WebSocket für Subscriptions. Seit v0.6.8 kann er zusätzlich einen zweiten, öffentlichen Listener öffnen (--public-rpc, unten). randprotocol_client::RpcClient (Rust) kapselt jede der folgenden Methoden. Diese Seite ist die Methodenliste, wie v0.6.8 (c9c9bd3c), der Build, den Chain 20 betreibt, sie bereitstellt; wo eine Methode im Code existiert, auf Chain 20 aber wirkungslos ist, steht das dabei.

curl -s http://127.0.0.1:8545 -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"rand_getHead","params":[]}'

Der öffentliche Endpunkt

https://rpc.randprotocol.org (derselbe Proxy liegt auch unter https://randprotocol.org/api/rpc) leitet an einen Chain-20-Archivknoten weiter, der jeden Block vorhält, für Wallets und Seiten ohne eigenen Knoten (rand --rpc https://rpc.randprotocol.org …). Er nimmt nur HTTP POST an, hat offenes CORS und keinen WebSocket und ist enger gefasst als ein Knoten:

  • Eine Anfrage pro Aufruf. Ein Batch wird mit -32600 abgelehnt.
  • Eine Allowlist von Methoden: seit 2026-10-01 dieselbe Menge wie beim öffentlichen Listener des Knotens selbst (rpc::PUBLIC_METHODS in v0.6.8). Die Lesezugriffe auf den Programmzustand, die rand program invoke braucht, rand_getAdmitted, die Aggregations-Lesezugriffe und die Vesting-Lesezugriffe gehören dazu, ebenso rand_checkTransaction und rand_sendTransaction. rand_mint, rand_importViewingKey, rand_getViewingNotes, rand_removeViewingKey und rand_getPeers gehören nicht dazu und werden mit -32601 method not allowed here beantwortet, ohne den Knoten zu erreichen: Ein öffentlicher Faucet ist eine Missbrauchsfläche, und ein Viewing Key sollte nur an einen Knoten gehen, den Sie selbst betreiben.
  • Ein Request-Body von höchstens 12 MiB. Darin passen jede Überweisung, jede Token-Aktion und jedes Deployment sowie ein Aufruf, dessen Beweis bis zu etwa 3,4 MB groß ist (die Transaktion ist hex-kodiert, und ihre Bundle- und Auth-Beweise belegen etwa 2,85 MB, bevor der Beweis des Aufrufs hinzukommt). Ein größerer Aufruf gehört an Ihren eigenen Knoten. Über dem Limit: HTTP 413 und -32600.
  • Pro Adresse 1.200 Anfragen pro Minute und 6 pro Minute für rand_sendTransaction. Darüber: HTTP 429 und -32005. Das Lesebudget ist auf die erste Synchronisation einer Wallet ausgelegt, das sind mehrere hundert Anfragen in einem Schub (645 bei Chain 18 auf Höhe 99.000).
  • -32000 upstream unavailable, wenn der dahinterliegende Knoten nicht antwortet.

Alles Übrige auf dieser Seite beschreibt den Knoten selbst.

Die zwei Listener des Knotens

Seit v0.6.8 (Audit v6) hat ein Knoten zwei JSON-RPC-Listener.

  • --rpc <ADDR>, der Listener des Betreibers. Alle Methoden, Batches und der WebSocket. Er identifiziert einen Aufrufer anhand seiner Socket-Adresse und vertraut Loopback: Die Viewing-Key-Methoden antworten nur auf Loopback, und Loopback wird nicht gemessen. Belassen Sie ihn auf 127.0.0.1. Ein Reverse-Proxy oder eine SSH-Weiterleitung kommt über Loopback an, sodass dahinter jeder Besucher der Betreiber ist: Richten Sie niemals einen öffentlichen Endpunkt auf diesen Port.
  • --public-rpc <ADDR>, der öffentliche Listener, genau für diesen Zwischenschritt. Er stellt eine feste Methodenmenge bereit, die Lesezugriffe, die eine Wallet, ein Explorer oder eine Seite braucht, sowie rand_sendTransaction (rpc::PUBLIC_METHODS). rand_importViewingKey, rand_getViewingNotes, rand_removeViewingKey, rand_mint und rand_getPeers werden dort nie bedient, ebenso wenig eine später hinzugefügte Methode, bevor sie aufgelistet ist; ein solcher Aufruf wird mit -32000 <method> is not served on this node's public listener beantwortet. Ein Batch ergibt -32600, und es gibt keine WebSocket-Route. Ein einziger Zähler deckt alle Aufrufer zusammen ab, 600 Anfragen im Schub und 150 pro Sekunde; darüber HTTP 429 mit einem -32000-Body. Limits pro Besucher gehören zum Proxy, der die Besucher sehen kann. Seine Aufrufer belegen höchstens die Hälfte der blockierenden Lese-Slots des Knotens, sodass der Listener des Betreibers nie ausgehungert wird.

Beide Listener teilen sich zwei Lese-Limits. Ein blockierender Lesezugriff, der nicht innerhalb von 30 s zurückkehrt, wird mit -32000 this read took longer than 30 s on this node; retry with a smaller range beantwortet. rand_getBlocks beendet seine Seite, sobald es 64 MiB an Blöcken gelesen hat.

--rpc-viewing-token-file <PATH> legt ein Bearer-Token auf die Viewing-Key-Methoden von --rpc: die erste Zeile der Datei, mindestens 32 Zeichen, gesendet als Authorization: Bearer <token>. Damit genügt Loopback allein nicht mehr, und ein Aufrufer von beliebiger Stelle, der es vorweist, wird bedient.

Konventionen

  • Validator-Adressen sind base58-Zeichenketten (32 Bytes). Hashes bestehen aus 64 Hex-Zeichen, mit oder ohne 0x. Abgeschirmte Werte — Commitments, Nullifier, Anker, Baumwurzeln, Witness-Ebenen — sind Word8: acht Little-Endian-u32-Wörter als 64 Hex-Zeichen in Kleinbuchstaben.
  • Abgeschirmte Adressen sind rand1 + base58, 1.667 Zeichen. Ein Parameter mit mehr als 2.000 Zeichen wird aufgrund seiner Länge abgelehnt, bevor er geparst wird.
  • Jeder u64-Betrag ist eine Dezimalzeichenkette ("1500000000" = 1,5 RAND; 1 RAND = 10⁹ Einheiten): RAND-Einheiten oder Token-Einheiten, Chain-Zustand oder das eigene Feld einer dekodierten Transaktion. Eine JSON-Zahl ist jenseits von 2⁵³ keine exakte Ganzzahl, und die Menge eines Tokens mit 9 Dezimalstellen überschreitet das bei einigen zehn Millionen Einheiten. Was das geändert hat, steht in der datierten Anmerkung unten.
  • Indizes, Nonces, Höhen, Blattindizes, Views, Längen, Dezimalstellen und Tageszähler (mint_day) sind nie Beträge und durchgehend JSON-Ganzzahlen.
  • Jede Anfrage muss ein id-Mitglied enthalten. Ein Objekt ohne id ist eine Notification und wird mit -32600 abgelehnt; ein explizites "id": null ist eine normale Anfrage.
  • Es gibt keine Guthaben-Methode und keine Konto-Methode. Eine Wallet berechnet ihr Guthaben, indem sie rand_getCommitments und rand_getNullifiers mit ihrem Viewing Key durchsucht. rand_getBalance, rand_getAccount und rand_getAssetBalance antworten mit -32601.

Breaking Change, 2026-09-20 (Chain 14): Jeder Betrag ist eine Dezimalzeichenkette

Vor Chain 14 waren Beträge innerhalb einer dekodierten Transaktion JSON-Ganzzahlen. Diese Ausnahme ist entfallen. Diese Felder wechselten von JSON-Zahlen zu Dezimalzeichenketten, ohne weitere Änderung an Bedeutung oder Position:

  • bundle.fee, in tx von rand_getTransaction und in transactions[] von rand_getBlockByHeight / rand_getBlockByHash;
  • action.amount für kind = mint, bond, unbond, withdraw, bridge_attest (dieselben drei Methoden);
  • action.amount und action.relayer_fee für kind = bridge_burn (dieselben drei Methoden);
  • locked in den Zeilen von rand_getAssets und von rand_getBridgeState.assets[].

Ein Client, der eines dieser Felder als Zahl liest, muss stattdessen eine Zeichenkette parsen. aggregation.subsidy_base von rand_status (nur Aggregations-Chains) wurde mit derselben Änderung zur Zeichenkette. Jeder andere Betrag war bereits eine Zeichenkette: rand_getSupply, rand_getEmission, rand_getValidators, Viewing Notes und jedes mit Chain 14 eingeführte Feld — burn_a und burn_r des Bundles, die Token-Mengen, locked, mint_cap_per_day und minted_today jedes Backings, registration_fee sowie der amount von token_mint, token_burn und register_token (initial_amount, initial.amount).

Batches

Ein POST-Body darf ein Array von höchstens 20 Anfrageobjekten sein; beantwortet wird er mit einem Array gleicher Länge in der Reihenfolge der Anfragen, Fehler eingeschlossen. Die Anfragen laufen nacheinander. Ein leeres Array, ein Array mit mehr als 20 Elementen oder ein Body, der weder Objekt noch Array ist, ergibt ein einzelnes -32600 mit Null-id. Der gesamte Body ist weiterhin durch das Request-Body-Limit des Knotens begrenzt, das für eine einzelne beweistragende Transaktion bemessen ist: Ein Batch aus zwei beweistragenden rand_sendTransaction-Aufrufen wird mit 413 abgelehnt. Bündeln Sie Lesezugriffe, nicht beweisbehaftete Übermittlungen.

Chain und Knoten

rand_chainId

Params []. Ergebnis: die Chain-ID (Ganzzahl); 20 auf dem testnet.

rand_tokenInfo

Params []. Ergebnis { "symbol": "RAND", "decimals": 9 }.

rand_getHead

Params []. Ergebnis { "height": 1998, "hash": "…", "view": 2251 }. view ist der aktuelle Konsens-View des Knotens, der der Höhe vorauseilt, wenn Views ablaufen.

rand_status (alias rand_syncStatus)

Params []. Ergebnis:

{
  "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: Dieser Knoten hält einen Validator-Schlüssel; active_validator: Dieser Schlüssel gehört zur Menge, die die aktuelle Epoche betreibt. reserved_peers (v0.6.8) zählt die Peers, die über das Limit für eingehende Verbindungen hinaus zugelassen sind: die Bootstraps, jeden --reserved-peer und jede aus einer signierten Peer-Bindung gelernte Validator-Identität, jeweils einmal; auf einem Flottenknoten sollte der Wert binnen einer Minute nach dem Start die Zahl der Validatoren erreichen. viewing_keys gibt an, wie viele Viewing Keys der Knoten für das knotenseitige Scannen im Speicher hält. verify_queue ist die Zahl der Transaktionen, die auf einen der vier Beweisverifikations-Worker warten (höchstens 64 tief). hc_bundle ist der Bundle-Guest, gegen den die Beweise dieser Chain laufen, und hc_auth der Auth-Guest, den ihr Genesis festlegt (geteilte Autorisierung, seit Chain 17), oder null auf einer Chain ohne einen solchen; ein Knoten, dessen Build von einem von beiden abweicht, weigert sich zu starten. testnet und binding_domain sind die gleichnamigen Genesis-Felder, wie rand_getLimits sie liefert. gas_prices sind die aktuellen Gaspreise des Tip-Ledgers, bei jedem Commit aktualisiert, als Dezimalzeichenketten; null auf einer Chain ohne gas-Abschnitt. Die Preise von Chain 20 sind dynamisch und bewegen sich pro Block nach Auslastung, nie unter die Untergrenzen von 100 und 800 und nie über die Obergrenzen von 10.000 und 80.000; lesen Sie sie daher hier oder in rand_getLimits und codieren Sie sie nicht fest. Das Objekt enthält außerdem ein aggregation-Objekt (sein subsidy_base eine Dezimalzeichenkette, der Rest Ganzzahlen), das auf einer Chain ohne aggregation-Abschnitt, wie Chain 20 es ist, durchgehend Nullen zeigt.

Das Objekt enthält außerdem disk_free_bytes (eine Zahl) und disk_low sowie das Aufbewahrungspaar: prune_floor, die niedrigste Höhe, die dieser Knoten noch vorhält (0 bei einem Archivknoten), und prune_history_secs, das Fenster, das ein mit --prune-history gestarteter Knoten aufbewahrt (null, wenn er alles aufbewahrt). Auf Chain 20 halten, wie auf Chain 19, 24 der 26 Validatoren 24 Stunden an Blöcken vor; die beiden Archivknoten halten alle vor. Siehe Pruned nodes.

rand_getPeers

Params []. Ergebnis: ein Array von { "peer_id": "12D3KooW…", "addrs": ["/ip4/…/tcp/30303"], "connected_secs": 1241 }.

rand_getBlockByHeight / rand_getBlockByHash

Params [height] oder [hash]. Ergebnis null, wenn unbekannt, sonst:

{
  "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": [ ]
}

Es werden nur committete Blöcke ausgeliefert. transactions hat dieselbe Form wie tx in rand_getTransaction. Ein Block trägt außerdem sealed, und jede seiner Transaktionen sealed_by; auf einer Chain ohne Aggregation lauten sie false und null.

rand_getBlocks

Parameter [from_height, to_height]. Ergebnis: Block-Header, älteste zuerst, höchstens 1.024 ab from_height (128 auf einem Node vor dem 2026-09-24): die Felder von rand_getBlockByHeight ohne transactions. Ein Bereich, der größer als das Limit ist oder über den Head hinausreicht, wird gekürzt, nicht abgelehnt, und seit v0.6.8 endet eine Seite außerdem, sobald sie 64 MiB an Blöcken gelesen hat; fahren Sie ab der letzten zurückgegebenen Höhe fort. -32602, wenn to_height kleiner als from_height ist.

Seit v0.6.8 trägt jeder Header außerdem public_notes: die Transaktionen bridge_attest, token_mint und register_token des Blocks, auf einer Chain mit Bridge-Gebühren auch seine bridge_burn-Transaktionen, als [{ "hash", "raw" }] (die Kodierung, die rand_getRawTransaction liefert); bei allen anderen Blöcken leer. Ein Burn wird mit geleerten Beweisen und "proofs_stripped": true ausgeliefert; sein hash ist die tatsächliche Transaktions-ID. Die erste Synchronisierung einer Wallet liest diese Seiten und braucht sonst nichts, um die öffentlichen Notes wiederherzustellen.

rand_getFinality

Parameter [height] oder [hash]. Ergebnis, eines von { "status": "committed", "height", "hash" }, { "status": "certified", "height", "hash", "qc_view" }, { "status": "proposed", "height", "hash" }, { "status": "unknown" }. Eine Höhe wird immer nur gegen die committete Chain geprüft, daher lautet die Antwort committed oder unknown; ein Hash kann zusätzlich certified ergeben (im nicht committeten Baum des Replikas, mit Quorum-Zertifikat) oder proposed (im Baum, ohne ein solches).

rand_getProposer

Parameter [view] oder [from_view, to_view], höchstens 64 Views. Ergebnis { "epoch": 3, "proposers": [ { "view": 2251, "proposer": "2nRdFC…" } ] }: der Leader jedes Views unter der aktuellen Validator-Menge, nicht unter der Menge, die in diesem View historisch aktiv war. -32602 bei einem rückwärts gerichteten Bereich oder mehr als 64 Views.

rand_getVersion

Parameter []. Ergebnis { "version", "git_sha", "chain_id", "hc_bundle", "hc_auth", "fri_profile" }. version ist die Version des Workspace-Crates; git_sha der beim Build erfasste Commit-Hash, mit angehängtem -dirty, wenn sich verfolgte Dateien unterschieden, oder "unknown". hc_auth ist der Genesis-Auth-Guest, wie in rand_status, oder null. Der öffentliche Endpunkt am 2026-10-01, auf Chain 20:

{ "version": "0.6.8", "git_sha": "c9c9bd3c1903aa4cc5833b7ab8c62fc3e6942017", "chain_id": 20,
  "hc_bundle": "60af094acfe65d85fdb18fb3d06cf9085dcf28c96e59e87f1ee527226e6e3fce",
  "hc_auth": "1e4e347f44cf86750b30a9a4bdf9ec9256efe353d4ff8017451eca7d195639c1",
  "fri_profile": "production" }

rand_getGenesisHash

Parameter []. Ergebnis: der Genesis-Hash als Hex; "6210cf071a390d7ac61d8cbea5dd9d139d1a493a862b54a45a498f36af2d5135" auf Chain 20 (der von Chain 19 war a3defc93…228a). Eine Chain-ID allein unterscheidet zwei Chain-Schnitte nicht; dieser Wert schon. Auf Chain 20 ist er außerdem Teil jeder Transaktionsbindung und jeder signierten Aktionsnachricht (binding_domain: 1, siehe rand_getLimits).

rand_getHealth

Parameter []. Ergebnis, eines von { "status": "disk_low", "free_bytes": "3221225472" }, { "status": "ok" }, { "status": "syncing", "behind": 412 }, { "status": "behind", "behind": 30 }. disk_low hat Vorrang vor allem anderen, wenn der freie Speicher im Dateisystem des Datenverzeichnisses unter dem Vierfachen des --min-free-disk-mb des Nodes liegt (Standard 1024, also unter 4 GB); free_bytes ist ein Dezimalstring. ok, wenn sync_target - height höchstens 2 beträgt und keine Sync-Batch-Anfrage aussteht; syncing, solange eine aussteht; behind, wenn der Node nicht synchronisiert und der Rückstand weiterhin über 2 liegt.

rand_getMempoolInfo

Parameter []. Ergebnis { "count": 2, "bytes": 2611200, "oldest_ms": 1450, "max_count": 10000 }. bytes summiert die kodierte Länge aller Transaktionen im Pool; oldest_ms ist null, wenn der Pool leer ist. Seit v0.6.8 ist der Pool außerdem in Bytes begrenzt, auf das Achtfache des Genesis-Werts max_block_bytes (160 MiB auf Chain 20): darüber verdrängt eine Transaktion, die pro KiB mehr über ihrem Mindestwert zahlt, die günstigste, und eine, die weniger oder gleich viel zahlt, wird mit mempool full abgelehnt. Governance-Aktionen passieren beide Limits.

Einreichen

rand_sendTransaction

Parameter [hex], wobei hex gleich bincode(Transaction) ist. Ergebnis: der Transaktions-Hash. Der Node validiert in der Reihenfolge der Zulassung (Transaktionen), nimmt die Transaktion in den Pool auf und verbreitet sie per Gossip. Fehler sind -32000 mit dem Grund: nullifier already spent, anchor is not one of the last 1024 roots, time 12 is outside [1500, 2524] (beide Fenster entsprechen dem Genesis-Wert proof_window_blocks, 1.024 auf Chain 20; 256 auf den Chains bis 19), 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; bei einem invoke cell <key> is no longer what this transition read (ein Zustandsurteil: die Zelle erneut lesen und neu beweisen) oder the vault holds … of asset … and the transition pays …; bei einer registrierenden Bond unter Zulassung per Abstimmung validator … has not been admitted by the validator set's vote (staking.admission_by_vote); ask the validators for an AdmitValidator first; bei einem Bundle, das nicht zum Genesis von Chain 20 passt, 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; bei den Bridge-Aktionen 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; bei einem Bundle, das einen Burn trägt, den seine Aktion nicht tragen darf, the bundle burns asset 2 on an action that burns no token, a burn of 5 is not allowed on this action oder RAND burned through burn_a (5); a RAND burn goes through burn_r; beim Zustand der Bridge 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; bei der Token-Registry wrong mint nonce und wrong token index. Annahme ist nicht Commitment: Fragen Sie rand_getTransaction oder rand_getTransactionStatus ab.

Eine Transaktion, die größer ist als das Block-Limit der Chain (max_block_bytes aus rand_getLimits), wird mit -32000 abgelehnt, das beide Größen nennt, noch bevor sie den Mempool erreicht. Der Request-Body ist begrenzt auf 2 × (2 × max_proof_bytes + 4 × 2048 + max_call_envelope_bytes + 16,384 + 64 KiB) + 256 KiB, beim Start aus dem Genesis berechnet: 8.867.840 Bytes auf einer Standard-Chain und 17.350.656 bei den Limits von Chain 20, dasselbe wie auf den Chains 17 bis 19 (34.127.872 auf den Chains 13 bis 15, deren Beweislimit 8 MiB betrug). 4 × 2048 sind die vier Envelopes des Bundles am Envelope-Limit. Ein Body darüber ergibt -32600 mit Nennung des Limits.

Nur -32000 (die Zulassung hat abgelehnt) und -32602 (sie ließ sich nicht dekodieren) sind ein Urteil über die Transaktion. Jeder andere Fehler, -32603 eingeschlossen, lässt ihr Schicksal offen: Der Node nimmt eine Transaktion in den Pool auf und verbreitet sie per Gossip, bevor er antwortet, sodass ein Node, der in diesem Fenster ausfällt, etwas zugelassen haben kann, wofür er nie geantwortet hat. randprotocol_client behandelt einen Versand nur bei diesen beiden Codes als abgelehnt.

rand_getTransactionStatus

Parameter [[hash, …]], 1 bis 64 Hashes. Ergebnis: ein Eintrag pro Hash, in derselben Reihenfolge:

[ { "hash": "…", "status": "committed", "height": 1998, "index": 0 },
  { "hash": "…", "status": "pending" },
  { "hash": "…", "status": "rejected", "reason": "bad mint signature" },
  { "hash": "…", "status": "unknown" } ]

Suchreihenfolge pro Hash: committet (Speicher), ausstehend (der Mempool), abgelehnt (der Cache abgelehnter Transaktionen, den refused_cache von rand_status zählt), sonst unknown. rejected umfasst nur Ablehnungen, die die eigenen Bytes der Transaktion betreffen und die kein späterer Block ändern kann: ein ungültiger Beweis, ein Bundle-Digest, der nicht dem entspricht, was sein Beweis veröffentlicht hat, eine fehlerhafte Mint-Signatur, die falsche Chain-ID, ein übergroßer Teil, ein wiederholter Nullifier oder eine wiederholte Commitment innerhalb der Transaktion, ein Envelope der falschen Größe, ein fehlender oder nicht passender Auth-Beweis, ein Bundle oder Auth-Beweis, der das falsche Gas-Limit angibt. Eine Ablehnung, die vom Zustand des Nodes in diesem Moment abhängt — ein ausgegebener Nullifier, ein Anchor oder time außerhalb des Fensters, eine Gebühr unter dem Mindestwert (der sich auf Chain 20 mit den Gaspreisen verschiebt), ein unbekanntes Programm, eine Register-Nonce, ein veralteter invoke-Lesezugriff — wird nicht gespeichert und ergibt unknown. -32602 bei einer leeren Liste oder mehr als 64 Hashes.

rand_mint (testnet-Faucet)

Parameter [address] oder [address, amount]; address ist eine rand1…-Adresse, amount ein String in Einheiten von höchstens 100000000000 (100 RAND, der Standardwert). Ergebnis: der Hash der Mint-Transaktion. Nur auf einer Chain, deren Genesis "faucet": true setzt; andernfalls -32000 faucet is disabled on this chain. Ein Observer antwortet faucet mints are signed by validators; ask a validator node.

Auf einer Chain, deren Genesis staking.faucet_recipients setzt, wie es bei Chain 20 der Fall ist (16 Wallets), können nur die aufgeführten Wallets bezahlt werden: Ein Mint an eine andere Adresse wird mit the faucet may not mint to this recipient (not in staking.faucet_recipients) abgelehnt. Das Genesis von Chain 20 setzt außerdem staking.faucet_minters (18 Validator-Schlüssel): Nur ein aufgeführter Schlüssel darf einen Mint signieren. Der Faucet hat zudem ein Budget pro Epoche, staking.faucet_budget_per_epoch (10.000 RAND pro Epoche von 1.000 Blöcken auf Chain 20); ein Mint darüber hinaus wird mit FaucetBudgetExhausted abgelehnt, einem Zustandsurteil, das unknown ergibt, sobald es den Pool verlassen hat.

Der Faucet ist pro Node-Prozess ratenbegrenzt: acht Mints direkt hintereinander, danach eine Auffüllung von einem Mint pro Sekunde. Darüber hinaus antwortet der Aufruf mit faucet is rate limited on this node (8 mints back to back, refilling at 1/s); try again shortly. Eine Faucet-Flut kann den Pool daher nicht vor einem Bridge-PauseMints füllen. Dieser ist, wie die drei übrigen Bridge-Governance-Aktionen, außerdem von der mempool full-Ablehnung des Pools ausgenommen und wird in einem Block zuerst eingeordnet.

Seit Chain 14 ist ein Mint geöffnet: Die Mint-Aktion trägt neben cm und amount auch pk, time und r der Note. Die Zulassung berechnet die Commitment neu und weist ein cm zurück, das sich nicht zu diesen Werten öffnen lässt (the mint's commitment does not open to its published note and amount). Der Minter signiert alle sieben Felder unter der Domain rand-mint-2; auf Chain 20 (binding_domain: 1) unter rand-mint-3, mit dem Genesis-Hash an erster Stelle. Eigentümer und Betrag einer Faucet-Note sind damit öffentlich, ebenso wie die Auszahlung eines Withdraw. Die Parameter von rand_mint sind unverändert.

rand_estimateFee

Parameter [spec], eines von {"kind":"bundle"}, {"kind":"deploy","words":n,"public_words":m}, {"kind":"call","tier":t,"bytes":b,"gas":g} mit t aus 10, 12, 14, 16, 18, 20. Ergebnis: die Mindestgebühr in Einheiten, als String. {"kind":"bundle"} ergibt "1000000". public_words (optional, Standard 0) wird wie Code pro Wort bezahlt, die Gebühr entspricht also der Deploy-Gebühr für n + m Wörter. bytes (optional, Standard 0) ist die Länge des Beweises des Aufrufs plus die Länge seines Eingabe-Umschlags.

Wie ein Aufruf bepreist wird, hängt von gas_metering in rand_getLimits ab:

  • "circuit", eine Chain mit eigenem gas-Abschnitt, wie Chain 20 sie hat. gas ist das Gas-Limit, das der Beweis des Aufrufs deklariert, und es ist erforderlich: Ohne es antwortet der Aufruf mit -32602 under the gas section a call estimate needs its gas. Die Antwort lautet 1,000,000 + gas_price × gas + byte_price × ⌈bytes / 1024⌉ zu den aktuellen Preisen der Chain-Spitze, also denen, die rand_getLimits liefert. Bei den Mindestpreisen von Chain 20, 100 und 800, ergibt ein Aufruf, der 20,479 Gas mit 1,300,000 Bytes an Beweis und Umschlag deklariert, "4063900". Die Preise ändern sich pro Block, schätzen Sie also kurz vor dem Senden.
  • "header", eine Gas-Richtlinie auf Node-Ebene bei einer Chain ohne diesen Abschnitt. Die Aufrufspezifikation nimmt keccak_log_height und sha256_log_height entgegen (optional, Standard 0, jeweils 0 bis 40, sonst -32602), die Höhen der Hash-Tabellen, die der Beweis-Header deklariert. Die Antwort ist der höhere Wert aus der Tier-Untergrenze des Ledgers und der Gas-Untergrenze dieses Headers. Unter einem gas-Abschnitt werden die beiden Höhen akzeptiert, aber nicht verwendet.
  • null, keines von beiden. Allein der Tier-Plan des Ledgers: Bis zum kostenlosen Kontingent (2,097,152 + 18,432 Bytes) kostet ein Aufruf die Gebühr seines Tiers; jedes KiB darüber, wobei ein angebrochenes KiB als volles zählt, fügt 1,000 Einheiten hinzu.

Seit v0.6.8 bepreist {"kind":"invoke", …, "created_cells": c} ein RPL-2-invoke: alle Felder einer Aufrufspezifikation plus created_cells (optional, Standard 0, höchstens max_writes, sonst -32602), die Zellen, die der Übergang anlegen würde. Jede erhöht die Gebühr um den cell_fee der Chain (rand_getLimits.program_state). Der Aufrufer zählt sie: ein Schreibzugriff mit einem Wert ungleich null auf eine Zelle, die rand_getProgramCell als Nullen liest. Auf Chain 20 ergibt der obige Aufruf mit zwei angelegten Zellen "24063900". Bei einer Chain ohne program_state-Abschnitt ist die Art -32602.

Fees enthält den Plan.

The pool

rand_getTreeInfo

Parameter []. Ergebnis { "next_index": 41, "root": "6b1d…c4", "nullifiers": 12 }: die Anzahl der Blätter, die aktuelle Wurzel, wie viele Notes ausgegeben wurden.

rand_getCommitments

Parameter [from_index] oder [from_index, limit]. Ergebnis: eine Seite von Blättern ab from_index, die ältesten zuerst, höchstens 1,000 Zeilen, wie groß limit auch ist.

[ { "index": 40, "cm": "2a9f…07", "height": 37,
    "envelope": { "kem_ct": "b41c…", "to_receiver": "77e0…", "to_sender": "0c31…", "body": "9dd2…" } } ]

rand_getNullifiers

Parameter [from_height] oder [from_height, limit]. Ergebnis: jeder Nullifier, der ab dieser Höhe veröffentlicht wurde, mit derselben Obergrenze von 1,000 Zeilen. Eine Seite kann mitten in einer Höhe enden; blättern Sie zurück bis zur höchsten gesehenen Höhe.

[ { "height": 37, "nullifier": "8c04…d1" }, { "height": 41, "nullifier": "12be…9a" } ]

rand_getCompactBlocks

Parameter [from_height, to_height], beide erforderlich. Ergebnis: eine Zeile pro Block, die ältesten zuerst, mit dem, was ein Light Wallet braucht, und sonst nichts:

[ { "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"] } ] } ]

Jede Transaktion mit Bundle besitzt hier vier Notes und vier Nullifier, also ihre vier Slots, einschließlich der Dummy-Slots, die kein Leser von echten unterscheiden kann (nur die erste Commitment-Zeile des Beispiels ist gezeigt). Seit v0.6.8 besitzen einige mehr Notes, nach diesen vier: Ein invoke besitzt eine Note pro Auszahlung, erst pays, dann mints, jeweils mit dem eigenen Umschlag der Auszahlung, sodass ein Zahlungsempfänger sie per Trial Decryption findet; bei einer Chain mit Bridge-Gebühren, wie Chain 20 sie hat, besitzt ein bridge_burn seine Treasury-Gebührennote und ein bridge_attest seine Gebührennote nach seiner Einzahlung. Der Umschlag einer Gebührennote ist leer, an niemanden versiegelt: Das Treasury-Wallet baut die Note aus den öffentlichen Feldern der Transaktion nach.

Höchstens 128 Blöcke pro Aufruf (ein weiterer Bereich wird gekappt) und, ab dem ersten Block, der immer vollständig geliefert wird, 1,000 Notes; setzen Sie beim zuletzt gelieferten height plus eins fort. Das commitments-Array auf Blockebene enthält bei Höhe 0 die Genesis-Einzahlungen und ist sonst leer; die abgeleiteten Notes eines Withdraw und eines BridgeAttest erscheinen unter ihrer Transaktion. -32602 bei rückwärts gerichtetem Bereich oder fehlender Grenze.

rand_getAnchor

Parameter [] für den Head oder [height]. Ergebnis { "height": 192, "root": "6b1d…c4" }, oder -32001 bei einer Höhe ohne aufgezeichneten Anker. Nur Wurzeln am Blockende sind Anker. Der Node kann für eine alte Höhe antworten, aber der Anker eines Bundles ist nur zulässig, wenn er zu den letzten proof_window_blocks Wurzeln gehört: 1,024 auf Chain 20, 256 auf Chains bis 19. Bauen Sie gegen den Head.

rand_getWitness

Parameter [index]. Ergebnis null hinter dem Ende des Baums, sonst der Merkle-Pfad dieses Blatts, Blatt zuerst, genau 32 Ebenen, mit der aktuellen Wurzel des Baums:

{ "index": 40, "root": "6b1d…c4", "path": ["0000…00", "f2a1…3b", "…"] }

Die teuerste Leseanfrage, die der Node bedient (er baut den vollständigen Baum der Tiefe 32 neu auf), und die einzige Anfrage, die etwas über den Aufrufer preisgibt. Ein Node führt höchstens zwei Baum-Neuaufbauten gleichzeitig aus, rand_getWitness und rand_getWitnesses zusammen; eine Anfrage, die länger als 10 s auf einen Slot wartet, wird mit -32000 witness builds are busy on this node; retry shortly abgewiesen.

rand_getWitnesses

Parameter [[index, …]], 1 bis 32 Blattindizes. Ergebnis { "root": "…", "witnesses": [ { "index": 7, "path": ["…"] }, { "index": 9, "path": null } ] }: rand_getWitness, über viele Blätter in einem Baumaufbau gefaltet, sodass ein Wallet, das mehrere Notes beweist, den Neuaufbau nur einmal bezahlt. Ein Index hinter dem Ende des Baums liest für diesen Eintrag path: null. -32602 bei leerer Liste oder mehr als 32 Indizes.

Viewing keys and disclosure

rand_importViewingKey

Parameter [viewing_key] oder [viewing_key, rescan_from_height], der Schlüssel als 64 Hexadezimalzeichen. Ergebnis { "imported": true, "rescan_from_height": 0, "viewing_keys": 3 }. Der Node hält den Schlüssel nur im Arbeitsspeicher: höchstens 64 pro Node, beim Neustart geleert; ein bereits gehaltener Schlüssel ist ein No-op ("imported": false). Der Import scannt nie; der Scan wird von der nächsten Methode angestoßen. -32602 bei einem fehlerhaften Schlüssel; -32000 beim 65. Schlüssel.

Die drei Viewing-Key-Methoden antworten nur einem Loopback-Aufrufer und weisen jeden anderen mit -32000 ab, es sei denn, der Node läuft mit --rpc-viewing-open hinter etwas, das authentifiziert. rand_removeViewingKey ([viewing_key] → { "removed": bool, "viewing_keys": n }) gibt einen Slot frei und überschreibt den Schlüssel mit Nullen. Das Register wird über eine Einweg-ID des Schlüssels geführt, blake3("rand-viewing-registry-id-1" ‖ nk), nie über den Schlüssel selbst, sodass der Import die einzige langlebige Kopie ist und das Entfernen sie löscht. Der JSON-Text der Anfrage selbst und die flüchtigen Kopien, die die Trial Decryption anlegt, werden nicht überschrieben.

rand_getViewingNotes

Parameter [viewing_key] oder [viewing_key, from_index, limit] (limit Standard und Maximum 1,000). Jeder Aufruf setzt den Scan des Schlüssels um bis zu 10,000 Blätter fort und liefert dann die Seite:

{ "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 ist received (der Umschlag wurde als Empfänger geöffnet und die Note nennt den pk des Schlüssels) oder sent (geöffnet über den ausgehenden Viewing Key). Das memo der Note ist das verschlüsselte Memo des Senders, UTF-8-Text von höchstens 510 Bytes, oder null, wenn keines vorhanden ist oder sein Feld fehlerhaft geöffnet wurde; ein fehlerhaftes Memo kostet den Zahlungsempfänger nie die Note. Ein Memo ist der Text von irgendjemandem: Zeigen Sie es als nicht vertrauenswürdig an. -32001 bei einem Schlüssel, den dieser Node nicht importiert hat.

rand_checkTransaction

Parameter [hash, key], key ein TxKey pro Transaktion als 64 Hexadezimalzeichen. Ergebnis null bei unbekanntem Hash, sonst das, was der Schlüssel offenlegt:

{ "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" } } ] }

Zustandslos: Der Schlüssel wird mit dem Aufruf verworfen. output ist bundle:0 … bundle:3 für die vier Ausgabeslots des Bundles (Slots 0–1 die Ausgaben des privaten Assets, Slots 2–3 die RAND-Ausgaben, Dummies eingeschlossen), deposit für den Einzahlungs-Umschlag einer Bridge-Attestierung, token_mint für die Note eines TokenMint, initial_mint für den Anfangs-Mint eines RegisterToken, mint:0 für den einen Umschlag eines Faucet-Mints oder (v0.6.8) payout:0 … payout:3 für die Notes, die ein invoke ausgezahlt hat, nummeriert nach ihrer Stelle im Übergang, erst pays, dann mints; asset_bundle:* entfällt mit dem zweiten Bundle. Auf einer Chain mit Bridge-Gebühren öffnet deposit die Netto-Einzahlung, den Bruttobetrag abzüglich der Gebühr. Die offengelegte note enthält ihr asset: Dieser Aufruf mit dem Schlüssel, unter dem der Sender versiegelt hat, ist die einzige Stelle, an der die RPC offenlegt, welches Asset ein Transfer bewegt hat. Sie enthält auch das memo, wie es rand_getViewingNotes tut: Der Schlüssel, der die Note öffnet, öffnet das Memo, aus demselben versiegelten Körper. Ein falscher Schlüssel liefert { "disclosed": [] }, nicht unterscheidbar von einer Transaktion, die nichts offenlegt. Die Umschläge eines Withdraw und eines Genesis-Alloc werden nicht versucht: Sie werden im Node unter sofort verworfenen Schlüsseln versiegelt, sodass für sie kein TxKey existiert. Der eines Faucet-Mints wird versucht: Sein Empfänger gewinnt den Schlüssel über die KEM-Hälfte des Umschlags zurück (rand tx-key).

Transaktionen

rand_getTransaction

Parameter [hash]. Ergebnis null, bis die Transaktion committet ist, danach:

{
  "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 ist bei den Aktionen ohne Bundle null. Die Beweise und Umschläge werden nur mit ihrer Länge angegeben. envelope_len beträgt auf Chain 20 für jeden Slot 1,860; deren Genesis legt den Note-Umschlag auf diese Größe fest (envelope_bytes in rand_getLimits); auf den Chains 14 bis 17 waren es 1,348. auth_commit und auth_proof_bytes gehören zur geteilten Autorisierung (seit Chain 17): die öffentliche Commitment c = H(AUTH, nk, salt), die der Bundle-Beweis und der Auth-Beweis beide veröffentlichen, und die Länge des Auth-Beweises. Auf einer Chain ohne hc_auth sind sie Nullen und 0.

bundle ist das Bundle mit verborgenem Asset (seit Chain 14): vier Eingabeslots und vier Ausgabeslots, also immer vier nullifiers, vier commitments und vier envelope_len, Dummies eingeschlossen. Jede Transaktion trägt höchstens eines; ein zweites Bundle gibt es nicht. Es hat kein Feld asset: Die Slots 0–1 tragen ein privates Asset und die Slots 2–3 RAND, und nichts Öffentliches sagt, welches Asset die Slots 0–1 bewegt haben. Ein Transfer von RAND und ein Transfer eines beliebigen RPL-Tokens sind beide "kind": "none", wobei burn_a, burn_r und burn_asset alle 0 sind — dieselbe Form, Feld für Feld. Eine Art token_transfer gibt es nicht. Die drei Burn-Felder sind die einzige öffentliche Aussage des Bundles darüber, dass Wert den Pool verlässt:

  • burn_a / burn_asset — ein Betrag des privaten Assets, der verbrannt wurde, und welches Asset. Ungleich null bei einem token_burn oder einem bridge_burn, wo sie amount und asset der Aktion entsprechen, und bei einem invoke, dessen inflow deposit oder burn ist.
  • burn_r — verbranntes RAND. Ungleich null bei einem bond (gleich seinem amount), einem register_aggregator und einem invoke, der RAND in den Vault des Programms einzahlt.
  • fee — die RAND-Gebühr, immer aus den Slots 2–3.

Darstellung der Aktionen (jeder amount, relayer_fee und initial_amount ein Dezimal-String; die Beträge eines Tokens sind in dessen eigenen Einheiten, nicht in denen von RAND):

kindfields
none—
mintcm, amount, minter (Validator, base58)
deployprogram, words, public_words_len
callprogram, proof_len, input_envelope_len (null, wenn der Aufruf keinen trägt)
bondvalidator, amount, registered
unbondvalidator, amount, nonce
withdrawvalidator, amount, nonce, time
bridge_attestattestation_len, recipient, asset, asset_index, amount, time, r, commitment, pq_signers (die Indizes der mitzeichnenden Guardians in pq_guardians; die 2,420 Byte langen Signaturen werden nicht dargestellt). asset_index, amount und commitment sind bei einer Rotation der Guardian-Menge null. r wird abgeleitet, blake3("rand-deposit-r-1" ‖ mu) über den Digest, den die Guardians signiert haben. Seit v0.6.8 zusätzlich deposit_amount (die Note des Einzahlers: amount, der von den Guardians signierte Bruttobetrag, abzüglich der Bridge-Gebühr) und fee_note ({ amount, asset, time, r, commitment }, die Note der Treasury ohne ihren Eigentümer, oder null ohne Bridge-Gebühren); commitment ist das Blatt der Netto-Einzahlung
bridge_burnasset, amount, relayer_fee, to_chain, token (die Deckung, die eingelöst wird), to. Ein Bundle trägt den gesamten Burn: Sein burn_asset und burn_a sind asset und amount der Aktion. Seit v0.6.8 zusätzlich release_amount (was der signierte Körper freigibt, amount abzüglich der Bridge-Gebühr) und fee_note, wie bei einer Attestierung
register_tokenname, symbol, decimals, authority ("none", "key", "bridge" oder "program"), index, initial_amount, initial ({ amount, recipient, time, r } oder null)
token_mintasset, amount, recipient, time, r, nonce
set_authorityasset, nonce, new_authority (base58, oder null bei einem Verzicht)
token_burnasset, amount; burn_asset / burn_a des Bundles wiederholen sie
pause_mintsnonce; ohne Bundle und gebührenfrei, signiert vom Pause-Schlüssel der Genesis
unpause_mintsnonce, pq_signers; ohne Bundle und gebührenfrei
register_bridged_tokenname, symbol, salt, chain, token, decimals (die Quell-Dezimalstellen der ersten Deckung), nonce, asset_id, pq_signers
list_backingtoken_index, chain, token, decimals, nonce, pq_signers
rotate_pq_guardiansnew_pq_guardians, nonce (die verbrauchte rotation_nonce), pq_signers (Indizes in die PQ-Menge vor der Rotation); ohne Bundle und gebührenfrei, nur auf Bridge-Chains mit rules_v2
rotate_pause_keynew_pause_key, nonce, pq_signers; dasselbe
rotate_pq_guardians_v2, rotate_pause_key_v2v0.6.8: die Felder von v1, bei der PQ-Form zusätzlich possession_signatures (eine Anzahl). Ohne Bundle und gebührenfrei; erforderlich auf einer Chain, deren Genesis bridge.rotation needs_possession setzt, wie es bei Chain 20 der Fall ist. Die Rotation wird delay_secs später wirksam (86,400 s auf Chain 20)
cancel_rotationv0.6.8: rotation_kind ("pq_guardians" oder "pause_key"), nonce; vom aktuellen Pause-Schlüssel signiert, verwirft eine ausstehende Rotation
admit_validatorv0.6.8: candidate (Adresse), candidate_key (hex), voters (Adressen). Ohne Bundle und gebührenfrei: die Abstimmung der Validator-Menge, einem neuen Schlüssel die Registrierung zu erlauben, auf einer Chain mit staking.admission_by_vote, wie Chain 20 eine ist
slash_equivocationv0.6.8: offender, view, first und second ({ hash, height }); nur Chains mit staking.slashing, was Chain 20 nicht ist
invokev0.6.8, RPL-2: die Felder eines Aufrufs (program, proof_len, input_envelope_len) und sein transition (unten). Nur Chains mit einem Abschnitt program_state, wie Chain 20 eine ist
register_aggregator, unbond_aggregator, withdraw_aggregator, slash_aggregator, aggregateihre öffentlichen Felder; nur Chains mit Aggregation
claim_vested, revoke_vesting, bond_vested, unbond_vestedentry (hex), amount (unvested bei einem Widerruf), nonce; time bei einem Claim oder einem Widerruf; validator und registers bei einem Bond; seit v0.6.8 signers bei einem Widerruf (die Positionen seiner Unterzeichner in den revokers des Eintrags). Ohne Bundle; nur Chains mit einem Genesis-Abschnitt vesting, was Chain 20 nicht ist

Die Registrierung und die Mints eines Tokens sind öffentlich, ebenso eine Bridge-Einzahlung: Jedes Wort einer geminteten Note steht in der Aktion (ihr from ist das feste MINT_FROM der Chain), sodass ein Empfänger die Note aus diesen Feldern rekonstruiert, ohne etwas zu entschlüsseln. Die Kind-Strings bridge_attest, token_mint, register_token und invoke sind das, worauf der Scan der Wallet schlüsselt, und werden durch einen Test festgeschrieben.

Ein invoke auf Höhe 3,079 von Chain 20, der eine Zelle las, sie löschte und zwei Notes aus dem Vault auszahlte:

{ "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": [] } }

Alles davon ist bewusst öffentlich. reads sind die Zellen, die das Programm gelesen hat, mit den Werten, die es gelesen hat: Der Beweis wurde gegen sie erstellt, und das Ledger weist die Transaktion zurück, sofern sie nicht weiterhin gelten. writes sind die Zellen, die es geschrieben hat; ein geschriebener Wert aus 64 Nullen löscht die Zelle. Ein Zellschlüssel oder -wert ist ein Word8. Was hineinkam, gehört zum Bundle: burn_r ist das in den Vault des Programms eingezahlte RAND, und burn_a von burn_asset ist der Token, den inflow benennt, deposit in den Vault oder burn (der eigene Token des Programms), none, wenn burn_a 0 ist. Was hinausging, ist eine von der Chain berechnete Note je Auszahlung, pays aus dem Vault, dann mints eines Tokens, dessen Mint-Autorität dieses Programm ist. Jedes Wort jeder Note steht hier unter den Feldnamen eines token_mint; time ist das des Bundles, cm das Blatt, das die Chain angehängt hat, und das from der Note ist das feste PROGRAM_FROM der Chain. Die acht Ausgabewörter des Programms stehen auf dem Beleg, wie die eines Aufrufs.

Keine Transfer-Antwort enthält Sender, Empfänger, Nonce, Betrag oder Asset: Ein solches Feld existiert in einem gespeicherten Transfer nicht.

rand_getRawTransaction

Parameter [hash]. Ergebnis: die vollständige committete Transaktion als bincode-Hex, Beweisbytes eingeschlossen — was ein Aggregator braucht und rand_getTransaction nie darstellt.

Programme und Belege

rand_getProgram

Parameter [program_id]. Ergebnis null oder { "id", "base_pc", "words_len", "code_hash", "deployed_at", "public_words_len", "public_digest" }. Kein Feld deployer: Ein Deploy wird von einem Bundle bezahlt. public_words_len ist die Länge der öffentlichen Eingabe des Programms zur Deploy-Zeit (0 ohne eine); public_digest ist deren Digest, der Wert, gegen den der Beweis jedes Aufrufs geprüft wird, oder null ohne eine.

rand_getProgramCode

Parameter [program_id]. Ergebnis null oder { "base_pc": 0, "words": [ … ] }.

rand_getProgramPublic

Parameter: [program_id]. Ergebnis: die zum Deploy-Zeitpunkt festgelegten öffentlichen Wörter des Programms als ein Hex-String, jedes Wort als seine 4 Little-Endian-Bytes (8 Hex-Ziffern pro Wort): [1, 2, 0xdeadbeef] ist "0100000002000000efbeadde". "" für ein Programm, das ohne öffentliche Eingabe deployt wurde, null für eine ID, die kein Programm hat. Eine Wallet, die einen Aufruf beweist, übergibt diese Wörter an den Prover; das Ledger prüft die Commitment des Beweises gegen den public_digest des Programms.

rand_getProgramCell

v0.6.8, RPL-2. Parameter: [program_id, key], der Schlüssel ein Word8 als 64 Hex-Ziffern (mit oder ohne 0x). Ergebnis: { "key": "<64 hex>", "value": "<64 hex>" }. Eine Zelle, die das Programm nie beschrieben hat oder in die es Nullen geschrieben hat (was sie löscht), wird als 64 Nullen gelesen, die einzige Kodierung für „nicht vorhanden“; dasselbe gilt für jeden Schlüssel eines Programms, das niemand deployt hat, da die Existenz des Programms nicht geprüft wird. { "enabled": false } auf einer Chain ohne Abschnitt program_state. Eine Zelle ist von Natur aus öffentlich: Das liest eine Wallet, um die reads eines invoke aufzubauen.

rand_getProgramCells

v0.6.8. Parameter: [program_id, { "after": "<64 hex>" | null, "limit": n }], das Objekt ist optional. Ergebnis: { "cells": [{ "key", "value" }, …], "next": "<64 hex>" | null }: die Zellen des Programms in Schlüsselreihenfolge (ein vorzeichenloser Vergleich der acht Wörter), beginnend nach after, höchstens limit davon (auf 1 bis 1.000 begrenzt). next ist der zuletzt gelieferte Schlüssel, wenn weitere folgen; er wird als after zurückgegeben. Auf der letzten Seite ist er null. Ein Programm ohne Zelle antwortet mit { "cells": [], "next": null }; ohne den Abschnitt { "enabled": false }.

rand_getProgramVault

v0.6.8. Parameter: [program_id]. Ergebnis: [{ "asset": 0, "amount": "123" }, …], aufsteigend nach Asset-Index (0 ist RAND, jeder andere Index stammt aus dem Token-Register), Beträge als Dezimal-Strings in den eigenen Einheiten des Assets. Eine Zeile mit Null existiert nicht; ein leerer Vault und ein Programm, das niemand deployt hat, ergeben daher []. Ohne den Abschnitt { "enabled": false }. Wert gelangt über das Bundle eines invoke in einen Vault (burn_r und burn_a von burn_asset, wenn der inflow deposit ist) und verlässt ihn als die Notes, die die pays der Transition benennen.

rand_getLimits

Parameter: []. Ergebnis: was eine Wallet aus dem Genesis der Chain braucht, um eine Transaktion zu bauen: die fünf Aufruflimits, die Größe der Note-Hülle, den v0.6-Schalter, den Auth-Guest, die Gas-Bedingungen und, seit v0.6.8, die Genesis-Felder von audit-v6 sowie die Limits des Programmzustands. Auf 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 } }

Ein Genesis ohne die fünf Limit-Felder (Chain 12) erhält 4096, 2097152, 4194304, 18432 und 0. max_proof_bytes war auf den Chains 13 bis 15 8.388.608.

FeldBedeutung
envelope_bytes1860, wenn das Genesis jede Note erzeugende Hülle auf genau diese Länge festlegt, das Format mit Memo; null bei einem Genesis ohne das Feld (Chains 14 bis 17), wo eine Wallet die 1.348-Byte-Hülle ohne Memo versiegelt. Einen anderen Wert gibt es nicht
hardening_v6true, wenn das Genesis die v0.6-Gültigkeitsregeln anwendet. Eine Wallet beweist einen Aufruf dann über die öffentliche Eingabe des Programms gefolgt vom Call-Binding der Transaktion, nicht über die öffentliche Eingabe allein: Zuerst werden die Notes des Fee-Bundles gewählt, an zweiter Stelle wird der Aufruf bewiesen, zuletzt das Bundle. Eine Chain mit dem Flag weist den alten Beweis zurück, eine Chain ohne es den neuen
hc_authder Auth-Guest, den das Genesis festlegt, als Hex, oder null. Ist er gesetzt, ist hc_bundle der Bundle-Guest v3, und jedes Bundle trägt auth_commit und einen Auth-Beweis: Die Wallet gibt dem Bundle-Guest nk und ein frisches Salt und beweist den Auth-Guest über den Spend-Key
gas_metering"circuit" auf einer Chain, deren Genesis einen Abschnitt gas hat (der Zähler im Circuit); "header" auf einer Chain ohne einen solchen, wenn der Knoten eine eigene Gas-Policy anwendet (--gas-price, --byte-price); null bei keinem von beiden
gas_price, byte_priceEinheiten pro Gas und Einheiten pro KiB des Beweises und der Eingabehülle eines Aufrufs, als Dezimal-Strings. Unter einem Abschnitt gas sind sie Konsenszustand und auf jedem Knoten gleich: mit gas.dynamic, wie auf Chain 20, die aktuellen Preise der Spitze, die sich pro Block nach Auslastung bewegen, nie unter die Genesis-Untergrenzen (100 und 800) fallen und nie über die Obergrenzen steigen; ohne gas.dynamic die festen Preise des Abschnitts. Ohne Abschnitt sind sie die eigene Policy dieses Knotens, und zwei Knoten können unterschiedlich antworten
bundle_gas_limitdas pauschale Gas, das jeder Bundle-Beweis deklarieren muss, aus dem Genesis-Abschnitt gas; null ohne einen solchen
adjust_bpsdie größte Preisbewegung des dynamischen Reglers in einem Block, in Basispunkten; null auf einer Chain ohne gas.dynamic
max_gas_price, max_byte_pricev0.6.8: die Obergrenzen, über die der Regler einen Preis nie hebt, als Dezimal-Strings; "10000" und "80000" auf Chain 20, null, wo das Genesis keine setzt (Chains 18 und 19)
byte_loadv0.6.8: "paying", wenn nur der Beweis und die Eingabehülle eines Aufrufs byte_price bewegen, sodass ein Block aus Transfers keinen bewegt, wie auf Chain 20; null, wo die Bytes jeder Transaktion zählen (Chains 18 und 19)
admission_by_votev0.6.8: ob ein Bond, der einen neuen Validator-Key registriert, zuvor die Abstimmung der Validatormenge braucht (rand_getAdmitted); true auf Chain 20
testnetv0.6.8: der Genesis-Marker testnet, der einen Faucet neben einem Bridge-Abschnitt erlaubt; true auf Chain 20, false auf jeder früheren Chain
slashingv0.6.8: { "equivocation_bps", "jail_epochs" }, was eine Equivocation des Leaders kostet, oder null; null auf Chain 20
binding_domainv0.6.8: 0, wo das Binding einer Transaktion und jede signierte Aktionsnachricht allein die Chain-ID binden (Chains 14 bis 19), 1, wo sie auch den Genesis-Hash tragen, sodass ein Beweis oder eine Signatur, die für eine Chain erstellt wurde, auf keiner anderen verifiziert (Chain 20). Eine Wallet entscheidet anhand der Chain-ID, welche Form sie beweist, nie anhand dieser Antwort: Die rand-Wallet ab v0.6.8 gibt den Chain-IDs 14 bis 19 die Chain-ID-Form und jeder anderen ID die an das Genesis gebundene Form und liest dieses Feld nur, um früh abzulehnen. Eine Wallet vor v0.6.8 kann auf Chain 20 nicht senden
proof_window_blocksv0.6.8: wie alt, in Blöcken, der Anker eines Bundles sein darf und wie weit hinter der Höhe sein time liegen darf, ein Fenster für beide; 1024 auf Chain 20, null (256) auf den Chains bis 19. Eine Wallet mit einem langsamen oder delegierten Prover liest es, um zu wissen, wie lange ein Beweis dauern darf
program_statev0.6.8, RPL-2: der Genesis-Abschnitt program_state und seine invoke-Limits, oder null; dann wird jeder invoke abgelehnt und kein Programm-Token kann registriert werden. cell_fee sind die RAND-Einheiten (ein Dezimal-String), um die sich die Fee-Untergrenze eines Invoke pro erzeugter Zelle erhöht, also pro Schreiben eines Werts ungleich null in eine Zelle, die als Nullen gelesen wird; Überschreiben, Löschen oder das Schreiben von Nullen kostet nichts. max_reads, max_writes und max_payouts (pays und mints zusammen) sind harte Obergrenzen. In der Praxis greift zuerst die Segmentregel: Die Kontextwörter der Transition (11 + 16 pro Read oder Write + 3 pro Payout) müssen neben die öffentliche Eingabe des Programms und die 8 Binding-Wörter passen, ohne die öffentliche Tabelle der zkVM wachsen zu lassen; für ein Programm ohne öffentliche Eingabe hat diese Tabelle 128 Zeilen, was 119 Kontextwörter übrig lässt

Ein Knoten, der ein Feld nicht kennt, antwortet ohne es. Nichts in dieser Antwort ist authentifiziert, daher übernimmt eine Wallet envelope_bytes nicht allein auf Wort des Knotens: Die rand-Wallet versiegelt auf den Chain-IDs 14 bis 17 die ältere Hülle, was auch immer der Knoten antwortet, und andere Clients sollten dasselbe tun.

rand_getReceipt

Parameter: [tx_hash]. Ergebnis: null, bis der Aufruf committet ist, dann { "tx", "program", "tier": 14, "outputs": [1, 0, 25, 0, 0, 0, 0, 0], "height": 17, "index": 0, "h_in": "9c0e…7f", "h_pub": null }. Kein Feld effect. h_pub ist der Digest der zum Deploy-Zeitpunkt festgelegten öffentlichen Eingabe des Programms, gegen den der Beweis des Aufrufs geprüft wurde, null für ein Programm ohne eine solche. Ein invoke (v0.6.8) hat den Receipt eines Aufrufs, und rand_getReceipts sowie das Topic receipts liefern ihn unverändert.

rand_getReceipts

Parameter: [program_id, from_height, to_height, limit?]. Ergebnis: { "receipts": [ … ], "next_height": 2051 }: die Receipts von program_id mit from_height <= height <= to_height, nach Höhe, dann Index, jeder genau das Objekt von rand_getReceipt. limit hat den Standardwert 256, ist auf 256 begrenzt und teilt nie eine Höhe: Sobald eine Seite limit Receipts enthält, liefert sie den Rest dieser Höhe dennoch aus. next_height ist die erste nicht gelieferte Höhe, oder null, wenn to_height die Seite beendet hat. -32602 für to_height unter from_height.

rand_getCallEnvelope

Parameter: [tx_hash]. Ergebnis: null oder { "tx", "h_in", "kem_ct", "to_sender", "to_auditor", "body" } als Hex — das versiegelte Eingabe-Transkript des Aufrufs, unverändert ausgeliefert; der Knoten hält keinen Schlüssel, der es öffnet. null, wenn der Aufruf keines veröffentlicht hat (--no-envelope), die Transaktion kein Aufruf ist oder es keinen Receipt gibt.

Staking und Supply

rand_getValidators

Parameter: []. Ergebnis: eine Zeile pro Registereintrag, in Adressreihenfolge, Beträge als Dezimal-Strings:

[{ "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) ist die erste Epoche, in der ein geslashter Schlüssel wieder in einer Menge sein darf (18446744073709551615 für immer), null, wenn er nicht gejailt ist. Chain 20 hat kein staking.slashing, daher ist der Wert dort immer null.

rand_getAdmitted

v0.6.8. Parameter []. Ergebnis { "admission_by_vote": true, "max": 256, "admitted": ["<address>", …] }: die Schlüssel, die das Validator-Set mit einem AdmitValidator aufgenommen hat und die noch nicht registriert sind, in Adressreihenfolge. Auf einer Chain, deren Genesis staking.admission_by_vote setzt, wie bei Chain 20, muss ein Bond, der einen neuen Schlüssel registriert, unter ihnen sein. max gibt an, wie viele das Ledger gleichzeitig hält. Auf einer Chain ohne das Flag ist admission_by_vote gleich false, die Liste ist stets leer und eine Registrierung braucht keine Abstimmung. Chain 20 antwortete am 2026-10-01 mit "admitted": [].

rand_getEpoch

Parameter []. Ergebnis { "epoch": 41, "epoch_blocks": 1000, "next_set": ["…", "…"] }; next_set ist eine Projektion.

rand_getSupply

Parameter []. Ergebnis:

{ "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 und slashed bewegen sich nur auf einer Aggregations-Chain. faucet_epoch und faucet_minted_in_epoch sind der Zähler des Faucets je Epoche gegenüber staking.faucet_budget_per_epoch (Konsenszustand auf Chain 20). Die vier vesting_*-Felder sind die Zähler des Genesis-Vestings, allesamt "0" auf einer Chain ohne vesting-Abschnitt, was auf Chain 20 zutrifft. program_rand_out und program_rand_held (v0.6.8, RPL-2; "0" ohne program_state-Abschnitt) sind das RAND, das Invokes als Notes aus Programm-Tresoren ausgezahlt haben (Pool-Seite, innerhalb von pool_value), und das, was die Tresore noch halten (Register-Seite, innerhalb von total_supply); es ist über das burn_r eines Invokes eingegangen und steht daher auf der Pool-Seite in burned. registration_fees_burned ist Σ der Token-Registrierungsgebühren, die unter dem Genesis-Wert tokens.burn_registration_fee verbrannt wurden, den Chain 20 setzt; invariant_holds zieht sie zusammen mit slashed von dem ab, was die Chain ausgegeben hat. Supply erklärt die Identität.

rand_getEmission

Parameter []. Ergebnis { "inflation": "0", "subsidy": null, "faucet": true }. inflation ist fest "0". subsidy ist der Zeitplan der Block-Aggregation (current, base, halving_blocks, sealed_blocks, next_halving_at) und null auf einer Chain ohne aggregation-Abschnitt, was auf Chain 20 zutrifft. faucet spiegelt rand_status.

Bridge

Alle vier antworten auf jeder Chain; auf einer Chain ohne bridge-Abschnitt lautet der Zustand { "enabled": false } und das Register []. Der Genesis von Chain 20 hat einen: Guardian-Set 1 (guardian_set_index 1) mit acht Guardians, acht PQ-Guardians, einem Pause-Schlüssel, burn_sequence 13 im Genesis, einer Replay-Untergrenze (min_inbound_sequence 3 für die Quell-Chains 2, 3 und 4 sowie 7 für die Quell-Chain 5), Bridge-rules_v2 mit einer globalen Mint-Obergrenze von 4.000 zUSD je 24-Stunden-Fenster über alle Backings hinweg und zwei in v0.6.8 neuen Gruppen: rotation (eine Rotation der PQ-Guardians oder des Pause-Schlüssels braucht den Besitznachweis durch die neuen Schlüssel und wird 86.400 s nach ihrem Commit wirksam) und fees (10 bps jeder Einzahlung und 10 bps jedes Burns, auf Rand als zUSD-Note an eine Treasury-Adresse einbehalten). Chain 19 hatte burn_sequence 8, Untergrenzen von 1 und 4 und keine der beiden Gruppen. Ihr tokens-Abschnitt hat eine registration_fee von 1 RAND (verbrannt), ein mint_cap_per_day je Backing von 10000000000000 (100.000 zUSD bei acht Dezimalstellen) und führt zUSD selbst auf: im Genesis von Chain 14 übernommen, dieselbe Asset-ID, Index 1, sieben Backings.

rand_getBridgeState

Parameter []. Ergebnis { "enabled": false } oder:

{
  "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": [ … ]
}
FeldBedeutung
emitterdie Adresse des ausgehenden Emitters dieser Chain, 32 Bytes hex
emittersQuell-Chain-ID → die dort vertrauenswürdige Emitter-Adresse
guardiansdie 20-Byte-Adressen des aktuellen Sets, hex
pq_guardiansdas PQ-Set: Dilithium2-Public-Keys (1.312 Bytes), hex, indexgleich mit dem aktuellen Guardian-Set (Set 1 auf Chain 20). Jedes BridgeAttest trägt ein Quorum von Mitsignaturen daraus. Eine Rotation des Guardian-Sets verändert es nie; nur ein rotate_pq_guardians tut das, auf einer rules_v2-Chain
mint_pausedsolange true, wird jedes Transfer-Attest mit bridge minting is paused abgelehnt; Burns und Rotationen bleiben offen
pause_noncewas das nächste Pausieren oder Fortsetzen tragen muss; beide erhöhen ihn
list_noncewas das nächste register_bridged_token oder list_backing tragen muss; beide erhöhen ihn
pause_keyder eine Dilithium2-Schlüssel, der das Minting pausieren darf, hex. Er kann nur pausieren: ein Fortsetzen braucht das Quorum der PQ-Guardians
registration_feewas eine RegisterBridgedToken über die Bundle-Basis hinaus schuldet, in RAND-Einheiten, als Dezimalstring
burn_sequencebisher ausgesendete ausgehende Nachrichten
rotation_noncewas das nächste rotate_pq_guardians / rotate_pause_key tragen muss
rules_v2die globale Mint-Obergrenze und ihr gleitendes Fenster, oder null auf einer Chain ohne Bridge-Rules v2. Unter ihnen ist auch die Obergrenze je Backing ein gleitendes Fenster, und eine Listung wird abgelehnt, solange das Minting pausiert ist. Seit v0.6.8 trägt es zusätzlich global_minted_in_window und global_mint_headroom, Dezimalstrings
min_inbound_sequencedie Replay-Untergrenze aus dem Genesis: Quell-Chain-ID → die niedrigste Sequenz, die ein Transfer von dieser Chain tragen darf, als einfache Zahlen; null auf einer Chain ohne eine solche (Chain 15 und früher). Ein bridge_attest darunter wird mit BelowReplayFloor abgelehnt, ein endgültiges Urteil. Ein Relayer liest sie, um einen Lock zu verwerfen, den die Chain, aus der diese hervorging, bereits gemintet hat
rotation_rulesv0.6.8: { "delay_secs", "needs_possession" } aus dem Genesis-bridge.rotation, oder null. Unter ihnen ist eine Rotation die _v2-Aktion, die die Besitzsignaturen der neuen Schlüssel trägt, und sie wartet delay_secs, bevor sie wirksam wird
pending_rotationsv0.6.8: Rotationen, die committet, aber noch nicht wirksam sind, je { "kind": "pq_guardians", "new_pq_guardians", "effective_at_secs" } oder { "kind": "pause_key", "new_pause_key", "effective_at_secs" }; null ohne rotation_rules. Ein cancel_rotation, vom aktuellen Pause-Schlüssel signiert, verwirft eine davon
feesv0.6.8: { "mint_bps", "burn_bps", "recipient" } aus dem Genesis-bridge.fees, oder null (Chains 14 bis 19). Die Chain behält diesen Anteil jeder Einzahlung und jedes Burns, abgerundet auf eine ganze Auszahlungseinheit des Backings, als zUSD-Note für recipient ein. Eine Einzahlung schreibt den Bruttobetrag abzüglich der Gebühr gut; der signierte Body eines Burns gibt seinen Betrag abzüglich der Gebühr frei. Eine Wallet liest es, um ihre eigene Einzahlung zu bewerten und, wenn sie recipient ist, um ihre Gebühren-Notes neu aufzubauen
assetsdie Zeilen von rand_getAssets

Keine Guthaben: überbrückter Wert sind Notes. Es gibt kein next_index mehr: Ein überbrückter Token wird unter einem Index gelistet, den seine Registrierung bereits festgelegt hat, bevor er eingezahlt werden kann, es bleibt also kein Index mehr vorherzusagen. Den Index eines gelisteten Tokens liest man aus assets oder rand_getTokens.

rand_getAssets

Parameter []. Ergebnis: das Asset-Register der Bridge, aufsteigend nach Index, oder []:

[{ "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" }]

Seit v0.6.8 trägt jede Backing-Zeile, hier und überall, wo Backings ausgeliefert werden (rand_getBridgeState.assets, die backings von rand_getToken, rand_getTokens und rand_getTokenSupply), minted_in_window (ein Dezimalstring) und mint_window_secs, beide null auf einer Chain mit Tageszähler, sowie mint_headroom: die größte Einzahlung auf dieses Backing, die die Obergrenzen zur Blockzeit des Heads zulassen, also die Obergrenze je Backing abzüglich dessen, was es gemintet hat, und unter Rules v2 höchstens so viel, wie das registerweite Fenster noch hat. Lesen Sie mint_headroom, nicht mint_cap_per_day − minted_today, was die globale Obergrenze ignoriert. Unter Rules v2, wie auf Chain 20, ist minted_today die Zählung des gleitenden Fensters, die Größe, gegen die die Obergrenze je Backing geprüft wird; die folgende Beschreibung des Tageszählers gilt für Chain 14.

Eine Zeile je Backing (Quell-Coin), ein Token mit sieben Backings sind also sieben Zeilen unter einem index. index ist das asset-Wort, das eine Note dieses Assets trägt; Index 0 ist RAND und steht nie im Register. decimals sind die Quell-Dezimalstellen des Backings. locked, mint_cap_per_day und minted_today sind Dezimalstrings in den achtstelligen Einheiten des Tokens selbst, nie in denen von RAND; mint_day ist eine einfache Ganzzahl, eine UTC-Tagesnummer. mint_cap_per_day ist das Genesis-tokens.mint_cap_per_day, das Meiste, was ein Backing je UTC-Tag der Blockzeit minten darf. minted_today ist das, was das Backing am mint_day gemintet hat, dem UTC-Tag (timestamp_ms / 86,400,000) des Head-Blocks, sodass ein Zähler von einem früheren Tag "0" zeigt, sobald der Head Mitternacht überschreitet. Eine Einzahlung über der Obergrenze wird mit MintCapExceeded abgelehnt und ist am nächsten Tag zulässig. chain und token sind die Wire-Identität, über die Guardians signieren; asset_id ist blake3 der beiden, was rand_bridgeAssetId berechnet.

rand_bridgeAssetId

Parameter [token_chain, token_address] (Ganzzahl, 32 Bytes hex). Ergebnis: die Asset-ID, 64 Hex-Zeichen. Reine Arithmetik.

rand_getBridgeBurn

Parameter [sequence]. Ergebnis null oder { "sequence": 0, "body_hex": "…", "digest": "…", "tx": "…", "height": 2, "amount": "…", "release_amount": "…", "fee": "…" }.

Die letzten drei sind neu in v0.6.8, auf jeder Chain, als Dezimalstrings in den achtstelligen Einheiten des Tokens. release_amount ist der Betrag, den der signierte Body trägt, direkt aus body_hex gelesen: was der Quell-Contract freigibt und woraus er die Relayer-Gebühr des Body zahlt. fee ist die Bridge-Gebühr, die die Chain als Treasury-Note einbehalten hat, und amount das, was das Bundle verbrannt hat, release_amount + fee. Ohne bridge.fees (Chains 14 bis 19) ist fee gleich "0". Sequenz 13 auf Chain 20, ein Burn von 0,999 zUSD: "amount": "99900000", "fee": "99900", "release_amount": "99800100".

Tokens (RPL)

Das RPL-Token-Register: jeder Token, überbrückt und nativ. Tokens erklärt den Standard.

rand_getTokens

Parameter [from_index, limit], beide optional (0 und 1000; limit wird auf 1.000 begrenzt). Ergebnis: das Register aufsteigend nach Index ab from_index, bereichsweise ab diesem Index gelesen:

{ "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 }
  ] }

Auf einer Chain ohne Abschnitt tokens: { "enabled": false, "tokens": [] }. index ist das Wort asset, das eine Note des Tokens trägt (0 ist RAND und wird nie aufgeführt). id ist die Asset-ID des Tokens und id_text ihre Textform mit Prüfsumme: bech32m, HRP rpl, über die 32 Bytes der ID, 62 Zeichen. authority ist eine von:

kindweitere Felder
none— (feste Menge oder verzichtet)
keykey, address
bridgebackings: [{ "chain", "token", "decimals", "locked", "mint_cap_per_day", "minted_today", "mint_day" }], die Felder von rand_getAssets, eine Zeile je Deckung
programprogram

Mengen, locked, mint_cap_per_day, minted_today und registration_fee sind Dezimalstrings (RAND-Einheiten für registration_fee, Token-Einheiten für die übrigen); next_index, mint_day und max_tokens sind Zahlen. max_tokens ist die Obergrenze des Registers im Genesis (4.096 auf Chain 20; null, wenn es keine gibt); darüber hinaus wird eine Registrierung mit RegistryFull abgelehnt. burn_registration_fee gibt an, ob die Gebühr einer Registrierung verbrannt statt an den Proposer gezahlt wird; bound_note_value, ob ein Mint oder eine Einzahlung ab 2⁶³ eine Gültigkeitsregel ist (die Zulassung lehnt eine solche auf jeder Chain ohnehin ab). Alle drei sind auf Chain 20 gesetzt. Eine Seite, die kürzer als limit ist, ist die letzte.

Eine program-Authority ({ "kind": "program", "program": "<id>" }) lässt sich nur auf einer Chain mit einem Abschnitt program_state registrieren, wie es Chain 20 ist (v0.6.8): Der Token beginnt mit der Menge null, und nur die Aufrufe dieses Programms prägen oder verbrennen ihn.

Ein Wallet löst eine Token-ID über diese Auflistung auf, nie über rand_getToken: Das Asset einer Überweisung ist on chain privat, und das Lesen des gesamten Registers kostet dasselbe, welcher Token auch gemeint ist.

rand_getToken

Parameter [token]: ein Register-Index (eine Zahl oder ein Dezimalstring), die 64-stellige Hex-ID (mit oder ohne 0x, in beliebiger Groß- und Kleinschreibung) oder die Textform rpl1… (ganz klein oder ganz groß geschrieben). Ergebnis: die Zeile des Tokens aus rand_getTokens oder null. Eine fehlerhafte ID — falsche Prüfsumme, anderes HRP, falsche Länge, gemischte Schreibweise, kein Hex — ergibt -32602, sodass ein Tippfehler nie einen anderen Token trifft. Eine Abfrage je Token verrät dem Node, für welchen Token sich der Aufrufer interessiert; sie ist für Explorer und einzelne Lesezugriffe gedacht.

rand_getTokenSupply

Parameter [token], dieselben Formen. Ergebnis null oder:

{ "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 ist für einen nativen Token leer; bei einem überbrückten Token ergeben die locked-Beträge zusammen total_supply. Es gilt derselbe Datenschutzhinweis wie bei rand_getToken.

Block-Aggregation (auf Chain 20 nicht aktiv)

Diese Methoden gibt es im Node für Chains, deren Genesis einen Abschnitt aggregation enthält. Auf Chain 20 ist das Register leer, und nichts wird je entsiegelt.

MethodeParameterErgebnis
rand_getAggregate[hash]covers, aggregator, subsidy, proving_share, n, height des versiegelnden Aggregats; null für jede andere Transaktion
rand_getAggregators[]das Aggregator-Register: address, bond, payout, nonce, unbonding je Zeile
rand_getUnsealed[from, limit]{ "bundles": [{ "hash", "height", "excess" }], "next_from" }, die Bundles, die ein Aggregator noch abdecken darf

Ein Aggregate wird wie alles andere über rand_sendTransaction eingereicht.

Genesis-Vesting (auf Chain 20 nicht aktiv)

Diese Methoden gibt es im Node für Chains, deren Genesis einen Abschnitt vesting enthält. Noch keine Chain hat einen: Auf Chain 20 antwortet jede mit { "enabled": false }. Der öffentliche Endpunkt leitet sie seit 2026-10-01 weiter.

MethodeParameterErgebnis
rand_getVesting[id] oder [id, at_ms], die 64-stellige Hex-ID des Eintragsder Eintrag: seine Klasse, der Begünstigte, der Plan (amount, start_ms, cliff_ms, linear_ms, step_ms), was beansprucht, widerrufen und gebunden wurde, sowie vested_now, claimable_now, unvested_now zu as_of_ms (standardmäßig die Zeit des Kopfblocks); null für eine unbekannte ID. Seit v0.6.8 listet ein widerrufbarer Eintrag revokers, den threshold davon, den ein Widerruf braucht, und das treasury, an das ein Widerruf zahlt (sie ersetzen den einzelnen revoker), und der Eintrag trägt revoke_nonce und locked_now
rand_getVestingSummary[]{ "enabled": true, "height", "as_of_ms", "entries", "issued", "released", "locked", "classes": [ … ] }: Summen je Klasse, ohne Schlüssel oder Eigentümer
rand_getVestingSchedule[from_ms, to_ms, step_ms], höchstens 1.000 Punkte{ "enabled": true, "issued", "points": [{ "t_ms", "locked" }] }: die gesperrte Gesamtsumme des Registers über die Zeit

Beträge sind Dezimalstrings. Die vier Vesting-Aktionen werden über rand_sendTransaction eingereicht.

Subscriptions (WebSocket)

ws://127.0.0.1:8545/ oder /ws. Der Socket bedient nur rand_subscribe und rand_unsubscribe und antwortet auf alles andere mit -32601. Drei Topics, unabhängige Streams ohne Reihenfolgegarantie untereinander:

  • newHeads — die Form von rand_getHead, einmal je committetem Block gesendet, in Reihenfolge, auch während der Synchronisierung. view ist hier der eigene View des Blocks.
  • receipts oder receipts <program_id> — eine Benachrichtigung je committetem Block, der mindestens eine passende Aufruf-Quittung enthält: { "height", "hash", "receipts": [ … ] }, jede Quittung in der Form von rand_getReceipt.
  • transaction <hash> — eine Benachrichtigung, danach entfernt der Node die Subscription: { "status": "committed", "height", "index" } oder { "status": "rejected", "reason" } bei einer Ablehnung, die die eigenen Bytes der Transaktion betrifft (dieselbe Grenze wie bei rand_getTransactionStatus). Eine zustandsabhängige Ablehnung wird nie gemeldet; kombinieren Sie sie daher mit einem Timeout.
{ "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 } } }

Grenzen: 64 Verbindungen je Node (die 65. wird beim Upgrade mit 503 abgelehnt), 8 Subscriptions je Verbindung, 64 KiB je Client-Frame, ein Ping alle 30 s, der innerhalb von 5 s beantwortet werden muss, und 256 Einträge Rückstand je Stream — ein Subscriber, der bei einem abonnierten Stream weiter zurückliegt, wird mit dem Code 1008 geschlossen und nicht gepuffert; verbinden Sie sich neu und füllen Sie die Lücke mit rand_getCompactBlocks (Heads), rand_getReceipts (Quittungen) oder rand_getTransactionStatus (eine Transaktion). Ein einfaches GET / ohne Upgrade-Header wird mit 400 beantwortet.

Fehler

CodeBedeutung
-32601unbekannte Methode (einschließlich der eingestellten Account-Methoden)
-32602ungültiger oder fehlender Parameter
-32000abgelehnt: eine Transaktion, die der Mempool verweigert hat, ein durch Ratenbegrenzung abgewiesener Faucet-Aufruf, ein Witness-Aufbau, der länger als 10 s gewartet hat, ein Lesezugriff über 30 s, eine Methode, die der öffentliche Listener nicht bedient, oder eine Subscription über dem Limit
-32001referenziertes Objekt nicht gefunden
-32010geprunt: eine Höhe unterhalb der Aufbewahrungsgrenze dieses Nodes; data.floor nennt sie (siehe unten)
-32603interner Fehler
-32600ungültige Anfrage: Body über der Größenbeschränkung, kein JSON, ein fehlerhafter Batch oder eine Notification
{ "jsonrpc": "2.0", "id": 1, "error": { "code": -32000, "message": "…" } }

Bei rand_sendTransaction sind nur -32000 und -32602 ein Urteil über die Transaktion; bei jedem anderen Code ist ihr Schicksal unbekannt (siehe rand_sendTransaction).

Geprunte Nodes: Fehler -32010

Ein Node, der mit --prune-history <window> gestartet wurde, behält das gesamte Ledger (Notes, Nullifier, Anker, das Register), aber nur die letzten <window> an Blöcken, Transaktionen und Quittungen; rand_status.prune_floor ist die niedrigste Höhe, die er noch vorhält. Auf Chain 20 laufen 24 der 26 Validatoren mit --prune-history 24h; die beiden Archive laufen ohne das Flag und behalten jeden Block, und der öffentliche Endpunkt leitet an eines davon weiter.

  • Nach Höhe, unterhalb der Grenze (Genesis ausgenommen): rand_getBlockByHeight, rand_getFinality nach Höhe sowie ein Bereich von rand_getBlocks, rand_getCompactBlocks oder rand_getReceipts, der darunter reicht, antworten mit -32010 pruned: height h is below this node's retention floor f und data: { "floor": f }. Fragen Sie ein Archiv. [0, 0] liefert weiterhin das Genesis.
  • Nach Hash: rand_getBlockByHash, rand_getReceipt, rand_getRawTransaction, rand_getCallEnvelope und rand_getAggregate antworten für einen geprunten Hash mit null, wie für einen, den es nie gab; nur ein Archiv kann die beiden Fälle unterscheiden. rand_getTransaction und rand_checkTransaction antworten ebenfalls mit null, und nur dann mit -32010, wenn eine erhalten gebliebene Positionszeile eine Höhe unterhalb der Grenze nennt. rand_getTransactionStatus fügt auf einem geprunten Node jedem Eintrag unknown das Feld floor hinzu.
  • Wallet-Scans bleiben unberührt: rand_getCommitments, rand_getNullifiers, rand_getAnchor und die Witness-Methoden lesen Familien, die nie geprunt werden.

Die Transaktion auf der Leitung

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

Die Standardkonfiguration von bincode: Ganzzahlen fester Breite, Längenpräfixe von 8 Byte, u32-Enum-Tags in Deklarationsreihenfolge. Die fünf Aggregation-Varianten folgen im Enum auf BridgeBurn und stehen vor RegisterToken (Transaktionen); Chain 20 lässt sie nie zu, ebenso wenig die vier Vesting-Varianten oder SlashEquivocation, doch ein Encoder, der Tag-Nummern fest codiert, muss sie trotzdem mitzählen.

Die letzten beiden Felder des Bundles kamen mit v0.6.3 und Chain 17 hinzu. bincode ist positionsbasiert, daher erzeugt ein Encoder, der für Chain 16 oder früher geschrieben wurde, keine Transaktion, die diese Chain decodiert, und jede Transaktions-ID hat sich mit ihnen geändert: Die Domäne der ID ist jetzt rand-txid-3, die auth_commit und den Digest des Auth-Beweises bindet. Ein Client, der IDs lokal neu berechnet, muss dies nachvollziehen. Auf Chain 20 trägt jedes Bundle einen Auth-Beweis, ob selbst erzeugt oder delegiert. v0.6.8 ändert nichts am Layout von Transaction oder Bundle; es hängt die Aktionen 28 bis 33 an.

Jede Transaktion trägt höchstens ein Bundle. Ein Bond trägt ein Bundle, dessen burn_r seinem amount entspricht, wobei burn_a und burn_asset 0 sind. Ein BridgeBurn oder ein TokenBurn verbrennt über das Bundle: burn_asset muss das asset der Aktion sein (nie 0), burn_a der amount der Aktion und burn_r 0, während fee in RAND aus den Slots 2–3 bezahlt wird. Jede andere Aktion verbrennt keinen Token, und RAND wird ausschließlich über burn_r verbrannt: Ein Bundle mit burn_asset 0 und burn_a ungleich null wird überall abgelehnt. Das r einer BridgeAttest wird abgeleitet, nicht gewählt: Die Zulassung verlangt blake3("rand-deposit-r-1" ‖ mu) über den Digest, den die Guardians signiert haben, und lehnt jeden anderen Wert ab (WrongDepositBlinding, eine dauerhafte Ablehnung). Ein überbrückter Token wird gelistet – bei Genesis oder durch ein RegisterBridgedToken / ListBacking –, bevor eine Attestierung dafür zulässig ist; die Attestierung einer nicht gelisteten Coin wird mit UnlistedToken abgelehnt.

Jeder Bundle-Beweis wird über die Transaktion erstellt, in der er mitgeführt wird, und gegen sie verifiziert: die gesamte Transaktion mit geleerten Beweisen, gebunden an die Chain-ID und, auf Chain 20 (binding_domain: 1), an den Genesis-Hash, unter neuen Tags. Auf den Chains 14 bis 19 bestand die Bindung allein aus der Chain-ID; ein für Chain 19 erstellter Beweis wird daher auf Chain 20 nicht verifiziert, und eine Wallet, die älter als v0.6.8 ist, kann dort nicht senden. Auf den Chains 18 bis 20 wird ein Bundle ohne seine beiden Beweise auf 7.936 Bytes kodiert und eine Transfer-Transaktion ohne sie auf 7.949 Bytes (5.848 und 5.861 auf den Chains 14 bis 16, mit Envelopes von 1.348 Bytes und ohne Auth-Felder). Ein Transfer im Netzwerk umfasst beim Produktionsprofil etwa 2,85 MB, fast ausschließlich Beweis: ein Bundle-Beweis von etwa 1,49 MB und ein Auth-Beweis von etwa 1,36 MB. Vor der geteilten Autorisierung waren es etwa 1,43 MB.

Zuletzt geprüft gegen den fullnode-Commit c0878c3f (Chain 21) am 2026-10-12. Wo Code und diese Seite voneinander abweichen, hat der Code recht; sagen Sie uns Bescheid.