Wie erstelle ich eine Blockchain mit Python?

Wussten Sie, dass Bitcoin auf Blockchain aufbaut? Heute werden wir eine Blockchain mit Python von Grund auf neu erstellen.

Was ist Blockchain?

2008 die Bitcoin-Papier wurde von einer unbekannten Person oder Gruppe namens Satoshi Nakamoto veröffentlicht. Bitcoin kam als Peer-to-Peer-Version von elektronischem Geld heraus, das Transaktionen ermöglichte, ohne über zentralisierte Institutionen (Banken) zu gehen. Die meisten Menschen wissen nicht, dass Satoshi in demselben Artikel eine verteilte Art der Speicherung von Informationen definiert hat, die heute als Blockchain bekannt ist.

Blockchain-Technologie

Einfach ausgedrückt ist Blockchain ein gemeinsam genutztes, unveränderliches digitales Hauptbuch, das Transaktionen über ein dezentrales Netzwerk von Computern speichert.

Wir können Blockchain in zwei einfache Begriffe unterteilen:

  • Block: Ein Bereich, in dem wir Transaktionen speichern
  • Kette: Eine Reihe verknüpfter Datensätze

Dies definiert Blockchain als eine Kette von verknüpften Blöcken, wobei jeder Block eine Transaktion speichert, die mit bestimmten Parametern durchgeführt wurde.

Jeder Block baut auf einem anderen Block auf, wodurch eine irreversible Kette von Blöcken entsteht. Mit anderen Worten, jeder Block hängt von einem anderen ab. Dies stellt sich als robustes und unveränderliches System heraus, in dem jeder mit den richtigen Berechtigungen die Integrität überprüfen kann.

Blockchain führt eine interessante Reihe von Funktionen ein:

  • Geschichte Unveränderlichkeit
  • Informationspersistenz
  • Keine Fehler bei gespeicherten Daten

Viele Systeme verlassen sich derzeit auf Blockchain, wie z. B. Kryptowährungen, Asset Transfer (NFTs) und möglicherweise in naher Zukunft Abstimmungen.

Erwähnenswert ist, dass eine Python-Blockchain kein komplexes Programm mit Tausenden von Codezeilen sein muss. Im Kern wäre es eine Liste von Transaktionen, die miteinander verknüpft sind.

Dies war natürlich eine kurze Erklärung, aber wenn Sie eine vollständige Anleitung wünschen, haben wir ein vollständiges Tutorial zu Blockchain für Anfänger erstellt. Schauen Sie es sich unbedingt an.

Lassen Sie uns ohne weitere Verzögerung eine einfache Blockchain mit Python erstellen.

Aufbau einer Blockchain mit Python

Bevor wir beginnen, definieren wir, was wir in diesem Tutorial tun werden:

  • Erstellen Sie ein einfaches Blockchain-System, das in Python geschrieben ist
  • Verwenden Sie unsere Blockchain mit vordefinierten Transaktionen, die als Zeichenfolgen dargestellt werden
  • Testen Sie die Unveränderlichkeit unserer Blockchain

Wir werden nicht JSON, sondern Python-Listen verwenden. Dadurch können wir den Prozess vereinfachen und uns auf die Anwendung der Schlüsselkonzepte einer Blockchain konzentrieren.

Was Sie brauchen, um diesem Tutorial zu folgen:

Erstellen der Block-Klasse

Öffnen Sie Ihren bevorzugten Code-Editor und erstellen Sie eine main.py-Datei. Dies ist die Datei, mit der wir arbeiten werden.

Jetzt importieren Hashlib, ein Modul, mit dem wir unidirektional verschlüsselte Nachrichten erstellen können. Kryptographietechniken wie Hashing sorgen dafür, dass Blockchain sichere Transaktionen erstellt.

  So exportieren und importieren Sie VMs in VMware Workstation

Eine Hash-Funktion ist ein Algorithmus, der einige Daten (normalerweise eine codierte Zeichenfolge) nimmt und eine eindeutige Kennung zurückgibt, die oft als „Digest“ oder „Signatur“ bezeichnet wird. Dieser letzte Teil ist entscheidend; Bei einer Hash-Funktion erzeugt ein geringfügiger Unterschied in der Eingabe eine radikal andere Kennung als Ausgabe. Wir werden dies später in Aktion sehen.

Importieren Sie vorerst einfach das integrierte Modul hashlib:

# main.py file
"""
A simple Blockchain in Python
"""

import hashlib

Dieses Modul enthält die meisten Hashing-Algorithmen, die Sie benötigen. Denken Sie daran, dass wir die Funktion hashlib.sha256() verwenden werden.

Kommen wir nun zum GeekCoinBlock, unserem völlig originellen 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 weiß, dass dies zu einem klobigen Stück Code führen kann. Lassen Sie uns jeden Teil im nächsten Abschnitt aufschlüsseln.

GeekCoinBlock Erklärung

Zuerst erstellen wir eine Klasse namens GeekCoinBlock, einen Wrapper für Objekte, die bestimmte Eigenschaften (Attribute) und Verhaltensweisen (Methoden) haben.

Dann definieren wir die Methode __init__ (auch Konstruktor genannt), die jedes Mal aufgerufen wird, wenn ein GeekCoinBlock-Objekt erstellt wird.

Diese Methode hat drei Parameter:

  • self (die Instanz jedes 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 die vorherige Hash- und Transaktionsliste und erstellen eine Instanzvariable block_data als Zeichenfolge. Dies passiert nicht mit echten Kryptowährungen, in denen wir diese Art von Daten als weiteren Hash speichern, aber der Einfachheit halber speichern wir jeden Datenblock als Zeichenfolge.

Schließlich erstellen wir den block_hash, den andere Blöcke verwenden, um die Kette fortzusetzen. Hier kommt Hashlib ins Spiel; Anstatt eine benutzerdefinierte Hash-Funktion zu erstellen, können wir das vorgefertigte sha256 verwenden, um unveränderliche Blöcke zu erstellen.

Diese Funktion erhält codierte Zeichenfolgen (oder Bytes) als Parameter. Deshalb verwenden wir die Methode block_data.encode(). Danach rufen wir hexdigest() auf, um die codierten Daten im Hexadezimalformat zurückzugeben.

Ich weiß, dass all dies überwältigend sein kann, also spielen wir mit Hashlib auf einer Python-Shell.

In [1]: import hashlib

In [2]: message = "Python is great"

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 is not great")

In [7]: h2
Out[7]: <sha256 ... object @ 0x7efcd55bfc90>

In [8]: h2.hexdigest()
Out[8]: 'fefe510a6a ... 97e010c0ea34'

Wie Sie sehen können, kann eine geringfügige Änderung der Eingabe wie „Python ist großartig“ zu „Python ist nicht großartig“ einen völlig anderen Hash erzeugen. Das hat alles mit der Blockchain-Integrität zu tun. Wenn Sie eine kleine Änderung in eine Blockchain einführen, wird sich ihr Hash dramatisch ändern. Aus diesem Grund ist das Sprichwort „Man kann eine Blockchain nicht korrumpieren“ wahr.

  Apple Music Vs Google Play Music Vs Spotify: Bester Streaming-Musikdienst

Verwenden unserer Blockklasse

Wir werden später eine ganze Blockchain-Klasse erstellen, aber jetzt verwenden wir unsere Block-Klasse, um eine Kette von Blöcken (Blockchain) zu erstellen.

Erstellen Sie in derselben Datei ein paar Transaktionen, die aus einfachen Zeichenfolgen bestehen, die in Variablen gespeichert sind, zum Beispiel:

class GeekCoinBlock:
    ...

t1 = "Noah sends 5 GC to Mark"
t2 = "Mark sends 2.3 GC to James"
t3 = "James sends 4.2 GC to Alisson"
t4 = "Alisson sends 1.1 GC to Noah"

Natürlich bezieht sich GC auf GeekCoin

Erstellen Sie nun den ersten Block unserer Blockchain mithilfe der GeekCoinBlock-Klasse und drucken Sie seine Attribute. Berücksichtigen Sie, dass der Parameter previous_hash des Genesis-Blocks (erster Block, der anderen Blöcken vorausgeht) immer eine beliebige Zeichenfolge 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, übergeben aber den Hash des ersten Blocks als Argument previous_hash.

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 Codestücks ausführen und analysieren. Geben Sie erneut Ihr Terminal ein:

❯ python main.py
Block 1 data: Noah sends 5 GC to Mark - Mark sends 2.3 GC to James - firstblock
Block 1 hash: 01e4e15242a9601725f4a86ca01fbddaaec7105b442955bb0efcadbfc759806d
Block 2 data: James sends 4.2 GC to Alisson - Alisson sends 1.1 GC to Noah - 01e4e15242a9601725f4a86ca01fbddaaec7105b442955bb0efcadbfc759806d
Block 2 hash: 448c4306caf7f6937b0307f92f27fbea3bb73b3470363dee5026a1209dadcfa8

Im Moment sehen Sie nur Text und etwa 64-Zeichen-Hashes, aber dies nimmt so ziemlich den Mechanismus einer Blockchain wieder auf.

Sie beginnen mit einem Genesis-Block, der Basis aller anderen Blöcke.

Jeder kann die Integrität der Kette validieren, und deshalb ist eine Blockchain ein so sicheres System. Wenn wir beispielsweise den Inhalt einer Transaktion geringfügig ändern, sagen Sie:

t2 = "Mark sends 2.3 GC to James" -> t2 = "Mark sends 3.2 GC to James" 

Wir sehen eine dramatische Veränderung im Hash der Blöcke.

Block 1 data: Noah sends 5 GC to Mark - Mark sends 3.2 GC to James - firstblock
Block 1 hash: 7a990bf1d70230bf2dad6160496c0b3046da7a17b1281fd1d4c63d4eac58e78c
Block 2 data: James sends 4.2 GC to Alisson - Alisson sends 1.1 GC to Noah - 7a990bf1d70230bf2dad6160496c0b3046da7a17b1281fd1d4c63d4eac58e78c
Block 2 hash: 569b977306ce88b53e001dca7ba00c03a51c60d6df4650e7657dcd136f2da0ac

Auf dieser können Sie das aktuelle Projekt einsehen GitHub-Repository.

Codieren einer Blockchain

Es ist nicht so schlau, unsere Systemintegrität auf handcodierten Variablen zu basieren, also brauchen wir einen anderen Ansatz.

Wir haben die Blöcke. Es ist an der Zeit, eine Klasse zu bauen, die sie zu einer Blockchain verbindet.

Beginnen wir damit, unsere vorherigen Transaktionen und Blockobjekte zu löschen und dann den folgenden Code zu verwenden.

# 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 ein riesiges Stück Code. Lassen Sie uns jeden Teil aufschlüsseln:

  • self.chain — Die Liste, in der alle Blöcke aufgezeichnet werden. Wir können auf jeden Block über Listenindizes zugreifen.
  • generate_genesis_block — Fügt die Genesis oder den ersten Block an die Kette an. Der vorherige Hash des Blocks ist „0“, und die Liste der Transaktionen ist einfach „Genesis Block“.
  • create_block_from_transaction — Dies ermöglicht es uns, Blöcke mit nur einer Liste von Transaktionen an die Kette anzuhängen. Es wäre sehr ärgerlich, jedes Mal, wenn wir eine Transaktion aufzeichnen möchten, manuell einen Block zu erstellen
  • display_chain — Druckt die Blockkette mit einer for-Schleife
  • last_block — Eine Eigenschaft, mit der wir auf das letzte Element der Kette zugreifen können. Wir haben es in der Methode create_block_from_transaction verwendet.
  Können Sie 911-Notrufe auf einem iPhone deaktivieren?

Lassen Sie uns diese Blockchain testen.

# main.py

import hashlib

class GeekCoinBlock:
    ...


class Blockchain:
    ...

t1 = "George sends 3.1 GC to Joe"
t2 = "Joe sends 2.5 GC to Adam"
t3 = "Adam sends 1.2 GC to Bob"
t4 = "Bob sends 0.5 GC to Charlie"
t5 = "Charlie sends 0.2 GC to David"
t6 = "David sends 0.1 GC to 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 nun die Datei main.py aus.

Data 1: Genesis Block - 0
Hash 1: 39331a6a2ea1cf31a5014b2a7c9e8dfad82df0b0666e81ce04cf8173cc5aed3e

Data 2: George sends 3.1 GC to Joe - Joe sends 2.5 GC to Adam - 39331a6a2ea1cf31a5014b2a7c9e8dfad82df0b0666e81ce04cf8173cc5aed3e
Hash 2: 98cf363aecb33989aea0425a3c1287268bd86f63851bc08c0734a31db08506d5

Data 3: Adam sends 1.2 GC to Bob - Bob sends 0.5 GC to Charlie - 98cf363aecb33989aea0425a3c1287268bd86f63851bc08c0734a31db08506d5
Hash 3: 6f1cfcc3082488b97db8fdf8ed33f9ac7519be3e285a37a6fcc2f1904f373589

Data 4: Charlie sends 0.2 GC to David - David sends 0.1 GC to Eric - 6f1cfcc3082488b97db8fdf8ed33f9ac7519be3e285a37a6fcc2f1904f373589
Hash 4: 869df2f03c9860767d35b30a46233fbeea89a3000ae5019d1491e3829d1ab929

Herzliche Glückwünsche! 🙌 Sie haben gerade eine einfache Python-Blockchain von Grund auf neu erstellt.

Sie können jetzt die Blockchain-Unveränderlichkeit stärken, indem Sie Getter und Setter verwenden und andere Funktionen wie Proof-of-Work, Mining oder jedes andere Konzept implementieren, das wir im Bitcoin Mining-Grundlagenartikel erläutert haben.

Fazit

Blockchain ist die Technologie hinter Bitcoin, Etherium und jeder anderen Kryptowährung da draußen. In diesem Artikel haben Sie gelernt, wie Sie eine Blockchain mit Python erstellen, indem Sie Hash-Algorithmen wie sha256, Klassen und Objekte verwenden.

Ihre Herausforderung besteht darin, ein Mining-System zu erstellen, und warum nicht, es mit einer REST-API unter Verwendung von Frameworks wie Django oder Flask zu implementieren.

Viele Menschen machen mit Kryptowährungen ein Vermögen. Stellen Sie sich vor, was Sie tun könnten, wenn Sie selbst eines erstellen. 🤑

Codieren Sie weiter! 👨‍💻