Structure d’une transaction
Ce que contiennent les octets d’une transaction Monero : préfixe, signature RingCT et partie élagable
Une transaction = un préfixe (version, entrées, sorties, extra) + la base RingCT (type, frais, montants chiffrés, engagements des sorties) + la partie élagable (Bulletproofs+, CLSAG, pseudo-sorties). Le hachage de la transaction est construit à partir des hachages des trois parties, si bien que la partie élagable peut être supprimée par les anciens nœuds (pruning) tout en restant vérifiable.
Préfixe
version = 2
unlock_time = 0 // champ hérité, toujours 0 désormais
vin[]: // entrées
txin_to_key:
amount = 0 // les montants sont cachés dans RingCT
key_offsets = [g₀, Δ₁, …, Δ₁₅] // 16 indices globaux, en décalages relatifs
k_image = I // key image, 32 octets
vout[]: // sorties
amount = 0
target: txout_to_tagged_key
key = P // clé à usage unique, 32 octets
view_tag = 1 byte
extra = [0x01 ‖ R, …] // clé de transaction et autres
Les key_offsets sont stockés sous forme de différences : le premier est l’indice absolu de la sortie, les autres sont les distances par rapport au précédent. Les petits nombres occupent moins d’octets en 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
Partie élagable
bulletproofs_plus[] = one aggregated proof
CLSAGs[] = { s[16], c1, D } per input
pseudoOuts[] = C̃, 32 bytes per input
Hachage de la transaction
Cet « arbre de trois hachages » permet à un nœud élagué de supprimer les preuves volumineuses des anciennes transactions (en gardant leur hachage) tout en pouvant toujours calculer le txid.
Frais
Les frais dépendent du poids de la transaction (≈ taille en octets, ajustée pour Bulletproofs+ afin que les transactions avec beaucoup de sorties ne soient pas disproportionnellement bon marché) et d’un niveau de priorité. Le tarif de base par octet s’adapte à la taille médiane des blocs — voir taille de bloc dynamique.
Ce qui change avec FCMP++
- Au lieu de
key_offsets— une référence au bloc dont l’état de l’arbre sert de base à la preuve. - Au lieu de CLSAG — une preuve d’appartenance et SA+L ; la key image reste.
- Format des sorties — Carrot (view tags de 3 octets, ancre Janus).