Hätten Sie gedacht, dass Bitcoin auf der Blockchain-Technologie aufbaut? Heute werden wir gemeinsam eine Blockchain mit Python von Grund auf entwickeln.
Was genau ist eine Blockchain?
Im Jahr 2008 wurde das Bitcoin-Whitepaper von einer unbekannten Person oder Gruppe namens Satoshi Nakamoto veröffentlicht. Bitcoin wurde als eine Peer-to-Peer-Version von elektronischem Geld vorgestellt, die Transaktionen ohne das Eingreifen zentralisierter Institutionen (wie Banken) ermöglichte. Weniger bekannt ist, dass Satoshi in diesem Dokument auch eine verteilte Methode zur Speicherung von Informationen definierte, die wir heute als Blockchain kennen.
Die Technologie hinter der Blockchain
Vereinfacht ausgedrückt ist eine Blockchain ein gemeinsam genutztes, manipulationssicheres digitales Register, das Transaktionen über ein dezentrales Netzwerk von Computern speichert.
Wir können die Blockchain in zwei Kernkonzepte unterteilen:
- Block: Ein Ort, an dem Transaktionen gespeichert werden.
- Kette: Eine Sequenz miteinander verbundener Datensätze.
Zusammenfassend ist eine Blockchain also eine Kette von Blöcken, in der jeder Block eine Transaktion speichert, die gemäß bestimmten Parametern abgewickelt wurde.
Jeder Block baut auf dem vorherigen Block auf, wodurch eine irreversible Kette von Blöcken entsteht. Anders gesagt, jeder Block ist von seinem Vorgänger abhängig. Dies führt zu einem robusten und unveränderlichen System, in dem jeder mit den entsprechenden Berechtigungen die Integrität überprüfen kann.
Die Blockchain bietet eine Reihe von vorteilhaften Eigenschaften:
- Historische Unveränderlichkeit
- Dauerhafte Datenspeicherung
- Fehlerfreie Speicherung der Daten
Zahlreiche Systeme nutzen heute die Blockchain, darunter Kryptowährungen, der Transfer von Assets (NFTs) und zukünftig möglicherweise auch Abstimmungsprozesse.
Es ist wichtig zu betonen, dass eine Blockchain in Python kein komplexes Programm mit Tausenden von Codezeilen sein muss. Im Wesentlichen handelt es sich um eine verkettete Liste von Transaktionen.
Dies war natürlich nur eine kurze Einführung, aber falls Sie eine ausführlichere Anleitung wünschen, haben wir ein umfassendes Tutorial für Blockchain-Einsteiger erstellt. Schauen Sie es sich unbedingt an.
Ohne weitere Umschweife, beginnen wir mit der Entwicklung einer einfachen Blockchain in Python.
Entwicklung einer Blockchain mit Python
Bevor wir starten, definieren wir die Ziele dieses Tutorials:
- Erstellung eines grundlegenden Blockchain-Systems in Python.
- Nutzung unserer Blockchain mit vordefinierten Transaktionen, die als Text dargestellt werden.
- Überprüfung der Unveränderlichkeit unserer Blockchain.
Anstelle von JSON werden wir Python-Listen verwenden. Dadurch wird der Prozess vereinfacht und wir können uns auf die zentralen Konzepte der Blockchain konzentrieren.
Was Sie benötigen, um diesem Tutorial zu folgen:
Erstellen der Block-Klasse
Öffnen Sie Ihren bevorzugten Code-Editor und erstellen Sie eine Datei namens main.py. Dies ist die Datei, mit der wir arbeiten werden.
Importieren Sie nun Hashlib, ein Modul zur Erstellung unidirektional verschlüsselter Nachrichten. Kryptographische Techniken wie Hashing gewährleisten, dass die Blockchain sichere Transaktionen ermöglicht.
Eine Hash-Funktion ist ein Algorithmus, der Daten (meist eine codierte Zeichenkette) empfängt und eine eindeutige Kennung, oft als „Digest“ oder „Signatur“ bezeichnet, zurückgibt. Dieser Aspekt ist entscheidend; bei einer Hash-Funktion erzeugt eine geringfügige Änderung der Eingabe eine vollkommen andere Kennung als Ergebnis. Wir werden dies später live demonstrieren.
Importieren Sie vorerst das integrierte Modul hashlib:
# main.py file """ Eine einfache Blockchain in Python """ import hashlib
Dieses Modul enthält die wichtigsten Hashing-Algorithmen. Wir werden die Funktion hashlib.sha256() verwenden.
Nun zum GeekCoinBlock, unserem einzigartigen Blockchain-Namen.
class GeekCoinBlock: def __init__(self, previous_block_hash, transaction_list): self.previous_block_hash = previous_block_hash self.transaction_list = transaction_list self.block_data = f"{' - '.join(transaction_list)} - {previous_block_hash}" self.block_hash = hashlib.sha256(self.block_data.encode()).hexdigest()
Ich bin mir bewusst, dass dies nach viel Code aussieht. Betrachten wir jeden Teil einzeln im nächsten Abschnitt.
Erläuterung des GeekCoinBlock
Zuerst erstellen wir eine Klasse namens GeekCoinBlock, die als Wrapper für Objekte dient, die bestimmte Eigenschaften (Attribute) und Verhaltensweisen (Methoden) haben.
Danach definieren wir die Methode __init__ (auch Konstruktor genannt), die jedes Mal aufgerufen wird, wenn ein GeekCoinBlock-Objekt erzeugt wird.
Diese Methode hat drei Parameter:
- self (die Instanz eines jeden Objekts)
- previous_block_hash (ein Verweis auf den vorherigen Block)
- transaction_list (eine Liste von Transaktionen, die im aktuellen Block durchgeführt wurden).
Wir speichern den vorherigen Hash und die Liste der Transaktionen und erzeugen eine Instanzvariable block_data als Zeichenkette. Bei echten Kryptowährungen würden diese Daten als weiterer Hash gespeichert werden, wir speichern jeden Datenblock aber der Einfachheit halber als Zeichenkette.
Abschließend erzeugen wir den block_hash, den andere Blöcke zur Fortsetzung der Kette verwenden. Hier kommt Hashlib ins Spiel; Anstatt eine eigene Hash-Funktion zu entwickeln, können wir das vorgefertigte sha256 nutzen, um unveränderliche Blöcke zu erzeugen.
Diese Funktion akzeptiert codierte Zeichenketten (oder Bytes) als Parameter. Daher nutzen wir die Methode block_data.encode(). Anschließend rufen wir hexdigest() auf, um die codierten Daten im Hexadezimalformat zurückzugeben.
Ich weiß, dass dies überwältigend sein kann, daher werden wir mit Hashlib in einer Python-Shell experimentieren.
In [1]: import hashlib In [2]: message = "Python ist super" In [3]: h1 = hashlib.sha256(message.encode()) In [4]: h1 Out[4]: <sha256 ... object @ 0x7efcd55bfbf0> In [5]: h1.hexdigest() Out[5]: 'a40cf9cca ... 42ab97' In [6]: h2 = hashlib.sha256(b"Python ist nicht super") In [7]: h2 Out[7]: <sha256 ... object @ 0x7efcd55bfc90> In [8]: h2.hexdigest() Out[8]: 'fefe510a6a ... 97e010c0ea34'
Wie Sie sehen können, kann eine kleine Änderung der Eingabe, wie von „Python ist super“ zu „Python ist nicht super“, einen völlig anderen Hash erzeugen. Dies ist entscheidend für die Integrität der Blockchain. Wenn Sie eine geringfügige Änderung in einer Blockchain vornehmen, ändert sich deren Hash drastisch. Aus diesem Grund stimmt das Sprichwort „Eine Blockchain kann nicht manipuliert werden“.
Nutzung unserer Block-Klasse
Wir werden später eine vollständige Blockchain-Klasse entwickeln, aber vorerst verwenden wir unsere Block-Klasse, um eine Kette von Blöcken (eine Blockchain) zu bilden.
Erstellen Sie in derselben Datei einige Transaktionen als einfache Strings, die in Variablen gespeichert sind, zum Beispiel:
class GeekCoinBlock: ... t1 = "Noah sendet 5 GC an Mark" t2 = "Mark sendet 2.3 GC an James" t3 = "James sendet 4.2 GC an Alisson" t4 = "Alisson sendet 1.1 GC an Noah"
GC steht hier für GeekCoin.
Erstellen Sie nun den ersten Block unserer Blockchain mithilfe der GeekCoinBlock-Klasse und geben Sie seine Attribute aus. Beachten Sie, dass der Parameter previous_hash des Genesis-Blocks (des ersten Blocks, der allen anderen vorausgeht) immer eine beliebige Zeichenkette oder ein Hash ist, in diesem Fall „firstblock“.
block1 = GeekCoinBlock('firstblock', [t1, t2]) print(f"Block 1 data: {block1.block_data}") print(f"Block 1 hash: {block1.block_hash}")
Dann machen wir dasselbe mit dem zweiten Block, wobei wir jedoch den Hash des ersten Blocks als Argument previous_hash übergeben.
block2 = GeekCoinBlock(block1.block_hash, [t3, t4]) print(f"Block 2 data: {block2.block_data}") print(f"Block 2 hash: {block2.block_hash}")
Lassen Sie uns die Ausgabe dieses Codes analysieren. Geben Sie erneut Ihr Terminal ein:
❯ python main.py Block 1 data: Noah sendet 5 GC an Mark - Mark sendet 2.3 GC an James - firstblock Block 1 hash: 01e4e15242a9601725f4a86ca01fbddaaec7105b442955bb0efcadbfc759806d Block 2 data: James sendet 4.2 GC an Alisson - Alisson sendet 1.1 GC an Noah - 01e4e15242a9601725f4a86ca01fbddaaec7105b442955bb0efcadbfc759806d Block 2 hash: 448c4306caf7f6937b0307f92f27fbea3bb73b3470363dee5026a1209dadcfa8
Sie sehen im Moment nur Text und 64-stellige Hashes, aber dies bildet den Mechanismus einer Blockchain ab.
Sie beginnen mit einem Genesis-Block, der die Grundlage aller anderen Blöcke bildet.
Jeder kann die Integrität der Kette validieren, und das macht eine Blockchain zu einem sicheren System. Wenn wir beispielsweise den Inhalt einer Transaktion geringfügig ändern, sagen wir:
t2 = "Mark sendet 2.3 GC an James" -> t2 = "Mark sendet 3.2 GC an James"
sehen wir eine deutliche Änderung im Hash der Blöcke.
Block 1 data: Noah sendet 5 GC an Mark - Mark sendet 3.2 GC an James - firstblock Block 1 hash: 7a990bf1d70230bf2dad6160496c0b3046da7a17b1281fd1d4c63d4eac58e78c Block 2 data: James sendet 4.2 GC an Alisson - Alisson sendet 1.1 GC an Noah - 7a990bf1d70230bf2dad6160496c0b3046da7a17b1281fd1d4c63d4eac58e78c Block 2 hash: 569b977306ce88b53e001dca7ba00c03a51c60d6df4650e7657dcd136f2da0ac
Sie können das aktuelle Projekt in diesem GitHub-Repository einsehen.
Programmierung einer Blockchain
Es ist nicht klug, unsere Systemintegrität von handgeschriebenen Variablen abhängig zu machen, daher benötigen wir eine andere Vorgehensweise.
Wir haben die Blöcke. Nun ist es an der Zeit, eine Klasse zu erstellen, die sie zu einer Blockchain verbindet.
Beginnen wir damit, unsere vorherigen Transaktionen und Blockobjekte zu löschen, und verwenden Sie dann den folgenden Code.
# main.py class Blockchain: def __init__(self): self.chain = [] self.generate_genesis_block() def generate_genesis_block(self): self.chain.append(GeekCoinBlock("0", ['Genesis Block'])) def create_block_from_transaction(self, transaction_list): previous_block_hash = self.last_block.block_hash self.chain.append(GeekCoinBlock(previous_block_hash, transaction_list)) def display_chain(self): for i in range(len(self.chain)): print(f"Data {i + 1}: {self.chain[i].block_data}") print(f"Hash {i + 1}: {self.chain[i].block_hash}n") @property def last_block(self): return self.chain[-1]
Das ist wieder eine ganze Menge Code. Betrachten wir jeden Teil:
- self.chain – Die Liste, in der alle Blöcke gespeichert werden. Wir können mit Listenindizes auf jeden Block zugreifen.
- generate_genesis_block – Fügt den Genesis-Block, also den ersten Block, zur Kette hinzu. Der vorherige Hash des Blocks ist „0“, und die Liste der Transaktionen ist einfach „Genesis Block“.
- create_block_from_transaction – Damit können wir Blöcke mit nur einer Liste von Transaktionen an die Kette anhängen. Es wäre sehr mühsam, jedes Mal einen Block manuell zu erstellen, wenn wir eine Transaktion aufzeichnen möchten.
- display_chain – Gibt die Blockkette mit einer for-Schleife aus.
- last_block – Eine Eigenschaft, die uns den Zugriff auf das letzte Element der Kette ermöglicht. Wir haben sie in der Methode create_block_from_transaction verwendet.
Testen wir diese Blockchain.
# main.py import hashlib class GeekCoinBlock: ... class Blockchain: ... t1 = "George sendet 3.1 GC an Joe" t2 = "Joe sendet 2.5 GC an Adam" t3 = "Adam sendet 1.2 GC an Bob" t4 = "Bob sendet 0.5 GC an Charlie" t5 = "Charlie sendet 0.2 GC an David" t6 = "David sendet 0.1 GC an Eric" myblockchain = Blockchain() myblockchain.create_block_from_transaction([t1, t2]) myblockchain.create_block_from_transaction([t3, t4]) myblockchain.create_block_from_transaction([t5, t6]) myblockchain.display_chain()
Führen Sie jetzt die Datei main.py aus.
Data 1: Genesis Block - 0 Hash 1: 39331a6a2ea1cf31a5014b2a7c9e8dfad82df0b0666e81ce04cf8173cc5aed3e Data 2: George sendet 3.1 GC an Joe - Joe sendet 2.5 GC an Adam - 39331a6a2ea1cf31a5014b2a7c9e8dfad82df0b0666e81ce04cf8173cc5aed3e Hash 2: 98cf363aecb33989aea0425a3c1287268bd86f63851bc08c0734a31db08506d5 Data 3: Adam sendet 1.2 GC an Bob - Bob sendet 0.5 GC an Charlie - 98cf363aecb33989aea0425a3c1287268bd86f63851bc08c0734a31db08506d5 Hash 3: 6f1cfcc3082488b97db8fdf8ed33f9ac7519be3e285a37a6fcc2f1904f373589 Data 4: Charlie sendet 0.2 GC an David - David sendet 0.1 GC an Eric - 6f1cfcc3082488b97db8fdf8ed33f9ac7519be3e285a37a6fcc2f1904f373589 Hash 4: 869df2f03c9860767d35b30a46233fbeea89a3000ae5019d1491e3829d1ab929
Herzlichen Glückwunsch! 🙌 Sie haben erfolgreich eine einfache Blockchain in Python von Grund auf entwickelt.
Sie können die Unveränderlichkeit der Blockchain jetzt verbessern, indem Sie Getter und Setter einsetzen und andere Funktionen wie Proof-of-Work, Mining oder jedes andere Konzept implementieren, das wir im Artikel über die Grundlagen des Bitcoin-Mining behandelt haben.
Schlussfolgerung
Die Blockchain ist die Technologie hinter Bitcoin, Ethereum und allen anderen Kryptowährungen. In diesem Artikel haben Sie gelernt, wie man eine Blockchain mit Python entwickelt, indem man Hash-Algorithmen wie sha256, Klassen und Objekte verwendet.
Ihre Aufgabe ist es nun, ein Mining-System zu erstellen und es mit einer REST-API unter Verwendung von Frameworks wie Django oder Flask zu implementieren.
Viele Leute verdienen ein Vermögen mit Kryptowährungen. Stellen Sie sich vor, was Sie tun könnten, wenn Sie Ihre eigene erstellen. 🤑
Programmieren Sie weiter! 👨💻