Usa esta página para leer rand_getSupply correctamente y para razonar sobre la emisión: de dónde viene RAND, adónde va, y la identidad que hace exacta la oferta de una cadena blindada aunque nadie pueda sumar sus notas.
De dónde viene y adónde va RAND
Una cadena blindada no puede sumar su propio dinero: el valor de una nota vive dentro de su compromiso. Lo que es público es cada cruce de la frontera del pool. Hay cinco tipos, y siete en una cadena con bóvedas de programa (RPL-2, chain 20):
| dirección | cruce | cuándo |
|---|---|---|
| entrada | una nota de depósito de génesis (alloc en el archivo de génesis, abierta desde chain 14) | bloque 0 |
| entrada | una emisión del faucet (Mint, hasta 100 RAND, firmada por un validador, con la apertura de la nota desde chain 14) | cadenas testnet con "faucet": true; en chain 20 solo a 16 wallets de la lista de permitidos, firmada por uno de los 18 emisores listados en el génesis, como máximo 10,000 RAND por época de 1,000 bloques |
| entrada | un Withdraw de un validador, que paga en una nota el stake liberado y las recompensas | en cualquier momento |
| salida | el fee de un bundle, hacia las rewards del proponente del bloque | cada bundle |
| salida | el burn_r de un bundle: un Bond que quema stake hacia el stake público de un validador | cada bond |
| salida | el burn_r de un Invoke: RAND depositado en la bóveda pública de un programa | chain 20, desde v0.6.8 |
| entrada | un pago de bóveda: RAND que un Invoke paga desde la bóveda de un programa como una nota, con su monto y destinatario públicos | chain 20, desde v0.6.8 |
En una cadena cuyo génesis establece tokens.burn_registration_fee, como el de chain 20, el registration_fee de 1 RAND de un registro de token también sale del pool a través de burned, pero no entra en ninguna entrada del registro: se destruye, y el proponente solo se queda con la base del bundle.
Junto al pool está el registro de validadores, que guarda los montos en claro porque el peso en el consenso debe ser público. El stake en el registro es RAND real: puede desvincularse y retirarse de vuelta a una nota. En chain 20 las bóvedas de programa son un segundo balance público a su lado: el RAND que deposita un invoke sigue siendo contabilizable allí hasta que un pago lo devuelve al pool como una nota.
No hay recompensas por bloque ni inflación en chain 20. La primera emisión programada de la cadena es el subsidio por agregación de bloques —una cantidad decreciente de RAND nuevo por bloque sellado, pagada al aggregator cuya prueba lo cubre— y no está activa en chain 20 (Proofs). Chain 20 es una cadena nueva, en vivo desde el 2026-10-01 a las 06:17 UTC, derivada de chain 19 (fullnode v0.6.8, un hard fork). Su génesis emitió 31,184.243719258 RAND: 26,000 en stake repartidos entre los 26 validadores de génesis y 5,184.243719258 en siete notas de depósito, los saldos de las siete wallets de operador trasladados desde chain 19. Lo que otras wallets tenían en chain 19, unos 519.9 RAND (emisiones del faucet a destinatarios de la lista de permitidos, pagos a usuarios), no se trasladó, ya que una nota no puede recrearse sin la dirección de su propietario; tampoco 0.499 RAND de recompensas de validadores sin retirar. Otras dos notas de génesis, nueve en total, llevan los 99 zUSD del bridge (10 y 89), que no es RAND y queda fuera de esta auditoría. rand_getSupply en chain 20 muestra genesis_deposited 5,184,243,719,258 unidades e invariant_holds: true (altura 3,037, 2026-10-01). Chain 19, derivada el mismo día de una instantánea de chain 18 en la altura 141,935, emitió 31,294.644359629 RAND: los mismos 26,000 en stake y 5,294.644359629 en siete notas, junto a una nota de 10 zUSD. Cada emisión del faucet posterior se suma a la cifra emitida, y cada comisión de registro quemada se resta de ella. Chain 15, derivada el 2026-09-26, emitió 23,000 RAND en el génesis, 18,000 en stake repartidos entre 18 validadores y 5,000 en cinco notas; sus ocho validadores posteriores hicieron bond desde notas existentes, lo cual no emitió nada.
Los tokens quedan fuera de esta auditoría
Los cruces anteriores son los de RAND. Un token RPL, puenteado o nativo, nunca cruza la frontera de RAND: el índice de activo 0 está reservado para RAND y el registro de tokens nunca lo asigna, de modo que un BridgeAttest, un TokenMint o la emisión inicial de un registro siempre depositan una nota de otro activo, y el burn_a de un BridgeBurn o de un TokenBurn siempre destruye una (el RAND quemado mediante burn_a es rechazado). fees_paid y burned se cuentan únicamente a partir del fee y el burn_r de un bundle, y una transferencia de tokens dentro del pool no mueve ningún contador, ya que su activo ni siquiera es público. En chain 20 un Invoke también puede introducir un token mediante burn_a: en la bóveda del programa (deposit), lo que deja su oferta sin cambios, o destruido (burn), solo para el token propio del programa. Las notas de comisión del bridge (chain 20, 10 bps de cada depósito y quema de zUSD, hacia una dirección de tesorería) son zUSD, nunca RAND: emitidas y respaldadas, de modo que el respaldo de un depósito y la oferta se mueven por el monto bruto y los de una quema bajan en amount − fee. La oferta propia de un token es el conteo público del registro: rand_getTokenSupply devuelve total_supply y, para un token puenteado, el monto locked de cada respaldo, que suman esa cifra (RPL tokens).
La identidad de auditoría
Seis contadores monótonos en unidades (1 RAND = 10⁹), dos que registran lo que se destruyó y, en chain 20, dos para las bóvedas de programa:
| contador | suma |
|---|---|
genesis_deposited | las notas de depósito alloc del archivo de génesis |
genesis_staked | los stakes con los que el génesis sembró el registro |
faucet_minted | cada Mint aceptado |
withdraw_deposited | las notas que crearon los Withdraw aceptados (amount − 0.001 RAND cada uno) |
fees_paid | cada comisión de bundle |
burned | cada burn_r de bundle (el stake de un Bond y, en chain 20, el depósito de bóveda de un invoke), y cada comisión de registro quemada |
slashed | las fianzas de aggregator penalizadas (agregación de bloques; 0 mientras esté desactivada) |
registration_fees_burned | las comisiones de registro quemadas bajo tokens.burn_registration_fee, también incluidas en burned |
program_rand_out | las notas de RAND que las bóvedas de programa han pagado (RPL-2; 0 sin una sección program_state) |
program_rand_held | el RAND que las bóvedas aún conservan: el burn_r de cada invoke menos program_rand_out. Llegó allí a través de burned, así que es el lado de las bóvedas de ese contador |
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 es lo que entró menos lo que salió —el mismo número que la suma de las notas, que nadie puede calcular. La base de 0.001 RAND de un withdraw no es un cruce: pasa de una fila del registro a la del proponente, y solo la nota cruzó. Que invariant_holds sea false es un error de consenso o una base de datos dañada, nunca un estado legítimo. Los dos términos de programa son cero en una cadena sin bóvedas de programa, así que la identidad allí es la de chain 19. Una sección vesting en el génesis, que ninguna cadena ha tenido, añadiría un tercer registro público del mismo modo (JSON-RPC).
Seguido a través de un bond y un withdraw de 1,000 RAND en una cadena que depositó 2,000 y puso 4,000 en stake:
| después de | burned | withdraw_deposited | fees_paid | pool_value | register_total | total_supply |
|---|---|---|---|---|---|---|
| génesis | 0 | 0 | 0 | 2,000 | 4,000 | 6,000 |
| un bond de 1,000 (comisión 0.001) | 1,000 | 0 | 0.001 | 999.999 | 5,000.001 | 6,000 |
| su unbond | 1,000 | 0 | 0.001 | 999.999 | 5,000.001 | 6,000 |
| su withdraw de 1,000 | 1,000 | 999.999 | 0.001 | 1,999.998 | 4,000.002 | 6,000 |
Cómo leerlo
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 }
Cada monto es una cadena decimal de unidades, porque un número JSON no es un entero exacto más allá de 2⁵³. El objeto completo incluye más campos de los que se muestran aquí, entre ellos el par por época del faucet faucet_epoch y faucet_minted_in_epoch, que chain 20 comprueba contra su presupuesto, program_rand_out y program_rand_held (desde v0.6.8), y cuatro contadores vesting_* que valen "0" en chain 20, cuyo génesis no tiene sección vesting (JSON-RPC). El explorador sirve el mismo objeto en GET /supply y las cifras principales en GET /stats.
Qué tan exacta es
Para todo lo que la cadena hizo por sí misma, los contadores son exactos: cada uno se incrementa en la ruta de código que aplica la acción, a partir de los campos públicos de la propia acción.
Dos entradas solían apoyarse en una afirmación, y chain 14 convierte ambas en comprobaciones (auditoría v3, POOL-1):
- Un
Mintdel faucet incluye la apertura de la nota. Junto acmyamount, la acción publicapk,timeyr. La admisión recalcula el compromiso de(pk, no sender, amount, asset 0, time, r)y rechaza cualquier discrepancia conthe mint's commitment does not open to its published note and amount, y ajustatimea la ventana del bundle. El minter firma los siete campos bajo el dominiorand-mint-2. Antes de esto, un validador podía publicar un importe y sellar una nota por otro distinto. El costo es que elpkdel propietario de una nota del faucet es público, igual que el pago de un retiro; los parámetros derand_mintno cambian. - Una nota
allocdel génesis también incluye su apertura. En una cadena con una seccióntokens, cada fila es{ cm, envelope, amount, opening: { pk, time, r } }, y un nodo recalcula el compromiso, en el asset 0 salvo que la apertura indique elassetde un token listado, y rechaza un archivo de génesis cuyocmno coincida. Solo las filas del asset 0 cuentan paragenesis_deposited. Uncmopaco era la única vía por la que el autor del génesis podía introducir en el pool una nota sin respaldo, de cualquier asset, sin que nadie pudiera comprobarlo. Por lo tanto, el propietario y el importe de una nota del génesis son públicos por diseño una vez publicado el archivo; solo permanece privado cuándo se gasta después y en qué.rand-node genesissiempre escribe la apertura.
En una cadena creada sin una sección tokens sigue vigente la regla anterior: genesis_deposited es la suma de los campos amount declarados, que se toman como válidos según el archivo de génesis. Ambos importes del génesis están en el hash del génesis, de modo que todos los nodos coinciden en ellos en cualquiera de los dos casos.
Los contadores deliberadamente no forman parte del estado de consenso —la raíz de estado no los incluye en el hash— y rand-node verify --mode quick recalcula cada uno reproduciendo la cadena, e informa de una discrepancia si la instantánea almacenada no coincide.