Rand Protocol
Dokumentation
Anleitungen

Beweise

Wie die Wallet einen Bundle-Beweis erzeugt, was er an Zeit und Bytes kostet, wie ein Node ihn verifiziert, was ein Constraint-Set ist und warum dessen Änderung ein Hard Fork ist – und die Block-Aggregation, die bevorstehende Änderung daran, wie Beweise in einen Block gelangen.

Verwenden Sie diese Seite, um eine Proving-Maschine zu dimensionieren, um zu verstehen, warum eine Überweisung über eine Minute dauert und warum der Blockplatz, nicht die Rechenleistung, den Durchsatz begrenzt, und um zu wissen, was bricht, wenn sich das Beweissystem ändert. Alles, was ein Validator akzeptiert, ist durch einen Beweis gedeckt, den er selbst verifiziert hat.

Was ein Beweis aussagt

Eine Relation, für jedes Programm, das die Chain ausführt:

Dieses RV32IM-Programm, gestartet bei base_pc, ausgeführt auf einem privaten Eingabevektor, auf den sich H_IN festlegt, und einem öffentlichen Eingabesegment, auf das sich H_PUB festlegt, hat innerhalb von 2ᵗ − 1 Zyklen gehalten, höchstens GAS_LIMIT Gas verbraucht und diese acht Ausgabeworte veröffentlicht.

Das Programm wird durch seinen In-Circuit-Digest hc identifiziert; der Verifier sieht nie ein Instruktionswort. Eine abgeschirmte Überweisung ist diese Relation, angewandt auf den Hidden-Asset-Bundle-Guest, ein von Hand assembliertes 4-in-4-out-Programm, dessen hc in der Genesis-Datei als hc_bundle festgeschrieben ist. Chain 20 legt Guest v3 fest (guests::bundle_hidden_v3, 60af094a…6e3fce, seit Chain 17). Die Chains 14 und 15 legten v1 fest (83d3a370…cd0ef8) und Chain 16 das verzweigungsfreie v2 (651043e2…839b). Seit Chain 17 trägt jedes Bundle zudem einen zweiten Beweis, den des Auth-Guest (guests::auth, Genesis hc_auth, 1e4e347f…5639c1): Der Bundle-Beweis nimmt den Viewing Key entgegen, und der Auth-Beweis zeigt, dass der Sender den dahinterstehenden Spend Key besitzt. Das ist die geteilte Autorisierung, und sie ermöglicht es einem gekoppelten Prover, der nur einen Viewing Key hält, den Bundle-Beweis zu erstellen. Der Hidden-Asset-Guest ersetzte den 2-in-2-out-Guest bundle der Chains bis 13, der im Fullnode nur für Tests fortbesteht und den keine Chain festlegt. Ein vertraulicher Aufruf ist dieselbe Relation, angewandt auf ein deployetes Programm (Programme).

Wie die Wallet ein Bundle beweist

rand send <rand1…> <amount> erledigt die private Arbeit lokal, und nur Beweise, Commitments, Nullifier und versiegelte Umschläge erreichen die Chain:

  1. Scannen Sie den Baum mit dem Viewing Key und wählen Sie Eingaben: höchstens zwei RAND-Notes, die den Betrag plus die Gebühr in den Slots 2–3 abdecken, und bei einer Token-Überweisung oder einem Burn höchstens zwei Notes des Tokens in den Slots 0–1, wobei die RAND-Notes allein die Gebühr abdecken. Ein unbenutzter Eingabe-Slot ist ein Dummy: Betrag 0, im Besitz der Wallet, sein Membership-Fehler im Circuit maskiert, der Nullifier trotzdem veröffentlicht. Seit Guest v2 ist der Guest verzweigungsfrei: Der Pfad eines Dummys wird über alle 32 Ebenen gehasht wie der einer echten Note.
  2. Abrufen des Head-Ankers (rand_getAnchor) und des Merkle-Zeugen mit 32 Ebenen jeder echten Eingabe (rand_getWitness(index)), wobei die zurückgegebene Wurzel gegen den Anker geprüft wird.
  3. Bauen von vier Ausgaben: die Note des Empfängers und die Wechselgeld-Note in der Gruppe, die Wert bewegt, auch bei Null vorhanden, und Dummys mit Betrag null an den übrigen Stellen, versiegelt an einen Wegwerfschlüssel.
  4. Versiegeln jeder Ausgabe in einem Umschlag (ML-KEM-768 an den Empfänger, dazu der Transaktionsschlüssel, eingewickelt unter dem ovk der Wallet), die ganze Transaktion mit ihrer Aktion zusammensetzen und ihr Binding bilden: blake3("rand-tx-bind-1" || …) über die Transaktion mit geleerten Beweisen, acht Worte (Transaktionen). Auf Chain 20, deren Genesis binding_domain: 1 setzt, ist es blake3("rand-tx-bind-2" || …) mit dem Genesis-Hash zuerst, dann der Chain-ID, sodass ein für eine Chain erzeugter Beweis auf keiner anderen verifiziert, auch nicht auf einer mit derselben Chain-ID. Eine Wallet, die älter ist als v0.6.8, nimmt das alte Binding, und Chain 20 weist ihre Beweise zurück.
  5. Autorisieren: Ziehen Sie ein frisches 256-Bit-Salt und beweisen Sie den Auth-Guest auf seiner privaten Eingabe von 16 Worten, dem Spend Key und dem Salt, mit dem Binding als öffentlichem Eingabesegment, auf Tier 10. Er leitet nk aus dem Spend Key ab und veröffentlicht c = H(AUTH, nk ‖ salt), das das Bundle als auth_commit trägt.
  6. Beweisen Sie den Bundle-Guest auf seiner privaten Eingabe von 1.212 Worten (der Viewing Key nk, vier Eingabe-Slots mit ihren Pfaden, der Anker, vier Ausgaben, fee, burn_a, burn_r, das private Asset A, time, das Salt) mit demselben Binding als öffentlichem Eingabesegment, auf Tier 14. Der Beweis zeigt Besitz, Membership, dass jede echte Eingabe das Asset ihres Slots trägt, die vier Nullifier, dasselbe c und die zwei Bilanzen in₀ + in₁ = out₀ + out₁ + burn_a und in₂ + in₃ = out₂ + out₃ + fee + burn_r. Das ist der Beweis, den ein gekoppelter Prover anstelle der Wallet erstellen kann; der Auth-Beweis wird auf dem eigenen Rechner der Wallet erstellt.
  7. Prüfen Sie den veröffentlichten Digest des Beweises gegen den aus dem Klartext berechneten und reichen Sie Transaction { chain_id, bundle, action: None } ein.

Die Reihenfolge ist seit Chain 14 wichtig: Die Umschläge und die Aktion existieren vor den Beweisen, weil die Beweise sich darauf festlegen. Bei einem Aufruf wird zuerst der Aufrufbeweis erstellt, und er steckt ebenfalls im Binding. Auf einer hardening_v6-Chain wird der Aufrufbeweis selbst über ein Call-Binding der Transaktion mit geleerten Beweisen beider Art erstellt (rand-call-bind-1 auf den Chains 16 bis 19, rand-call-bind-2 mit dem Genesis-Hash auf Chain 20), das die Nullifier des Gebühren-Bundles abdeckt, sodass es nicht unter einem anderen Bundle kopiert werden kann.

proving bundle (tier 14; about a minute on a laptop)…
proved in 98.3s: tier 14, 1423170 bytes
submitted transfer 4f2c…  1.5 RAND out, 98.499 RAND change, fee 0.001 RAND, anchored at height 192

Das Transkript ist das Ausgabeformat der Wallet aus der Anleitung des Fullnodes mit Stand Chain 14; die gezeigte Byte-Zahl ist die eines auf Chain 14 committeten Bundle-Beweises im Produktionsprofil. Die Wallet seit Chain 17, v0.6.8 auf Chain 20 eingeschlossen, gibt vor diesen zwei Zeilen aus, proving the spend authorisation on this machine (tier 10; seconds)… und authorisation proved in …: tier 10, … bytes, und formuliert die Bundle-Zeile als proving the bundle (tier 14; about a minute and a half on a laptop)….

Dieselbe Maschinerie bezahlt jede Aktion, stets mit genau einem Bundle: Ein Deploy, ein Aufruf, eine Token-Registrierung oder ein Token-Mint läuft auf einer Selbstüberweisung von RAND mit Wert null, ein Bond auf einem Bundle, das den Einsatz über burn_r verbrennt, und ein Token-Burn oder ein Bridge-Burn auf einem Bundle, das das Asset aus den Slots 0–1 verbrennt (burn_a, burn_asset) und die RAND-Gebühr aus den Slots 2–3 zahlt. Das Asset, das eine Überweisung bewegt, ist ein Witness-Wort und steht in keinem öffentlichen Feld.

Was es kostet

Gemessen auf dem Entwicklungs-Laptop (Apple Silicon, Release-Build), die Zahlen, die die eigenen Dokumente des Fullnodes festhalten:

GuestWorteZyklenTierBeweisenBeweisgröße (Produktion, 80 Queries)
Bundle-Guest v3 (Chains 17 bis 20)—4.024 Zyklen und 273 Poseidon2-Permutationen Spielraum im Tier-14-Budget14≈ 100 s, 5,7 GB Spitze; 102,5 bis 134,0 s gemessen auf Chain 18 (2026-09-30)≈ 1,50 MB; 1.494.151 bis 1.504.260 Bytes gemessen auf Chain 18 (2026-09-30)
Auth-Guest (Chains 17 bis 20)—25010≈ 7 s; 6,6 bis 19,9 s gemessen auf Chain 18 (2026-09-30)≈ 1,37 MB; 1.364.940 bis 1.375.371 Bytes gemessen auf Chain 18 (2026-09-30)
Hidden-Asset-Bundle v1, 4-in-4-out (Chains 14 und 15)—unter dem Tier-14-Budget mit etwa 2.071 Zyklen (13 %) Reserve14≈ 98–100 s, 5,7 GB Spitze≈ 1,43 MB; 1.422.116 und 1.423.170 Bytes gemessen auf Chain 14
bundle, 2-in-2-out (ausgemustert; Chains bis 13)3.811≈ 9.16014≈ 100 s (94,6–97,9 s allein; je 114 s bei zweien gleichzeitig)1.321.773 Bytes gemessen auf Chain 8
private_payment (ein Aufruf)klein< 1.00010≈ 7 s≈ 1,37 MB (fib auf Tier 10: 1.367.688 Bytes unter Constraint-Set 7; 1.298.729 unter Set 6)
ein Aufruf ohne Hash-Tabelle (Off-Chain-Ledger, Chain 18)773—14114,8 s1.498.589 Bytes
ein Aufruf mit der SHA-256-Tabelle (Proof of Liabilities, Chain 18)994—14122,9 s1.911.152 Bytes
ein Aufruf mit der Keccak-Tabelle (anonyme Abstimmung, Chain 18)——1229,2 s3.346.865 Bytes

Die Verifikation ist der Konsenskostenpunkt, den jeder Node trägt: etwa 16 ms mit warmem Verifier Key, etwa 230 ms beim ersten Mal, wenn ein Key für eine bestimmte Form gebaut wird. Der Verifier Key hängt nicht vom Programminhalt ab — er ist indiziert über (tier, program_log_height, input_log_height, keccak_log_height, sha256_log_height, public_log_height) —, sodass ein Node pro Form einen baut und wiederverwendet; bei einem deployeten Programm wird der Key beim Deploy einmalig im Hintergrund berechnet (etwa 2 s auf einem Laptop, 7 s auf einem Server mit 2 vCPUs). Das 2-in-2-out-Bundle von Chain 13 und früher deklarierte die Form program 12, input 10, keccak 0, sha256 0, public 2, mem 16; ein Bundle-Beweis von Chain 14 deklariert public 4, die Höhe der acht Binding-Worte, trägt keine der beiden Hash-Tabellen und wird abgewiesen, bevor ein Verifier Key gebaut wird, wenn er ein anderes Tier, eine der beiden Tabellen oder eine andere öffentliche Höhe deklariert. Seit Constraint-Set 7 hat jede deklarierte Tabelle mindestens 2⁷ Zeilen, sodass ein Bundle-Beweis von Chain 20 public 7 deklariert.

Eine Transfer auf chain 20 trägt daher etwa 2,87 MB Beweis, den Bundle-Beweis und den Auth-Beweis, ein Aufruf zusätzlich einen dritten Beweis. Jeder muss in das Genesis-max_proof_bytes passen, auf chain 20 sind das 4.194.304 (4 MiB), wie auf den chains 17 bis 19; auf den chains 13 bis 16 waren es noch 8 MiB.

Der Hidden-Asset-Guest passt nur deshalb in Stufe 14, weil er seine privaten Eingaben in einer Schleife liest und die Geschwister-Lesevorgänge der Merkle-Prüfung zusammenfasst. In dem älteren, ausgerollten Stil landet dieselbe Relation in Stufe 16, mit etwa 400 s und 21–22 GB, was Wallets mit 16 GB ausschließen würde.

Das Beweisen ist CPU-gebunden, und die Wallet nutzt heute auf allen Plattformen das CPU-Backend. In den Läufen mit großen Stufen war der Prover single-threaded: Ein Droplet mit 16 vCPUs lief mit 99 % eines einzelnen Kerns, und der Speicher, nicht die Kerne, entschied darüber, ob ein Beweis fertig wurde (Speicherbedarf beim Beweisen). Das Flag --cuda bei send, bond, call, deploy, bridge-mint und bridge-burn wählt ein NVIDIA-Backend, das einen Build mit --features cuda voraussetzt. Seine Kernel liefen am 2026-09-28 erstmals auf echter Hardware, einer NVIDIA H100, und stimmten mit der CPU-Referenz überein. Im vom Release eingebundenen circuits-Checkout ist jedoch kein PTX eingecheckt, sodass ein Build mit no PTX for the GPU kernels fehlschlägt, bis die Kernel kompiliert sind. Auf einem GPU-Knoten der Flotte wurde noch kein Produktionsbeweis gemessen. Einen Rückfall auf die CPU gibt es bewusst nicht. Ein CUDA-Aufruf kann außerdem keinen Eingabe-Umschlag versiegeln, weil der Salt den Prover nie verlässt. Der Spitzenspeicher für einen Hidden-Asset-Bundle-Beweis der Stufe 14 beträgt etwa 5,7 GB (Production FRI, CPU); die größeren Speicherklassen betreffen die Interpreter- und Rekursionsbeweise weiter unten (≥ 64 GB und mehr).

Wie ein Knoten verifiziert

Die Zulassung führt zuerst die günstigen Prüfungen aus (Transaktionen), danach:

  • berechnet den Bundle-Digest aus dem veröffentlichten Klartext neu (Anker, vier Nullifier, vier Commitments, fee, burn_a, burn_r, burn_asset, time, das auth_commit des Bundles und ein auf null festgelegtes Taint-Wort) und verlangt, dass er dem entspricht, was der Beweis veröffentlicht hat. Ein Beweis, dessen Witness die Relation verletzt hat, veröffentlicht einen befleckten Digest, der zu keinem Klartext passt. Einige Prüfungen sind stattdessen strukturell (der Guest liefert Absender, Asset und Zeit einer Ausgabe selbst, sodass ein Prover sie nicht wählen kann), und das private Asset steckt nicht im Digest;
  • dekodiert den Beweis und prüft seine deklarierten Höhen gegen die Stufe (check_declared_heights), sodass die Schranke der Kette für die Gestalt eines Beweises die des Verifiers ist. Bevor eine Signatur oder ein Beweis geprüft wird, läuft auf jeder eingereichten oder per Gossip verbreiteten Transaktion ein Screening auf kanonische Beweise (und, unter hardening_v6, bei der Blockvalidierung); seit fullnode v0.6.8 (audit v6, ZKV-4) begrenzt dieses Screening zuerst jeden deklarierten Grad auf 25 Bit (MAX_HONEST_DEGREE_BITS, die Obergrenze der Speichertabelle plus eins), sodass ein Header mit riesigem Grad einen Knoten nicht mehr festhält, während der ehrliche Faltungsplan dafür neu abgeleitet wird, und eine Panic im Screening die Transaktion ablehnt, statt den Knoten anzuhalten;
  • berechnet das Binding der Transaktion und führt Machine::verify_public(hc_bundle, &binding, proof) aus — den Batch-Verifier plus die Prüfung, dass H_PUB der Digest dieser acht Wörter ist. Ein Beweis, der auf eine Transaktion mit einer anderen Aktion, einem anderen Umschlag oder einer anderen Chain-ID kopiert wurde, oder auf chain 20 auf das Genesis einer anderen Chain, verifiziert daher nicht (bis chain 13 war das Segment leer, und nichts band einen Beweis an seine Transaktion);
  • verifiziert den Auth-Beweis gegen hc_auth und dasselbe Binding und verlangt, dass das von ihm veröffentlichte c gleich auth_commit ist. Ein Bundle ohne Auth-Beweis wird abgelehnt (AuthMissing), ebenso eines, dessen c abweicht (AuthMismatch);
  • verlangt, dass das GAS_LIMIT des Bundle-Beweises dem Genesis-bundle_gas_limit von 20.479 entspricht und das des Auth-Beweises 1.279 beträgt, den Header-Obergrenzen der beiden Guests (BundleGasLimit, AuthGasLimit);
  • führt bei einem Aufruf dasselbe gegen den gespeicherten code_hash des Programms aus, mit den öffentlichen Wörtern des Programms gefolgt vom Call-Binding als Segment (ein RPL-2-Invoke hängt seinen Übergang als Kontextwörter an, Programme), und prüft dann die Gebühr gegen das Gas-Limit, das der Beweis deklariert, und gegen seine Bytes (Gebühren).

Eine über RPC oder Gossip eingereichte Transaktion wird auf einem von vier Workern hinter einer Warteschlange der Tiefe 64 verifiziert, außerhalb der Konsensschleife, und erst nach erfolgreicher Verifikation weiter per Gossip verbreitet; ein Token-Bucket pro Peer (Burst 16, Auffüllung 4 pro Sekunde) begrenzt, was ein Peer einen Knoten verifizieren lassen kann, und ein Cache mit 8.192 Einträgen beantwortet die Wiederholung einer dauerhaft abgelehnten Transaktion kostenlos. Die Verifikation der Beweise in einem vorgeschlagenen Block läuft weiterhin auf der Konsensschleife, wenn der Block angewendet wird. Ein Knoten, der synchronisiert, verifiziert jedes Zertifikat und jeden Beweis jedes Blocks neu, bevor er ihn akzeptiert; nichts wird vertraut, nur weil ein Quorum es signiert hat.

Stufen

StufeZyklusbudget (2ᵗ − 1)CPU-Zeilenverwendet von
101.0232¹⁰der Auth-Guest; private_payment, fib
124.0952¹²
1416.3832¹⁴der Hidden-Asset-Bundle-Guest (und der ausgemusterte bundle-Guest); der größte Aufruf
1665.5352¹⁶der EVM-Aufrufbeweis in der Testsuite; das übersetzte ERC-20-approve (auf chain 13 aufgerufen)
18262.1432¹⁸ERC-20-transfer und transferFrom, übersetzt oder interpretiert
201.048.5752²⁰SPL Token, übersetzt oder auf dem sBPF-Interpreter-Guest

Seit fullnode v0.5.6 (2026-09-25) wird ein Aufruf-Beweis oberhalb von Stufe 14 abgelehnt (CallTierTooHigh), bevor ein Verifier-Schlüssel gebaut wird, und ein Block, der einen enthält, ist ungültig; ein Aufruf darf außerdem höchstens 128 Keccak-f-Permutationen und 128 SHA-256-Kompressionen enthalten. Die Stufen 16 bis 20 lassen sich weiterhin beweisen, aber nur off chain: Keine der Zeilen darüber kann auf chain 20 aufgerufen werden, und chain 20 lehnt das Deployment eines Programms ab, das für jeden Aufruf der Stufe 14 zu groß ist, nämlich mehr als 8.180 Wörter ohne öffentliche Eingabe (ProgramUncallable) (das Budget).

Der Prover wählt die kleinste Stufe, deren Budget die Zyklen plus die Zeilen für Programm und Eingabe-Digest abdeckt; ein Lauf, der nicht passt, scheitert vor dem Beweisen. Nur die Stufe ist öffentlich. Jeder Schritt vervierfacht die Beweiszeit etwa und vergrößert den Beweis ein wenig. Auf chain 20 richtet sich die Gebühr eines Aufrufs nach dem Gas-Limit, das sein Beweis deklariert, und nach seiner Größe in Bytes, nicht nach der Stufe (Gebühren).

Constraint-Sets und Hard Forks

Ein Constraint-Set ist die exakte Menge an Tabellen, Spalten, Bussen, öffentlichen Werten und FRI-Parametern, die der Verifier prüft. Ein Beweis, der unter einem Set erzeugt wurde, verifiziert unter einem anderen nicht, in keiner Richtung, und der Start-Replay eines Knotens verifiziert jeden Beweis seiner Chain neu — ein Knoten, der aus einem anderen Set gebaut wurde, scheitert daher am ersten Beweis und kürzt seine Chain. Deshalb wird jede Änderung am Set als neue Chain-ID ausgeliefert, mit allen Knoten auf einem Build, und deshalb meldet rand_status hc_bundle und hc_auth, und ein Knoten, dessen Build vom Genesis abweicht, verweigert den Start.

SetDatumwas sich geändert hat
22026-09-10fünf Soundness-Korrekturen nach dem ersten Review
32026-09-11Poseidon2-Chip, hc im Circuit, die Programmtabelle als Witness, Sub-Word-Speicher, RV32M, FRI auf 27 Queries neu abgestimmt
42026-09-11die gesalzene Eingabe-Commitment H_IN mit eigener Tabelle; der Loader für flache Binärdateien
52026-09-12die optionale keccak-Tabelle; vom Beweis deklarierte Speicherhöhe; zwei kritische Korrekturen aus dem zk-Audit; FRI zurück auf 80 Queries; MAX_PROOF_BYTES auf 2 MiB
62026-09-14die obligatorische public-Tabelle und H_PUB; die optionale sha256-Tabelle; die EVM- und sBPF-Interpreter-Guests als Bibliotheken; 34 öffentliche Werte. Das liefen die chains 12 bis 15.
72026-09-28jeder LogUp-Abschluss über den BLIND-Bus verblindet; jede deklarierte Tabelle auf mindestens 2⁷ Zeilen aufgefüllt; 32-Bit-Bereichsprüfungen für Eingabe-, öffentliche und Salt-Wörter; der Syscall POSEIDON2_LEN (7); JALR löscht Bit 0 seines Ziels und verlangt funct3 = 0; Verifier-Schlüssel mit Salt aus key_derivation_v2. Das liefen die chains 16 und 17.
82026-09-29der Gas-Zähler: die Spalte GAS in der cpu-Tabelle und der öffentliche Wert GAS_LIMIT; 35 öffentliche Werte. Das laufen die chains 18 bis 20.

Die chains 14 und 15 änderten kein Constraint. Der Knoten von chain 15 hält Poseidon2s 86 Rundenkonstanten als literale Tabelle statt als gesäte Ziehung (audit ZKV-2) — dieselben Werte, sodass sich weder ein Hash noch ein Digest noch ein Beweis verändert hat. Chain 14: Das Hidden-Asset-Bundle ist ein neuer Guest (ein neues hc_bundle), und das Transaktions-Binding nutzt das öffentliche Segment, das Set 6 bereits im Circuit bindet. Es ist trotzdem ein Hard Fork — das Wire-Format des Bundles, der festgelegte Guest und jede Transaktions-ID haben sich geändert, eine Transaktion von chain 13 mit einem Bundle wird vom neuen Build abgelehnt, und eine vor dem Fork gebaute Wallet erzeugt Beweise mit leerem Segment, die die Chain ablehnt.

Die drei Chains seitdem haben jeweils verändert, was ein Proof ist. Chain 16 (Fullnode v0.6.1, 2026-09-28) wechselte zu Constraint-Set 7, fixierte den verzweigungsfreien Bundle-Guest v2 und setzte hardening_v6, nachdem die Prüfung vom 2026-09-27 gezeigt hatte, dass kurze Tabellen und ungeblindete LogUp-Terminals private Daten preisgaben (Wie die zkVM funktioniert). Jeder Verifier-Schlüssel änderte sich. Chain 17 (v0.6.3, 2026-09-29) behielt Set 7 bei und ergänzte die geteilte Autorisierung: Bundle-Guest v3, den Auth-Guest, zwei neue Felder im Wire-Format des Bundles und die Transaktions-ID-Domäne rand-txid-3. Chain 18 (v0.6.7-rc1, 2026-09-29) wechselte für den Gas-Zähler zu Constraint-Set 8. Die gemessenen Mehrkosten bei der Proof-Größe liegen unter 1 %. Chain 19 (2026-10-01) ist ein Re-Genesis von Chain 18 auf demselben v0.6.7-Build und änderte nichts an den Proofs. Chain 20 (Fullnode v0.6.8, 2026-10-01) behält Constraint-Set 8 sowie dieselben Guests und Verifier-Schlüssel bei und ändert, woran ein Proof gebunden ist: Die Transaktions- und Aufruf-Bindungen tragen den Genesis-Hash (binding_domain: 1), eine öffentliche Eingabe, die Wallet und Ledger berechnen, sodass sich kein Circuit verändert hat. Dennoch ist es ein Hard Fork, denn die Proofs einer v0.6.7-Wallet werden dort nicht verifiziert. Jeder Build lehnt die vorangegangenen Chains anhand des Genesis-Hashs ab.

Zwei im Code festgehaltene Audit-Hinweise, die man kennen sollte: Der öffentliche Wert TIER wird vom Verifier gegen den Proof-Header und die Degree-Bits des Batches geprüft, vom Circuit selbst aber nicht eingeschränkt (Audit ZL1, für das nächste Set vorgemerkt statt behoben, weil sein Entfernen das Layout der öffentlichen Werte verschiebt); und H_IN ist eine für den Guest sichtbare Commitment, die der Verifier absichtlich nicht mit einem vom Aufrufer gelieferten Wert vergleicht.

Ausblick: Block-Aggregation

Bei etwa 1,43 MB pro Bundle-Proof mit verborgenem Asset auf den Chains 14 und 15 fasste ein 4-MiB-Block (der Standard und der von Chain 12) zwei Shielded-Transfers; bei den ~1,3 MB des 2-in-2-out-Bundles waren es drei. Die Chains 13, 14 und 15 hoben die Blockobergrenze auf 20 MiB an (max_block_bytes), Platz für vierzehn. Chain 20 behält 20 MiB, und ein Transfer trägt dort etwa 2,87 MB Proof, sodass ein Block etwa sieben fasst. Die Abhilfe, für die sich der Fullnode entschieden hat (2026-09-12), statt Pruning oder eines größeren Blocks, ist die Aggregation auf Blockebene: ein rekursiver Proof pro versiegeltem Fenster, der N Bundle-Proofs verifiziert, sodass die Historie durchgängig proof-tragend bleibt, während die rohen Proofs verworfen werden können. Sie ist gebaut und gemergt, aber nicht aktiviert, und seit Chain 14 muss sie neu vermessen werden, bevor sie es sein kann: Ihre zugelassene Bundle-Form wurde mit dem leeren öffentlichen Segment gemessen (public 2), ein transaktionsgebundenes Bundle deklariert aber public 4, sodass kein auf Chain 14 bewiesenes Bundle dazu passt. Die Constraint-Sets 7 und 8 haben die Form erneut verschoben: Ein Bundle-Proof deklariert jetzt public 7 und veröffentlicht 35 Werte, die Schnittstelle des Aggregats umfasst also 35 Wörter pro Proof. Ein Node-Build weigert sich, auf einem Genesis zu starten, der einen Abschnitt aggregation enthält, und die Chains 14 bis 20 wurden ohne einen solchen geschnitten. Ein Genesis mit dynamischen Gaspreisen, wie der von Chain 20, wird neben einem Abschnitt aggregation ebenfalls abgelehnt. Seit Fullnode v0.5.8 bindet der Aggregat-Proof außerdem seinen Aggregator (Audit AGG-2: Das Programm absorbiert aggregate_binding(chain_id, aggregator, nonce)), sodass der Programm-Digest der zugelassenen Form auf einem Build gemessen werden muss, der diese Änderung enthält. Die Aktivierung wartet zudem noch auf eine Ende-zu-Ende-Übung mit einem gefälschten Aggregat gegen den korrigierten Rekursions-Verifier, die noch nicht durchgeführt wurde, und auf eine Entscheidung zum Auth-Proof: Das Aggregat-Programm verifiziert nur Bundle-Proofs, sodass das Versiegeln eines Fensters auf einer Chain mit geteilter Autorisierung einen Transfer von etwa 2,87 MB auf etwa 1,37 MB verkleinern würde, nicht auf null.

Was gebaut ist:

  • eine zweite, Goldilocks-native Maschine (die Rekursions-VM, randprotocol-rvm), deren Verifier-Programm einen RV32-Proof in etwa 1,97 Millionen Zeilen auf Tier 21 prüft (2.044.506 unter Constraint-Set 7), und ein N-generisches Aggregat-Programm über ein Fenster von Bundle-Proofs;
  • zwei Rollen: Validatoren bleiben CPU-schonend und verifizieren ein Aggregat pro versiegeltem Block; Aggregatoren (ein permissionless, mit Bond abgesichertes Register mit einer Shielded-Auszahlungsadresse) beweisen Aggregate auf GPU-Maschinen und erhalten den Proving-Anteil der abgedeckten Bundles plus eine Block-Subvention in neuem RAND nach einem Halbierungsplan;
  • fünf Aktionen (RegisterAggregator, UnbondAggregator, WithdrawAggregator, SlashAggregator, Aggregate; SlashAggregator bleibt im Wire-Format und wird abgelehnt, weil ein wiederholtes Aggregat dieselbe Nonce erneut signiert und keine Equivokation ist), eine neunstufige Zulassung, das Versiegeln und Pruning abgedeckter Bundles auf etwa 3 KB öffentlicher Felder je Bundle, eine Sync im versiegelten Format, die einen frischen Node eine Rekursionsverifikation pro Fenster kostet, die RPC-Methoden rand_getAggregate, rand_getAggregators, rand_getUnsealed, rand_getRawTransaction und den Daemon rand-node aggregate --watch.

Gemessen auf dem FRI-Testprofil: ein N=1-Aggregat wurde auf einem ausgelasteten Laptop in etwa 26 Minuten bewiesen (327.035 Bytes); ein frischer Node wendete einen versiegelten Batch aus sieben Blöcken in unter einer Sekunde mit einer Rekursionsverifikation an. Maschinenklassen, wie sie zunächst begrenzt wurden: N=1 benötigt ≥ 64 GB Host-Speicher, N=2 ≥ 128 GB, N=3 ≥ 160 GB; das produktive N ≥ 2 gehört zum CUDA-Backend, das einen GPU-Node braucht, den es noch nicht gibt. Gemessen auf einer 256-GB-Maschine unter Constraint-Set 7 (2026-09-28 und 29), benötigte das N=2-Aggregat 133 GB, N=3 benötigte 221 GB, und der produktive Exit-Proof (das Verifier-Programm über einem inneren Proof) überschritt 256 GB. Nichts davon wurde unter Constraint-Set 8 neu gemessen. Bis die Aggregation aktiviert wird, ersetzt auf Chain 20 kein Aggregat einen Proof: Ihre beiden Archive-Nodes behalten jeden rohen Proof, und ihre Validatoren prunen Historie, die älter als 24 Stunden ist.

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.