Una transazione byte per byte
Analisi completa dell'hex di una transazione RingCT: ogni campo, ogni funzione, su dati reali e casuali
Una transazione Monero è composta da tre blocchi di byte consecutivi: il prefisso (input, output, extra), la base RingCT (commissione, importi cifrati, commitment) e la parte potabile (prunable: Bulletproofs+, CLSAG, pseudo-output). Qui sotto c'è uno strumento che analizza byte per byte qualsiasi transazione v2, calcola il txid, verifica il bilancio e, data una view key, trova i "tuoi" output e ne decifra gli importi. Per una transazione casuale mostra tutti i segreti, così puoi vedere come ogni funzione viene applicata a numeri concreti.
Come leggere i byte
La serializzazione di Monero è semplice: niente intestazioni né nomi dei campi, solo valori uno dopo l'altro. Due tipi di mattoncini:
- varint: un intero a lunghezza variabile, 7 bit per byte, il bit più alto significa "segue un altro byte".
0x02= 2,0x80 0x01= 128,0x80 0xb5 0x18= 400000. - chiave / punto / scalare: esattamente 32 byte, senza lunghezza. Anche gli array di punti la cui lunghezza è nota dal contesto (ad es. gli
sdi CLSAG, in base alla dimensione del ring) arrivano senza lunghezza.
Quindi il parser deve conoscere il formato in anticipo: il tipo RingCT, letto a metà, decide come leggere tutto ciò che segue.
Quali funzioni si applicano dove
| Campo | Calcolato da | Formula | Approfondimento |
|---|---|---|---|
| extra: R | mittente | R = r·G | stealth address |
| output: P | mittente | P = Hs(8·r·A ‖ i)·G + B | stealth address |
| view tag | mittente | Keccak("view_tag" ‖ 8rA ‖ i)[0] | view tag |
| ecdhInfo | mittente | v ⊕ Keccak("amount" ‖ Hs(8rA ‖ i))[0..8] | Pedersen |
| outPk | mittente | C = y·G + v·H, y = Hs("commitment_mask" ‖ Hs(8rA ‖ i)) | Pedersen |
| ring | wallet del mittente | 16 indici globali, distribuzione gamma sull'età | esche |
| key image | proprietario dell'input | I = x·Hp(P) | key image |
| pseudoOuts | mittente | C̃ = y'·G + v·H, maschere scelte in modo che Σ C̃ = Σ C + fee·H | RingCT |
| CLSAG | proprietario dell'input | un anello di sfide su P_i e C_i − C̃ | ring signature |
| Bulletproofs+ | mittente | prova che 0 ≤ v < 2⁶⁴ per tutti gli output | range proof |
Cosa fa un nodo con questi byte
- Li analizza; qualsiasi byte in più o in meno comporta il rifiuto.
- Verifica che le key image siano nuove e nel sottogruppo corretto.
- Ricostruisce i 16 indici globali dagli offset e carica dal proprio database le chiavi e i commitment di quegli output.
- Verifica il bilancio
Σ C̃ = Σ outPk + fee·H: lo fa anche lo strumento qui sotto. - Verifica Bulletproofs+ e la CLSAG di ogni input.
Cosa fa il wallet del destinatario
- Prende
Rda extra e calcola il segreto condiviso8·a·R(un'operazione per transazione). - Per ogni output: un hash → confronta il view tag; se non coincide, stop.
- Se coincide, confronta
Hs(8aR ‖ i)·G + Bcon la chiave dell'output. - L'output è nostro: decifra l'importo, ricostruisce la maschera e verifica
y·G + v·Hrispetto aoutPk.
Lo strumento mostra tutti questi passaggi con numeri concreti.
Il parser è stato verificato rispetto alla decodifica JSON di monerod di transazioni reali di tipo 5 e tipo 6 e di una transazione coinbase: ogni campo e il txid coincidono. Il pulsante "tx reale dalla mainnet" ne carica una: confronta il txid con un qualsiasi block explorer.
Come sarà una transazione FCMP++?
Il formato delle transazioni FCMP++ potrebbe ancora cambiare prima dell'hard fork, quindi qui non c'è un parser di byte per esso. Ma dall'implementazione attuale la struttura generale è chiara, ed è sorprendentemente simile a quella di oggi:
| In RingCT | In FCMP++ | Funzioni |
|---|---|---|
| 16 offset per input | un riferimento al blocco rispetto al cui albero è costruita la prova | radice del Curve Tree su tutti gli output |
key image I = x·Hp(P) | la stessa L = x·Hp(O) | doppie spese individuate come prima |
pseudo-output C̃ | C̃ = C + r_c·G: parte della tupla rerandomizzata | rerandomizzazione |
| CLSAG per input | SA+L per input (pochi punti e scalari) | Schnorr generalizzato |
| — | una sola prova di appartenenza per l'intera transazione | Generalized Bulletproofs + divisori |
| view tag da 1 byte, ECDH su Ed25519 | view tag da 3 byte, X25519, ancora Janus | Carrot |
Guarda la rerandomizzazione su numeri concreti nello strumento. Quando il formato sarà definitivo, qui verrà aggiunta anche un'analisi byte per byte delle transazioni FCMP++.