Esegui un nodo Rand
Il full node di riferimento e il suo wallet sono scritti in Rust e si compilano dai sorgenti. Ne risultano due binari: rand-node, il nodo e gli strumenti per gli operatori, e rand, un wallet che custodisce una chiave di spesa shielded, dialoga con qualsiasi nodo via JSON-RPC ed esegue localmente il prover zkVM per ogni trasferimento e per ogni chiamata riservata. Una testnet sperimentale, la chain 21, è attiva con 26 validatori su droplet DigitalOcean. Non è sottoposta ad audit e non ha alcun valore reale. I binari Linux x86_64 di entrambi sono allegati alla release v0.8.0, la build su cui è stata aggiornata la flotta.
# 1. Rust (rustup recupera la toolchain 1.98.1 indicata) e le dipendenze di build di RocksDB
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
sudo apt install build-essential clang cmake pkg-config libssl-dev # Linux
# 2. Clona e compila (10–20 min la prima volta)
git clone https://github.com/randprotocol/fullnode.git
cd fullnode
cargo build --release # target/release/rand-node, target/release/rand
# 3. Una chain con due validatori su questa macchina (RPC su 8545 e 8546)
scripts/local-testnet.sh
target/release/rand --rpc http://127.0.0.1:8545 status
# 4. Test; in release perché la generazione delle prove STARK è lenta in debug (678 test, circa 43 minuti, misurati il 2026-09-14)
cargo test --workspace --release
# La release v0.8.0 (c0878c3f) esegue la chain 21, e nessuna release precedente lo fa: la chain 21 esegue il constraint set 9, di cui nessuna versione più vecchia include le verifier key e la codifica delle prove. Compilala dal tag, oppure su Linux x86_64
# scarica i binari della release e verificali con gli SHA256SUMS pubblicati insieme ad essa
git checkout v0.8.0 && cargo build --release
curl -LO https://github.com/randprotocol/fullnode/releases/download/v0.8.0/rand-node -LO https://github.com/randprotocol/fullnode/releases/download/v0.8.0/rand \
-LO https://github.com/randprotocol/fullnode/releases/download/v0.8.0/msauth-vk-production.bin# la verifier key multisig fissata: rand-node la carica dal file accanto al proprio binario e rifiuta di avviarsi senza di essa
sha256sum rand-node rand msauth-vk-production.bin # deve stampare i valori della release (SHA256SUMS, firmato come SHA256SUMS.sig):
# 324a4ab1029d39e67fc2de36b036341b0f88f13089997d7fe24c596363a58278 rand-node
# e3a38e74ee28743a960fc1c3eb1ac6c538e18dc259411e10afff7f54e268bbf4 rand
# 68facb06c7f321aaf1d4d541acf6b5c0e9d7f17788ed1c9add6c5a8a8f7acd30 msauth-vk-production.bin
# L'identità del tuo nodo: chiave di validatore Dilithium2 e peer id p2p in un unico file. Genera la tua
# e tienila fuori dal checkout; il repository non traccia più alcuna chiave
rand-node keygen --out node.key.json
# Il genesis è incluso nel repository; ogni nodo deve possedere lo stesso identico file.
# init ne stampa l'hash, che deve coincidere con quello riportato di seguito
rand-node init --datadir ./data --genesis deploy/genesis-chain21.json
# Collegati ai validatori pubblici (la chain 21 ha mantenuto le chiavi della chain 14, quindi i suoi peer id e IP).
# Ometti --validator: la tua chiave non è nel validator set. Un validatore richiede anche NTP
rand-node run --datadir ./data --key node.key.json \
--listen /ip4/0.0.0.0/tcp/30303 --rpc 127.0.0.1:8545 --no-mdns \
--bootstrap /ip4/164.90.239.200/tcp/30303/p2p/12D3KooWEQEbUwZRgqhDPXhW7vNBmcRcnhUDGUADe81VFdv3ALYe \
--bootstrap /ip4/165.245.173.74/tcp/30303/p2p/12D3KooWJyc5oDHggAr89e9QrRFBy9Tg8TxXh18yzrb1SM6KKLYw \
--bootstrap /ip4/188.166.235.187/tcp/30303/p2p/12D3KooWSyX84P1DAbWByLHpRBMLRWD53r3Jj4aqVt6tHoF8B2ZQ
# Un wallet è una chiave separata, shielded. Il suo indirizzo rand1… è un testo di circa 1,6 KB
rand keygen && rand address
# Un mint del faucet è firmato da un validatore, quindi richiede l'RPC di un validatore: funziona sulla
# chain locale con due validatori così com'è; un observer risponde "ask a validator node". Sulla chain 21
# il faucet emette solo verso i 16 wallet che il suo genesis include nella allowlist, e solo dai validatori che indica
rand faucet # 100 RAND in una nota che solo tu puoi aprire
rand balance # scansiona l'albero con la tua chiave; nessun altro può farlo
rand send <rand1 address> 1.5 # chiede conferma, genera la prova (~2 min), attende il commit
# Assembla un guest integrato: paga l'eccedenza oltre 1000 se quattro saldi privati la coprono
rand program build --guest private_payment --arg 1000 --out pp.json
rand program deploy pp.json # stampa il program id (il suo hash di contenuto)
# Genera la prova in locale; sulla chain vanno solo la prova, otto parole di output e una trascrizione sigillata degli input
rand call <program id> --input 400 --input 250 --input 300 --input 75
rand receipt <tx> # output [1, 0, 25, 0, ...]: l'eccedenza, pubblicata come dato
# Più tardi, apri la trascrizione e confrontala con l'H_IN pubblicato dalla prova
rand open-call <tx> # inputs: [400, 250, 300, 75] — verdict: faithful
Requisiti
- OS
- Linux x86_64 o macOS arm64
- Rust
- 1.98.1, fissato da rust-toolchain.toml; lo installa rustup
- Dipendenze di build
- Compilatore C++, cmake, pkg-config, header di OpenSSL (RocksDB)
- Prima compilazione
- Da 10 a 20 minuti: RocksDB e Plonky3 dai sorgenti
- Porte
- TCP 30303 in ingresso sui nodi pubblici; RPC su 127.0.0.1:8545
- Server
- Un'istanza cloud da 1 a 2 vCPU esegue un validatore della testnet
- Orologio
- NTP (chrony) su un validatore: trattiene il proprio voto per un blocco più di 15 s in anticipo rispetto al proprio orologio, quindi un orologio in ritardo smette di votare senza segnalarlo
- Generazione delle prove
- Oggi solo CPU: un trasferimento shielded richiede circa due minuti su un laptop (una prova di autorizzazione da 7 s e una prova del bundle da circa 110 s) e circa 6 GB di memoria; una piccola chiamata aggiunge circa 30 s
Scegli un ruolo
- Osservatore aperto a tutti
Lo stesso binario senza --validator. Sincronizza la chain, verifica ogni certificato e ogni prova di bundle e di chiamata, riesegue ogni blocco, confronta le ricevute e serve JSON-RPC. È ciò che esegue una nuova chiave sulla testnet pubblica.
- Validatore con bond
Vota e propone con HotStuff concatenato. Sulla chain 21, come sulla chain 20, un nuovo validatore viene ammesso prima tramite voto: i validatori che detengono più di due terzi dello stake firmano un'azione AdmitValidator per la sua chiave. Poi registra la chiave del nodo (rand-node register --v2), vincola almeno 1.000 RAND da un wallet ed entra nel set al terzo confine di epoca da 1.000 blocchi dopo il vincolo (il ritardo di vincolo di due epoche della chain 18). La chain 18 è partita con 26 validatori da 1.000 RAND ciascuno; più di due terzi dello stake, 18 su 26, devono essere online e votare per effettuare il commit. Genera la tua chiave: nessuna chiave di validatore è più conservata nel repository, e i file di chiave inclusi nel commit per le chain precedenti sono seed pubblicati.
- Wallet e prover locale
Il client rand custodisce una chiave di spesa a 256 bit e non firma nulla: l'autorizzazione è data da due prove, una piccola generata con la chiave di spesa e la prova del bundle 4-in-4-out. Scansiona l'albero alla ricerca delle proprie note, genera entrambe le prove sulla tua macchina, con la stessa forma per RAND e per qualsiasi token RPL, e per una chiamata riservata dimostra anche il programma. Sulla chain arrivano solo prove, commitment, nullifier e buste sigillate.
Non esegui un nodo? Lo stesso wallet è disponibile come app per iOS, Android, Chrome e Firefox: Wallet.
Ogni nodo controlla tutto
Un nodo che si sincronizza riverifica ogni certificato, riesegue ogni blocco comprese le sue prove e confronta le ricevute prima di accettare. All'avvio controlla il proprio database, tronca tutto ciò che è incoerente conservando il proprio stato di sicurezza del voto, e recupera di nuovo il tratto mancante dai peer.
# Nodo fermo: hash, QC, firme, prove, riesecuzione
rand-node verify --datadir ./data --mode full
rand-node verify --datadir ./data --repair
I test di guasto vengono eseguiti sulla testnet live
- ›Fermare uno dei quattro validatori: la chain continua a fare commit e il nodo si riallinea in pochi secondi quando torna.
- ›Fermarne due su quattro: la chain si arresta senza quorum e riprende senza fork quando tornano.
- ›Corrompere il database di un nodo: rilevato all'avvio, troncato, risincronizzato dai peer, identico byte per byte al termine.
- ›Trasferimenti tramite nodi diversi: tutti confermati, saldi identici ovunque, offerta invariata.
- ›Un collegamento con un peer interrotto viene ristabilito dalla logica di ricomposizione entro circa 30 secondi.
Non ancora implementato
Elencato perché il divario tra il paper e il nodo sia leggibile e non dedotto.
- ›Stato persistente per programma e chiamate tra programmi
- ›Un compilatore nel wallet stesso: un programma è un guest assemblato integrato oppure un'immagine compilata con la toolchain separata rand-guest
- ›Slashing e jailing, ricompense di blocco, mercati delle commissioni, il beacon del leader basato su hash-sortition
- ›Un accumulatore di nullifier, il pruning delle prove dopo la finalità, il batching delle prove
- ›Una prova di tier 20 del trasferimento SPL Token e il mercato di prover GPU descritto nel paper