Устройство транзакции
Что лежит в байтах транзакции 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 байта на вход
Хеш транзакции
Такое «дерево из трёх хешей» позволяет узлу в режиме pruning выбросить тяжёлые доказательства у старых транзакций (оставив хеш), а txid всё равно вычисляется.
Комиссии
Комиссия зависит от веса транзакции (≈ размер в байтах, с поправкой для Bulletproofs+, чтобы транзакции с многими выходами не были непропорционально дешёвыми) и от уровня приоритета. Базовая ставка за байт подстраивается под медианный размер блока — см. динамический размер блока.
Что изменится с FCMP++
- Вместо
key_offsets— ссылка на блок, по состоянию дерева в котором строится доказательство. - Вместо CLSAG — доказательство членства и SA+L; key image остаётся.
- Формат выходов — Carrot (3-байтовые view tags, якорь от Janus).