Usa questa pagina per generare la chiave giusta per ogni scopo, per analizzare o validare un indirizzo e per sapere che cosa si rivela consegnando una chiave a qualcuno. Su questa chain non esistono account: un saldo è un fatto che riguarda un file di chiavi, mai la chain.
Due chiavi, due tipi di indirizzo
| chiave del nodo | chiave del wallet | |
|---|---|---|
| scritta da | rand-node keygen | rand keygen |
| segreto | un seed di 32 byte | una spend key a 256 bit |
| identità pubblica | un indirizzo di 32 byte, base58, da 32 a 44 caratteri | un indirizzo schermato, rand1…, di 1.665 o 1.666 caratteri |
| firma | blocchi, voti, mint del faucet, Unbond, Withdraw, una Registration e, sulla chain 20, un voto AdmitValidator; come autorità di mint Key di un token, TokenMint e SetAuthority. Sulla chain 20 ciascuno di questi messaggi copre anche l’hash di genesi (Transazioni) | niente: un trasferimento è autorizzato dalle sue prove |
| appare on-chain come | proponente di un blocco, riga del registro dei validatori, minter di un mint del faucet, autorità key di un token | mai in un trasferimento, dove è sigillata dentro le buste. È pubblicata dove il valore entra nel pool con un importo pubblico: un deposito del bridge, un mint di token e, sulla chain 20, il pagamento di un’invocazione indicano l’indirizzo del destinatario; l’indirizzo di pagamento di un validatore è nel registro, il genesi della chain 20 indica la tesoreria delle commissioni del bridge e, dalla chain 14, un mint del faucet e una nota alloc di genesi pubblicano la pk del proprietario, i primi 32 byte dell’indirizzo |
| file | { "seed", "address", "public_key" }, modalità 0600 | { "version": 2, "spend_key": "<64 hex>" }, modalità 0600 |
Le due non si mescolano mai. I validatori sono identificati dal primo tipo, e la stessa forma di chiave Dilithium2 serve per l’autorità di mint Key di un token (rand token create --authority-key-out scrive un file con la forma di quello di rand-node keygen), per la chiave di pausa del bridge e per le sue sei chiavi guardiane post-quantistiche. Le chiavi di attestazione dei guardiani sono secp256k1, con indirizzi di 20 byte in stile Ethereum (Bridge). Il valore è detenuto sotto il secondo tipo.
L’indirizzo trasparente
Una chiave del nodo è un seed di 32 byte da cui si deriva in modo deterministico una coppia di chiavi Dilithium2: una chiave pubblica di 1.312 byte e firme di 2.420 byte. L’indirizzo è un hash BLAKE3 con separazione di dominio della chiave pubblica, reso in base58:
address = blake3("rand-address" || public_key) // 32 bytes, shown as base58
Gli oggetti firmati (voti, blocchi, mint, azioni di staking) portano la chiave pubblica completa, così un verificatore controlla blake3("rand-address" || public_key) == address invece di fidarsi di un indirizzo nudo. Lo stesso seed produce anche l’identità libp2p del nodo, una chiave ed25519 ricavata da blake3("rand-p2p-identity" || seed), che è il peer id dopo /p2p/ in un multiaddr di bootstrap.
rand-node keygen --out node.key.json # prints the address
rand-node address --key node.key.json # address, public key (hex), libp2p peer id
Esempio: EdrEC2QRQrQF64iRXxF9927jNj6RidiHHByzx5xD6F1e è uno dei validatori della chain 20. Le chain da 15 a 20 riutilizzano le diciotto chiavi ruotate per la chain 14, quindi i loro indirizzi e peer id non cambiano e nessun indirizzo o peer id di validatore della chain 13 è ancora in uso; altri otto validatori si sono vincolati sulla chain 15 e tutti e 26 sono nel file di genesi dalla chain 16 in poi.
L’indirizzo schermato
Un wallet è un solo segreto, la spend key a 256 bit sk, e tutto il resto ne è una derivazione. La derivazione usa Poseidon2 con un tag di dominio come prima parola assorbita (H(domain, msg)), la stessa funzione che la zkVM calcola nel circuito:
spend key sk 256 bits, in wallet.key.json
│
├─ viewing key nk = H(NK, sk) sees the whole history; cannot spend
│ ├─ pk = H(PK, nk) the field a note names its owner by
│ ├─ nullifier(cm) = H(NF, nk, cm) what a spend publishes
│ ├─ ovk opens envelopes this wallet sent
│ └─ ML-KEM-768 decapsulation key opens envelopes sent to this wallet
└─ address rand1 + base58(pk || kem_ek)
L’indirizzo è composto dai 32 byte di pk seguiti dalla chiave di incapsulamento ML-KEM-768 di 1.184 byte, in base58 dopo il prefisso rand1: 1.665 o 1.666 caratteri (la lunghezza in base58 dipende dai byte iniziali; circa un indirizzo su quattordici è quello più corto), circa 1,6 KB, e nessun checksum. Il mittente ha bisogno della chiave di incapsulamento per sigillare la busta della nota, ed è per questo che si trova nell’indirizzo. È pubblica per progetto: chiunque può pagarla e possederla non dice nulla su ciò che essa detiene.
rand keygen # wallet.key.json; refuses to overwrite an existing file
rand address # rand1… on stdout, its fingerprint XXXX-XXXX-XXXX-XXXX on stderr
Dalla v0.5.10 rand address stampa su stdout esattamente l’indirizzo e un a capo, quindi $(rand address) funziona in uno script. L’impronta va su stderr.
L’analisi, esattamente come la esegue ShieldedAddress::parse: si rimuove rand1, si decodifica il base58 e si richiedono esattamente 32 + 1.184 = 1.216 byte; i primi 32 sono pk come otto parole u32 little-endian, il resto è la chiave di incapsulamento. L’RPC rifiuta qualsiasi parametro più lungo di 2.000 caratteri prima di analizzarlo.
Accanto al file di chiavi, il wallet conserva <key>.key.json.notes.json, una cache delle note che questa chiave ha aperto. Contiene i testi in chiaro delle note, perciò è scritta in modalità 0600 come la chiave; ogni sua riga è recuperabile ripetendo la scansione dalla foglia 0.
Condividere un indirizzo: l’impronta e i link randpay:
Un indirizzo è troppo lungo per essere letto ad alta voce o confrontato a occhio e non ha checksum, perciò dalla v0.5.10 ogni wallet mostra accanto ad esso un’impronta. L’impronta serve solo per la visualizzazione: nulla on-chain né sulla rete ne porta una.
fingerprint = first 80 bits of blake3("rand-address-fingerprint-1" || pk_bytes || kem_ek)
= 16 Crockford base32 characters, shown as XXXX-XXXX-XXXX-XXXX
L’hash è calcolato sui 1.216 byte grezzi che l’indirizzo codifica. L’alfabeto è 0123456789ABCDEFGHJKMNPQRSTVWXYZ; l’analisi ignora maiuscole e trattini e legge O come 0 e I o L come 1.
Un link randpay: porta un indirizzo e, facoltativamente, che cosa pagargli:
randpay:<rand1…>[?amount=<decimal>][&asset=<index | 64 hex | rpl1…>][&memo=<percent-encoded UTF-8>]
amount è nelle unità di visualizzazione dell’asset (RAND decimale con nove decimali, un token con i decimals della propria riga di registro) e non deve essere zero. memo è al massimo di 510 byte di UTF-8. Lo schema viene riconosciuto senza distinguere maiuscole e minuscole; un parametro sconosciuto, ripetuto o con una codifica percentuale errata viene rifiutato.
rand address --uri --amount 1.5 --memo "invoice #42" --qr # a randpay: link, as a terminal QR
rand contacts add alice rand1q9f… # shows the fingerprint, asks add? [y/N]
rand send alice 1.5 --memo "coffee" # to a contact, with a memo
rand send <TO> accetta un indirizzo rand1…, un link randpay: o il nome di un contatto salvato, provati in quest’ordine. amount, asset e memo di un link completano ciò che la riga di comando omette, e un valore indicato in entrambi i modi che non coincide viene rifiutato. Prima di generare la prova, send stampa to <contact, if any> · fingerprint XXXX-XXXX-XXXX-XXXX · <amount> <asset> e chiede conferma; uno script passa --yes. I contatti sono memorizzati accanto alla chiave in <key>.contacts.json, modalità 0600. Il memo viaggia dentro la busta della nota (Note).
Non esistono rand balance <address> né una RPC per il saldo: la chain non può rispondere a questa domanda per nessuno. Un wallet calcola il proprio saldo scansionando con la sua viewing key ogni busta presente sulla chain (Note).
Chiavi che puoi consegnare a qualcun altro
La divulgazione è una proprietà delle chiavi, e la chain non può imporne alcuna.
| chiave | apre | granularità |
|---|---|---|
la viewing key nk (64 hex) | ogni nota che il wallet abbia mai ricevuto e, tramite ovk, ogni nota che abbia mai inviato, con il nullifier di ciascuna spesa | tutto o niente, retroattiva e valida per il futuro |
una chiave di transazione TxKey (32 byte) | esattamente la singola busta che ha sigillato: la nota e, dalla chain 18, il suo memo | un pagamento |
una chiave di chiamata K_call | la trascrizione degli input privati di una chiamata confidenziale | una chiamata |
Una viewing key non può spendere. Dalla chain 17 (autorizzazione divisa) la prova del bundle è realizzata a partire da nk, e ogni bundle porta anche una seconda, piccola prova di autorizzazione che solo la spend key può produrre e che è legata a quella singola transazione (Note). È ciò che permette di consegnare nk a un prover delegato, e quindi l’intera cronologia del wallet, senza che possa spendere; il wallet produce sempre la prova di autorizzazione sulla propria macchina. Indirizzi, chiavi e note esistenti non cambiano con la divisione. Il wallet deriva nk a ogni esecuzione e non lo memorizza mai; ogni TxKey è estratta ex novo per ogni busta e scartata dopo la sigillatura. A un nodo si può consegnare una viewing key con rand_importViewingKey (in memoria, al massimo 64 per nodo, scompare al riavvio) perché effettui la scansione per conto del titolare — è il percorso dell’explorer — e rand_checkTransaction(hash, key) verifica un pagamento rispetto a una TxKey in un’unica chiamata senza stato. rand viewing-key stampa nk, e rand tx-key <hash> stampa la chiave di ciascun output di una transazione che questo wallet è in grado di aprire.
Gli id dei token non sono indirizzi
Un token RPL ha un terzo tipo di identificatore testuale, e nomina un token, mai un detentore. L’id di asset di 32 byte del token è mostrato come 64 caratteri esadecimali e come rpl1…: bech32m (BIP-350) con la parte leggibile rpl sui 32 byte dell’id, 52 caratteri di dati più un checksum di 6 caratteri, 62 caratteri. L’analisi è rigorosa: un checksum errato, un’altra parte leggibile, un payload che non sia esattamente di 32 byte o l’uso misto di maiuscole e minuscole vengono rifiutati, così un errore di battitura non si risolve mai in un token diverso. Una nota non porta l’id; la sua parola asset è l’indice denso del token nel registro (Token RPL).
Il destinatario del bridge
Il formato di trasmissione del bridge ha uno slot di 32 byte per il destinatario, e un indirizzo schermato non vi entra. Oggi lo slot porta un hash dell’indirizzo:
recipient_hash = blake3("rand-shielded-recipient" || pk_bytes || kem_ek)
Il depositante sulla chain di origine indica l’hash, i guardiani lo firmano e la transazione BridgeAttest porta l’indirizzo completo perché il ledger lo verifichi rispetto ad esso (Bridge).
L’indirizzo schermato breve: provato sulla chain 11, ripristinato
La chain 11 (tag del fullnode v0.2, 2026-09-17) ha sostituito l’indirizzo lungo con un receiver id di 53–55 caratteri, rand1 + base58(blake3(receiver signing key) ‖ checksum), e ha spostato la chiave di incapsulamento ML-KEM in un receiver record firmato, che il mittente recuperava dal registro dell’explorer oppure riceveva direttamente all’interno di una richiesta di pagamento. È rimasta in funzione un giorno ed è stata ripristinata lo stesso giorno (fullnode 17db41d); la chain 12 è tornata all’indirizzo lungo, esattamente come descritto sopra, e ogni chain successiva, chain 20 inclusa, lo mantiene.
Perché è stata abbandonata. Un receiver id è un hash, e un mittente non può sigillare una nota verso un hash. Il primo pagamento a un wallet che non si era mai registrato richiedeva che il destinatario consegnasse una richiesta di pagamento o un file di record, e la registrazione stessa veniva pagata con un auto-trasferimento, che un wallet nuovo e vuoto non può effettuare. Entrambi i percorsi di consegna, inoltre, rivelavano al registro chi stava per essere pagato. Il progetto che mantiene un indirizzo breve, l’invio incondizionato e la privacy crittografica è un indirizzo ibrido: una chiave X25519 di 32 byte inclusa nell’indirizzo (circa 93 caratteri), la chiave post-quantistica tramite lookup, con il primo pagamento a un wallet non registrato riservato nei confronti di avversari classici e ogni pagamento successivo interamente post-quantistico. Questo è specificato di seguito; finché non verrà rilasciato, l’indirizzo lungo resta l’indirizzo.
La specifica della chain 11 e la sua implementazione restano nella cronologia del fullnode (docs/superpowers/specs/2026-09-17-short-shielded-address.md, tag v0.2) per le parti che il progetto ibrido riutilizza: la receiver signing key derivata, il record firmato e il relativo verificatore, e il registro come stato della chain.