Skip to main content

Proof of Work (dowód pracy) to algorytm zapewniający spójność oraz bezpieczeństwo w zdecentralizowanych sieciach Blockchain. PoW rozwiązuje fundamentalny problem konsensusu pomiędzy niezależnymi węzłami w systemach rozproszonych.

Problem konsensusu nie jest nowy i od lat 70 opracowano różne algorytmy (np. Paxos, Raft) działające w tradycyjnych systemach rozproszonych. W 2009 roku wraz z upublicznieniem pierwszej zdecentralizowanej kryptowaluty Bitcoin opartej o blockchain, algorytm dowodu pracy (ang. Proof of Work) został szerzej rozpowszechniony. Następne lata udowodniły, że PoW skutecznie zabezpiecza działanie otwartej sieci blockchain. Dzisiaj obok metody Proof of Stake, jest najpopularniejszym mechanizmem konsensusu wykorzystywanym w kryptowalutach.

Co to jest konsensus

W tradycyjnych walutach wirtualnych (np. PLN) bezpieczeństwem transakcji zajmuje się scentralizowana jednostka pośrednicząca, której ufają obie strony transakcji (np. bank). Zaufana jednostka utrzymuje globalny rejestr aktualnego stanu wszystkich rachunków swoich klientów. Przykładowo, jeśli Ania robi przelew o wartości 10 PLN do Andrzeja, to bank odejmuje 10 PLN z rachunku Ani i dodaje analogiczną kwotę do rachunku Andrzeja. Jeśli Ania nie posiada środków na swoim koncie, to transakcja jest odrzucona.

źródło: blockgeeks.com

W kryptowalutach opartych o sieć blockchain nie istnieje zaufany pośrednik posiadający scentralizowaną bazę wszystkich rachunków oraz transakcji. Sama idea zdecentralizowanej sieci przeczy takiemu rozwiązaniu. Brak zaufanego pośrednika rodzi problemy wiarygodności przy zawieraniu transakcji bezpośrednio pomiędzy stronami. Raz zawarta transakcja nie powinna być nigdy zmieniona, a środki wydane powinny pochodzić z rachunku który nimi dysponuje.

Rozproszony konsensus

W sieci blockchain rejestr transakcji przechowywany jest przez wszystkie węzły podłączone do sieci. Ale jak sprawić, aby wszystkie węzły miały aktualne dane? Jeśli dopuścimy do braku spójności danych pomiędzy węzłami, możemy narazić się na sytuację w której ktoś będzie próbował wydać swoje bitcoiny dwa razy (albo i więcej jeśli jest chytry – double-spending problem).

Odpowiedzią na ten problem jest tzw. mining (pl. górnictwo). Prawdziwym celem miningu nie jest zarabianie na wydobywaniu kryptowaluty, ale walidacja transakcji i wymuszenie synchronizacji danych pomiędzy węzłami. Proces miningu grupuje oczekujące na potwierdzenie transakcje w bloki. Blok następnie jest walidowany przez innych górników i dołączony do blockchainu – tym samym potwierdzając zawarte w nim transakcje. Prawidłowa decyzja (walidacja bloku) powinna zostać podjęta nawet, gdy w jej udziale uczestniczą nieuczciwe węzły lub część z nich przestała działać.

W sieci bitcoin nowy blok zostaje “wykopany” średnio co 10 minut przez losowego górnika. Następnie omówimy jak to możliwe, że górnicy nie mogą tworzyć nowych bloków kiedy im się to podoba zgarniając nagrody i destabilizując sieć.

Algorytm

Proof of Work opiera się na prostym mechanizmie, gdzie jedna strona udowania drugiej, że wykonała odpowiednią ilość pracy w określonym celu. Wynik pracy powinien być łatwy do weryfikacji, ale kosztowny do wyliczenia. To koszt pracy, którą należy wykonać w celu dostarczenia rozwiązania powinien sprawić, że nadużycia będą niemożliwe lub bardzo kosztowne.

Omawiając implementację algorytmu Proof of Work w praktyce wybierzemy Bitcoina. Mining polega na podwójnym wygenerowaniu hasha kryptograficzną funkcją skrótu SHA-256. Funkcja zwraca liczbę o długości 256 bajtów zakodowaną w notacji szesnastkowej.

Obliczenie dowolnego hasha nie jest problemem. Problemem jest obliczenie takiego hasha, który będzie spełniał konkretne wymagania. W przypadku bitcoina, hash powinien być mniejszy od zadanej liczby celu (upraszczając – musi zaczynać się od określonej ilości cyfr 0). Górnik który pierwszy wygeneruje hash spełniający aktualne wymagania sieci, ma możliwość dołączenia swojego nowego bloku do blockchaina (hash staje się identyfikatorem bloku) za co wynagradzany zostaje kryptowalutą Bitcoin. Pomiędzy górnikami wywiązuje się rywalizacja, kto pierwszy dostarczy prawidłowe rozwiązanie i będzie miał prawo do nagrody. Szansa na obliczenie pasującego hasha przez konkretnego górnika jest bardzo mała, zapewaniając element losowości.

Generowanie hasha następuje na podstawie nagłówka nowo-tworzonego bloku:
SHA256(Version + Previous block hash + Merkle root + Time + Bits + Nonce)
Nazwa polaOpis
VersionWersja protokołu używanego przez klienta Bitcoin.
Previous block hashHash poprzedniego bloku.
Merkle rootTransakcje w bloku przechowywane są w formie drzewa Merkle. Pole przechowuje korzeń drzewa.
TimeTimestamp utworzenia bloku. Liczba sekund od 1970-01-01T00:00 UTC
BitsAktualna wartość celu (target value) do spełnienia przez hash.
NonceZnaleziona liczba w procesie miningu. Dowód wykonanej pracy.
Pola tworzące nagłówek bloku w sieci Bitcoin

Nonce to zagadka którą należy rozwiązać, aby finalny hash spełnił kryterium celu. Nonce to liczba, która jest odnajdywana przez górnika w wyniku przeprowadzenia ogromnej liczby operacji hashowania.

Zrobimy teraz ręczną walidację istniejącego bloku o numerze 676060 i sprawdzimy, czy wygenerowany hash jest mniejszy, niż zdefiniowana wartość celu (target value). Tym samym ręcznie potwierdzimy poprawność hasha bloku.

źródło: blockchain.com

Hash bloku 000000000000000000096a64cf8b815041bb0efadc7a785cd5d8925a49ba0efd powinien spełniać kryterium celu z pola Bits 386,719,599. Górnik za znalezienie Nonce spełniającego założenie hasha został nagrodzony bitcoinami o wartości 6.25BTC (plus prowizja od transakcji).

Następnie przejdziemy do poprawnej interpretacji tych wartości, ponieważ Hash jak i Target value (pole Bits) są wartościami zakodowanymi, których nie możemy łatwo interpretować w podanej formie.

Za pomocą kalkulatora konwertujemy hash z formatu szesnastkowego do dziesiętnego:

Hash (hex): 000000000000000000096a64cf8b815041bb0efadc7a785cd5d8925a49ba0efd
Hash (dec): 901835385203564892682937710280032399122927602378608381

Pole Bits przechowujące skompresowaną wartość target value konwertujemy do postaci szesnastkowej (blockchain.com wyświetla format dziesiętny):

Target value (dec): 386719599
Target value (hex): 170CDF6F

Otrzymana liczba wciąż zapisana jest w skompresowanym formacie wykładnik / współczynnik, gdzie pierwsze dwie cyfry 0x17 to wykładnik, a pozostałe sześć 0x0CDF6F to współczynnik.

Finalnie wartość celu przedstawimy jako 256 bitowa liczbę wyliczoną według wzoru:

target = współczynnik * 2^(8 * (wykładnik – 3))
target (hex) = 0x0CDF6F * 0x02^(0x08 * (0x17 - 0x03))
target (hex) = 0x0CDF6F * 0x02^(0x08 * 0x14)
target (hex) = 0x0CDF6F * 0x02^0xA0
target (dec) = 843631 * 2^160
target (dec) = 1.232968088 × 10^54
target (dec) = 1232968087803106959787092839109270560155354027163385856
target (hex) = CDF6F0000000000000000000000000000000000000000 (180 bit)
target (hex) = 0000000000000000000CDF6F0000000000000000000000000000000000000000 (256 bit)

Po przeprowadzeniu prostych operacji na dużych liczbach, możemy finalnie zweryfikować, czy hash bloku jest mniejszy od wyliczonej wartości celu.

System dziesiętny Hash (dec) < Target value (dec):

901835385203564892682937710280032399122927602378608381 < 1232968087803106959787092839109270560155354027163385856

System szesnastkowy: Hash (hex) < Target value (hex):

000000000000000000096A64CF8B815041BB0EFADC7A785CD5D8925A49BA0EFD < 0000000000000000000CDF6F0000000000000000000000000000000000000000

Nasze obliczenia potwierdziły fakt, że hash bloku 676060 spełnia wymagania wartości celu. W tym artykule pominiemy walidację samego hasha, czy został on stworzony na podstawie odpowiednich pól:

SHA256(Version + Previous block hash + Merkle root + Time + Bits + Nonce)

Analogiczną walidację (oraz kilka innych) przeprowadzają wszystkie węzły podłączone do sieci Bitcoin, które przechowują własną kopię blockchain i dbają o jej poprawność.

Koszt energetyczny

Początkowo w sieci Bitcoin do obliczeń PoW wykorzystywane były zwykłe procesory (CPU). Wraz ze wzrostem ilości górników biorących udział w miningu, rosła trudność obliczania dowodu pracy. Niezależnie od możliwości obliczania hashy przez górników, nowy blok w sieci bitcoin powinien być generowany co około 10 minut. Gdy bloki generowane są szybciej wtedy kryterium celu zostaje odpowiednio zmniejszone, aby wydłużyć obliczenia pasującej wartości Nonce. Jeśli bloki generowane są wolniej niż co 10 minut, wtedy kryterium jest zwiększone i zmienna Nonce zostaje znaleziona szybciej.

Procesory CPU zostały zastąpione przez szybsze karty graficzne (GPU). Z czasem układy GPU stały się zbyt wolne i zostały zastąpione przez wyspecjalizowane układy scalone (ang. ASIC) stworzone wyłącznie do obliczania hashy. Ciekawostką jest, że energia wykorzystywana do obliczeń PoW w sieci Bitcoin przewyższa konsumpcję energii elektrycznej niektórych Państw!

Źródło: Cambridge Bitcoin Electricity Consumption Index

Według danych University of Cambridge za rok 2019 sieć Bitcoin zużywała rocznie 143 TWh. Przypuszczamy, że na fali ostatnich wzrostów popularności tej kryptowaluty, algorytm PoW zużywa aktualnie więcej energii elektrycznej niż Polska!

Odpowiedzią na wysokie koszty funkcjonowania algorytmów Proof of Work jest wprowadzenie zupełnie nowej grupy algorytmów Proof of Stake, a także Proof of Space.