“FlyClient”: Neues Protokoll für effizientere Light Clients wurde vorgestellt

Ein spannendes Paper mit einem neuen Konzept für deutlich effizientere Light-Clients wurde veröffentlicht und findet in der Kryptographie-Community große Beachtung.

Anfang März veröffentlichte Benedikt Bünz (kein Unbekannter, er war bereits einer der Autoren des Bulletproofs Papers) gemeinsam mit Lucianna Kiffer und zwei weiteren Co-Autoren ein Paper, in dem sie ein neues Protokoll für Light Clients, ähnlich dem SPV-Protokoll (simplified payment verification), vorstellen. Das originale Paper finden Sie hier: https://eprint.iacr.org/2019/226.

Light Clients sind entscheidende Elemente im Blockchain-Ökosystem. Sie ermöglichen BenutzerInnen, mit “normalen” Endgeräten (keine Server oder Hochleistungscomputer) auf sichere und dezentrale Weise auf eine Blockchain zuzugreifen, um mit ihr zu interagieren, ohne die gesamte (viele Gigabyte große) Blockchain synchronisieren und verifizieren zu müssen. Schon im ursprünglichen Bitcoin Paper hat Satoshi Nakamoto die Wichtigkeit von solchen Light Clients hervorgehoben und das SPV-Protokoll in seinen Grundzügen bereits dort beschrieben.

Was ist ein Light Client Protokoll?

Ein Light Client Protokoll ermöglicht es einer neuen Node (ein neuer Teilnehmer, der sich mit dem Peer-to-peer Netz verbindet) zu entscheiden, welche “Version” der Blockchain die gültige ist, ohne dabei die volle Arbeit der Validierung der gesamten Blockchain leisten zu müssen (was bei Bitcoin oder Ethereum mittlerweile mehrere Tage dauern kann).

Light Clients kontrollieren lediglich anhand der Block-Header, welche die Chain mit der meisten geleisteten Work ist – ohne den Inhalt aller Transaktionen überprüfen zu müssen. Bei Blockchains mit Proof-of-work, wozu auch Bitcoin zählt, kann man dann von der Annahme ausgehen, dass die ehrliche Chain, jene mit der meisten geleisteten Gesamt-Work ist.

Wenn also eine Node hypothetisch aus einem „Dornröschen-Schlaf“ erwachen würde und nach dem aktuellen Block-Header fragt, dann steht diese aufwachende Node möglicherweise vor dem Problem, dass ihm mehrere verschiedene Blockchain-Spitzen angeboten werden, von denen aber nur eine die echte und somit gültige Blockchain ist. Wie kann die Node nun feststellen, welche Chain die „ehrliche“ (also die mit der meisten kumulativen Work) ist ohne auf ein zentrales Service Dritter angewiesen zu sein?

In den von Satoshi Nakamoto ursprünglich beschriebenen SPV (simplified payment verification) clients („light clients“) wird dies folgendermaßen gewährleistet: Es werden alle Block-Header heruntergeladen (der Block-Inhalt allerdings nicht) und dabei wird überprüft, ob die Work tatsächlich geleistet wurde (indem einfach der Hash-Wert des Blockheaders nachgerechnet wird und geprüft wird, ob dieser entsprechend den Proof-of-work Anforderungen mit ausreichend vielen Nullen beginnt). Prinzipiell ist das bereits eine ressourcenschonende Herangehensweise.

Die benötigten Ressourcen wachsen aber auch bei SPV im Laufe der Zeit linear mit der Anzahl der Blöcke an, da man für SPV die Header aller Blöcke benötigt (und herunterladen muss), um die Verkettung und die kumulierte PoW zu validieren.

Bei Bitcoin funktioniert das auch bei der aktuellen Größe der Blockchain noch halbwegs gut, aber beispielsweise bei Ethereum mit seiner größeren Anzahl an Blöcken (aktuell bereits über 7,4 Millionen) und seinen zusätzlich auch noch signifikant größeren Blockheadern (ein Ethereum Blockheader ist mindestens 508 Byte groß während ein Bitcoin Blockheader nur 80 Byte umfasst) ergibt bei Ethereum die Summe der Blockheader alleine mittlerweile schon eine Datenmenge von über 3,7 GB, die ein Light Client herunterladen und verarbeiten müsste. Diese Menge wächst linear mit jedem Block. Eine langfristig skalierende Lösung ist das für beide Netzwerke also nicht.

Wenn man mit diesem Hintergrundwissen nun an low-end oder Internet-of-Things (IoT) Devices denkt, merkt man schnell, dass eine solche Größe auf diesen Geräten schon heute nicht mehr wirklich machbar erscheint und man somit erst wieder auf zentrale Services oder ähnliches angewiesen ist.

Im nun veröffentlichten Paper schlagen Bünz et al. ein Protokoll vor, bei dem man nicht mehr alle Block-Header anfordern muss, sondern nur einige, zufällig gewählte (die Anzahl der „Stichproben“ kann noch variiert und so das erreichte Sicherheitslevel des Protokolls justiert werden). Dabei wird aber trotzdem die wichtige Eigenschaft gewährleistet, validieren zu können, ob die Chain die kumulierte Work, die sie zu haben vorgibt, auch wirklich geleistet hat (um nach wie vor die Chain mit der meisten Work identifizieren zu können).

Dies bedeutet, dass sich die Datenmenge die ein Light-Client verarbeiten muss, deutlich verkleinern würde, das heißt IoT Devices oder Regionen in denen mobile Bandbreite immer noch knapp ist, würden wieder die Möglichkeit bekommen, Blockchains sicher, trustless und ohne Mittelsmann direkt verwenden zu können.

Wie funktioniert das vorgeschlagene Protokoll im Detail?

Um das vorgeschlagene Protokoll umzusetzen bräuchte es eine (bei Bitcoin und Ethereum sogar soft-fork-fähige) Änderung in der jeweiligen Blockchain, bei der folgender Punkt verändert werden muss: Es muss ein zusätzliches Feld im Block-Header eingefügt werden (was auf den ersten Blick widersprüchlich erscheinen mag, da dadurch die Blockheader ja nochmals um ein Feld größer werden).

Dieses neue Feld beinhaltet den Root-Hash einer zusätzlichen Merkle-Struktur, nämlich eines sogenannten “Merkle-Mountain-Range” commitment (MMR). Ein MMR ist (ähnlich wie ein Merkle-Tree) eine Datenstruktur, die unabhängig von ihrer Gesamtgröße durch einen einzelnen Root-Hash validiert werden kann. In diesen MMR fügen die Miner nun bei jedem neuen Block den jeweils letzten Block-Hash (und auch die gesamte bisher geleistete Work) ein, sodass der resultierende MMR Root-Hash (der dann in diesem neuen Header-Feld steht) quasi alle bisherigen Block-Header und die geleistete Work beweisbar „festhält“.

Alle Miner prüfen dieses neue Feld und ein Block wird nur dann als gültig akzeptiert, wenn der Ersteller des Blocks die Daten korrekt in diesen MMR eingetragen hat. Der große Vorteil von MMR gegenüber Merkle-Trees ist der, dass das Einfügen von Daten viel effizienter abläuft, da man den „Baum“ nicht jedes Mal neu ausbalancieren und somit ältere Sub-Bäume nicht immer wieder neu berechnen muss.

Ferner kann man, wenn man zwei MMR Root-Hashes hat, beweisen, ob der ältere ein „Sub“-Tree des neueren ist. Diese Eigenschaft kann man nun nutzen um zu beweisen, dass zwischen zwei gegebenen Block-Headern (also zwischen 2 Root-Hashes zweier MMRs), z.B. aus Block #1000 und aus Block #2000, auch tatsächlich 999 andere Blöcke liegen, die auch real gemined wurden. Das bedeutet also, dass man bei Merkle-Mountain-Ranges – anders als bei einem Merkle-Tree, bei dem man nur beweisen kann, dass ein Eintrag (irgendwo) enthalten ist – auch den exakten Abstand (gemessen an Ihrer Einfüge-Position) zwischen zwei Einträgen sowie die Reihenfolge in der sie eingefügt wurden beweisen kann.

Um jetzt nicht nur den Abstand zwischen zwei Block-Headern, sondern auch die geleistete Work validieren zu können, wird im FlyClient Protokoll die MMR Struktur leicht angepasst. Normalerweise funktionieren gewöhnliche Merkle-Trees und MMRs so, dass ein Knoten immer den Hash seiner beiden Kind-Knoten beinhaltet (bis nach oben zum Root-Knoten der dann den Root-Hash beinhaltet). Für FlyClient wird dies nun dahingehend erweitert, dass jeder Knoten auch zusätzlich die Summe der geleisteten Work seiner Kind-Knoten beinhaltet (einfach an den Hash angefügt). Ein Knoten in diesem MMR sieht dann so aus: “Hash(block)|Summe_der_geleisteten_Work_aller_Kindknoten” (das “|” Symbol steht hierbei für Konkatenierung).

Ein “FlyClient” macht zum Validieren nun folgendes: Er holt sich von einer Full-Node zuerst den aktuellen Block der Blockchain und fordert danach stichprobenartig weitere (zufällig gewählte) Block-Header an, die ihm die Full-Node liefert. Der FlyClient kann dann anhand des MMR-Root-Hashes (und den dazugehörigen proofs, also die fehlenden Hashes zum Validieren des Root-Hashes) prüfen, ob der jeweils gelieferte Block-Header tatsächlich unverändert in der Chain vorgekommen ist und ob die in dem Block vorgeblich angeführte, kumulativ geleistete Work auch korrekt ist. Das bedeutet nun: Wenn der Client genügend viele dieser Stichproben an Block-Headern durchführt und bei allen mittels des MMR validieren kann, dass 1.) diese Proben Teil jener Chain waren, die zu dieser Chain-Spitze geführt hat, 2.) auch die geleistete Work in den Headern validiert und 3.) man verifizieren kann, dass die vorgeblichen „Abstände“ zwischen den Blöcken auch richtig sind, kann ein FlyClient mit großer Wahrscheinlichkeit (diese kann durch die Anzahl der Stichproben variieren) sagen, ob die Chain tatsächlich die angegebene Work geleistet hat. Somit können im Vergleich zu SPV Clients enorme Ressourcen gespart werden.

Anmerkung: Die Eigenschaft, dass die „Abstände“ zwischen den Blöcken auch bewiesen werden können, ist wichtig. Denn dadurch kann ein Angreifer, der normalerweise weniger Mining-Leistung als ein ehrlicher Miner hat, nicht einfach einzelne wenige Blöcke gültig minen und daraufhin vorgeben, dass zwischen diesen (tatsächlich erstellten) Blöcken noch tausende andere Blöcke mit ausreichend geleisteter Work liegen. So könnte er einem Client vortäuschen, dass die geleistete Gesamt-Wort seiner Chain deutlich höher ist, als dies real der Fall ist. Aus diesem Grund müssen bei SPV auch ALLE Blockheader heruntergeladen und verifiziert werden. Im FlyClient Protokoll vereitelt die Verwendung von MMRs diese Art von Angriff.

Nochmals die Genialität dieses Protokolls in zwei Sätzen zusammengefasst: Ein FlyClient muss nur eine begrenzte Anzahl an Block-Headern überprüfen (deutlich, deutlich weniger als bisherige SPV Clients!) und kann trotzdem mit ähnlicher Sicherheit wie ein SPV Client die geleistete Work einer Chain validieren. Am Beispiel Ethereum, wo die Block-Header heute schon über 3,7 Gigabyte groß sind, würde das Client FlyClient Protokoll zur Validierung der Chain nur ca. 500 KB an Daten benötigen (3,7 GB vs. 500 KB).

Noch handelt es sich bei FlyClient nur um ein vor kurzem veröffentlichtes wissenschaftliches Paper, das noch nicht in der Praxis umgesetzt wurde, und es wird noch Monate oder Jahre dauern, bis wir eine entsprechende Implementierung in einer der großen Blockchains sehen werden. Aber es eröffnet eine zuversichtliche Perspektive, um auch bei stetig wachsender Größe der Blockchain künftig weiterhin einfachen Devices einen direkten und trustless Zugang zur Blockchain zu ermöglichen.