Usa questa pagina per impostare la commissione di una transazione, per stimare quanto costa un deploy o una chiamata e per capire come viene pagato un validatore. Le commissioni sono soglie minime in RAND. Ogni azione tranne la chiamata ne paga una fissa. Su chain 20 una chiamata paga il limite di gas dichiarato dalla sua prova e i suoi byte, a prezzi che si muovono con il riempimento dei blocchi e si fermano a un tetto.
I minimi
Le commissioni sono espresse in unità di 10⁻⁹ RAND. Le costanti si trovano in randprotocol_core::gas:
| transazione | minimo | oggi |
|---|---|---|
qualsiasi bundle: un trasferimento di RAND o di un qualsiasi token RPL, un bond, un deposito bridge (BridgeAttest, pagato dal suo relayer), un TokenMint, un SetAuthority, un TokenBurn, un ListBacking | BUNDLE_BASE = 1.000.000 unità | 0,001 RAND |
| Deploy | BUNDLE_BASE + DEPLOY_PER_WORD (100.000) × (parole del programma + parole pubbliche) | un programma da 256 parole: 0,0266 RAND; un programma da 4.096 parole: 0,4106 RAND; l’immagine SPL Token da 65.096 parole con il suo input pubblico da 27.151 parole: 9,2257 RAND (distribuita su chain 13, 2026-09-19). Da chain 16 (hardening_v6, chain 20 inclusa) un deploy che nessuna chiamata può contenere viene rifiutato, come ProgramUncallable: più di 8.180 parole per un programma senza input pubblico, meno se ne ha uno. Quell’immagine verrebbe rifiutata su chain 20 |
| Call | su una catena il cui genesis ha una sezione gas (chain 20, come chain 18 e 19): BUNDLE_BASE + gas_price × il limite di gas che la prova della chiamata dichiara + byte_price × ogni KiB (un KiB parziale conta come intero) di prova della chiamata più envelope di input, dal byte 0. Vedi Gas su chain 18. Su una catena senza la sezione: BUNDLE_BASE + call_fee(tier), dove call_fee = CALL_BASE (1.000.000) + 100.000 ogni due livelli sopra il 10, più 1.000 unità per ogni KiB (un KiB parziale conta come intero) di prova della chiamata più envelope di input oltre la franchigia di 2.097.152 + 18.432 byte | chain 20, ai prezzi iniziali di 100 e 800 unità: una chiamata di livello 14 che dichiara il tetto del livello di 20.479 gas, con 1.350.000 byte di prova ed envelope, ha un minimo di 0,0041 RAND; il valore predefinito del wallet paga di più (sotto). Senza sezione gas, come su chain 15: livello 10: 0,002; livello 14: 0,0022 RAND, entro la franchigia. Da v0.5.6 una chiamata sopra il livello 14 viene rifiutata qualunque cosa paghi (MAX_CALL_TIER). La chiamata ERC-20 approve eseguita su chain 13 il 2026-09-19 (livello 16, una prova da 3.412.405 byte) pagò 0,00357 RAND e da v0.5.6 verrebbe rifiutata su qualsiasi catena |
| Invoke (RPL-2, chain 20) | il minimo di una chiamata, più il program_state.cell_fee del genesis per ogni cella che la transizione crea (una cella scritta con valore diverso da zero dove non ne era memorizzato alcuno); riscrivere o eliminare una cella non aggiunge nulla | il cell_fee di chain 20 è 0,01 RAND: la chiamata di livello 14 qui sopra, che crea due celle, ha un minimo di 0,0241 RAND |
| BridgeBurn | BRIDGE_BURN_FEE = 10 × BUNDLE_BASE: la base più il costo proprio del bridge, entrambi pagati dall’unico bundle che un burn trasporta | 0,01 RAND; su chain 20 il bridge trattiene inoltre 10 bps degli zUSD bruciati (sotto) |
| RegisterToken, RegisterBridgedToken | BUNDLE_BASE + la registration_fee del registro dei token (un parametro del genesis) | chain 20: 0,001 + 1 RAND = 1,001 RAND, di cui 1 RAND viene bruciato |
| Mint (faucet), Unbond | 0; nessun bundle, firmato dal validatore | — |
| PauseMints, UnpauseMints | 0; nessun bundle, autorizzato dalla chiave di pausa o da un quorum di guardiani PQ, così che una pausa funzioni da un wallet che non detiene RAND | — |
| Withdraw | 0 sul wire; la base di 0,001 RAND viene prelevata dall’importo ritirato | un withdraw di 1.000 RAND crea una nota da 999,999 |
La commissione è una parola pubblica del bundle ed è sempre in RAND. Il guest del bundle per asset nascosti la vincola alla relazione di bilancio del gruppo RAND in₂ + in₃ = out₂ + out₃ + fee + burn_r (slot 2–3), così viene pagata da note schermate senza rivelare quali; un token si muove attraverso gli slot 0–1 dello stesso bundle con una propria relazione, in₀ + in₁ = out₀ + out₁ + burn_a. Una sola prova sposta quindi un token e paga la sua commissione in RAND, e un wallet che detiene un token ma nessun RAND spendibile viene rifiutato prima della generazione della prova.
Il costo del bridge ricade sul burn perché è l’unica transazione del bridge il cui mittente detiene di sicuro RAND; un deposito paga solo la base, dato che il depositante non ha ancora RAND. La commissione di registrazione è un fatto del ledger e non parte di fee_floor, perciò viene verificata con le regole proprie dell’azione (RegistrationFeeTooLow), nello stesso modo in cui la parte di gas o di livello di una chiamata viene addebitata dopo che la sua prova è stata decodificata. Il minimo di una chiamata viene verificato due volte, perché ciò che dichiara è attendibile solo dopo che la sua prova è stata verificata. Su chain 20 la prima verifica, prima di ogni verifica crittografica, prezza i byte della chiamata e un limite dichiarato pari a 1 (anche un Invoke deve lì la sua commissione per le celle); la seconda prezza il limite che la prova verificata dichiara. Su una catena senza sezione gas le due sono BUNDLE_BASE + CALL_BASE e il minimo esatto per livello.
Chiedi al nodo invece di tirare a indovinare:
rand fee bundle # 0.001 RAND
rand fee deploy 256 # 0.0266 RAND
rand fee call 14 --gas 20479 --bytes 1350000 # 0.0041 RAND at chain 20's starting prices
→ {"method":"rand_estimateFee","params":[{"kind":"call","tier":14,"gas":20479,"bytes":1350000}]}
← "4103100"
Quella risposta è 1,000,000 + 100 × 20,479 + 800 × 1,319 ai prezzi iniziali; il nodo applica i prezzi correnti della punta della catena nel momento in cui gli si chiede. Su chain 20 il campo gas della specifica della chiamata è obbligatorio via JSON-RPC (-32602 se manca). rand fee call <tier> senza --gas invia il tetto del livello e, senza --bytes, non prezza alcun byte. Un invoke viene prezzato allo stesso modo, con "kind":"invoke" e "created_cells": c che aggiunge c commissioni per le celle (24103100 per l’esempio qui sopra con due celle, richiesto a chain 20 il 2026-10-01). Su chain 15, che non aveva sezione gas, rand fee call 14 rispondeva 0,0022 RAND.
I valori predefiniti del wallet sono esattamente i minimi, salvo per una chiamata su chain 20, il cui valore predefinito aggiunge un margine (sotto); rand send --fee <RAND> e il flag --fee su bond, call, bridge-mint, bridge-burn (predefinito 0,01) e sui sottocomandi token li alzano. Tutto ciò che supera il minimo è una mancia.
Gas su chain 18
Chain 18, attiva dal 2026-09-29 al 2026-10-01, è stata la prima catena con misurazione del gas, e chain 19, il suo re-genesis sulla stessa build, portava la stessa sezione gas. Chain 20 (v0.6.8) mantiene ogni regola di questa sezione e aggiunge due tetti di prezzo e un carico di byte contato solo sui byte che pagano (sotto). Una catena senza sezione gas mantiene la tabella dei livelli della tabella qui sopra.
Cosa viene contato. Un gas è una riga della tabella cpu della zkVM, quindi un’istruzione ordinaria costa 1. Le syscall sono gli unici altri costi:
| operazione | gas |
|---|---|
qualsiasi istruzione, HALT, WRITE_OUTPUT, READ_INPUT, READ_PUBLIC | 1 |
POSEIDON2 su n parole | 3 + 3 × ⌈n/4⌉ (ogni riga di assorbimento costa 3) |
SHA256, una compressione | 64 |
KECCAK, una permutazione | 192 |
Il limite dichiarato. Una prova di chiamata porta un valore pubblico in più rispetto a prima, GAS_LIMIT, e il circuito (insieme di vincoli 8) dimostra che il gas della esecuzione è pari o inferiore ad esso. Il gas esatto resta privato. Un limite sopra il tetto dell’intestazione della prova stessa viene rifiutato prima che venga costruita qualsiasi chiave del verificatore:
gas_max = (2ᵗ − 1) + 2^(t−2) + 191 × (keccak rows / 32) + 63 × (sha256 rows / 64)
Sono 1.279 al livello 10, 5.119 al livello 12 e 20.479 al livello 14 per una chiamata che non usa nessuna delle due tabelle di hash.
Il minimo. Il ledger addebita il limite dichiarato e i byte, ai prezzi in vigore all’inizio del blocco:
fee ≥ BUNDLE_BASE + gas_price × gas_limit + byte_price × ⌈bytes / 1024⌉
bytes è la prova della chiamata più l’envelope di input. La tabella dei livelli e la sua franchigia non si applicano su una catena di questo tipo. Il pool richiede esattamente ciò che richiede un blocco e rifiuta una chiamata più economica come FeeTooLow.
I bundle e la prova di autorizzazione dichiarano limiti fissati. Ogni prova di bundle deve dichiarare esattamente il bundle_gas_limit del genesis, 20.479 (il tetto del livello 14), altrimenti la transazione viene rifiutata come BundleGasLimit. Chain 20, come ogni catena da 17 in poi, usa l’autorizzazione divisa, quindi ogni bundle porta una prova di autorizzazione di livello 10, che deve dichiarare 1.279 (AuthGasLimit). Nessuno dei due è un addebito: un trasferimento, un bond o un deploy paga ancora il suo minimo fisso dalla tabella qui sopra. Il wallet dichiara entrambi i valori da sé.
I prezzi si muovono. La sezione gas di chain 20 ha un controllore dynamic, quindi gas_price e byte_price sono stato del ledger, vincolati nella state root. Una volta per blocco, dopo le sue transazioni, ciascuno si muove in base a quanto il blocco era pieno rispetto a un obiettivo:
price' = min(max_price, max(min_price, price + ⌊price × adjust_bps × (used − target) / (10,000 × target)⌋))
used è limitato al doppio dell’obiettivo, quindi adjust_bps è il massimo spostamento che un blocco può produrre in entrambe le direzioni. max_price è il tetto del genesis; chain 18 e 19 non ne avevano. byte_price segue i byte paganti del blocco (sotto); gas_price segue la somma dei limiti dichiarati dalle sue chiamate e dai suoi invoke più 20.479 per ogni bundle.
gas di chain 20, sezione | valore |
|---|---|
gas_price, byte_price al genesis | 100 unità per gas; 800 unità per KiB |
min_gas_price, min_byte_price | 100; 800, quindi i prezzi iniziali sono anche i minimi |
max_gas_price, max_byte_price | 10.000; 80.000: i massimi, 100 volte i minimi (novità di chain 20) |
byte_load | paying (novità di chain 20) |
target_block_bytes | 10.485.760, metà del limite di 20 MiB per blocco |
target_block_gas | 262.144 |
adjust_bps | 1.250: al massimo il 12,5% a blocco |
bundle_gas_limit | 20.479 |
metering | circuit |
Un blocco al di sotto dei propri target fa scendere i prezzi, quindi su una chain poco trafficata restano ai minimi. rand_getLimits restituisce i valori correnti di gas_price e byte_price in cima alla chain con gas_metering: "circuit", bundle_gas_limit, adjust_bps e, dalla v0.6.8, max_gas_price, max_byte_price e byte_load (null su una chain che non li prevede); rand_status riporta gli stessi due prezzi come gas_prices.
Massimi e carico di byte pagante
Entrambi sono campi del genesis in gas.dynamic, introdotti nella v0.6.8 (audit v6, POOL-2), e chain 20 è la prima chain a impostarli. Correggono un difetto delle chain 18 e 19. Lì byte_price si muoveva con la lunghezza codificata di ogni transazione, mentre a pagarlo è solo una chiamata. Sette trasferimenti (circa 2,85 MB ciascuno, commissione fissa) riempiono un blocco fino a circa 1,9 volte il target di byte e alzano il prezzo di circa l’11% a blocco, senza alcun massimo: circa 65 blocchi di questo tipo lo portano a 1.000 volte il valore iniziale, e una chiamata costa allora circa 1 RAND invece di circa 0,004.
- Massimi.
max_gas_priceemax_byte_pricesono prezzi che il controllore non supera mai. Il passo è lo stesso e poi viene limitato (gas::next_price_capped), quindi un prezzo al proprio massimo vi resta per qualsiasi serie di blocchi pieni e scende al primo blocco sotto il target. Un genesis deve fissare ciascun massimo uguale o superiore al prezzo iniziale. Ai massimi di chain 20 la chiamata di tier 14 vista sopra, 20.479 gas e 1.319 KiB, ha un minimo di 0,3113 RAND, il più alto che il suo minimo possa raggiungere. - Il carico di byte pagante. Con
byte_load: "paying"ibytes_useddel blocco contano solo i byte su cui si applica il prezzo per byte: la prova più l’envelope di input di ogniCalleInvoke(gas::call_bytes), nulla di un trasferimento, di un bond o di un burn. Un blocco di trasferimenti non muove alcun prezzo per byte.Ledger::block_usagecalcola il valore sia per il proposer sia per la replica, così i due concordano.
Con il carico pagante un blocco pieno di trasferimenti non dà alcun segnale di prezzo a una chiamata, perciò un proposer onesto riserva anche spazio per le chiamate. Questa è una politica del nodo, non una regola di validità: finché una call o un invoke è nel pool e paga il proprio minimo corrente, le transazioni a commissione fissa occupano al massimo tre quarti dei byte del blocco nel primo passaggio, e ciò che le chiamate lasciano dell’ultimo quarto viene poi riempito con i trasferimenti trattenuti (Mempool).
Cosa paga il wallet per una chiamata
rand call esegue prima il programma nell’emulatore e stampa gas: <exact> (declaring <limit>, tier <t>). Per impostazione predefinita dichiara il gas esatto arrotondato per eccesso a un multiplo di 2^(tier − 2); --gas-limit N dichiara un valore esatto e --gas-limit max il massimo dell’header.
Due fattori rendono la commissione predefinita più alta del minimo:
- La prova è valutata al limite massimo. Dalla chain 16 (
hardening_v6, chain 20 inclusa) la prova di una chiamata è legata alla propria transazione, quindi la commissione è fissata prima che la prova esista. Il wallet valuta il limite massimo di prova della chain, 4 MiB, al posto della dimensione reale della prova (wallet::hardened_call_quote_bytes). Questo può solo far pagare di più. - Due passi di prezzo di margine.
rand_getLimitsrestituisce i prezzi della testa confermata e una chiamata viene inclusa due o tre blocchi dopo, quindi l’impostazione predefinita moltiplica il minimo per(1 + adjust_bps / 10,000)², che su chain 20 è 1,125².
Misurate su chain 18 il 2026-09-30, quattro chiamate sono costate tra 0,0057 e 0,0075 RAND ciascuna con queste impostazioni predefinite (Example programs). --fee sostituisce il valore predefinito; il wallet rivaluta la prova reale prima dell’invio e rifiuta una commissione inferiore al proprio minimo.
Dove va la commissione
Tutta la commissione, minimo e mancia, viene accreditata ai rewards del proposer del blocco nel registro dei validator, l’unico punto di questa chain che memorizza un importo in chiaro, con un’eccezione. In un genesis con tokens.burn_registration_fee (chain 20, come ogni chain dalla 15), la registration_fee di una RegisterToken o di una RegisterBridgedToken viene bruciata e il proposer trattiene fee − registration_fee; rand_getSupply la conta in registration_fees_burned. Su chain 14, priva del flag, il proposer tratteneva l’intera commissione. Nient’altro viene bruciato e non c’è alcuna ripartizione. Un validator trasforma le ricompense accumulate in una nota con rand-node withdraw (Staking). La commissione di cella di un invoke fa parte della commissione del suo bundle e va al proposer insieme al resto. Su chain 20 non ci sono ricompense di blocco né inflazione: le commissioni sono l’intero reddito di un validator.
Una commissione su chain 20 non è in RAND e non va a nessun validator. Secondo bridge.fees del genesis (novità della v0.6.8) il bridge trattiene 10 bps di ogni deposito di zUSD e di ogni burn di zUSD, arrotondati per difetto a un’unità intera di rilascio del collaterale, come nota zUSD verso un indirizzo di tesoreria indicato dal genesis. Un deposito accredita al depositante l’importo lordo meno la commissione; un burn rilascia amount − fee sulla chain di origine. La nota della commissione resta emessa e garantita. Vedi Bridge e RPL tokens.
Il mempool ordina i candidati in base a quanto pagano sopra il proprio minimo per KiB, poi in base alla commissione (Mempool), quindi una commissione più alta conta solo in caso di congestione. Un trasferimento pesa circa 2,85 MB (misurato su chain 18): una prova del bundle da 1,49 MB e una prova di autorizzazione da 1,36 MB, quindi ne entrano circa sette nel blocco da 20 MiB di chain 20. L’osservazione del fullnode stesso era che un mercato delle commissioni sui byte, non sugli opcode, è ciò che il minimo dovrebbe diventare prima della mainnet. Il prezzo per byte di chain 20 è quel mercato per le chiamate, mosso solo dai byte per cui le chiamate pagano; il minimo di un trasferimento resta fisso.
Perché qui il gas è un prezzo, non un limite
Ethereum misura ogni opcode perché ogni nodo esegue ogni transazione e l’esecuzione è illimitata. Su Rand nessun nodo esegue nulla: il mittente esegue il programma una volta, off chain, e consegna alla chain una prova. Il lavoro di un nodo per transazione è una sequenza fissa — decodificare i campi pubblici, eseguire i controlli gratuiti, verificare una STARK — e questa verifica costa circa 16 ms con una chiave del verificatore già in cache, qualunque cosa abbia fatto il programma. Così i tre compiti del gas si separano:
- La terminazione è imposta dal tier: un’esecuzione che non termina entro
2ᵗ − 1cicli non può essere provata affatto, e il prover assorbe il fallimento. - La valutazione del lavoro è ciò che fa il minimo del gas, dalla chain 18. Il costo della rete per istruzione è prossimo a zero, ma il lavoro di prova del mittente è reale, e un minimo fisso valutava una chiamata da un milione di cicli come una da mille. Fino alla chain 18 il minimo era fisso per tier.
- Il dimensionamento dei blocchi è un budget di byte (
MAX_BLOCK_BYTES= 4 MiB per impostazione predefinita, altrimenti ilmax_block_bytesdel genesis) e un numero di transazioni (2.000).
Due avvertenze che il fullnode dichiara apertamente: i byte variano (una prova supera il megabyte, quindi lo spazio nei blocchi, non il calcolo, è la risorsa scarsa), e la crescita dello stato — l’albero, l’insieme dei nullifier, i byte dei programmi distribuiti — è valutata solo dalla commissione di deploy per parola e dalla base fissa, il che è adeguato per una testnet e merita una revisione quando la dimensione dello stato conterà.
Cosa paga invece il mittente: la prova
L’unico costo variabile è la produzione della prova STARK, e lo paga solo la macchina del mittente. In ordine di effetto:
- Il tier
t ∈ {10, 12, 14, 16, 18, 20}(una chiamata oltre il 14 è rifiutata sulla chain dalla v0.5.6; un bundle è fissato a 14 e, dalla chain 17, porta accanto una prova di autorizzazione di tier 10, circa 7 s in più): la tabella cpu viene riempita fino a2ᵗrighe e ogni passo quadruplica all’incirca la traccia riempita. Misurato sul laptop di sviluppo:private_paymental tier 10 in circa 7 s; la guest del bundle con asset nascosto al tier 14 in circa 100 s, qualunque asset sposti. - I cicli eseguiti, perché decidono il tier: le istruzioni eseguite, non quelle scritte.
- La dimensione del programma, in modo debole: una riga di digest ogni quattro parole all’inizio della traccia.
- La dimensione dell’input privato, allo stesso modo.
- Quali tabelle sono presenti: una tabella keccak o sha256 costa la quota delle proprie colonne solo se la guest l’ha usata.
- Il profilo FRI: 80 query invece di 27 triplicano la dimensione della prova ma cambiano appena il tempo di prova.
La prova non dipende dagli importi, da quante note possiede il mittente né dalla dimensione della chain: l’appartenenza è provata rispetto a un albero a profondità fissa, quindi un trasferimento costa lo stesso al blocco dieci e al blocco dieci milioni.
Riferimento
| costante | valore |
|---|---|
BUNDLE_BASE | 1.000.000 unità |
BRIDGE_BURN_FEE | 10.000.000 unità (10 × BUNDLE_BASE) |
registration_fee (sezione tokens del genesis) | 1.000.000.000 unità sulla catena 20, bruciate (burn_registration_fee) |
DEPLOY_PER_WORD | 100.000 unità |
CALL_BASE, CALL_PER_TIER_STEP | 1.000.000; 100.000 unità; la tabella dei tier di una catena senza sezione gas |
GAS_PRICE_DEFAULT, BYTE_PRICE_DEFAULT | 100 unità per gas; 800 unità per KiB. I prezzi iniziali della catena 20 e i suoi prezzi minimi |
KECCAK_GAS, SHA256_GAS, POSEIDON2_ABSORB_GAS | 192; 64; 3 gas per riga |
max_gas_price, max_byte_price (gas.dynamic del genesis) | 10.000 unità per gas; 80.000 unità per KiB sulla catena 20; nessun massimale se assenti (catene 18 e 19) |
byte_load (gas.dynamic del genesis) | paying sulla catena 20: solo i byte delle prove e delle envelope di call e invoke muovono byte_price; se assente, i byte di ogni transazione |
cell_fee (program_state del genesis) | 10.000.000 unità (0,01 RAND) per ogni cella creata sulla catena 20; al massimo 1.000 RAND |
bundle_gas_limit (sezione gas del genesis) | 20.479 sulla catena 20, gas_max(14, 0, 0); una prova di autorizzazione dichiara 1.279, gas_max(10, 0, 0) |
adjust_bps (gas.dynamic del genesis) | 1.250 sulla catena 20; un genesis può impostare da 1 a 5.000 |
MAX_PROGRAM_WORDS | 4.096, a meno che il genesis non imposti max_program_words (al massimo 65.535; la catena 20 imposta 65.535, e hardening_v6 rifiuta un programma di oltre 8.180 word che nessuna call potrebbe contenere) |
MAX_PROOF_BYTES | 2 MiB, a meno che il genesis non imposti max_proof_bytes (4 MiB sulla catena 20; 8 MiB sulle catene da 13 a 15) |
MAX_BLOCK_BYTES, MAX_BLOCK_TXS | 4 MiB (a meno che il genesis non imposti max_block_bytes; 20 MiB sulla catena 20), 2.000 |
| tier | 10, 12, 14, 16, 18, 20; cicli ≤ 2ᵗ − 1 |
MAX_CALL_TIER | 14: una prova di call oltre questo valore viene rifiutata all’ammissione e in un blocco (dalla v0.5.6) |