Към съдържанието
ДаретеEN

Ъпгрейди

Taproot

Как работи Taproot в биткойн: BIP 341 добавя P2TR изходи, Schnorr подписи и Tapscript. Вижте как се харчат key path и script path.

От Dimitar Zurnov · Обновено на 4 ноември 2026
Адаптирано от Learn Me a Bitcoin на Greg Walker.

Taproot е ъпгрейд на биткойн, което е било активирано на блок 709,632 на 14 ноември 2021 г. Основната му промяна е нов вид изход, Pay to Taproot, или P2TR. Изход P2TR може да се похарчи по два начина: с един подпис от един ключ или с един от много скриптове, наредени в дърво. Неизползваните скриптове остават скрити. Taproot е въвел и Schnorr подписи, и преработен скриптов език, наречен Tapscript.

Три BIP-а го дефинират. BIP 340 описва Schnorr подписите, BIP 341 описва правилата за изходите и харченето, а BIP 342 описва Tapscript. Идеята е била предложена за първи път от Gregory Maxwell през 2018 г.

Кога Taproot е бил активиран?

Taproot използва сигнализиране с version bits, което чете полето version в заглавките на блоковете. Майнърите са задавали бит 2, за да покажат подкрепа. Прозорецът за сигнализиране е бил от 24 април 2021 г. до 11 август 2021 г. За да се заключи ъпгрейдът, трябвало е 90% от блоковете в един период за корекция на трудността (1,815 от 2,016) да сигнализират.

Периодът, който е завършил на блок 687,455, е имал 1,983 от 2,016 блока (98.36%) със сигнал. Ъпгрейдът затова се е заключил на блок 687,456 на 13 юни 2021 г. Минималната височина на активация, 709,632, не е позволявала ъпгрейдът да влезе в сила по-рано. То е влязло в сила на тази височина, в 05:15:27 UTC на 14 ноември 2021 г.

Как се изгражда P2TR изход?

P2TR изходът се изгражда на четири стъпки. Всяка стъпка подава резултата си към следващата.

Ключът на P2TR изхода идва от вътрешния публичен ключ и корена на скриптовото дърво през tweak и се поставя в scriptPubKey. Вътрешен ключ P a2fc329a…e4a29fa4 Merkle root b5b72eea…b152e7c Tweak t = tagged hash на P и корена bf0094ea…92060cde Q = P + t x G Изходен ключ Q, 32 байта 562529047f…6bce5d72 OP_1 + 32-байтов push scriptPubKey, 34 байта 5120562529047f…6bce5d72
Стойностите по-долу са тези от примерите на страницата.

1. Вътрешният публичен ключ. Taproot ключовете са 32 байта, само x-координатата. Y-координатата се приема за четна. За да получите такъв ключ от 33-байтов компресиран ключ, махнете първия байт. Примерният ключ е a2fc329a085d8cfc4fa28795993d7b666cee024e94c40115141b8e9be4a29fa4.

2. Скриптовото дърво (по желание). Всеки лист има версия и скрипт. Tapscript използва версия на листа c0 (192). Хешът на листа е tagged hash (хеш с етикет) с етикет TapLeaf, върху версията на листа, compact size на скрипта и самия скрипт. За скрипта от един байт 5187 (OP_1 OP_EQUAL) хешът на листа е:

6b13becdaf0eee497e2f304adcfa1c0c9e84561c9989b7f2b5fc39f5f90a60f6

Два листа се обединяват в клон. Клонът е tagged hash с етикет TapBranch върху двата хеша, като по-малкият е първи. Повтаряйте, докато остане един хеш. Това е merkle root (коренът на Меркъл). Без скриптове няма корен, а при един лист коренът е хешът на този лист.

3. Tweak-ът. Tweak-ът е tagged hash с етикет TapTweak върху вътрешния ключ и merkle root-а. Без скриптово дърво tweak-ът се изчислява само от вътрешния ключ. Примерният tweak, с корен от дърво с пет листа, е bf0094eae70ba67e2f9fc3c4b81f078c90931855a8d24c959619174c92060cde.

4. Ключът на изхода. Ключът на изхода Q е точката на вътрешния ключ плюс tweak-а, умножен по генераторната точка: Q = P + t × G. Q е стойността, която се записва на веригата. В примера е 562529047f476b9a833a5a780a75845ec32980330d76d1ac9f351dc76bce5d72.

Заключващият скрипт е OP_1, следван от 32-байтов push на Q. Това е 5120, последвано от Q, общо 34 байта. Адресът му е с 62 знака и започва с bc1p, защото кодировката е bech32m, дефинирана в BIP 350.

Версията на листа трябва да е четна, защото най-малкият бит на control байта държи флага за четност. Тя не може да е 0x50, защото така се означава annex. Tapscript ползва 0xc0, а другите допустими стойности са изброени в BIP 341.

Как се харчи P2TR изход?

Има два начина, а witness-ът показва кой от тях е използван. Харчене по key path има един елемент в witness-а. Харчене по script path има два или повече.

Харченето по key path показва един подпис. Харченето по script path показва входовете на скрипта, листовия скрипт и control блока. Харчене по key path <подпис, 64 байта> Witness-ът има един елемент скрито Харчене по script path хеш листов скрипт хеш 1. входове на скрипта 2. листовият скрипт 3. control блок контролен байт вътрешен ключ, 32 байта merkle път, 32 байта за всяка стъпка
Разкрива се само подписът или листът, който е бил използван. Останалото дърво остава като хешове.

Харчене по key path

Харченето по key path отключва изхода с подпис от ключа, върху който е приложен tweak-ът. Първо приложете tweak-а върху частния ключ. Използвайте d, частния ключ, или n - d, ако точката на публичния ключ има нечетна y-координата, за да съвпадне с четния x-only ключ. След това добавете tweak-а:

tweaked private key = (d + t) mod n

Тук n е редът на кривата secp256k1. Подпишете съобщението за подписване (sighash) с този ключ чрез Schnorr подпис. Witness-ът тогава съдържа един елемент, 64-байтов подпис. 65-байтовият подпис включва байт за тип на хеша. Типът по подразбиране при Taproot е 0x00, който подписва цялата трансакция, както SIGHASH_ALL. Когато се ползва този тип, байт за тип на хеша не се добавя.

Хешът за подписване е tagged hash с етикет TapSighash, върху байта за епоха 0x00 и общото съобщение за подписване. То съдържа данните на трансакцията, които подписът покрива, включително входа, който се харчи, и изходите. За да изчислите tweak-а, ви трябва merkle root-ът на скриптовото дърво, затова го пазете. Без него не можете да харчите по key path.

Харчене по script path

Харченето по script path разкрива един лист. Witness-ът съдържа тези части, в този ред:

  1. Входовете на скрипта: елементите от стека, които листовият скрипт иска, например подпис. Лист, който не иска нищо, няма елементи тук.
  2. Самият листов скрипт.
  3. Control блокът.

Control блокът има три части. Първият байт е control байтът: версията на листа плюс един бит. Този бит показва четността на y-координатата на ключа след tweak: 1, ако е нечетна. Следващите 32 байта са вътрешният ключ.

След това идва merkle пътят: 32 байта за всеки съседен хеш, нужен за възстановяване на корена. Пътят може да съдържа най-много 128 хеша, така че control блокът е най-много 33 + 32 × 128 = 4,129 байта.

Примерният control блок за листа 5387 е c1, следван от вътрешния ключ и пътя. c1 означава, че версията на листа е c0, а y-координатата на изходния ключ е нечетна. Листът е на три нива под корена, затова пътят му съдържа три 32-байтови хеша, а целият control блок е 129 байта.

Подписът при харчене по script path ползва различно разширение на съобщението за подписване. То добавя хеша на листа и две полета. Флагът за разширение е 1, така че подписаното съобщение е различно от това при key path.

Annex е незадължителен елемент, който започва с 0x50. Той е запазен за бъдещи ъпгрейди, затова не го включвайте.

Какво е Tapscript?

Tapscript е скриптовият език, който ползва всеки лист. Почти е същият като езика Script. Промените са тези:

  • OP_CHECKSIG и OP_CHECKSIGVERIFY вече проверяват Schnorr подписи.
  • OP_CHECKMULTISIG и OP_CHECKMULTISIGVERIFY са деактивирани.
  • OP_CHECKSIGADD (0xba) е нов. Позволява на скрипта да брои валидните подписи и работи с пакетна (batch) проверка.
  • Кодовете, които са били резервирани, вече са OP_SUCCESSx. Скрипт, който съдържа някой от тях, е валиден, без значение къде се намира.

Tapscript премахва и старите лимити. Преди това листовият скрипт е бил ограничен до 10,000 байта и 201 операции без push. Тези лимити са отпаднали. Вместо тях всеки скрипт има бюджет за подписи: 50 плюс размера на witness-а, а всяка проверка на подпис струва 50 от него. Така всеки скрипт може да съдържа поне една проверка на подпис, а бюджетът се брои за всеки скрипт поотделно, не за целия блок.

Защо Taproot е частен и ефективен?

Скриптовото дърво може да съдържа много условия за харчене, но Taproot разкрива само онова, което използвате. Останалите остават като хешове. Харченето по key path не разкрива никакъв скрипт, така че никой не може да види, че има други условия.

Taproot е и компактен. P2TR изходът е 34 байта, колкото е P2WSH изходът, въпреки че може да съдържа цяло дърво от условия. Цената на дълбокото дърво се плаща при харчене, с по-дълъг merkle път.

Дървото е и ваш избор. Поставете скрипта, който очаквате да ползвате най-често, близо до корена, защото merkle пътят му е по-къс и по-евтин за харчене. Дизайнът оставя място и за бъдещи ъпгрейди. Нови версии на листа могат да добавят типове скриптове по-късно, а annex е запазен за бъдеща употреба.

Къде можете да го видите?

Блокът за активация е 709,632. Хешът му е 0000000000000000000687bca986194dc2c1f949318629b44bb54ec0a94d8244, а времето на блока е 14 ноември 2021 г., 05:15:27 UTC. Taproot се надгражда върху witness формата от SegWit, затова прочетете първо страницата за SegWit, ако още не сте я чели. Страницата за Schnorr подписите обяснява схемата за подписи по-подробно.

В този раздел: Ъпгрейди

Целият курс „Биткойн от нулата“

Нещо не изглежда наред? Кажете ни