Rand Protocol
Documentation
Concepts fondamentaux

Offre

Comment RAND est émis et détruit, les franchissements publics de la frontière du pool, l'émission de genèse de la chaîne 20, et l'invariant d'audit de l'offre que chaque nœud vérifie.

Utilisez cette page pour lire correctement rand_getSupply et raisonner sur l’émission : d’où vient le RAND, où il va, et l’identité qui rend exacte l’offre d’une chaîne blindée alors que personne ne peut additionner ses notes.

D’où vient le RAND et où il va

Une chaîne blindée ne peut pas additionner sa propre monnaie : la valeur d’une note réside dans son engagement. Ce qui est public, ce sont tous les passages de la frontière du pool. Il y en a cinq sortes, et sept sur une chaîne dotée de coffres de programme (RPL-2, chaîne 20) :

senspassagequand
entréeune note de dépôt de genèse (alloc dans le fichier de genèse, ouverte depuis la chaîne 14)bloc 0
entréeun mint du faucet (Mint, jusqu’à 100 RAND, signé par un validateur, portant l’ouverture de la note depuis la chaîne 14)chaînes testnet avec "faucet": true ; sur la chaîne 20, seulement pour 16 portefeuilles autorisés, signé par l’un des 18 minters listés dans la genèse, au plus 10 000 RAND par époque de 1 000 blocs
entréeun Withdraw de validateur, qui verse la mise libérée et les récompenses dans une noteà tout moment
sortiele fee d’un bundle, vers les rewards du proposeur du blocchaque bundle
sortiele burn_r d’un bundle : un Bond qui brûle une mise vers le stake public d’un validateurchaque bond
sortiele burn_r d’un Invoke : du RAND déposé dans le coffre public d’un programmechaîne 20, depuis v0.6.8
entréeun paiement de coffre : du RAND qu’un Invoke verse depuis le coffre d’un programme sous forme de note, montant et destinataire publicschaîne 20, depuis v0.6.8

Sur une chaîne dont la genèse définit tokens.burn_registration_fee, comme celle de la chaîne 20, les 1 RAND de registration_fee d’un enregistrement de jeton quittent aussi le pool via burned, mais n’entrent dans aucune entrée du registre : ils sont détruits, et le proposeur ne garde que la base du bundle.

À côté du pool se trouve le registre des validateurs, qui détient des montants en clair parce que le poids de consensus doit être public. La mise dans le registre est du vrai RAND : elle peut être dé-liée puis retirée vers une note. Sur la chaîne 20, les coffres de programme forment un second solde public à ses côtés : le RAND qu’un invoke y dépose reste dénombrable jusqu’à ce qu’un paiement le renvoie au pool sous forme de note.

Il n’y a ni récompense de bloc ni inflation sur la chaîne 20. La première émission programmée de la chaîne est la subvention d’agrégation de blocs — une quantité décroissante de nouveau RAND par bloc scellé, versée à l’agrégateur dont la preuve le couvre — et elle n’est pas active sur la chaîne 20 (Preuves). La chaîne 20 est une chaîne neuve, en service depuis le 2026-10-01 à 06:17 UTC, issue de la chaîne 19 (fullnode v0.6.8, un hard fork). Sa genèse a émis 31 184,243719258 RAND : 26 000 misés sur les 26 validateurs de genèse et 5 184,243719258 dans sept notes de dépôt, les soldes des sept portefeuilles d’opérateur repris de la chaîne 19. Ce que les autres portefeuilles détenaient sur la chaîne 19, environ 519,9 RAND (mints du faucet vers des destinataires autorisés, paiements à des utilisateurs), n’a pas été repris, car une note ne peut être recréée sans l’adresse de son propriétaire ; les 0,499 RAND de récompenses de validateurs non retirées non plus. Deux autres notes de genèse, neuf au total, portent les 99 zUSD du bridge (10 et 89), qui ne sont pas du RAND et sortent de cet audit. rand_getSupply sur la chaîne 20 indique genesis_deposited 5 184 243 719 258 unités et invariant_holds: true (hauteur 3 037, 2026-10-01). La chaîne 19, issue le même jour d’un instantané de la chaîne 18 à la hauteur 141 935, a émis 31 294,644359629 RAND : les mêmes 26 000 misés et 5 294,644359629 dans sept notes, à côté d’une note de 10 zUSD. Chaque mint du faucet depuis s’ajoute au chiffre émis, et chaque frais d’enregistrement brûlé en retranche. La chaîne 15, issue le 2026-09-26, a émis 23 000 RAND à la genèse, dont 18 000 misés sur 18 validateurs et 5 000 dans cinq notes ; ses huit validateurs ultérieurs se sont liés à partir de notes existantes, ce qui n’a rien émis.

Les jetons sont hors de cet audit

Les passages ci-dessus sont ceux du RAND. Un jeton RPL, ponté ou natif, ne franchit jamais la frontière du RAND : l’indice d’actif 0 est réservé au RAND et le registre des jetons ne l’attribue jamais, de sorte qu’un BridgeAttest, un TokenMint ou le mint initial d’un enregistrement dépose toujours une note d’un autre actif, et que le burn_a d’un BridgeBurn ou d’un TokenBurn en détruit toujours une (du RAND brûlé via burn_a est refusé). fees_paid et burned se comptent à partir du seul fee et du seul burn_r d’un bundle, et un transfert de jeton à l’intérieur du pool ne fait bouger aucun compteur, puisque son actif n’est même pas public. Sur la chaîne 20, un Invoke peut aussi faire entrer un jeton par burn_a : dans le coffre du programme (deposit), ce qui laisse son offre inchangée, ou détruit (burn), pour le seul jeton du programme. Les notes de frais du bridge (chaîne 20, 10 bps de chaque dépôt et burn de zUSD, vers une adresse de trésorerie) sont du zUSD, jamais du RAND : émises et adossées, si bien que l’adossement d’un dépôt et l’offre varient du brut, et que ceux d’un burn baissent de amount − fee. L’offre propre d’un jeton est le décompte public du registre : rand_getTokenSupply renvoie total_supply et, pour un jeton ponté, le montant locked de chaque adossement, dont la somme lui est égale (Jetons RPL).

L’identité d’audit

Six compteurs monotones en unités (1 RAND = 10⁹), deux qui enregistrent ce qui a été détruit, et sur la chaîne 20 deux pour les coffres de programme :

compteursomme
genesis_depositedles notes de dépôt alloc du fichier de genèse
genesis_stakedles mises dont la genèse a doté le registre
faucet_mintedchaque Mint accepté
withdraw_depositedles notes créées par les Withdraw acceptés (amount − 0.001 RAND chacun)
fees_paidchaque frais de bundle
burnedchaque burn_r de bundle (la mise d’un Bond et, sur la chaîne 20, le dépôt en coffre d’un invoke), et chaque frais d’enregistrement brûlé
slashedles cautions d’agrégateur sanctionnées (agrégation de blocs ; 0 tant qu’elle est désactivée)
registration_fees_burnedles frais d’enregistrement brûlés sous tokens.burn_registration_fee, aussi inclus dans burned
program_rand_outles notes de RAND que les coffres de programme ont versées (RPL-2 ; 0 sans section program_state)
program_rand_heldle RAND que les coffres détiennent encore : le burn_r de chaque invoke moins program_rand_out. Il y est arrivé par burned, c’est donc le côté coffres de ce compteur
pool_value     = genesis_deposited + faucet_minted + withdraw_deposited + program_rand_out − fees_paid − burned
register_total = Σ over the register of (stake + pending + rewards)
total_supply   = pool_value + register_total + program_rand_held
issued         = genesis_deposited + genesis_staked + faucet_minted

invariant:       total_supply == issued − slashed − registration_fees_burned

pool_value est ce qui est entré moins ce qui est sorti — le même nombre que la somme des notes, que personne ne peut calculer. La base de 0,001 RAND d’un withdraw n’est pas un passage : elle passe d’une ligne du registre à celle du proposeur, et seule la note a franchi la frontière. Un invariant_holds à false est un bug de consensus ou une base de données endommagée, jamais un état légitime. Les deux termes de programme sont nuls sur une chaîne sans coffres de programme, l’identité y est donc celle de la chaîne 19. Une section vesting de genèse, qu’aucune chaîne n’a eue, ajouterait de la même manière un troisième registre public (JSON-RPC).

Suivie à travers un bond et un withdraw de 1 000 RAND sur une chaîne qui a déposé 2 000 et misé 4 000 :

aprèsburnedwithdraw_depositedfees_paidpool_valueregister_totaltotal_supply
genèse0002 0004 0006 000
un bond de 1 000 (frais 0,001)1 00000,001999,9995 000,0016 000
son unbond1 00000,001999,9995 000,0016 000
son withdraw de 1 0001 000999,9990,0011 999,9984 000,0026 000

La lire

curl -s http://127.0.0.1:8545 -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"rand_getSupply","params":[]}'
{ "height": 1998,
  "genesis_deposited": "2000000000000", "genesis_staked": "4000000000000",
  "faucet_minted": "0", "withdraw_deposited": "999999000000",
  "fees_paid": "1000000", "burned": "1000000000000",
  "slashed": "0", "registration_fees_burned": "0",
  "pool_value": "1999998000000", "register_total": "4000002000000",
  "total_supply": "6000000000000", "invariant_holds": true }

Chaque montant est une chaîne décimale d’unités, parce qu’un nombre JSON n’est pas un entier exact au-delà de 2⁵³. L’objet complet porte plus de champs que ceux montrés ici, dont la paire par époque du faucet, faucet_epoch et faucet_minted_in_epoch, que la chaîne 20 vérifie par rapport à son budget, program_rand_out et program_rand_held (depuis v0.6.8), et quatre compteurs vesting_* qui valent "0" sur la chaîne 20, dont la genèse n’a pas de section vesting (JSON-RPC). L’explorateur sert le même objet à GET /supply et les chiffres principaux dans GET /stats.

Quelle exactitude

Pour tout ce que la chaîne a fait elle-même, les compteurs sont exacts : chacun est incrémenté dans le chemin de code qui applique l’action, à partir des champs publics de l’action elle-même.

Deux entrées reposaient jusqu’ici sur une affirmation, et la chaîne 14 les transforme toutes deux en vérifications (audit v3, POOL-1) :

  • Un Mint du faucet porte l’ouverture de la note. Outre cm et amount, l’action publie pk, time et r. L’admission recalcule l’engagement de (pk, no sender, amount, asset 0, time, r) et refuse toute discordance avec the mint's commitment does not open to its published note and amount, et contraint time à la fenêtre du bundle. Le minter signe les sept champs sous le domaine rand-mint-2. Auparavant, un validateur pouvait publier un montant et sceller une note d’une valeur différente. Le coût est que la clé pk du propriétaire d’une note du faucet est publique, comme l’est le versement d’un retrait ; les paramètres de rand_mint restent inchangés.
  • Une note alloc de genesis porte aussi son ouverture. Sur une chaîne dotée d’une section tokens, chaque ligne est { cm, envelope, amount, opening: { pk, time, r } }, et un nœud recalcule l’engagement, à l’asset 0 sauf si l’ouverture désigne l’asset d’un jeton listé, et refuse tout fichier de genesis dont le cm ne correspond pas. Seules les lignes d’asset 0 comptent dans genesis_deposited. Un cm opaque était l’unique moyen pour l’auteur d’un genesis d’introduire dans le pool une note sans contrepartie, de n’importe quel asset, sans que personne puisse le vérifier. Le propriétaire et le montant d’une note de genesis sont donc publics par conception dès la publication du fichier ; seuls le moment de sa dépense et sa destination restent privés. rand-node genesis écrit toujours l’ouverture.

Sur une chaîne créée sans section tokens, l’ancienne règle s’applique toujours : genesis_deposited est la somme des champs amount déclarés, reprise telle quelle du fichier de genesis. Les deux montants de genesis figurent dans le hash de genesis, de sorte que tous les nœuds s’accordent sur eux dans les deux cas.

Les compteurs ne font volontairement pas partie de l’état de consensus — la racine d’état ne les hache pas — et rand-node verify --mode quick les recalcule tous en rejouant la chaîne, et signale une discordance si l’instantané stocké diffère.

Dernière vérification par rapport au commit c0878c3f de fullnode (chaîne 21) le 2026-10-12. Lorsque le code et cette page divergent, c'est le code qui a raison ; signalez-le-nous.