Tecnico › Rete

Struttura delle transazioni

Cosa c'è nei byte di una transazione Monero: prefisso, firma RingCT e parte potabile

In breve

Una transazione = un prefisso (versione, input, output, extra) + la base RingCT (tipo, commissione, importi cifrati, commitment degli output) + la parte potabile (Bulletproofs+, CLSAG, pseudo-output). L'hash della transazione è costruito dagli hash delle tre parti, così la parte potabile può essere scartata dai vecchi nodi (pruning) restando verificabile.

Prefisso

version        = 2
unlock_time    = 0                       // campo legacy, ora sempre 0
vin[]:                                   // input
  txin_to_key:
    amount       = 0                     // gli importi sono nascosti in RingCT
    key_offsets  = [g₀, Δ₁, …, Δ₁₅]      // 16 indici globali, come offset relativi
    k_image      = I                     // key image, 32 byte
vout[]:                                  // output
  amount = 0
  target: txout_to_tagged_key
    key      = P                         // chiave monouso, 32 byte
    view_tag = 1 byte
extra          = [0x01 ‖ R, …]           // chiave della transazione e altro

I key_offsets sono memorizzati come differenze: il primo è l'indice assoluto dell'output, gli altri sono distanze dal precedente. I numeri piccoli occupano meno byte come varint.

Base RingCT

type       = 6                           // RCTTypeBulletproofPlus
txnFee     = fee in atomic units (varint)
ecdhInfo[] = encrypted amount, 8 bytes per output
outPk[]    = commitment C, 32 bytes per output

Parte potabile

bulletproofs_plus[] = one aggregated proof
CLSAGs[]            = { s[16], c1, D } per input
pseudoOuts[]        = C̃, 32 bytes per input

Hash della transazione

txid = Keccak( H(prefix) ‖ H(RingCT base) ‖ H(prunable) )

Questo "albero di tre hash" permette a un nodo pruned di scartare le pesanti prove delle vecchie transazioni (conservandone l'hash) pur potendo ancora calcolare il txid.

Commissioni

La commissione dipende dal peso della transazione (≈ dimensione in byte, corretta per Bulletproofs+ così che le transazioni con molti output non risultino sproporzionatamente economiche) e da un livello di priorità. La tariffa base per byte si adatta alla dimensione mediana dei blocchi: vedi dimensione dinamica dei blocchi.

Cosa cambia con FCMP++

  • Invece di key_offsets: un riferimento al blocco rispetto al cui stato dell'albero viene costruita la prova.
  • Invece di CLSAG: una prova di appartenenza e SA+L; la key image resta.
  • Formato degli output: Carrot (view tag da 3 byte, ancora Janus).