White Paper Bitcoina po polsku. Manifest Satoshi Nakamoto

Manifest Satoshi Nakamoto – twórcy Bitcoina znajduje się pod tym adresem (w języku angielskim): https://bitcoin.org/bitcoin.pdf

Poniżej zamieszczono tłuczenie tego tekstu w języku polskim:


Bitcoin: System elektronicznej gotówki oparty na sieci peer-to-peer

Satoshi Nakamoto
[email protected]
www.bitcoin.org

Streszczenie: Czysto równorzędna wersja elektronicznej gotówki umożliwiłaby przesyłanie płatności online bezpośrednio od jednej strony do drugiej, bez udziału instytucji finansowej. Sygnatury cyfrowe stanowią część rozwiązania, ale główne korzyści są utracone, jeśli wciąż wymagane jest zaufanie do trzeciej strony, by zapobiec podwójnym wydatkom. Proponujemy rozwiązanie problemu podwójnych wydatków za pomocą sieci równorzędnej. Sieć stempluje czasowe transakcje, haszując je w ciąg hashowy oparty na dowodzie pracy, tworząc zapis, który nie może być zmieniony bez powtórzenia dowodu pracy. Najdłuższy łańcuch nie tylko stanowi dowód na kolejność zdarzeń, ale też dowód na to, że pochodzi z największej puli mocy CPU. O ile większość mocy CPU jest kontrolowana przez węzły, które nie współpracują ze sobą, by zaatakować sieć, wygenerują one najdłuższy łańcuch i wyprzedzą atakujących. Sieć sama w sobie wymaga minimalnej struktury. Komunikaty są rozsyłane najlepszym wysiłkiem, a węzły mogą opuszczać i dołączać do sieci wedle uznania, akceptując najdłuższy łańcuch dowodu pracy jako dowód na to, co działo się podczas ich nieobecności.

1. Wprowadzenie

Handel w Internecie prawie całkowicie polega na instytucjach finansowych pełniących rolę zaufanych stron trzecich w procesie przetwarzania płatności elektronicznych. Choć system działa wystarczająco dobrze dla większości transakcji, wciąż cierpi na inherentne słabości modelu opartego na zaufaniu. Transakcje całkowicie nieodwracalne nie są naprawdę możliwe, ponieważ instytucje finansowe nie mogą uniknąć mediacji w przypadku sporów. Koszt mediacji zwiększa koszty transakcyjne, ograniczając minimalną praktyczną wielkość transakcji i odcinając możliwość dokonywania małych nieformalnych transakcji. Istnieje również szerszy koszt w postaci utraty zdolności do dokonywania płatności nieodwracalnych za nieodwracalne usługi. Z możliwością odwrócenia transakcji, potrzeba zaufania się szerzy. Handlowcy muszą uważać na swoich klientów, dokuczać im o informacje, których w przeciwnym razie nie potrzebowaliby. Pewien procent oszustw jest akceptowany jako nieunikniony. Te koszty i niepewności płatnicze można uniknąć osobiście, korzystając z fizycznej waluty, ale nie istnieje mechanizm umożliwiający dokonywanie płatności za pośrednictwem kanału komunikacyjnego bez zaufanej strony trzeciej.

Potrzebny jest system płatności elektronicznych oparty na dowodach kryptograficznych, a nie zaufaniu, pozwalający dwóm chętnym stronom dokonywać transakcji bez potrzeby zaufanej strony trzeciej. Transakcje, które są obliczeniowo niemożliwe do odwrócenia, chronią sprzedawców przed oszustwami, a rutynowe mechanizmy depozytowe mogą łatwo być wprowadzone, aby chronić kupujących. W niniejszej pracy proponujemy rozwiązanie problemu podwójnego wydawania pieniędzy, korzystając z rozproszonego serwera znaczników czasowych peer-to-peer do generowania obliczeniowego dowodu chronologicznego porządku transakcji. System jest bezpieczny, o ile uczciwe węzły kontrolują wspólnie więcej mocy obliczeniowej niż jakakolwiek grupa atakujących węzłów.

2. Transakcje

Definiujemy elektroniczną monetę jako łańcuch cyfrowych podpisów. Każdy właściciel przekazuje monetę dalej, podpisując cyfrowo skrót poprzedniej transakcji i klucz publiczny kolejnego właściciela, i dodając je na końcu monety. Odbiorca może zweryfikować podpisy, aby zweryfikować łańcuch posiadania.

Oczywiście problem polega na tym, że odbiorca nie może zweryfikować, czy któryś z właścicieli nie podwoił wydatkować monety. Powszechnym rozwiązaniem jest wprowadzenie zaufanego organu centralnego, czyli mennicy, który sprawdza każdą transakcję pod kątem podwójnego wydatkowania. Po każdej transakcji moneta musi zostać zwrócona do mennicy, aby wydać nową monetę, a tylko monety wydane bezpośrednio przez mennicę są uznawane za wiarygodne, że nie zostały podwójnie wydane. Problem z tym rozwiązaniem polega na tym, że los całego systemu pieniężnego zależy od firmy prowadzącej mennicę, a każda transakcja musi przez nią przejść, tak jak w przypadku banku. Potrzebujemy sposobu, aby odbiorca wiedział, że poprzedni właściciele nie podpisali żadnych wcześniejszych transakcji. Dla naszych celów, najwcześniejsza transakcja jest tą, która się liczy, więc nie obchodzi nas późniejsze próby podwójnego wydawania. Jedynym sposobem potwierdzenia braku transakcji jest świadomość wszystkich transakcji. W modelu opartym na mennicy, mennica była świadoma wszystkich transakcji i decydowała, która dotarła pierwsza. Aby osiągnąć to bez zaufanej strony, transakcje muszą być publicznie ogłaszane [1], a potrzebujemy systemu, który pozwoli uczestnikom na uzgodnienie jednej historii kolejności, w jakiej zostały odebrane. Odbiorca potrzebuje dowodu, że w momencie każdej transakcji większość węzłów uznała ją za pierwszą otrzymaną.

3. Serwer czasu

Proponowane przez nas rozwiązanie zaczyna się od serwera czasu. Serwer czasu działa poprzez wygenerowanie skrótu (hash) bloku elementów, które mają zostać oznaczone znacznikiem czasowym, a następnie szeroko publikuje ten skrót, np. w gazecie lub na grupie dyskusyjnej Usenet [2-5]. Znacznik czasowy udowadnia, że dane musiały istnieć w momencie wygenerowania skrótu, aby móc zostać do niego dołączone. Każdy znacznik czasowy zawiera skrót poprzedniego znacznika czasowego, tworząc łańcuch, gdzie każdy kolejny znacznik czasowy wzmacnia poprzednie.

4. Dowód wykonanej pracy

Aby zaimplementować rozproszony serwer znaczników czasowych w oparciu o sieć peer-to-peer, będziemy musieli użyć systemu proof-of-work podobnego do Hashcash Adama Backa [6], zamiast postów w gazetach lub Usenet. Proof-of-work polega na skanowaniu wartości, która po zahashowaniu, na przykład za pomocą SHA-256, zaczyna się od określonej liczby zer. Średni wysiłek wymagany do wykonania zadania jest wykładniczy w liczbie zer wymaganych do wygenerowania hasha, a można go zweryfikować wykonując pojedyncze hashowanie.

Dla naszej sieci znaczników czasowych, implementujemy proof-of-work poprzez inkrementację nonce w bloku, aż zostanie znaleziona wartość, która zapewni hasz bloku wymaganą liczbę zer. Gdy już wykorzystano wysiłek procesora, aby spełnić wymagania proof-of-work, bloku nie można zmienić bez ponownego wykonania pracy. W miarę łańcuchowego dodawania kolejnych bloków, zmiana jednego bloku wymagałaby ponownego wykonania pracy dla wszystkich bloków po nim.

Rozwiązanie oparte na dowodzie pracy rozwiązuje także problem ustalania reprezentacji w podejmowaniu decyzji większościowych. Gdyby większość opierała się na zasadzie jeden-adres-IP-jeden-głos, mogłaby zostać podważona przez osoby dysponujące wieloma adresami IP. Dowód pracy jest w zasadzie jedno-CPU-jeden-głos. Decyzja większości jest reprezentowana przez łańcuch o największym nakładzie pracy w postaci dowodu pracy. Jeśli większość mocy CPU jest kontrolowana przez uczciwe węzły, to uczciwy łańcuch będzie rósł najszybciej i przewyższy każde konkurujące łańcuchy. Aby zmodyfikować blok z przeszłości, atakujący musiałby powtórzyć dowód pracy bloku i wszystkich bloków po nim, a następnie dogonić i przewyższyć nakład pracy uczciwych węzłów. Później pokażemy, że prawdopodobieństwo, że wolniejszy atakujący dogoni resztę, maleje wykładniczo wraz z dodawaniem kolejnych bloków. Aby zrekompensować rosnącą prędkość sprzętu i zmienny zainteresowanie uruchamianiem węzłów w czasie, trudność dowodu pracy jest ustalana na podstawie ruchomej średniej, która dąży do uzyskania określonej liczby bloków na godzinę. Jeśli są generowane zbyt szybko, trudność wzrasta.

5. Sieć

Kroki do uruchomienia sieci są następujące:

  1. Nowe transakcje są rozsyłane do wszystkich węzłów.
  2. Każdy węzeł zbiera nowe transakcje do bloku.
  3. Każdy węzeł pracuje nad znalezieniem trudnego dowodu pracy dla swojego bloku.
  4. Gdy węzeł znajdzie dowód pracy, rozsyła blok do wszystkich węzłów.
  5. Węzły akceptują blok tylko wtedy, gdy wszystkie transakcje w nim są ważne i nie zostały już wykorzystane.

Węzły wyrażają swoje akceptowanie bloku, pracując nad stworzeniem kolejnego bloku w łańcuchu, używając hasha akceptowanego bloku jako poprzedniego hasha. Węzły zawsze uważają, że najdłuższy łańcuch jest poprawnym i będą dalej pracować nad jego rozszerzeniem. Jeśli dwa węzły równocześnie rozsyłają różne wersje kolejnego bloku, niektóre węzły mogą otrzymać jedną z nich pierwsze. W takim przypadku pracują nad pierwszą, którą otrzymali, ale zachowują drugą gałąź na wypadek, gdyby stała się dłuższa. Kryterium rozstrzygnięcia to znalezienie kolejnego dowodu pracy i gdy jedna gałąź staje się dłuższa; węzły, które pracowały nad inną gałęzią, przełączą się na dłuższą. Nowe transakcje nie muszą docierać do wszystkich węzłów. Jeśli docierają do wielu węzłów, to niedługo znajdą się w bloku. Rozsyłanie bloków jest również odporne na utracone wiadomości. Jeśli węzeł nie otrzyma bloku, poprosi o niego, gdy otrzyma następny blok i zorientuje się, że go nie otrzymał.

6. Motywacja

Zgodnie z konwencją, pierwsza transakcja w bloku to specjalna transakcja, która rozpoczyna nową monetę, należącą do twórcy bloku. To dodaje motywację dla węzłów do wspierania sieci i zapewnia sposób na początkowe rozprowadzenie monet w obiegu, ponieważ nie ma centralnej władzy, która by je wydawała. Stałe dodawanie określonej ilości nowych monet jest analogiczne do wydobywania złota, gdzie wydajemy zasoby, aby dodać złoto do obiegu. W naszym przypadku wydajemy czas procesora i elektryczność.

Motywacja może być również finansowana z opłat transakcyjnych. Jeśli wartość wyjściowa transakcji jest mniejsza niż jej wartość wejściowa, różnica stanowi opłatę transakcyjną, która jest dodawana do wartości motywacyjnej bloku zawierającego transakcję. Po osiągnięciu ustalonej liczby monet w obiegu, motywacja może przechodzić całkowicie na opłaty transakcyjne i być całkowicie wolna od inflacji.

Motywacja może pomóc zachęcić węzły do pozostania uczciwymi. Jeśli chciwy atakujący jest w stanie zbudować więcej mocy procesora niż wszyscy uczciwi węzły razem wzięte, musiałby wybierać między oszustwem poprzez kradzież swoich płatności, a wykorzystaniem mocy procesora do generowania nowych monet. Powinien stwierdzić, że bardziej opłacalne jest gra według zasad, które dają mu więcej nowych monet niż wszystkim innym razem wziętym, niż podważanie systemu i ważności swojego własnego bogactwa.

7. Odzyskiwanie przestrzeni dyskowej

Kiedy ostatnia transakcja w monetę zostanie pogrzebana pod wystarczającą ilością bloków, wydane transakcje przed nią mogą być odrzucane, aby zaoszczędzić miejsce na dysku. Aby ułatwić to bez naruszania hasha bloku, transakcje są hashowane w drzewie Merkle’a [7] [2] [5], z tylko korzeniem uwzględnionym w haśle bloku. Stare bloki mogą być skompresowane poprzez odcięcie gałęzi drzewa. Wewnętrzne hashe nie muszą być przechowywane.

Nagłówek bloku bez transakcji miałby około 80 bajtów. Jeśli założymy, że bloki są generowane co 10 minut, to 80 bajtów * 6 * 24 * 365 = 4,2 MB na rok. Z uwzględnieniem tego, że systemy komputerowe zwykle sprzedawane są z 2 GB pamięci RAM na rok 2008, a prawo Moore’a przewiduje wzrost o 1,2 GB rocznie, przechowywanie nagłówków bloków w pamięci nie powinno stanowić problemu.

8. Uproszczona weryfikacja płatności

Możliwe jest weryfikowanie płatności bez uruchamiania pełnego węzła sieciowego. Użytkownik potrzebuje tylko kopii nagłówków bloków z najdłuższym łańcuchem dowodów pracy, którą może uzyskać, zapytując węzłów sieciowych, aż będzie przekonany, że ma najdłuższy łańcuch, oraz uzyskać odnośnik Merkle łączący transakcję z blokiem, w którym jest czasowo oznaczona. Nie może sprawdzić transakcji samodzielnie, ale przez jej powiązanie z miejscem w łańcuchu, może zobaczyć, że węzeł sieciowy ją zaakceptował, a bloki dodane po niej dalsze potwierdzają, że sieć ją zaakceptowała.

W ten sposób weryfikacja jest wiarygodna, o ile uczciwe węzły kontrolują sieć, ale jest bardziej podatna na ataki, jeśli sieć jest zdominowana przez atakującego. Podczas gdy węzły sieci mogą zweryfikować transakcje dla siebie, uproszczona metoda może być oszukana przez sfabrykowane transakcje atakującego, tak długo jak atakujący będzie w stanie dominować sieć. Jedną z strategii ochrony przed tym byłoby akceptowanie alertów od węzłów sieci, gdy wykryją one nieprawidłowy blok, co skłoniłoby oprogramowanie użytkownika do pobrania całego bloku i podejrzanych transakcji w celu potwierdzenia nieścisłości. Firmy, które otrzymują częste płatności, prawdopodobnie wciąż będą chciały uruchamiać swoje własne węzły dla bardziej niezależnego zabezpieczenia i szybszej weryfikacji.

9. Łączenie i podział wartości

Choć możliwe byłoby indywidualne zarządzanie każdą monetą, byłoby to niewygodne, aby dokonać osobnej transakcji dla każdego centa w przekazie. Aby umożliwić podział i łączenie wartości, transakcje zawierają wiele wejść i wyjść. Zazwyczaj będzie tam pojedyncze wejście z większej poprzedniej transakcji lub wiele wejść łączących mniejsze kwoty i co najwyżej dwa wyjścia: jedno dla płatności i jedno zwracające resztę, jeśli istnieje, do nadawcy.

Należy zauważyć, że rozgałęzienie, gdzie transakcja zależy od kilku innych transakcji, a te z kolei od wielu innych, nie jest tutaj problemem. Nigdy nie ma potrzeby wyciągania całkowicie samodzielnej kopii historii transakcji.

10. Prywatność

Tradycyjny model bankowości osiąga poziom prywatności poprzez ograniczenie dostępu do informacji tylko dla stron zaangażowanych oraz zaufanej trzeciej strony. Konieczność publicznego ogłaszania wszystkich transakcji uniemożliwia stosowanie tego sposobu, ale prywatność może być nadal zachowana przez zerwanie przepływu informacji w innym miejscu: przez zachowanie anonimowości kluczy publicznych. Publiczność może zobaczyć, że ktoś przesyła pewną kwotę komuś innemu, ale bez informacji łączącej transakcję z konkretnymi osobami. Jest to podobne do poziomu informacji ujawnianych przez giełdy papierów wartościowych, gdzie czas i wielkość poszczególnych transakcji, „taśma”, są publikowane, ale bez ujawnienia tożsamości stron.

Jako dodatkowe zabezpieczenie, dla każdej transakcji powinna być użyta nowa para kluczy, aby uniknąć powiązania ich z jednym właścicielem. W przypadku transakcji wielo-wejściowych, jakieś powiązania są nadal nieuniknione, ponieważ ujawniają one, że ich wejścia należały do tego samego właściciela. Ryzyko polega na tym, że jeśli właściciel klucza zostanie ujawniony, to powiązania te mogą ujawnić inne transakcje, które należały do tego samego właściciela.

11. Obliczenia

Rozważamy scenariusz, w którym atakujący próbuje wygenerować alternatywny łańcuch szybciej niż uczciwy łańcuch. Nawet jeśli mu się to uda, nie oznacza to, że system staje się podatny na dowolne zmiany, takie jak tworzenie wartości z powietrza lub zabieranie pieniędzy, które nigdy nie należały do atakującego. Węzły nie będą akceptować nieprawidłowej transakcji jako płatności, a uczciwe węzły nigdy nie zaakceptują bloku zawierającego takie transakcje. Atakujący może jedynie spróbować zmienić jedną ze swoich transakcji, aby odzyskać pieniądze, które niedawno wydał. Wyścig między uczciwym łańcuchem a łańcuchem atakującego można opisać jako losowy ruch binomowy. Wydarzeniem sukcesu jest przedłużenie uczciwego łańcucha o jeden blok, zwiększając jego przewagę o +1, a wydarzeniem porażki jest przedłużenie łańcucha atakującego o jeden blok, zmniejszając różnicę o -1. Prawdopodobieństwo, że atakujący dogoni uczciwy łańcuch z określonej pozycji, jest analogiczne do problemu Ruiny Gracza. Załóżmy, że gracz z nieograniczonym kredytem zaczyna od deficytu i gra potencjalnie nieskończoną liczbę razy, aby spróbować osiągnąć równowagę. Możemy obliczyć prawdopodobieństwo, że kiedykolwiek osiągnie równowagę, lub że atakujący dogoni uczciwy łańcuch, następująco [8]: p = prawdopodobieństwo, że uczciwy węzeł znajdzie następny blok q = prawdopodobieństwo, że atakujący znajdzie następny blok qz = prawdopodobieństwo, że atakujący kiedykolwiek dogoni uczciwy łańcuch będąc z tyłu o z bloków.

Zakładając, że p > q, prawdopodobieństwo maleje wykładniczo w miarę zwiększania liczby bloków, które musi dogonić atakujący. Z szansami przeciwko niemu, jeśli nie dokona szczęśliwego skoku naprzód na początku, jego szanse stają się zanikająco małe, gdy oddala się coraz bardziej. Teraz rozważymy, jak długo odbiorca nowej transakcji musi czekać, zanim będzie dostatecznie pewny, że nadawca nie może zmienić transakcji. Zakładamy, że nadawcą jest atakujący, który chce sprawić, żeby odbiorca uwierzył, że zapłacił mu przez pewien czas, a następnie zmieni to, aby zapłacić sobie. Odbiorca zostanie ostrzeżony, gdy to się stanie, ale nadawca liczy, że będzie już za późno. Odbiorca generuje nową parę kluczy i przekazuje klucz publiczny nadawcy krótko przed podpisaniem. Uniemożliwia to nadawcy przygotowanie łańcucha bloków z wyprzedzeniem poprzez pracę nad nim ciągle, aż będzie miał wystarczającą przewagę, a następnie wykonanie transakcji w tym momencie. Po wysłaniu transakcji nieuczciwy nadawca zaczyna pracować w tajemnicy nad równoległym łańcuchem zawierającym alternatywną wersję swojej transakcji. Odbiorca czeka, aż transakcja zostanie dodana do bloku, a po niej zostanie powiązanych z nią z blokami z innych transakcji kolejno z blokiem z numerem z+1, z+2 itd. Nie zna dokładnej ilości postępu, jaki zrobił atakujący, ale zakładając, że uczciwe bloki zajmowały średni spodziewany czas na blok, potencjalny postęp atakującego będzie miał rozkład Poissona z wartością oczekiwaną:

Aby uzyskać prawdopodobieństwo, że atakujący nadal może nadrobić stratę, mnożymy gęstość Poissona dla każdego możliwego postępu, jaki mógł zrobić, przez prawdopodobieństwo, że mógłby nadrobić stratę od tego punktu:

Przeformułowując, aby uniknąć sumowania nieskończonego końca rozkładu, otrzymujemy:

Konwersja na kod w języku C…

#include <math.h>
double AttackerSuccessProbability(double q, int z)
{
 double p = 1.0 - q;
 double lambda = z * (q / p);
 double sum = 1.0;
 int i, k;
 for (k = 0; k <= z; k++)
 {
 double poisson = exp(-lambda);
 for (i = 1; i <= k; i++)
 poisson *= lambda / i;
 sum -= poisson * (1 - pow(q / p, z - k));
 }
 return sum;
}

Uruchamiając obliczenia, można zauważyć, że prawdopodobieństwo spada wykładniczo wraz z z.

q=0.1
z=0 P=1.0000000
z=1 P=0.2045873
z=2 P=0.0509779
z=3 P=0.0131722
z=4 P=0.0034552
z=5 P=0.0009137
z=6 P=0.0002428
z=7 P=0.0000647
z=8 P=0.0000173
z=9 P=0.0000046
z=10 P=0.0000012

q=0.3
z=0 P=1.0000000
z=5 P=0.1773523
z=10 P=0.0416605
z=15 P=0.0101008
z=20 P=0.0024804
z=25 P=0.0006132
z=30 P=0.0001522
z=35 P=0.0000379
z=40 P=0.0000095
z=45 P=0.0000024
z=50 P=0.0000006

Rozwiązując dla P mniejszego niż 0,1% (0,001), uzyskujemy:

P < 0.001
q=0.10 z=5
q=0.15 z=8
q=0.20 z=11
q=0.25 z=15
q=0.30 z=24
q=0.35 z=41
q=0.40 z=89
q=0.45 z=340

12. Wnioski

Zaproponowaliśmy system transakcji elektronicznych, który nie polega na zaufaniu. Rozpoczęliśmy od standardowego ramienia monet opartych na cyfrowych podpisach, które zapewnia silną kontrolę nad posiadaniem, ale jest niewystarczające bez sposobu zapobiegania podwójnemu wydawaniu. Aby rozwiązać ten problem, zaproponowaliśmy sieć peer-to-peer wykorzystującą proof-of-work do rejestrowania publicznej historii transakcji, która szybko staje się obliczeniowo praktycznie niemożliwa do zmiany dla atakującego, jeśli uczciwe węzły kontrolują większość mocy CPU. Sieć jest wytrzymała dzięki swojej nieustrukturyzowanej prostocie. Węzły pracują jednocześnie, bez dużej koordynacji. Nie muszą być identyfikowane, ponieważ wiadomości nie są przesyłane do określonego miejsca i muszą być dostarczane jedynie w najlepszym możliwym sposobie. Węzły mogą wchodzić i wychodzić z sieci według uznania, akceptując chain proof-of-work jako dowód tego, co się działo podczas ich nieobecności. Głosują za pomocą swojej mocy CPU, wyrażając swoje akceptacje ważnych bloków, pracując nad ich rozszerzaniem i odrzucając niepoprawne bloki, odmawiając pracy na nich. Wszelkie potrzebne zasady i zachęty mogą być egzekwowane za pomocą tego mechanizmu konsensusu.

Comments (No)

Leave a Reply