Utilisez cette page pour générer la bonne clé selon l’usage, pour analyser ou valider une adresse, et pour savoir ce que révèle le fait de remettre une clé à quelqu’un. Il n’y a pas de comptes sur cette chaîne : un solde est un fait qui concerne un fichier de clé, jamais la chaîne.
Deux clés, deux types d’adresse
| clé de nœud | clé de portefeuille | |
|---|---|---|
| écrite par | rand-node keygen | rand keygen |
| secret | une graine de 32 octets | une clé de dépense de 256 bits |
| identité publique | une adresse de 32 octets, en base58, de 32 à 44 caractères | une adresse protégée, rand1…, de 1 665 ou 1 666 caractères |
| signe | les blocs, les votes, les mints du faucet, Unbond, Withdraw, une Registration et, sur la chaîne 20, un vote AdmitValidator ; en tant qu’autorité de mint Key d’un token, TokenMint et SetAuthority. Sur la chaîne 20, chacun de ces messages couvre aussi le hash de genèse (Transactions) | rien : un transfert est autorisé par ses preuves |
| apparaît sur la chaîne comme | un proposeur de bloc, une ligne du registre des validateurs, le minteur d’un mint du faucet, une autorité key d’un token | jamais dans un transfert, où elle est scellée dans des enveloppes. Elle est publiée là où de la valeur entre dans le pool avec un montant public : un dépôt de pont, un mint de token et, sur la chaîne 20, le versement d’un invoke nomment l’adresse du destinataire ; l’adresse de versement d’un validateur figure dans le registre, la genèse de la chaîne 20 nomme la trésorerie de frais du pont, et depuis la chaîne 14 un mint du faucet et une note alloc de genèse publient le pk du propriétaire, les 32 premiers octets de l’adresse |
| fichier | { "seed", "address", "public_key" }, mode 0600 | { "version": 2, "spend_key": "<64 hex>" }, mode 0600 |
Les deux ne se mélangent jamais. Les validateurs sont identifiés par le premier type, et la même forme de clé Dilithium2 sert l’autorité de mint Key d’un token (rand token create --authority-key-out écrit un fichier de la forme de celui de rand-node keygen), la clé de pause du pont et ses six clés de gardiens post-quantiques. Les clés d’attestation des gardiens sont en secp256k1, avec des adresses de 20 octets de style Ethereum (Pont). La valeur est détenue sous le second type.
L’adresse transparente
Une clé de nœud est une graine de 32 octets dont on dérive de façon déterministe une paire de clés Dilithium2 : une clé publique de 1 312 octets et des signatures de 2 420 octets. L’adresse est un hash BLAKE3 à séparation de domaine de la clé publique, rendu en base58 :
address = blake3("rand-address" || public_key) // 32 bytes, shown as base58
Les objets signés (votes, blocs, mints, actions de staking) portent la clé publique complète, de sorte qu’un vérificateur contrôle blake3("rand-address" || public_key) == address au lieu de se fier à une adresse nue. La même graine produit aussi l’identité libp2p du nœud, une clé ed25519 issue de blake3("rand-p2p-identity" || seed), qui est l’identifiant de pair après /p2p/ dans une multiadresse d’amorçage.
rand-node keygen --out node.key.json # prints the address
rand-node address --key node.key.json # address, public key (hex), libp2p peer id
Exemple : EdrEC2QRQrQF64iRXxF9927jNj6RidiHHByzx5xD6F1e est l’un des validateurs de la chaîne 20. Les chaînes 15 à 20 réutilisent les dix-huit clés renouvelées pour la chaîne 14 ; leurs adresses et identifiants de pair sont donc inchangés, et aucune adresse ni aucun identifiant de pair de validateur de la chaîne 13 n’est encore en usage ; huit validateurs de plus se sont engagés sur la chaîne 15, et les 26 figurent dans le fichier de genèse à partir de la chaîne 16.
L’adresse protégée
Un portefeuille est un seul secret, la clé de dépense de 256 bits sk, et tout le reste en est une dérivation. La dérivation utilise Poseidon2 avec une balise de domaine comme premier mot absorbé (H(domain, msg)), la même fonction que le zkVM calcule dans le circuit :
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’adresse est constituée des 32 octets de pk suivis de la clé d’encapsulation ML-KEM-768 de 1 184 octets, en base58 après le préfixe rand1 : 1 665 ou 1 666 caractères (la longueur en base58 dépend des premiers octets ; environ une adresse sur quatorze est la plus courte), soit environ 1,6 Ko, et sans somme de contrôle. L’expéditeur a besoin de la clé d’encapsulation pour sceller l’enveloppe de la note, c’est pourquoi elle figure dans l’adresse. Elle est publique par conception : n’importe qui peut payer à cette adresse, et la détenir ne dit rien de ce qu’elle contient.
rand keygen # wallet.key.json; refuses to overwrite an existing file
rand address # rand1… on stdout, its fingerprint XXXX-XXXX-XXXX-XXXX on stderr
Depuis la v0.5.10, rand address affiche exactement l’adresse et un saut de ligne sur la sortie standard, de sorte que $(rand address) fonctionne dans un script. L’empreinte va sur la sortie d’erreur.
Analyse, exactement comme le fait ShieldedAddress::parse : retirer rand1, décoder le base58 et exiger exactement 32 + 1 184 = 1 216 octets ; les 32 premiers sont pk sous forme de huit mots u32 en little-endian, le reste est la clé d’encapsulation. Le RPC refuse tout paramètre de plus de 2 000 caractères avant de l’analyser.
À côté du fichier de clé, le portefeuille conserve <key>.key.json.notes.json, un cache des notes que cette clé a ouvertes. Il contient les textes en clair des notes ; il est donc écrit en mode 0600 comme la clé ; chacune de ses lignes peut être retrouvée en rebalayant depuis la feuille 0.
Partager une adresse : l’empreinte et les liens randpay:
Une adresse est trop longue pour être lue à voix haute ou comparée à l’œil, et elle ne porte aucune somme de contrôle ; depuis la v0.5.10, chaque portefeuille affiche donc une empreinte à côté. L’empreinte sert uniquement à l’affichage : rien sur la chaîne ni sur le réseau n’en porte.
fingerprint = first 80 bits of blake3("rand-address-fingerprint-1" || pk_bytes || kem_ek)
= 16 Crockford base32 characters, shown as XXXX-XXXX-XXXX-XXXX
Le hash porte sur les 1 216 octets bruts que l’adresse encode. L’alphabet est 0123456789ABCDEFGHJKMNPQRSTVWXYZ ; l’analyse ignore la casse et les traits d’union, et lit O comme 0 et I ou L comme 1.
Un lien randpay: porte une adresse et, facultativement, ce qu’il faut lui payer :
randpay:<rand1…>[?amount=<decimal>][&asset=<index | 64 hex | rpl1…>][&memo=<percent-encoded UTF-8>]
amount est exprimé dans les unités d’affichage de l’actif (RAND décimal à neuf décimales, un token selon les decimals propres à sa ligne du registre) et ne doit pas être nul. memo fait au plus 510 octets d’UTF-8. Le schéma est reconnu sans tenir compte de la casse ; un paramètre inconnu, répété, ou un pourcentage mal encodé est refusé.
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> accepte une adresse rand1…, un lien randpay: ou le nom d’un contact enregistré, essayés dans cet ordre. Les amount, asset et memo d’un lien complètent ce que la ligne de commande omet, et une valeur donnée des deux façons qui diffère est refusée. Avant de produire la preuve, send affiche to <contact, if any> · fingerprint XXXX-XXXX-XXXX-XXXX · <amount> <asset> et demande confirmation ; un script passe --yes. Les contacts sont stockés à côté de la clé dans <key>.contacts.json, mode 0600. Le mémo voyage à l’intérieur de l’enveloppe de la note (Notes).
Il n’existe ni rand balance <address> ni RPC de solde : la chaîne ne peut répondre à cette question pour personne. Un portefeuille calcule son solde en balayant toutes les enveloppes de la chaîne avec sa clé de visualisation (Notes).
Les clés que l’on peut confier à quelqu’un d’autre
La divulgation est une propriété des clés, et la chaîne ne peut en contraindre aucune.
| clé | ouvre | granularité |
|---|---|---|
la clé de visualisation nk (64 hex) | chaque note que le portefeuille a jamais reçue et, via ovk, chaque note qu’il a jamais envoyée, avec le nullifier de chaque dépense | tout ou rien, rétroactive et prospective |
une clé de transaction TxKey (32 octets) | exactement l’enveloppe qu’elle a scellée : la note et, depuis la chaîne 18, son mémo | un paiement |
une clé d’appel K_call | la transcription des entrées privées d’un appel confidentiel | un appel |
Une clé de visualisation ne peut pas dépenser. Depuis la chaîne 17 (autorisation scindée), la preuve du bundle elle-même est produite à partir de nk, et chaque bundle porte aussi une seconde petite preuve d’autorisation que seule la clé de dépense peut produire et qui est liée à l’unique transaction (Notes). C’est ce qui permet de remettre nk à un prouveur délégué, et donc tout l’historique du portefeuille, sans qu’il puisse dépenser ; le portefeuille produit toujours la preuve d’autorisation sur sa propre machine. Les adresses, les clés et les notes existantes ne changent pas avec cette scission. Le portefeuille dérive nk à chaque exécution et ne le stocke jamais ; chaque TxKey est tirée à neuf pour chaque enveloppe et supprimée après le scellement. On peut confier une clé de visualisation à un nœud avec rand_importViewingKey (en mémoire, 64 au plus par nœud, perdue au redémarrage) afin qu’il balaie pour le compte du titulaire — c’est la voie de l’explorateur — et rand_checkTransaction(hash, key) vérifie un paiement contre une TxKey en un seul appel sans état. rand viewing-key affiche nk, et rand tx-key <hash> affiche la clé de chaque sortie d’une transaction que ce portefeuille peut ouvrir.
Les identifiants de token ne sont pas des adresses
Un token RPL possède un troisième type d’identifiant textuel, et il désigne un token, jamais un détenteur. L’identifiant d’actif de 32 octets du token s’affiche en 64 caractères hexadécimaux et sous la forme rpl1… : bech32m (BIP-350) avec la partie lisible rpl sur les 32 octets de l’identifiant, 52 caractères de données plus une somme de contrôle de 6 caractères, soit 62 caractères. L’analyse est stricte : une mauvaise somme de contrôle, une autre partie lisible, une charge utile qui ne fait pas exactement 32 octets, ou une casse mélangée sont refusées, si bien qu’une faute de frappe ne se résout jamais en un autre token. Une note ne porte pas l’identifiant ; son mot asset est l’indice dense du token dans le registre (Tokens RPL).
Le destinataire du pont
Le format de transmission du pont comporte un emplacement de destinataire de 32 octets, et une adresse protégée n’y tient pas. Aujourd’hui, l’emplacement contient un hash de l’adresse :
recipient_hash = blake3("rand-shielded-recipient" || pk_bytes || kem_ek)
Le déposant sur la chaîne source nomme le hash, les gardiens le signent, et la transaction BridgeAttest porte l’adresse complète pour que le registre la vérifie par rapport à lui (Pont).
L’adresse protégée courte : essayée sur la chaîne 11, abandonnée
La chaîne 11 (tag fullnode v0.2, 2026-09-17) a remplacé l’adresse longue par un identifiant de destinataire de 53 à 55 caractères, rand1 + base58(blake3(receiver signing key) ‖ checksum), et a déplacé la clé d’encapsulation ML-KEM dans un enregistrement de destinataire signé, qu’un expéditeur récupérait depuis le registre de l’explorateur ou recevait en ligne dans une demande de paiement. Elle a fonctionné un jour et a été annulée le jour même (fullnode 17db41d) ; la chaîne 12 est revenue à l’adresse longue, exactement telle que décrite ci-dessus, et toutes les chaînes suivantes, chaîne 20 comprise, la conservent.
Pourquoi elle a été retirée. Un identifiant de destinataire est un hachage, et un expéditeur ne peut pas sceller une note à un hachage. Le premier paiement vers un portefeuille qui ne s’était jamais enregistré exigeait que le destinataire transmette une demande de paiement ou un fichier d’enregistrement, et l’enregistrement lui-même se payait par un auto-transfert, qu’un portefeuille neuf et vide ne peut pas effectuer. Les deux voies de remise indiquaient en outre au registre qui allait être payé. La conception qui conserve une adresse courte, l’envoi inconditionnel et la confidentialité cryptographique est une adresse hybride : une clé X25519 de 32 octets en ligne (environ 93 caractères), la clé post-quantique par consultation, le premier paiement vers un portefeuille non enregistré étant confidentiel face aux adversaires classiques et chaque paiement suivant entièrement post-quantique. Elle est spécifiée ci-après ; tant qu’elle n’est pas déployée, l’adresse longue reste l’adresse.
La spécification de la chaîne 11 et son implémentation restent dans l’historique du fullnode (docs/superpowers/specs/2026-09-17-short-shielded-address.md, tag v0.2) pour les éléments que la conception hybride réutilise : la clé de signature de destinataire dérivée, l’enregistrement signé et son vérificateur, et le registre comme état de la chaîne.