Технический › Сеть

Устройство транзакции

Что лежит в байтах транзакции Monero: префикс, RingCT-подпись и prunable-часть

Коротко

Транзакция = префикс (версия, входы, выходы, extra) + RingCT-база (тип, комиссия, зашифрованные суммы, обязательства выходов) + prunable-часть (Bulletproofs+, CLSAG, псевдовыходы). Хеш транзакции строится из хешей трёх частей, поэтому prunable-часть можно удалить со старых узлов (pruning), сохранив проверяемость.

Префикс

version        = 2
unlock_time    = 0                       // устаревшее поле, сейчас всегда 0
vin[]:                                   // входы
  txin_to_key:
    amount       = 0                     // в RingCT суммы скрыты
    key_offsets  = [g₀, Δ₁, …, Δ₁₅]      // 16 глобальных индексов, относительными смещениями
    k_image      = I                     // key image, 32 байта
vout[]:                                  // выходы
  amount = 0
  target: txout_to_tagged_key
    key      = P                         // одноразовый ключ, 32 байта
    view_tag = 1 байт
extra          = [0x01 ‖ R, …]           // транзакционный ключ и прочее

key_offsets записаны как разности: первый — абсолютный индекс выхода, остальные — расстояние до предыдущего. Маленькие числа в varint занимают меньше байт.

RingCT-база

type       = 6                           // RCTTypeBulletproofPlus
txnFee     = комиссия в атомарных единицах (varint)
ecdhInfo[] = зашифрованная сумма, 8 байт на выход
outPk[]    = обязательство C, 32 байта на выход

Prunable-часть

bulletproofs_plus[] = одно агрегированное доказательство
CLSAGs[]            = { s[16], c1, D } на вход
pseudoOuts[]        = C̃, 32 байта на вход

Хеш транзакции

txid = Keccak( H(префикс) ‖ H(RingCT-база) ‖ H(prunable) )

Такое «дерево из трёх хешей» позволяет узлу в режиме pruning выбросить тяжёлые доказательства у старых транзакций (оставив хеш), а txid всё равно вычисляется.

Комиссии

Комиссия зависит от веса транзакции (≈ размер в байтах, с поправкой для Bulletproofs+, чтобы транзакции с многими выходами не были непропорционально дешёвыми) и от уровня приоритета. Базовая ставка за байт подстраивается под медианный размер блока — см. динамический размер блока.

Что изменится с FCMP++

  • Вместо key_offsets — ссылка на блок, по состоянию дерева в котором строится доказательство.
  • Вместо CLSAG — доказательство членства и SA+L; key image остаётся.
  • Формат выходов — Carrot (3-байтовые view tags, якорь от Janus).