Rand Protocol
Documentação
Conceitos fundamentais

Oferta

Como a RAND é emitida e destruída, as travessias públicas da fronteira do pool, a emissão de gênese da chain 20 e o invariante de auditoria da oferta que cada nó verifica.

Use esta página para ler rand_getSupply corretamente e para raciocinar sobre a emissão: de onde vem o RAND, para onde ele vai e a identidade que torna exata a oferta de uma chain blindada, mesmo que ninguém consiga somar as suas notas.

De onde o RAND vem e para onde vai

Uma chain blindada não consegue somar o próprio dinheiro: o valor de uma nota vive dentro do seu compromisso. O que é público é cada travessia da fronteira do pool. Há cinco tipos, e sete em uma chain com cofres de programa (RPL-2, chain 20):

sentidotravessiaquando
entradauma nota de depósito de gênese (alloc no arquivo de gênese, aberta desde a chain 14)bloco 0
entradauma emissão do faucet (Mint, até 100 RAND, assinada por um validador, com a abertura da nota desde a chain 14)chains de testnet com "faucet": true; na chain 20, apenas para 16 carteiras em lista de permissão, assinada por um dos 18 minters listados na gênese, no máximo 10.000 RAND por época de 1.000 blocos
entradaum Withdraw de validador, que paga em uma nota o stake liberado e as recompensasa qualquer momento
saídao fee de um bundle, para os rewards do proponente do blocotodo bundle
saídao burn_r de um bundle: um Bond que queima stake para o stake público de um validadortodo bond
saídao burn_r de um Invoke: RAND depositado no cofre público de um programachain 20, desde a v0.6.8
entradaum pagamento do cofre: RAND que um Invoke paga do cofre de um programa como uma nota, com valor e destinatário públicoschain 20, desde a v0.6.8

Em uma chain cuja gênese define tokens.burn_registration_fee, como a da chain 20, o registration_fee de 1 RAND do registro de um token também sai do pool por burned, mas não entra em nenhum registro: é destruído, e o proponente fica apenas com a base do bundle.

Ao lado do pool fica o registro de validadores, que guarda valores em claro porque o peso no consenso precisa ser público. O stake no registro é RAND de verdade: pode ser desvinculado e sacado de volta para uma nota. Na chain 20, os cofres de programa são um segundo saldo público ao lado dele: o RAND que um invoke deposita continua contável ali até que um pagamento o devolva ao pool como uma nota.

Não há recompensas de bloco nem inflação na chain 20. A primeira emissão programada da chain é o subsídio de agregação de blocos — uma quantidade decrescente de RAND novo por bloco selado, paga ao agregador cuja prova o cobre — e ele não está ativo na chain 20 (Provas). A chain 20 é uma chain nova, no ar desde 2026-10-01 às 06:17 UTC, derivada da chain 19 (fullnode v0.6.8, um hard fork). Sua gênese emitiu 31.184,243719258 RAND: 26.000 em stake distribuídos entre os 26 validadores da gênese e 5.184,243719258 em sete notas de depósito, os saldos das sete carteiras de operadores trazidos da chain 19. O que as outras carteiras tinham na chain 19, cerca de 519,9 RAND (emissões do faucet para destinatários em lista de permissão, pagamentos a usuários), não foi trazido, pois uma nota não pode ser recriada sem o endereço de seu dono; tampouco os 0,499 RAND de recompensas de validadores não sacadas. Duas outras notas de gênese, nove no total, carregam os 99 zUSD da bridge (10 e 89), que não são RAND e estão fora desta auditoria. rand_getSupply na chain 20 lê genesis_deposited 5.184.243.719.258 unidades e invariant_holds: true (altura 3.037, 2026-10-01). A chain 19, derivada no mesmo dia de um snapshot da chain 18 na altura 141.935, emitiu 31.294,644359629 RAND: os mesmos 26.000 em stake e 5.294,644359629 em sete notas, ao lado de uma nota de 10 zUSD. Toda emissão do faucet desde então soma ao valor emitido, e toda taxa de registro queimada subtrai dele. A chain 15, derivada em 2026-09-26, emitiu 23.000 RAND na gênese, 18.000 em stake entre 18 validadores e 5.000 em cinco notas; seus oito validadores posteriores fizeram bond a partir de notas existentes, o que não emitiu nada.

Os tokens estão fora desta auditoria

As travessias acima são do RAND. Um token RPL, com bridge ou nativo, nunca cruza a fronteira do RAND: o índice de ativo 0 é reservado ao RAND e o registro de tokens nunca o concede, de modo que um BridgeAttest, um TokenMint ou a emissão inicial de um registro sempre deposita uma nota de algum outro ativo, e o burn_a de um BridgeBurn ou de um TokenBurn sempre destrói uma (RAND queimado por burn_a é recusado). fees_paid e burned são contados apenas a partir do fee e do burn_r de um bundle, e uma transferência de token dentro do pool não move nenhum contador, já que seu ativo nem sequer é público. Na chain 20, um Invoke também pode receber um token por burn_a: para o cofre do programa (deposit), o que deixa sua oferta inalterada, ou destruído (burn), somente para o token do próprio programa. As notas de taxa da bridge (chain 20, 10 bps de cada depósito e queima de zUSD, para um endereço de tesouraria) são zUSD, nunca RAND: emitidas e lastreadas, de modo que o lastro de um depósito e a oferta se movem pelo valor bruto e os de uma queima caem em amount − fee. A oferta própria de um token é a contagem pública do registro: rand_getTokenSupply retorna total_supply e, para um token com bridge, o valor locked de cada lastro, cuja soma é igual a ele (Tokens RPL).

A identidade de auditoria

Seis contadores monotônicos em unidades (1 RAND = 10⁹), dois que registram o que foi destruído e, na chain 20, dois para os cofres de programa:

contadorsoma
genesis_depositedas notas de depósito alloc do arquivo de gênese
genesis_stakedos stakes com que a gênese semeou o registro
faucet_mintedtodo Mint aceito
withdraw_depositedas notas que os Withdraws aceitos criaram (amount − 0.001 RAND cada)
fees_paidtoda taxa de bundle
burnedtodo burn_r de bundle (o stake de um Bond e, na chain 20, o depósito de um invoke no cofre) e toda taxa de registro queimada
slashedbonds de agregadores sofrendo slashing (agregação de blocos; 0 enquanto estiver desligada)
registration_fees_burnedas taxas de registro queimadas sob tokens.burn_registration_fee, também contidas em burned
program_rand_outnotas de RAND que os cofres de programa pagaram (RPL-2; 0 sem uma seção program_state)
program_rand_heldo RAND que os cofres ainda guardam: o burn_r de cada invoke menos program_rand_out. Ele chegou lá por burned, de modo que é o lado dos cofres desse 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 é o que entrou menos o que saiu — o mesmo número que a soma das notas, que ninguém consegue calcular. A base de 0,001 RAND de um withdraw não é uma travessia: ela passa de uma linha do registro para a do proponente, e só a nota cruzou. invariant_holds ser falso é um bug de consenso ou um banco de dados danificado, nunca um estado legítimo. Os dois termos de programa são zero em uma chain sem cofres de programa, de modo que ali a identidade é a da chain 19. Uma seção vesting na gênese, que nenhuma chain teve, acrescentaria um terceiro registro público da mesma forma (JSON-RPC).

Acompanhando um bond e um withdraw de 1.000 RAND em uma chain que depositou 2.000 e fez stake de 4.000:

apósburnedwithdraw_depositedfees_paidpool_valueregister_totaltotal_supply
gênese0002.0004.0006.000
um bond de 1.000 (taxa 0,001)1.00000,001999,9995.000,0016.000
seu unbond1.00000,001999,9995.000,0016.000
seu withdraw de 1.0001.000999,9990,0011.999,9984.000,0026.000

Como lê-la

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 }

Todo valor é uma string decimal de unidades, porque um número JSON não é um inteiro exato além de 2⁵³. O objeto completo traz mais campos do que os mostrados aqui, entre eles o par por época do faucet faucet_epoch e faucet_minted_in_epoch, que a chain 20 confere contra o seu orçamento, program_rand_out e program_rand_held (desde a v0.6.8) e quatro contadores vesting_* que leem "0" na chain 20, cuja gênese não tem seção vesting (JSON-RPC). O explorer serve o mesmo objeto em GET /supply e os números principais em GET /stats.

Quão exata ela é

Para tudo o que a chain fez por si mesma, os contadores são exatos: cada um é incrementado no caminho de código que aplica a ação, a partir dos campos públicos da própria ação.

Duas entradas costumavam se apoiar em uma afirmação, e a chain 14 transforma ambas em verificações (auditoria v3, POOL-1):

  • Um Mint do faucet carrega a abertura da nota. Além de cm e amount, a ação publica pk, time e r. A admissão recalcula o compromisso de (pk, no sender, amount, asset 0, time, r) e recusa uma divergência com the mint's commitment does not open to its published note and amount, e mantém time dentro da janela do bundle. O minter assina os sete campos sob o domínio rand-mint-2. Antes disso, um validador podia publicar um valor e selar uma nota de outro valor. O custo é que o proprietário pk de uma nota do faucet é público, como é o pagamento de um withdraw; os parâmetros de rand_mint permanecem inalterados.
  • Uma nota alloc do genesis também carrega a sua abertura. Em uma chain com uma seção tokens, cada linha é { cm, envelope, amount, opening: { pk, time, r } }, e um nó recalcula o compromisso, no asset 0, a menos que a abertura nomeie o asset de um token listado, e recusa um arquivo de genesis cujo cm não corresponda. Somente as linhas do asset 0 contam para genesis_deposited. Um cm opaco era a única forma de um autor do genesis colocar no pool uma nota sem lastro, de qualquer asset, sem que ninguém pudesse verificá-la. O proprietário e o valor de uma nota do genesis são, portanto, públicos por concepção depois que o arquivo é publicado; apenas quando ela é gasta depois, e em quê, permanece privado. rand-node genesis sempre escreve a abertura.

Em uma chain criada sem uma seção tokens, a regra anterior continua valendo: genesis_deposited é a soma dos campos amount declarados, aceita como confiável a partir do arquivo de genesis. Os dois valores de genesis estão no hash do genesis, de modo que todos os nós concordam com eles em ambos os casos.

Os contadores deliberadamente não fazem parte do estado de consenso — a state root não os inclui no hash — e rand-node verify --mode quick recalcula cada um deles reproduzindo a cadeia, relatando uma divergência se o snapshot armazenado discordar.

Última verificação em relação ao commit c0878c3f do fullnode (chain 21) em 2026-10-12. Onde o código e esta página divergirem, o código está certo; avise-nos.