BitCoinem interesowałem się kilka lat temu i pewnie przekręcę trochę (albo nawet i dużo), ale myślę, że ogólną ideę uda mi się przekazać.
Blockchain to po polsku łańcuch bloków. Każdy blok wskazuje na poprzedni tak samo jak każdy commit w Gicie ma wskaźniki na parent commity (tyle, że w przypadku Gita może być więcej niż jeden parent commit, a w przypadku BitCoina nie ma takich kombinacji). Blok zawiera też adres pod który wpada nagroda za wykopanie bloku.
Ogólnie blok składa się z:
- referencji do poprzedniego bloku (hash),
- nonce (losowa liczba),
- adres na który wpada nagroda za wykopanie bloku,
- transakcje itp itd
Żeby wykopać blok trzeba znaleźć nonce, który spełnia wymagania podane przez sieć. Konkretniej:
- funkcja hashuj(hash_poprzedniego_bloku, nonce, hash_obecnego_bloku_bez_nonce) zwraca liczbę z pewnego zakresu (np 32-bitową)
- sieć (tzn uczestnicy) wyznacza trudność, czyli liczbę należącą do przedziału [0, maksymalny_hash] (na wykresach podana jest odwrotność tej liczby)
- aby wykopać blok trzeba znaleźć taki nonce, by funkcja hashuj dała w wyniku liczbę mniejszą niż zadana trudność
Funkcja hashuj jest szybka, więc można szybko zweryfikować czy ktoś rzeczywiście wyliczył poprawną wartość. Z drugiej strony znalezienie nonce, dla którego wartość funkcji hashuj jest poniżej wartości trudności (czyli będzie dowodem wykopania bloku) może być bardzo trudne. Załóżmy, że funkcja hashuj zwraca liczbę między 1, a milion, a trudność wynosi 100. Prawdopodobieństwo, że przypadkowy nonce będzie dowodem na wykopanie bloku wynosi 100:miliona, czyli 1:10 tysięcy. Trzeba sprawdzić średnio 10 tysięcy nonce (pewnie nagiąłem tutaj prawa statystyki, ale niezbyt mocno), by w końcu trafić na ten właściwy, a innym wystarczy policzenie hasha raz by zweryfikować czy znaleźliśmy poprawną wartość.
Kopanie BitCoinów jest podobne do łamania haseł czy kluczy prywatnych - tam też trzeba znaleźć takie współczynniki dla funkcji by osiągnąć wynik spełniający określone wymagania. Dla przykładu łamanie RSA polega na rozkładzie iloczynu na czynniki pierwsze - te czynniki pierwsze są zwykle bardzo duże, więc trzeba ogromnej ilości prób by je znaleźć. Jednak jeśli już je znajdziemy to wyliczenie iloczynu jest proste i szybkie. Innym przykładem może być odzyskiwanie haseł z hashy. Hash jest funkcją stratną, więc wystarczy znaleźć taki ciąg znaków, by jego hash pokrywał się z zadanym - nie musi być identyczny jak oryginał. Szukanie takiego ciągu znaków też jednak wymaga wielu prób, więc łamanie zahasowanych haseł jest trudne. Weryfikacja jest prosta i szybka, bo liczenie hasha zwykle jest tak skonstruowane że jest szybkie (nikt chyba nie chce długo czekać, aż system policzy niepotrzebnie skomplikowanego hasha i dopiero wtedy uwierzytelni użytkownika).