Извлеките script и control block из нужного input

Prevout — непотраченный output, на который ссылается конкретный input. Базовую связь outpoint и value объясняет модель UTXO и сдача, а форматы адресов Bitcoin относятся только к кодированию получателя; здесь критичен raw scriptPubKey. Сначала возьмите исходный witness: только если в нём не меньше двух элементов и первый byte именно последнего элемента равен 0x50, этот последний элемент считается annex и удаляется. Не ищите 0x50 в более ранних элементах. После такой нормализации для script path должны остаться минимум два элемента: предпоследний — tapscript s, последний — control block c; остальные образуют входной stack.

Control block по BIP-341
ЧастьРазмерРоль
c[0]1 byteleaf version в верхних 7 битах и parity output key в младшем бите
c[1:33]32 bytesx-only internal public key p
c[33:]32 × m bytesMerkle path, где m — от 0 до 128
Весь c33 + 32m bytesЛюбая другая длина не соответствует control-block rule
Control block по BIP-341
Часть
c[0]
Размер
1 byte
Роль
leaf version в верхних 7 битах и parity output key в младшем бите
Часть
c[1:33]
Размер
32 bytes
Роль
x-only internal public key p
Часть
c[33:]
Размер
32 × m bytes
Роль
Merkle path, где m — от 0 до 128
Часть
Весь c
Размер
33 + 32m bytes
Роль
Любая другая длина не соответствует control-block rule

Пересчитайте commitment без направлений left/right

Получите leaf version v = c[0] & 0xfe. Начальный k — tagged hash TapLeaf от v, CompactSize длины tapscript и точных bytes s. Затем для каждого 32-byte элемента e из control block вычисляйте TapBranch от пары min(k,e) || max(k,e) в лексикографическом byte order. Нельзя менять script encoding, декомпилировать opcodes заново или добавлять left/right bits: их нет в доказательстве.

Контрольный расчёт

  1. 1
    Привяжите input

    Сохраните raw spending transaction, input index, outpoint и raw prevout scriptPubKey.

  2. 2
    Нормализуйте witness

    Удалите только последний элемент и только при двух условиях вместе: witness содержит минимум два элемента, а last[0] = 0x50. После этого выделите предпоследний tapscript и последний control block.

  3. 3
    Разберите c

    Проверьте длину, получите parity bit, even leaf version, internal key и path cartridges по 32 bytes.

  4. 4
    Вычислите leaf

    Используйте tagged hash TapLeaf и CompactSize фактической byte-length script, а не число opcodes.

  5. 5
    Сверните path

    На каждом шаге сортируйте два 32-byte hash лексикографически и применяйте tagged hash TapBranch.

  6. 6
    Сверьте output

    Вычислите tweak, точку Q, x-only key и Y parity; сравните их с q prevout и c[0].

Internal key и Merkle root должны дать exact output key

Интерпретируйте p через BIP-340 lift_x; невалидная точка останавливает проверку. Затем t = tagged hash TapTweak(p || MerkleRoot) рассматривают как число и отвергают, если оно не меньше порядка secp256k1. Вычислите Q = P + tG. Успех commitment требует одновременно x(Q) = q из exact prevout и y(Q) mod 2 = c[0] & 1.

Mismatch и recovery
Где расходитсяЧастая причинаЧто делать
Control-block lengthОбрезан witness либо annex не удалён по точному last[0] = 0x50 ruleСнова декодировать исходный witness и только затем выбрать последний element
TapLeafИзменён script byte, leaf version или CompactSizeСравнить raw hex без reassembly
TapBranchНеверная byte order или path другого leafЛогировать k/e до каждого tagged hash
Tweak/output keyНе тот internal key, prevout или сетьСверить outpoint и 32-byte witness program
ParityПотерян low bit c[0]Сравнить Y parity Q, не только x-only key
Mismatch и recovery
Где расходится
Control-block length
Частая причина
Обрезан witness либо annex не удалён по точному last[0] = 0x50 rule
Что делать
Снова декодировать исходный witness и только затем выбрать последний element
Где расходится
TapLeaf
Частая причина
Изменён script byte, leaf version или CompactSize
Что делать
Сравнить raw hex без reassembly
Где расходится
TapBranch
Частая причина
Неверная byte order или path другого leaf
Что делать
Логировать k/e до каждого tagged hash
Где расходится
Tweak/output key
Частая причина
Не тот internal key, prevout или сеть
Что делать
Сверить outpoint и 32-byte witness program
Где расходится
Parity
Частая причина
Потерян low bit c[0]
Что делать
Сравнить Y parity Q, не только x-only key

Не подменяйте эту задачу доказательством BIP-322: оно отвечает на вопрос о контроле адреса. Также вынесите nLockTime, CLTV и CSV в отдельную проверку — timelock может находиться внутри совпавшего tapscript, но не влияет на вычисление commitment. При mismatch не подписывайте и не broadcast: сохраните raw prevout, witness и промежуточные hashes, запросите корректный control block у создателя policy/PSBT и повторите расчёт второй реализацией.

Stop-сигналы

  • есть tapscript/control block, но неизвестны exact input и prevout scriptPubKey;
  • hex script пересобрали из ассемблерного текста и считают тем же byte sequence;
  • Merkle siblings складывают по визуальному left/right вместо лексикографической сортировки;
  • сравнили только x(Q), но проигнорировали parity bit;
  • commitment match выдают за успешное script execution или готовность spend;
  • annex удаляют без двух условий BIP-341 или BIP-342 применяют к leaf version не 0xc0;
  • для публичного пересчёта требуют private key или seed.

Источники

Мы используем прямые ссылки и фиксируем дату проверки. Полный текст чужих материалов не перепечатывается.

  1. BIP-341 — Taproot consensus rules Bitcoin BIPs · Проверено 24 августа 2026 г. в 09:25 GMT+5
  2. BIP-342 — Validation of Taproot Scripts Bitcoin BIPs · Проверено 24 августа 2026 г. в 09:25 GMT+5
  3. BIP-340 — Schnorr signatures for secp256k1 Bitcoin BIPs · Проверено 24 августа 2026 г. в 09:25 GMT+5
  4. Bitcoin Core — Taproot interpreter implementation Bitcoin Core · Проверено 24 августа 2026 г. в 09:25 GMT+5
Материал носит информационный характер и не является индивидуальной рекомендацией. Криптоактивы связаны с риском волатильности, технических сбоев, хищения и полной потери средств.