Wersja Bitcoin Core 0.22.0 aktywuje najnowszą aktualizację protokołu Bitcoin, czyli Taproot. Taproot to nazwa zbiorcza softforku, określająca aktualizację protokołu Bitcoin, obejmującą zmianami zakres z 3 BIPów:

Co to jest Taproot? Czym jest Taproot? Artykuł pozwoli zrozumieć Ci, na czym polegają zmiany protokołu obejmujące softfork Taproot i jakie możliwości Bitcoin oferuje po ich wprowadzeniu.

Uruchomienie Taproot

Taproot został wprowadzony do blockchaina Bitcoin, jako softfork, czyli zmiana niełamiąca konsensusu. Uruchomienie softforka skoordynowane zostało w ramach tzw. Speedy Trial Activation, polegającego na sygnalizowaniu chęci i gotowości do uruchomienia softforka, poprzez odpowiednią flagę w wykopywanych przez górników blokach. Wersja Bitcoin Core, która ustawiała flagę Taproot to 0.21.1. Wymagane było osiągnięcie progu sygnalizacji 90% na przestrzeni 2016 wykopanych bloków, co oznacza, że 1815 bloków z 2016 wykopanych, musi posiadać ustawioną flagę sygnalizującą gotowość do Taproot.

Softfork Taproot spotkał się z aprobatą społeczności, w tym górników. Jego aktywacja nastąpiła z wykopaniem bloku 709,632, czyli 14 listopada 2021.

Wersja Bitcoin Core zawierająca funkcjonalności aktualizacji Taproot to wspomniana na wstępie wersja 0.22.0.

Aktualizacja Taproot w skrócie

Aktualizacja Taproot z wykorzystaniem podpisów Schnorra oraz MAST wprowadza do Bitcoina nowy typ transakcji: P2TR. Ten typ transakcji:

  • zwiększa prywatność adresów multisignature, wykorzystując podpisy Schnorr i ich możliwość agregacji do pojedynczej sygnatury i klucza. Oznacza to, że adresy multisig będą nie do rozróżnienia względem normalnych adresów.
  • zwiększa możliwości tworzenia skryptów zabezpieczających wydanie Bitcoinów oraz znacząco poprawia ich prywatność – można tworzyć reguły wydania BItcoinów (wysłania transakcji), definiując wiele alternatywnych warunków, jednak w taki sposób, że warunki te nie będą jawnie widoczne w blockchainie, a nawet nie będą widoczne w momencie wydawania tych Bitcoinów (oprócz pojedynczego warunku z listy zdefiniowanych, tego, który ma autoryzować konkretną transakcję).

Język Tapscript to uaktualniona nazwa języka skryptowego Bitcoin, zawierająca m.in. komendy dodane do tego języka, w celu umożliwienia funkcjonalności opisanych wyżej.

Dalsza część artykułu wyjaśnia wprowadzone w protokół zmiany, mechanikę ich działania i możliwości wykorzystania.

1. MAST – Merkelized Alternative Script Tree

MAST, czyli Merkelized Alternative Script Tree to technika, sposób wykorzystania drzewa Merkle (ang. Merkle Tree), aby zakodować (w uproszczeniu: sprowadzić do krótkiej postaci tekstu o określonej ilości znaków) skrypt zabezpieczający UTXO do wydania w ramach transakcji. Mechanizmów “zakodowania” skryptów, lub dowolnych danych istnieje wiele, jednak skrypt zakodowany z wykorzystaniem MAST ma bardzo ciekawe właściwości, które wręcz rewolucjonizują możliwości wykorzystania Bitcoina.

Transakcje Bitcoin, czyli operacje transferu kryptowaluty Bitcoin między adresami, składają się z metadanych, wejść i wyjść (UTXO). Wejścia transakcji to struktura, zawierająca istniejące wyjścia (UTXO) oraz kryptograficzne dowody prawa do ich wydania (przez aktualnego właściciela). Wyjścia transakcji to nowe UTXO (pojedyncze lub lista), których prawo następnego wydania będzie miał odbiorca transakcji. UTXO jest zabezpieczone kryptograficznie przez skrypt – prosty program komputerowy. Użytkownik ma możliwość wydania UTXO (pojedyncze lub listę), przekształcenia go za pośrednictwem w transakcji w inne UTXO (pojedyncze lub listę), jeśli w ramach transakcji dostarczy wspomniany wcześniej kryptograficzny dowód spełnienia zaprogramowanych “wymagań” skryptu.

Wykorzystując MAST, możemy zakodować skrypt w taki sposób, że wydanie UTXO zabezpieczone takim skryptem, wymaga dostarczenia dowodu spełnienia tylko części tego skryptu (jeśli jest to zasadne dla skryptu). Załóżmy, że istnieje skrypt zabezpieczający UTXO, który umożliwia jego wydanie, spełniając jeden z warunków (dowolny):

  • warunek A – UTXO można wydać dostarczając cyfrowy podpis kluczem XXX
  • warunek B – UTXO można wydać dostarczając cyfrowy podpis kluczem YYY, ale dopiero za 6 miesięcy

Wykorzystując P2TR celem wydania UTXO zabezpieczonego skryptem według powyższych wymagań – możemy dostarczyć dowód spełnienia tylko części skryptu np. A, bez konieczności ujawnienia reszty skryptu. Możliwości tego mechanizmu wynikają z zastosowania drzewa Merkle i podziału skryptu w taki sposób, że można dostarczyć jedynie dowody istnienia warunków skryptu, zamiast ich jawnej postaci.

Poniżej znajduje się wyjaśnienie podstaw działania mechanizmu MAST.

1.1 Drzewa Merkle – czym są, po co i jak działają?

Drzewa Merkle wykorzystywane są powszechnie w blockchainie. To struktura danych zbudowana z hashów kryptograficznych. Umożliwia ona szybką walidację poprawności danych. W jaki sposób?

Hash, będący sumą kontrolną, to cyfrowa plomba, dowód poprawności danych. Hash tworzy się poprzez wykorzystanie funkcji hashującej na danych. Funkcja hashująca “hashuje” dane, czego rezultatem jest hash. Zmiana choćby najmniejszej części danych spowoduje przy ponownej próbie wygenerowania uzyskanie innego hasha. Tym samym hashe zabezpieczają niezmienność danych.

Załóżmy, że posiadamy hash blockchaina, zabezpieczający jego spójność, tzn. wiemy że dane tworzące ten hash są poprawnym blockchainem. Blockchain składa się z bloków. Załóżmy, że mamy dane bloku XXX (nie hash danych, a konkretne dane bloku) i chcemy sprawdzić, czy blok ten należy do blockchaina. Sam hash blockchaina i dane bloku, są jeszcze niewystarczające w tym przypadku, aby stwierdzić, że blok zawiera się w tym blockchainie. Potrzebujemy więcej danych. Załóżmy, że wynikowy hash całego blockchaina powstał w określony sposób: hash blockchaina to hash danych, gdzie danymi są hashe wszystkich bloków tego blockchaina. Więc, aby przeprowadzić sprawdzenie, że blok XXX jest poprawny, należy:

  1. posiadać hash całego blockchaina
  2. posiadać hashe wszystkich bloków oprócz XXX
  3. policzyć hash bloku XXX
  4. policzyć hash blockchaina poprzez zhashowanie hashów wszystkich bloków, łącznie z obliczonym samodzielnie hashem bloku XXX i sprawdzić, czy wygenerowany hash wynikowy blockchaina zgadza się z oczekiwanym, czyli hashem z punktu 1.

Drzewa Merkle optymalizują ten proces.

Wykorzystując drzewa Merkle, możemy stworzyć strukturę hashów bloków blockchaina w taki sposób, że walidacja bloku nie będzie wymagała sprawdzania hashów wszystkich bloków blockchaina (tak jak w przykładzie wyżej), a jedynie kilku hashów. Drzewo Merkle tworzy, jak nazwa wskazuje drzewo, gdzie na szczycie drzewa znajduje się hash blockchaina, a jego wierzchołki niższego rzędu to hashe “bloków i innych hashów, stworzonych z hashowania bloków”. Choć brzmi to skomplikowanie – celem jest, aby drzewo zawierało więcej hashów, niż ilość hashów wszystkich bloków, ponieważ te dodatkowe niosą następującą informację: “ten hash oznacza, że część bloków, załóżmy 1000, jest poprawnych, więc nie potrzebujesz 1000 hashów, tylko ten jeden, dowodzący poprawność 1000 bloków”. Efekt zastosowania takiej struktury jest następujący: w większości przypadków sprawdzenie poprawności zawartości bloku w blockchainie wykorzystując drzewa Merkle, wymaga obliczenia hasha tego bloku, oraz wykonania z wykorzystaniem tego hasha jeszcze kilku innych hashowań, z kilkoma innymi hashami. Do dowodzenia zawarcia bloku w blockchainie, wystarczy więc zaledwie parę hashów. Ostatecznie weryfikacja przeprowadzona w taki sposób jest szybsza i efektywniejsza niż naiwny algorytm przedstawiony wyżej.

Przykład drzewa Merkle zawierającego hashe bloków.
Przykład drzewa Merkle zawierającego hashe bloków.

Dla przykładu z diagramu: obliczenie zawartości bloku D w blockchainie wymaga obliczenia hashu bloku D (uzyskując HASH_D), zhashowania go z hashem bloku C, czyli HASH_C (uzyskując HASH_CD) i zhashowania HASH_CD z HASH_AB uzyskując hash blockchaina (HASH_ABCD).

1.2 Skrypt Bitcoin w drzewie Merkle, czyli MAST

MAST to skrypt zabezpieczający wydanie UTXO, który tworzy strukturę drzewa Merkle. Jak to właściwie działa?

Warunki definiujące możliwość wydania UTXO, w taki sposób, że wystarczy spełnienie jednego z tych warunków, aby wydać UTXO – są zapisane w drzewie Merkle. Typ transakcji Bitcoin zabezpieczający UTXO w softforku Taproot z wykorzystaniem MAST, to P2TR. UTXO zakodowane P2TR, posiada w sobie węzeł drzewa MAST, a więc postać sumy kontrolnej kolektywnego skryptu (zawierającego wszystkie warunki). Chcąc wydać UTXO, nie ma potrzeby ujawniania w transakcji całego skryptu, a jedynie część skryptu, pojedynczy warunek, jaki spełniamy w ramach tej transakcji (jawnie) oraz dowody kryptograficzne istnienia pozostałych warunków (poprawności drzewa Merkle) jednak bez ujawniania tych warunków. To nie tylko pozwala na oszczędność rozmiaru transakcji w stosunku do obecnego P2SH (w znacznej części przypadków), ale też wprowadza rewolucyjne możliwości zwiększenia prywatności transakcji, ponieważ w momencie zatwierdzania transakcji ujawniamy wyłącznie warunek, który spełniamy, a nie cały skrypt jak do tej pory w P2SH.

Porównanie rozmiarów wejść/wyjść transakcji dla popularnych typów transakcji, w tym Taproot. Źródło: Twitter, @murchandamus
Porównanie rozmiarów wejść/wyjść transakcji dla popularnych typów transakcji, w tym Taproot. Źródło: Twitter, @murchandamus

2. Podpisy Schnorra

Bitcoin wykorzystywał dotychczas podpisy kryptograficzne oparte na kryptografii krzywych eliptycznych, konkretnie ECDSA. Softfork Taproot wprowadza nowy algorytm tworzenia cyfrowych podpisów do Bitcoina, nazywany Schnorr.

Jednym z głównych zastosowań kryptografii w blockchainie jest tworzenie cyfrowych podpisów, czyli tzw. sygnatur. Sygnatura to uniwersalny mechanizm zabezpieczania spójności danych, który wykorzystuje kryptografię asymetryczną (czyli kryptografię dwóch kluczy: publicznego i prywatnego). Mając klucz prywatny (niejawny, musi go znać tylko właściciel zgodnie z nazwą) mogę wygenerować podpis, sygnaturę na danych. Taka sygnatura może być publicznie jawna. Bardzo łatwo można zweryfikować, sprawdzając, czy jest poprawna (dla określonych danych), i czy ja ją wykonałem, wykorzystując mój kluczy publiczny, który jawnie udostępniam (bo mogę i jest to bezpieczne). Podpis może być wykonany na danych, np. celem autoryzacji transakcji, będąc zgodą na transakcję i jednocześnie zabezpieczając jej spójność.

W praktyce, sygnatury Schnorra są od 6 do 9 bajtów mniejsze, niż podpisy oparte o ECDSA. Oznacza to oszczędność pamięci w bloku.

Podpisy Schnorra są “liniowe”, co daje im potężne możliwości, a mianowicie: agregację kluczy (ang. key aggregation). Na co pozwala ten mechanizm? Agregacja kluczy umożliwia stworzenie adresów multisignature, czyli takich wymagających kilka podpisów, w taki sposób, że całość zdefiniowana jest za pomocą jednej sygnatury i jednego klucza publicznego, dowodzącego poprawność sygnatury. Taka sygnatura i klucz, jest efektem przekształceń kryptograficznych i agregacji kilku kluczy i sygnatur do dokładnie jednej sygnatury i jednego klucza. To pozwala na definiowanie adresów multisignature, które są nierozróżnialne względem normalnych adresów, kontrolowanych przez pojedynczy klucz publiczny. Rewolucyjnie zwiększa to prywatność w blockchainie Bitcoin, ponieważ odróżnienie adresów multisig, od pojedynczych adresów jest niemożliwe.

Musig2, to uaktualniona wersja algorytmu Musig1. Musig2 to algorytm, protokół tworzenia sygnatur multisignature bazujących na kryptografii Schnorra, z wykorzystaniem opisanej wyżej właściwości agregacji kluczy. Wykorzystanie tego protokołu przez portfele Bitcoin, czy Lightning Network znacząco ułatwi tworzenie adresów multisig bazujących na podpisach Schnorra.

CISA, czyli tzw. Cross Input Signature Aggregation, to algorytm umożliwiający tworzenie pojedynczego podpisów dla wielu różnych danych wejściowych. Mechanizm agregacji kluczy opisany wyżej, agreguje kilka podpisów i kluczy do jednego, ale te podpisy dotyczą tych samych danych np. określonej transakcji. CISA to inny mechanizm – uzyskujemy finalnie jedną sygnaturę, która w rzeczywistości agreguje w sobie wiele różnych sygnatur, różnych danych (np. jeden podpis dla wielu UTXO). Chociaż jest to mechanizm możliwy z wykorzystaniem właściwości podpisów Schnorra, to softfork Taproot nie pozwala jeszcze tworzyć takich sygnatur.

3. P2TR (Pay to Taproot) – nowy typ transakcji

Ze względu na swoją specyfikę, wyróżniamy kilka typów skryptów zabezpieczające UTXO, są to między innymi: P2PK (Pay To Public Key), P2SH (Pay To Script Hash), P2PKH (Pay To Public Key Hash), P2MS (Pay to Multi Sig). Softfork Taproot wprowadza nowy typ skryptów zabezpieczających UTXO: P2TR, czyli Pay to Taproot.

W zależności od wykorzystanego typu skryptu zabezpieczających UTXO, nazwa tego skryptu często potocznie określa typ transakcji. Tak więc transakcja typu P2TR to transakcja, której wyjściem będą Bitcoiny (w postaci UTXO możliwych do kontroli przez odbiorcę transakcji), zabezpieczona sygnaturą Schnorra (wygenerowaną pojedynczym kluczem lub zagregowaną sygnaturą multisig) lub korzeniem drzewa MAST. Tym samym P2TR łączy w jedno, możliwości oferowane aktualnie przez P2PK i P2SH – jednocześnie dodając nowe ekscytujące funkcjonalności wynikające z zastosowania podpisów Schnorra i MAST.

4. Nowy format adresu: bech32m

Adres Bitcoin to przyjazna dla użytkownika postać skryptów zabezpieczających UTXO. Wysyłanie transakcji z perspektywy użytkowników np. portfeli krptowalutowych wykorzystuje adresy, które podczas przetwarzania w węzłach tłumaczone są do skryptów niższego poziomu, wykonywanych przez oprogramowanie węzłów.

bech32m to nowa wersja formatu bech32, który niestety okazał się mieć lukę bezpieczeństwa. Nowy format adresu bech32m będzie wykorzystywany w transakcjach typu P2TR.

5. Tapscript

W celu umożliwienia realizacji transakcji P2TR, język skryptowy Bitcoin został zaktualizowany. Nazwa skryptu po aktualizacji to Tapscript. Zmiany to przede wszystkim:

  • kody operacji OP_CHECKSIG i OP_CHECKSIGVERIFY zostały zaktualizowane, aby poprawnie weryfikowały sygnatury Schnorra
  • kody operacji OP_CHECKMULTISIG i OP_CHECKMULTISIGVERIFY zostały wyłączone. Zastąpi je kod OP_CHECKSIGADD.
  • wprowadzono nowe oznaczenie kodów operacji: OP_SUCCESSx, które zastąpią niektóre z niewykorzystywanych dzisiaj kodów operacji (dokładnie kody operacji o numerach 80, 98, 126-129, 131-134, 137-138, 141-142, 149-153, 187-254). Innymi słowy: niektóre z dzisiaj niewykorzystywanych kodów zmienią swoją nazwę na kod OP_SUCCESSx, gdzie x to liczba całkowita. Zmiana ma na celu ułatwić wprowadzanie zmian do języka skryptowego Bitcoin w przyszłych softforkach (do tej pory wykorzystywano do tego głównie operacje OP_NOPx). Skrypt zawierający operację OP_SUCCESSx, która nie posiada jeszcze przypisanej funkcjonalności spowoduje ewaluacje całego skryptu do “prawdy” i przerwie dalsze wykonanie skryptu, jak tylko operacja zostanie wykryta. W przypadku softforku to stare węzły mają być w stanie przetwarzać bloki według nowych reguł, ale nowe węzły (zaktualizowane) niekoniecznie mają przetwarzać bloki według starych reguł. Wykorzystując operację OP_SUCCESSx do wprowadzania zmian w protokół – nadanie konkretnego znaczenia dla kodu w softforku, gdzie wcześniej ten kod powodował sukcesywne zakończenie skryptu, będzie nadal działać poprawnie na węzłach, które się nie zaktualizują. Jednocześnie może nie działać już poprawnie na węzłach, które zawierają softfork, nadający znaczenie takiemu kodowi.

6. Adaptor signatures – bezpieczne coin swapy

Wspomniane wcześniej możliwości przekształceń liniowych podpisów Schnorra umożliwiają jeszcze jedną bardzo ciekawą funkcjonalność, tzw. adaptor signatures, tutaj określane, jako sygnatury typu adaptor.

Właściwości sygnatur adaptor, są następujące: jeśli istnieje “sekretna wartość”, sygnatura typu adaptor dla pewnych danych oraz normalna sygnatura dla tych danych, to znając dowolne 2 wartości z podanych 3, można otrzymać trzecią. Jednocześnie można wygenerować niezależną sygnaturę typu adaptor bazującą na “sekretnej wartości”, nie znając tej wartości, a jedynie istniejącą sygnaturę typu adaptor bazującą na tej wartości.

Ich zastosowanie zobrazujemy na przykładzie tzw. coin swap, czyli bezpiecznej i prywatnej dla obu stron transakcji wymiany 1 Bitcoina między uczestnikami. Alicja wysyła Bobowi 1 swój Bitcoin, w zamian za 1 Bitcoin od Boba (pozornie bez sensu, taka transakcja ma pewną wartość w kontekście prywatności). Bardziej zaawansowany przypadek wykorzystania coin swap może obejmować różne blockchainy (np. Bitcoin i Litecoin).

  1. Załóżmy, że Alicja dysponuje sekretną wartością A, podpisem na transakcję przesyłu 1 Bitcoina dla Boba i podpisem typu adaptor, będącą kombinacją tego podpisu i sekretnej wartości A.
  2. Alicja przekazuje Bobowi niepodpisaną transakcję na 1 Bitcoin dla Boba i podpis typu adaptor na tą transakcję. Podpis adaptor nie jest podpisem dla tej transakcji, Bob więc nie może zatwierdzić tej transakcji w blockchainie.
  3. Wykorzystując otrzymany podpis typu adaptor, Bob przy użyciu swoich kluczy, tworzy własny podpis typu “adaptor” na transakcję przesyłu 1 Bitcoina do Alicji. Właściwości podpisów typu adaptor, zapewniają, że mimo iż Bob nie zna sekretnej wartości A, to wygenerowany przez niego podpis typu adaptor dla transakcji będzie poprawny względem sekretnej wartości A i Alicja będzie mogła wykorzystać jego właściwości. Bob przekazuje więc podpis typu adaptor Alicji oraz niepodpisaną transakcję przesyłu 1 Bitcoina do Alicji.
  4. W tym momencie Alicja, znając sekretną wartość A, sygnaturę typu adaptor otrzymaną od Boba, może stworzyć podpis dla otrzymanej od Boba transakcji przesyłu 1 Bitcoina do Alicji i opublikować ją w blockchain, tym samym otrzymując od Boba 1 Bitcoina.
  5. Jednocześnie Bob po zobaczeniu takiej zatwierdzonej transakcji w blockchain, na podstawie jej podpisu (wygenerowanego przez Alicję) i wygenerowanej przez siebie sygnatury typu adaptor, może poznać sekretną wartość A. Mając sekretną wartość A i sygnaturę typu adaptor otrzymaną na początku od Alicji, może stworzyć poprawną sygnaturę na niepodpisaną transakcję otrzymaną na początku od Alicji (na przesył 1 Bitcoina od Alicji do Boba).
  6. Po zatwierdzeniu transakcji przez Boba, obie strony sukcesywnie wymieniły środki.

Efektem zastosowania powyższego mechanizmu jest wytworzenie podpisu transakcji przez stronę drugą, bez posiadania klucza prywatnego właściciela. Alicja uzyskuje podpis Boba na transakcję, nie posiadając kluczy prywatnych Boba! Analogicznie Bob uzyskuje podpis Alicji.

Wykorzystując mechanikę podpisów typu adaptor, opisana w ten sposób transakcja typu coin swap wygląda dla obserwatorów, jak normalna transakcja, co jest zaletą w stosunku do istniejących sposobów realizacji podobnego efektu.

Podsumowanie

Zmiany w Bitcoinie obejmujące Taproot przede wszystkim zwiększą prywatność transakcji Bitcoin, choć są to także optymalizacje wydajności (wykorzystania pamięci) blockchaina Bitcoin. Język skryptowy Tapscript i możliwości tworzenia alternatywnych warunków wydawania Bitcoinów bez potrzeby ich jawnej publikacji, to furtka do nowych scenariuszy zabezpieczania Bitcoinów i regulacji sposobów ich wykorzystania z zachowaniem prywatności.

Z aktualizacji skorzysta też Lightning Network, czyli technologia mikropłatności, tzw. druga warstwa Bitcoina. Podpisy Schnorra umożliwią docelowo tworzenie transakcji będących otwarciem kanałów, które będą nie do odróżnienia od standardowych transakcji.

Wprowadzenie do protokołu mechanizmów MAST, podpisów Schnorra to też potencjalne możliwości wykorzystania ciekawych właściwości tych mechanizmów w przyszłości (np. w opisanym wyżej CISA).