Technique › Réseau

Structure d’une transaction

Ce que contiennent les octets d’une transaction Monero : préfixe, signature RingCT et partie élagable

En bref

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

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

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).