Aufbau einer Blockchain mit Python - Vollständig

Blog

Aufbau einer Blockchain mit Python - Vollständig

Aufbau einer Blockchain mit Python - Vollständig

Blockchain ist der aktuelle Trend, der die Softwareentwicklungstrends dominiert. Die Entwicklung und Gestaltung von Blockchain umfasst drei Hauptkomponenten: Client, Miner und Blockchain. Dieses Tutorial soll Ihnen ein klares Verständnis des Prozesses des Aufbaus Ihrer eigenen Blockchain vermitteln.

Publikum

Jeder Programmierbegeisterte, der mit dem jüngsten Trend der Blockchain-Entwicklung Schritt halten möchte, kann von diesem Tutorial profitieren. Wenn Sie ein Lernender sind, der die Grundlagen der Blockchain-Entwicklung erlernen möchte, ist dieses Tutorial genau das Richtige für Ihre Bedürfnisse.

Voraussetzungen

Dieses Tutorial wurde unter der Annahme geschrieben, dass der Lernende eine Vorstellung von der Programmierung in Python und eine grundlegende Idee von Blockchain hat. Wenn Sie mit einem dieser Konzepte noch nicht vertraut sind, empfehlen wir Ihnen, zuerst Tutorials auszuwählen, die auf diesen Konzepten basieren, bevor Sie in dieses Tutorial einsteigen.

1. Einleitung

Im Tutorial zu Blockchain haben wir uns ausführlich mit der Theorie hinter der Blockchain beschäftigt. Die Blockchain ist der grundlegende Baustein hinter der weltweit beliebtesten digitalen Währung Bitcoin. Das Tutorial befasste sich eingehend mit den Feinheiten von Bitcoin und erklärte die Blockchain-Architektur vollständig. Der nächste Schritt ist der Aufbau unserer eigenen Blockchain.

Satoshi Nakamoto hat die erste virtuelle Währung der Welt namens Bitcoin geschaffen. Mit Blick auf den Erfolg von Bitcoin haben viele andere ihre eigenen virtuellen Währungen geschaffen. Um nur einige zu nennen − Litecoin, Zcash und so weiter.

Jetzt möchten Sie vielleicht auch Ihre eigene Währung einführen. Nennen wir dies TPCoin (TutorialsPoint Coin). Sie werden eine Blockchain schreiben, um alle Transaktionen aufzuzeichnen, die sich mit TPCoin befassen. Der TPCoin kann zum Kauf von Pizzas, Burgern, Salaten usw. verwendet werden. Möglicherweise gibt es andere Dienstleister, die Ihrem Netzwerk beitreten und TPCoin als Währung für die Bereitstellung ihrer Dienste akzeptieren. Die Möglichkeiten sind endlos.

Lassen Sie uns in diesem Tutorial verstehen, wie Sie ein solches System aufbauen und Ihre eigene digitale Währung auf den Markt bringen.

An der Blockchain-Projektentwicklung beteiligte Komponenten

Die gesamte Blockchain-Projektentwicklung besteht aus drei Hauptkomponenten −

  • Klient
  • Minenarbeiter
  • Blockchain

Klient

Der Kunde ist derjenige, der Waren von anderen Anbietern kauft. Der Kunde kann selbst Verkäufer werden und nimmt Geld von anderen gegen die von ihm gelieferten Waren an. Wir gehen hier davon aus, dass der Kunde sowohl Lieferant als auch Empfänger von TPCoins sein kann. Daher erstellen wir in unserem Code eine Clientklasse, die Geld senden und empfangen kann.

Reaktiv-native Aufzählungsliste

Bergmann

Der Miner ist derjenige, der die Transaktionen aus einem Transaktionspool abholt und zu einem Block zusammenstellt. Der Miner muss einen gültigen Arbeitsnachweis vorlegen, um die Mining-Belohnung zu erhalten. Das gesamte Geld, das der Bergmann als Gebühr sammelt, wird er behalten. Er kann dieses Geld für den Kauf von Waren oder Dienstleistungen von anderen registrierten Anbietern im Netzwerk ausgeben, genau wie es ein oben beschriebener Kunde tut.

Blockchain

Schließlich ist eine Blockchain eine Datenstruktur, die alle abgebauten Blöcke in einer chronologischen Reihenfolge verkettet. Diese Kette ist unveränderlich und somit temperaturbeständig.

Sie können diesem Tutorial folgen, indem Sie den in jedem Schritt angezeigten Code in ein neues Jupyter-Notebook eingeben. Alternativ können Sie das gesamte Jupyter-Notebook von www.anaconda.com herunterladen.

Im nächsten Kapitel werden wir einen Client entwickeln, der unser Blockchain-System verwendet.

2. Kunden entwickeln

Ein Kunde ist jemand, der TPCoins besitzt und diese für Waren/Dienstleistungen von anderen Anbietern im Netzwerk, einschließlich seiner eigenen, abwickelt. Wir sollten a . definieren Klient Klasse zu diesem Zweck. Um eine weltweit eindeutige Identifikation für den Kunden zu schaffen, verwenden wir PKI (Public Key Infrastructure). Lassen Sie uns in diesem Kapitel ausführlich darüber sprechen.

Der Kunde sollte in der Lage sein, Geld von seiner Brieftasche an eine andere bekannte Person zu senden. Ebenso sollte der Kunde in der Lage sein, Geld von einem Dritten anzunehmen. Um Geld auszugeben, würde der Kunde eine Transaktion erstellen, in der der Name des Absenders und der zu zahlende Betrag angegeben sind. Für den Geldempfang gibt der Kunde dem Dritten – im Wesentlichen einem Absender des Geldes – seine Identität bekannt. Wir speichern nicht den Guthabenbetrag, den der Kunde in seiner Brieftasche hält. Während einer Transaktion berechnen wir den tatsächlichen Saldo, um sicherzustellen, dass der Kunde über einen ausreichenden Saldo für die Zahlung verfügt.

Um die . zu entwickeln Klient -Klasse und für den Rest des Codes im Projekt müssen wir viele Python-Bibliotheken importieren. Diese sind unten aufgeführt −

# import libraries import hashlib import random import string import json import binascii import numpy as np import pandas as pd import pylab as pl import logging import datetime import collections 

Zusätzlich zu den oben genannten Standardbibliotheken werden wir unsere Transaktionen signieren, Hash der Objekte erstellen usw. Dazu müssen Sie die folgenden Bibliotheken importieren −

# following imports are required by PKI import Crypto import Crypto.Random from Crypto.Hash import SHA from Crypto.PublicKey import RSA from Crypto.Signature import PKCS1_v1_5 

3. Kundenklasse

Die Klient Klasse erzeugt die Privatgelände und öffentlich Schlüssel mit dem eingebauten Python RSA Algorithmus. Der interessierte Leser kann verweisen auf dieses Tutorial für die Implementierung von RSA. Bei der Objektinitialisierung erstellen wir private und öffentliche Schlüssel und speichern deren Werte in der Instanzvariablen.

self._private_key = RSA.generate(1024, random) self._public_key = self._private_key.publickey() 

Beachten Sie, dass Sie Ihren privaten Schlüssel niemals verlieren sollten. Zur Aufzeichnung kann der generierte private Schlüssel auf einen gesicherten externen Speicher kopiert werden oder Sie können einfach die ASCII-Darstellung davon auf ein Blatt Papier schreiben.

Das erzeugte öffentlich key wird als Identität des Clients verwendet. Dazu definieren wir eine Eigenschaft namens Identität die die HEX-Darstellung des öffentlichen Schlüssels zurückgibt.

@property def identity(self): return binascii.hexlify(self._public_key.exportKey(format='DER')) .decode('ascii') 

Die Identität ist für jeden Client einzigartig und kann öffentlich zugänglich gemacht werden. Jeder könnte Ihnen damit virtuelle Währung senden Identität und es wird Ihrer Brieftasche hinzugefügt.

Der vollständige Code für die Klient Klasse wird hier gezeigt −

class Client: def __init__(self): random = Crypto.Random.new().read self._private_key = RSA.generate(1024, random) self._public_key = self._private_key.publickey() self._signer = PKCS1_v1_5.new(self._private_key) 

@property
def identity(self):
return
binascii.hexlify(self._public_key.exportKey(format=‘DER’)).decode(‘ascii’)

Testclient

Jetzt werden wir Code schreiben, der die Verwendung des Klient Klasse −

Dinesh = Client()  
print (Dinesh.identity)

Der obige Code erstellt eine Instanz von Klient und weist es der Variablen zu Dinesh . Wir drucken den öffentlichen Schlüssel von Dinesh indem du es anrufst Identität Methode. Die Ausgabe wird hier angezeigt −

30819f300d06092a864886f70d010101050003818d0030818902818100b547fafceeb131e07  
0166a6b23fec473cce22c3f55c35ce535b31d4c74754fecd820aa94c1166643a49ea5f49f72
3181ff943eb3fdc5b2cb2db12d21c06c880ccf493e14dd3e93f3a9e175325790004954c34d3
c7bc2ccc9f0eb5332014937f9e49bca9b7856d351a553d9812367dc8f2ac734992a4e6a6ff6
6f347bd411d07f0203010001

4. Transaktionsklasse

Lassen Sie uns in diesem Kapitel a Transaktion Klasse, damit ein Kunde Geld an jemanden senden kann. Beachten Sie, dass ein Kunde sowohl Sender als auch Empfänger des Geldes sein kann. Wenn Sie Geld erhalten möchten, erstellt ein anderer Absender eine Transaktion und gibt Ihre . an öffentlich darin ansprechen. Wir definieren die Initialisierung einer Transaktionsklasse wie folgt −

def  init  (self, sender, recipient, value):  
self.sender = sender
self.recipient = recipient
self.value = value
self.time = datetime.datetime.now()

Die drin Methode nimmt drei Parameter an – die des Absenders öffentlich Schlüssel, der des Empfängers öffentlich Schlüssel und den zu sendenden Betrag. Diese werden in den Instanzvariablen zur Verwendung durch andere Methoden gespeichert. Zusätzlich erstellen wir eine weitere Variable zum Speichern der Transaktionszeit.

Als nächstes schreiben wir eine Utility-Methode namens to_dict die alle vier oben genannten Instanzvariablen in einem Dictionary-Objekt vereint. Dies dient nur dazu, die gesamten Transaktionsinformationen über eine einzige Variable zugänglich zu machen.

Wie Sie aus dem vorherigen Tutorial wissen, ist der erste Block in der Blockchain a Genesis Block. Der Genesis-Block enthält die erste Transaktion, die vom Ersteller der Blockchain initiiert wurde. Die Identität dieser Person kann wie bei Bitcoins geheim gehalten werden. Wenn also diese erste Transaktion erstellt wird, kann der Ersteller seine Identität einfach als . senden Genesis . Daher prüfen wir beim Erstellen des Wörterbuchs, ob der Absender Genesis und wenn ja, weisen wir der Identitätsvariablen einfach einen Zeichenfolgenwert zu; andernfalls weisen wir die Identität des Absenders dem . zu Identität Variable.

if self.sender == Genesis:  
identity = Genesis
else:
identity = self.sender.identity

Wir konstruieren das Wörterbuch mit der folgenden Codezeile

return collections.OrderedDict({  
‘sender’: identity,
‘recipient’: self.recipient,
‘value’: self.value,
‘time’ : self.time})

Der gesamte Code für die to_dict Methode ist unten gezeigt −

def to_dict(self):  
if self.sender == Genesis:
identity = Genesis
else:
identity = self.sender.identity

return collections.OrderedDict({
‘sender’: identity,
‘recipient’: self.recipient,
‘value’: self.value,
‘time’ : self.time})

Schließlich signieren wir dieses Dictionary-Objekt mit dem privaten Schlüssel des Absenders. Wie zuvor verwenden wir die eingebaute PKI mit SHA-Algorithmus. Die generierte Signatur wird dekodiert, um die ASCII-Darstellung zum Drucken und Speichern in unserer Blockchain zu erhalten. Die sign_transaktion Methodencode wird hier angezeigt −

def sign_transaction(self):  
private_key = self.sender._private_key
signer = PKCS1_v1_5.new(private_key)
h = SHA.new(str(self.to_dict()).encode(‘utf8’))
return binascii.hexlify(signer.sign(h)).decode(‘ascii’)

Das werden wir jetzt testen Transaktion Klasse.

Transaktionsklasse testen

Zu diesem Zweck erstellen wir zwei Benutzer, genannt Dinesh und Ramesh . Dinesh sendet 5 TPCoins an Ramesh. Dazu erstellen wir zunächst die Clients Dinesh und Ramesh.

Dinesh = Client()  
Ramesh = Client()

Denken Sie daran, wenn Sie a . instanziieren Klient Klasse, die öffentlich und für den Client eindeutige private Schlüssel erstellt würden. Da Dinesh Zahlungen an Ramesh sendet, benötigt er den öffentlichen Schlüssel von Ramesh, der unter Verwendung der Identitätseigenschaft des Clients erhalten wird.

Daher erstellen wir die Transaktionsinstanz mit dem folgenden Code −

t = Transaction(  
Dinesh,
Ramesh.identity,
5.0
)

Beachten Sie, dass der erste Parameter der Absender ist, der zweite Parameter der öffentliche Schlüssel des Empfängers und der dritte Parameter der zu übertragende Betrag. Die sign_transaktion -Methode ruft den privaten Schlüssel des Absenders aus dem ersten Parameter zum Singen der Transaktion ab.

Nachdem das Transaktionsobjekt erstellt wurde, signieren Sie es, indem Sie es aufrufen sign_transaktion Methode. Diese Methode gibt die generierte Signatur im druckbaren Format zurück. Wir generieren und drucken die Signatur mit den folgenden zwei Codezeilen −

signature = t.sign_transaction()  
print (signature)

Wenn Sie den obigen Code ausführen, sehen Sie eine Ausgabe ähnlich dieser −

HTML-Chatbox-Code
7c7e3c97629b218e9ec6e86b01f9abd8e361fd69e7d373c38420790b655b9abe3b575e343c7  
13703ca1aee781acd7157a0624db3d57d7c2f1172730ee3f45af943338157f899965856f6b0
0e34db240b62673ad5a08c8e490f880b568efbc36035cae2e748f1d802d5e8e66298be826f5
c6363dc511222fb2416036ac04eb972

Da unsere grundlegende Infrastruktur zum Erstellen eines Kunden und einer Transaktion nun fertig ist, werden wir nun mehrere Kunden haben, die mehrere Transaktionen wie in einer realen Situation durchführen.

5. Mehrere Transaktionen erstellen

Die von verschiedenen Clients getätigten Transaktionen werden im System in eine Warteschlange gestellt; die Miner holen die Transaktionen aus dieser Warteschlange ab und fügen sie dem Block hinzu. Sie werden dann den Block abbauen und der gewinnende Miner hätte das Privileg, den Block zur Blockchain hinzuzufügen und dadurch etwas Geld für sich selbst zu verdienen.

Wir werden diesen Mining-Prozess später beschreiben, wenn wir die Erstellung der Blockchain besprechen. Bevor wir den Code für mehrere Transaktionen schreiben, fügen wir eine kleine Hilfsfunktion hinzu, um den Inhalt einer bestimmten Transaktion zu drucken.

Transaktion anzeigen

Die display_transaktion Die Funktion akzeptiert einen einzelnen Parameter des Transaktionstyps. Das Dictionary-Objekt innerhalb der empfangenen Transaktion wird in eine temporäre Variable namens . kopiert diktieren und mit den Wörterbuchschlüsseln werden die verschiedenen Werte auf der Konsole ausgegeben.

def display_transaction(transaction):  
#for transaction in transactions:
dict = transaction.to_dict()
print ('sender: ' + dict[‘sender’])
print (‘-----’)
print ('recipient: ' + dict[‘recipient’])
print (‘-----’)
print ('value: ' + str(dict[‘value’]))
print (‘-----’)
print ('time: ' + str(dict[‘time’]))
print (‘-----’)

Als nächstes definieren wir eine Transaktionswarteschlange zum Speichern unserer Transaktionsobjekte.

Transaktionswarteschlange

Um eine Warteschlange zu erstellen, deklarieren wir ein globales aufführen Variable namens Transaktionen wie folgt −

transactions = []  

Wir werden einfach jede neu erstellte Transaktion an diese Warteschlange anhängen. Bitte beachten Sie, dass wir der Kürze halber die Warteschlangenverwaltungslogik in diesem Tutorial nicht implementieren.

Mehrere Clients erstellen

Jetzt beginnen wir mit der Erstellung von Transaktionen. Zuerst erstellen wir vier Kunden, die sich gegenseitig Geld senden, um verschiedene Dienstleistungen oder Waren von anderen zu beziehen.

Dinesh = Client()  
Ramesh = Client()
Seema = Client()
Vijay = Client()

Zu diesem Zeitpunkt haben wir vier Kunden namens Dinesh, Ramesh, Seema und Vijay. Wir gehen derzeit davon aus, dass jeder dieser Kunden einige TPCoins für Transaktionen in seinen Wallets hält. Die Identität jedes dieser Clients würde unter Verwendung der Identitätseigenschaft dieser Objekte angegeben.

Erste Transaktion erstellen

Nun starten wir unsere erste Transaktion wie folgt −

t1 = Transaction(  
Dinesh,
Ramesh.identity,
15.0
)

In dieser Transaktion sendet Dinesh 5 TPCoins an Ramesh. Damit die Transaktion erfolgreich ist, müssen wir sicherstellen, dass Dinesh genügend Geld für diese Zahlung in seiner Brieftasche hat. Beachten Sie, dass wir eine Genesis-Transaktion benötigen, um den TPCoin-Umlauf im System zu starten. Sie werden den Transaktionscode für diese Genesis-Transaktion in Kürze schreiben, während Sie mitlesen.

Wir werden diese Transaktion mit dem privaten Schlüssel von Dinesh signieren und wie folgt zur Transaktionswarteschlange hinzufügen −

t1.sign_transaction()  
transactions.append(t1)

Nach der ersten Transaktion von Dinesh werden wir mehrere weitere Transaktionen zwischen verschiedenen Kunden erstellen, die wir oben erstellt haben.

Hinzufügen weiterer Transaktionen

Wir werden nun mehrere weitere Transaktionen erstellen, wobei jede Transaktion ein paar TPCoins an eine andere Partei verteilt. Wenn jemand Geld ausgibt, muss er nicht nach ausreichend Guthaben in dieser Brieftasche suchen. Der Miner würde sowieso jede Transaktion für das Guthaben validieren, das der Absender beim Initiieren der Transaktion hat.

Bei unzureichendem Guthaben markiert der Miner diese Transaktion als ungültig und fügt sie diesem Block nicht hinzu.

Der folgende Code erstellt und fügt unserer Warteschlange neun weitere Transaktionen hinzu.

t2 = Transaction(  
Dinesh,
Seema.identity,
6.0
)
t2.sign_transaction()
transactions.append(t2)
t3 = Transaction(
Ramesh,
Vijay.identity,
2.0
)
t3.sign_transaction()
transactions.append(t3)
t4 = Transaction(
Seema,
Ramesh.identity,
4.0
)
t4.sign_transaction()
transactions.append(t4)
t5 = Transaction(
Vijay,
Seema.identity,
7.0
)
t5.sign_transaction()
transactions.append(t5)
t6 = Transaction(
Ramesh,
Seema.identity,
3.0
)
t6.sign_transaction()
transactions.append(t6)
t7 = Transaction(
Seema,
Dinesh.identity,
8.0
)
t7.sign_transaction()
transactions.append(t7)
t8 = Transaction(
Seema,
Ramesh.identity,
1.0
)
t8.sign_transaction()
transactions.append(t8)
t9 = Transaction(
Vijay,
Dinesh.identity,
5.0
)
t9.sign_transaction()
transactions.append(t9)
t10 = Transaction(
Vijay,
Ramesh.identity,
3.0
)
t10.sign_transaction()
transactions.append(t10)

Wenn Sie den obigen Code ausführen, haben Sie zehn Transaktionen in der Warteschlange, damit die Miner ihre Blöcke erstellen können.

Dumping-Transaktionen

Als Blockchain-Manager möchten Sie möglicherweise regelmäßig den Inhalt der Transaktionswarteschlange überprüfen. Zu diesem Zweck können Sie die display_transaktion Funktion, die wir zuvor entwickelt haben. Um alle Transaktionen in der Warteschlange auszugeben, iterieren Sie einfach die Transaktionsliste und rufen Sie für jede referenzierte Transaktion die display_transaktion Funktion wie hier gezeigt −

for transaction in transactions:  
display_transaction (transaction)
print (‘--------------’)

Die Transaktionen sind zur Unterscheidung durch eine gestrichelte Linie getrennt. Wenn Sie den obigen Code ausführen, sehen Sie die Transaktionsliste wie unten gezeigt −

sender:  
30819f300d06092a864886f70d010101050003818d0030818902818100bb064c99c49214
4a9f463480273aba93ac1db1f0da3cb9f3c1f9d058cf499fd8e54d244da0a8dd6ddd329e
c86794b04d773eb4841c9f935ea4d9ccc2821c7a1082d23b6c928d59863407f52fa05d8b
47e5157f8fe56c2ce3279c657f9c6a80500073b0be8093f748aef667c03e64f04f84d311
c4d866c12d79d3fc3034563dfb0203010001

recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100be93b516b28c6e
674abe7abdb11ce0fdf5bb728b75216b73f37a6432e4b402b3ad8139b8c0ba541a72c8ad
d126b6e1a1308fb98b727beb63c6060356bb177bb7d54b54dbe87aee7353d0a6baa93977
04de625d1836d3f42c7ee5683f6703259592cc24b09699376807f28fe0e00ff882974484
d805f874260dfc2d1627473b910203010001

value: 15.0

time: 2019-01-14 16:18:01.859915


sender:
30819f300d06092a864886f70d010101050003818d0030818902818100bb064c99c49214
4a9f463480273aba93ac1db1f0da3cb9f3c1f9d058cf499fd8e54d244da0a8dd6ddd329e
c86794b04d773eb4841c9f935ea4d9ccc2821c7a1082d23b6c928d59863407f52fa05d8b
47e5157f8fe56c2ce3279c657f9c6a80500073b0be8093f748aef667c03e64f04f84d311
c4d866c12d79d3fc3034563dfb0203010001

recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100a070c82b34ae14
3cbe59b3a2afde7186e9d5bc274955d8112d87a00256a35369acc4d0edfe65e8f9dc93fb
d9ee74b9e7ea12334da38c8c9900e6ced1c4ce93f86e06611e656521a1eab561892b7db0
961b4f212d1fd5b5e49ae09cf8c603a068f9b723aa8a651032ff6f24e5de00387e4d0623
75799742a359b8f22c5362e5650203010001

value: 6.0

time: 2019-01-14 16:18:01.860966


sender:
30819f300d06092a864886f70d010101050003818d0030818902818100be93b516b28c6e
674abe7abdb11ce0fdf5bb728b75216b73f37a6432e4b402b3ad8139b8c0ba541a72c8ad
d126b6e1a1308fb98b727beb63c6060356bb177bb7d54b54dbe87aee7353d0a6baa93977
04de625d1836d3f42c7ee5683f6703259592cc24b09699376807f28fe0e00ff882974484
d805f874260dfc2d1627473b910203010001

recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100cba097c0854876
f41338c62598c658f545182cfa4acebce147aedf328181f9c4930f14498fd03c0af6b0cc
e25be99452a81df4fa30a53eddbb7bb7b203adf8764a0ccd9db6913a576d68d642d8fd47
452590137869c25d9ff83d68ebe6d616056a8425b85b52e69715b8b85ae807b84638d8f0
0e321b65e4c33acaf6469e18e30203010001

value: 2.0

time: 2019-01-14 16:18:01.861958


Der Kürze halber habe ich nur die ersten paar Transaktionen in der Liste gedruckt. Im obigen Code drucken wir alle Transaktionen beginnend mit der allerersten Transaktion mit Ausnahme der Genesis-Transaktion, die dieser Liste nie hinzugefügt wurde. Da die Transaktionen in regelmäßigen Abständen zu den Blöcken hinzugefügt werden, werden Sie im Allgemeinen daran interessiert sein, nur die Liste der Transaktionen anzuzeigen, die noch abgebaut werden müssen. In diesem Fall müssen Sie eine entsprechende zum Schleife, um die Transaktionen zu durchlaufen, die noch nicht abgebaut wurden.

Bisher haben Sie gelernt, wie man Clients erstellt, ihnen erlaubt, sich untereinander auszutauschen und eine Warteschlange der ausstehenden Transaktionen zu verwalten, die abgebaut werden sollen. Nun kommt der wichtigste Teil dieses Tutorials und das ist das Erstellen einer Blockchain selbst.

6. Blockklasse

Ein Block besteht aus einer unterschiedlichen Anzahl von Transaktionen. Der Einfachheit halber gehen wir in unserem Fall davon aus, dass der Block aus einer festen Anzahl von Transaktionen besteht, in diesem Fall also drei. Da der Block die Liste dieser drei Transaktionen speichern muss, deklarieren wir eine Instanzvariable namens verifizierte_transaktionen wie folgt −

self.verified_transactions = []  

Wir haben diese Variable benannt als verifizierte_transaktionen um anzuzeigen, dass nur die verifizierten gültigen Transaktionen zum Block hinzugefügt werden. Jeder Block enthält auch den Hash-Wert des vorherigen Blocks, sodass die Blockkette unveränderlich wird.

Um den vorherigen Hash zu speichern, deklarieren wir eine Instanzvariable wie folgt −

self.previous_block_hash =  

Schließlich deklarieren wir eine weitere Variable namens Nuntius zum Speichern der vom Miner während des Mining-Prozesses erstellten Nonce.

self.Nonce =  

Die vollständige Definition von Block Klasse ist unten angegeben −

class Block:  
def init (self):
self.verified_transactions = []
self.previous_block_hash =
self.Nonce =

Da jeder Block den Wert des Hashwerts des vorherigen Blocks benötigt, deklarieren wir eine globale Variable namens last_block_hash wie folgt −

Reagieren-Bild-Zoom
last_block_hash =  

Lassen Sie uns nun unseren ersten Block in der Blockchain erstellen.

7. Genesis-Block erstellen

Wir gehen davon aus, dass der Urheber von TPCoins zunächst 500 TPCoins an einen bekannten Kunden ausgibt Dinesh . Dazu erstellt er zunächst eine Dinesh-Instanz −

Dinesh = Client()  

Wir erstellen dann eine Genesis-Transaktion und senden 500 TPCoins an die öffentliche Adresse von Dinesh.

t0 = Transaction (  
Genesis,
Dinesh.identity,
500.0
)

Jetzt erstellen wir eine Instanz von Block Klasse und nenne es block0 .

block0 = Block()  

Wir initialisieren die previous_block_hash und Nuntius Instanzvariablen zu Keiner , da dies die allererste Transaktion ist, die in unserer Blockchain gespeichert wird.

block0.previous_block_hash = None  
Nonce = None

Als Nächstes fügen wir die obige t0-Transaktion zu der hinzu verifizierte_transaktionen innerhalb des Blocks gepflegte Liste −

block0.verified_transactions.append (t0)  

An diesem Punkt ist der Block vollständig initialisiert und kann unserer Blockchain hinzugefügt werden. Zu diesem Zweck werden wir die Blockchain erstellen. Bevor wir den Block zur Blockchain hinzufügen, werden wir den Block hashen und seinen Wert in der globalen Variablen namens . speichern last_block_hash die wir vorher erklärt haben. Dieser Wert wird vom nächsten Miner in seinem Block verwendet.

Wir verwenden die folgenden zwei Codierungszeilen, um den Block zu hashen und den Digest-Wert zu speichern.

digest = hash (block0)  
last_block_hash = digest

8. Python Creating Blockchain

Eine Blockchain enthält eine Liste von Blöcken, die miteinander verkettet sind. Um die gesamte Liste zu speichern, erstellen wir eine Listenvariable namens TPCoins −

TPCoins = []  

Wir werden auch eine Utility-Methode namens schreiben dump_blockchain zum Dumping des Inhalts der gesamten Blockchain. Wir drucken zunächst die Länge der Blockchain aus, damit wir wissen, wie viele Blöcke aktuell in der Blockchain vorhanden sind.

def dump_blockchain (self):  
print ('Number of blocks in the chain: ' + str(len (self)))

Beachten Sie, dass im Laufe der Zeit die Anzahl der Blöcke in der Blockchain für den Druck außergewöhnlich hoch wäre. Wenn Sie den Inhalt der Blockchain drucken, müssen Sie sich daher möglicherweise für den Bereich entscheiden, den Sie untersuchen möchten. Im folgenden Code haben wir die gesamte Blockchain gedruckt, da wir in der aktuellen Demo nicht zu viele Blöcke hinzufügen würden.

Um durch die Kette zu iterieren, richten wir a zum Schleife wie folgt −

for x in range (len(TPCoins)):  
block_temp = TPCoins[x]

Jeder referenzierte Block wird in eine temporäre Variable namens . kopiert block_temp .

Wir drucken die Blocknummer als Überschrift für jeden Block. Beachten Sie, dass die Zahlen mit Null beginnen würden, der erste Block ist ein Genesis-Block, der mit Null nummeriert ist.

print ('block # ' + str(x))  

Innerhalb jedes Blocks haben wir eine Liste von drei Transaktionen (außer dem Genesis-Block) in einer Variablen namens . gespeichert verifizierte_transaktionen . Wir iterieren diese Liste in a zum Schleife und für jedes abgerufene Element rufen wir display_transaktion Funktion zum Anzeigen der Transaktionsdetails.

for transaction in block_temp.verified_transactions:  
display_transaction (transaction)

Die gesamte Funktionsdefinition ist unten gezeigt −

def dump_blockchain (self):  
print ('Number of blocks in the chain: ' + str(len (self)))
for x in range (len(TPCoins)):
block_temp = TPCoins[x]
print ('block # ' + str(x))
for transaction in block_temp.verified_transactions:
display_transaction (transaction)
print (‘--------------’)
print (‘=====================================’)

Beachten Sie, dass wir hier die Trennzeichen an geeigneten Stellen im Code eingefügt haben, um die darin enthaltenen Blöcke und Transaktionen abzugrenzen.

Da wir jetzt eine Blockchain zum Speichern von Blöcken erstellt haben, besteht unsere nächste Aufgabe darin, Blöcke zu erstellen und sie der Blockchain hinzuzufügen. Dazu fügen wir einen Genesis-Block hinzu, den Sie bereits im vorherigen Schritt angelegt haben.

9. Genesis-Block hinzufügen

Das Hinzufügen eines Blocks zur Blockchain beinhaltet das Anhängen des erstellten Blocks an unser TPCoins aufführen.

TPCoins.append (block0)  

Beachten Sie, dass der Genesis-Block im Gegensatz zu den übrigen Blöcken im System nur eine Transaktion enthält, die vom Urheber des TPCoins-Systems initiiert wird. Jetzt werden Sie den Inhalt der Blockchain ausgeben, indem Sie unsere globale Funktion aufrufen dump_blockchain -

dump_blockchain(TPCoins)  

Wenn Sie diese Funktion ausführen, sehen Sie die folgende Ausgabe −

Number of blocks in the chain: 1  
block # 0
sender: Genesis

recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100ed272b52ccb539
e2cd779c6cc10ed1dfadf5d97c6ab6de90ed0372b2655626fb79f62d0e01081c163b0864
cc68d426bbe9438e8566303bb77414d4bfcaa3468ab7febac099294de10273a816f7047d
4087b4bafa11f141544d48e2f10b842cab91faf33153900c7bf6c08c9e47a7df8aa7e60d
c9e0798fb2ba3484bbdad2e4430203010001

value: 500.0

time: 2019-01-14 16:18:02.042739


=====================================

An diesem Punkt ist das Blockchain-System einsatzbereit. Wir werden es nun den interessierten Kunden ermöglichen, Miner zu werden, indem wir ihnen eine Mining-Funktionalität zur Verfügung stellen.

10. Miner erstellen

Um das Mining zu ermöglichen, müssen wir eine Mining-Funktion entwickeln. Die Mining-Funktionalität muss einen Digest für eine bestimmte Nachrichtenzeichenfolge generieren und einen Arbeitsnachweis liefern. Lassen Sie uns dies in diesem Kapitel besprechen.

Message-Digest-Funktion

Wir schreiben eine Nutzenfunktion namens sha256 zum Erstellen eines Digests zu einer gegebenen Nachricht −

def sha256(message):  
return hashlib.sha256(message.encode(‘ascii’)).hexdigest()

Die sha256 Funktion nimmt a Botschaft als Parameter, kodiert ihn in ASCII, generiert einen hexadezimalen Digest und gibt den Wert an den Aufrufer zurück.

Bergbaufunktion

Wir entwickeln jetzt die Bergwerk Funktion, die unsere eigene Mining-Strategie umsetzt. Unsere Strategie in diesem Fall wäre, einen Hash für die angegebene Nachricht zu generieren, dem eine bestimmte Anzahl von Einsen vorangestellt ist. Die angegebene Anzahl von Einsen wird als Parameter für angegeben Bergwerk Funktion als Schwierigkeitsgrad angegeben.

Wenn Sie beispielsweise einen Schwierigkeitsgrad von 2 angeben, sollte der generierte Hash für eine bestimmte Nachricht mit zwei Einsen beginnen - wie 11xxxxxxxx. Wenn der Schwierigkeitsgrad 3 ist, sollte der generierte Hash mit drei Einsen beginnen - wie 111xxxxxxxx. Angesichts dieser Anforderungen entwickeln wir nun die Mining-Funktion, wie in den unten angegebenen Schritten gezeigt.

Schritt 1

Die Mining-Funktion benötigt zwei Parameter - die Nachricht und den Schwierigkeitsgrad.

def mine(message, difficulty=1):  

Schritt 2

Der Schwierigkeitsgrad muss größer oder gleich 1 sein, wir stellen dies mit der folgenden assert-Anweisung −

assert difficulty >= 1  

Schritt 3

Wir erstellen ein Präfix variabel über den eingestellten Schwierigkeitsgrad.

prefix = ‘1’ * difficulty  

Beachten Sie, dass bei einem Schwierigkeitsgrad von 2 das Präfix 11 ist und bei einem Schwierigkeitsgrad von 3 das Präfix 111 usw. Wir prüfen, ob dieses Präfix im generierten Digest der Nachricht vorhanden ist. Um die Nachricht selbst zu verdauen, verwenden wir die folgenden zwei Codezeilen −

for i in range(1000):  
digest = sha256(str(hash(message)) + str(i))

Wir fügen immer wieder eine neue Nummer hinzu ich in den Nachrichten-Hash in jeder Iteration und generieren Sie einen neuen Digest für die kombinierte Nachricht. Als Eingabe für die sha256 Funktion ändert sich in jeder Iteration, die verdauen auch der Wert würde sich ändern. Wir prüfen, ob das verdauen Wert hat oben eingestellt Präfix .

Was ist Lagerfeuermünze?
if digest.startswith(prefix):  

Wenn die Bedingung erfüllt ist, beenden wir die zum Schleife und gib die zurück verdauen Wert für den Anrufer.

Das ganze Bergwerk Code wird hier angezeigt −

def mine(message, difficulty=1):  
assert difficulty >= 1
prefix = ‘1’ * difficulty
for i in range(1000):
digest = sha256(str(hash(message)) + str(i))
if digest.startswith(prefix):
print ('after ' + str(i) + ' iterations found nonce: '+ digest)
return digest

Für Ihr Verständnis haben wir die drucken -Anweisung, die den Digest-Wert und die Anzahl der Iterationen ausgibt, die erforderlich waren, um die Bedingung zu erfüllen, bevor die Funktion verlassen wird.

Testen der Mining-Funktion

Um unsere Mining-Funktion zu testen, führen Sie einfach die folgende Anweisung aus −

mine (test message, 2)  

Wenn Sie den obigen Code ausführen, sehen Sie die Ausgabe ähnlich der untenstehenden −

after 138 iterations found nonce:  
11008a740eb2fa6bf8d55baecda42a41993ca65ce66b2d3889477e6bfad1484c

Beachten Sie, dass der generierte Digest mit 11 beginnt. Wenn Sie den Schwierigkeitsgrad auf 3 ändern, beginnt der generierte Digest mit 111 und erfordert natürlich mehr Iterationen. Wie Sie sehen, kann ein Miner mit mehr Rechenleistung eine bestimmte Nachricht früher abbauen. So konkurrieren die Miner untereinander um ihre Einnahmen.

Jetzt sind wir bereit, unserer Blockchain weitere Blöcke hinzuzufügen.

bash: mongod: Befehl nicht gefunden

11. Blöcke hinzufügen

Jeder Miner holt die Transaktionen aus einem zuvor erstellten Transaktionspool ab. Um die Anzahl der bereits abgebauten Nachrichten zu verfolgen, müssen wir eine globale Variable erstellen −

last_transaction_index = 0  

Wir werden jetzt unseren ersten Miner haben, der der Blockchain einen Block hinzufügt.

Hinzufügen des ersten Blocks

Um einen neuen Block hinzuzufügen, erstellen wir zuerst eine Instanz des Block Klasse.

block = Block()  

Wir holen die Top 3 Transaktionen aus der Warteschlange ab −

for i in range(3):  
temp_transaction = transactions[last_transaction_index]

block.verified_transactions.append (temp_transaction)
last_transaction_index += 1

block.previous_block_hash = last_block_hash
block.Nonce = mine (block, 2)
digest = hash (block)

TPCoins.append (block)
last_block_hash = digest

Wenn Sie diese beiden Blöcke hinzufügen, sehen Sie auch die Anzahl der Iterationen, die erforderlich waren, um die Nonce zu finden. Zu diesem Zeitpunkt besteht unsere Blockchain aus insgesamt 4 Blöcken, einschließlich des Genesis-Blocks.

Dumping der gesamten Blockchain

Sie können den Inhalt der gesamten Blockchain mit der folgenden Anweisung überprüfen −

dump_blockchain(TPCoins)  

Sie würden die Ausgabe ähnlich der unten gezeigten sehen −

Number of blocks in the chain: 4  
block # 0
sender: Genesis

recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100ed272b52ccb539e2cd779
c6cc10ed1dfadf5d97c6ab6de90ed0372b2655626fb79f62d0e01081c163b0864cc68d426bbe943
8e8566303bb77414d4bfcaa3468ab7febac099294de10273a816f7047d4087b4bafa11f141544d4
8e2f10b842cab91faf33153900c7bf6c08c9e47a7df8aa7e60dc9e0798fb2ba3484bbdad2e44302
03010001

value: 500.0

time: 2019-01-14 16:18:02.042739


=====================================
block # 1
sender:
30819f300d06092a864886f70d010101050003818d0030818902818100bb064c99c492144a9f463
480273aba93ac1db1f0da3cb9f3c1f9d058cf499fd8e54d244da0a8dd6ddd329ec86794b04d773e
b4841c9f935ea4d9ccc2821c7a1082d23b6c928d59863407f52fa05d8b47e5157f8fe56c2ce3279
c657f9c6a80500073b0be8093f748aef667c03e64f04f84d311c4d866c12d79d3fc3034563dfb02
03010001

recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100be93b516b28c6e674abe7
abdb11ce0fdf5bb728b75216b73f37a6432e4b402b3ad8139b8c0ba541a72c8add126b6e1a1308f
b98b727beb63c6060356bb177bb7d54b54dbe87aee7353d0a6baa9397704de625d1836d3f42c7ee
5683f6703259592cc24b09699376807f28fe0e00ff882974484d805f874260dfc2d1627473b9102
03010001

value: 15.0

time: 2019-01-14 16:18:01.859915


sender:
30819f300d06092a864886f70d010101050003818d0030818902818100bb064c99c492144a9f463
480273aba93ac1db1f0da3cb9f3c1f9d058cf499fd8e54d244da0a8dd6ddd329ec86794b04d773e
b4841c9f935ea4d9ccc2821c7a1082d23b6c928d59863407f52fa05d8b47e5157f8fe56c2ce3279
c657f9c6a80500073b0be8093f748aef667c03e64f04f84d311c4d866c12d79d3fc3034563dfb02
03010001

recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100a070c82b34ae143cbe59b
3a2afde7186e9d5bc274955d8112d87a00256a35369acc4d0edfe65e8f9dc93fbd9ee74b9e7ea12
334da38c8c9900e6ced1c4ce93f86e06611e656521a1eab561892b7db0961b4f212d1fd5b5e49ae
09cf8c603a068f9b723aa8a651032ff6f24e5de00387e4d062375799742a359b8f22c5362e56502
03010001

value: 6.0

time: 2019-01-14 16:18:01.860966


sender:
30819f300d06092a864886f70d010101050003818d0030818902818100be93b516b28c6e674abe7
abdb11ce0fdf5bb728b75216b73f37a6432e4b402b3ad8139b8c0ba541a72c8add126b6e1a1308f
b98b727beb63c6060356bb177bb7d54b54dbe87aee7353d0a6baa9397704de625d1836d3f42c7ee
5683f6703259592cc24b09699376807f28fe0e00ff882974484d805f874260dfc2d1627473b9102
03010001

recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100cba097c0854876f41338c
62598c658f545182cfa4acebce147aedf328181f9c4930f14498fd03c0af6b0cce25be99452a81d
f4fa30a53eddbb7bb7b203adf8764a0ccd9db6913a576d68d642d8fd47452590137869c25d9ff83
d68ebe6d616056a8425b85b52e69715b8b85ae807b84638d8f00e321b65e4c33acaf6469e18e302
03010001

value: 2.0

time: 2019-01-14 16:18:01.861958


=====================================
block # 2
sender:
30819f300d06092a864886f70d010101050003818d0030818902818100a070c82b34ae143cbe59b
3a2afde7186e9d5bc274955d8112d87a00256a35369acc4d0edfe65e8f9dc93fbd9ee74b9e7ea12
334da38c8c9900e6ced1c4ce93f86e06611e656521a1eab561892b7db0961b4f212d1fd5b5e49ae
09cf8c603a068f9b723aa8a651032ff6f24e5de00387e4d062375799742a359b8f22c5362e56502
03010001

recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100be93b516b28c6e674abe7
abdb11ce0fdf5bb728b75216b73f37a6432e4b402b3ad8139b8c0ba541a72c8add126b6e1a1308f
b98b727beb63c6060356bb177bb7d54b54dbe87aee7353d0a6baa9397704de625d1836d3f42c7ee
5683f6703259592cc24b09699376807f28fe0e00ff882974484d805f874260dfc2d1627473b9102
03010001

value: 4.0

time: 2019-01-14 16:18:01.862946


sender:
30819f300d06092a864886f70d010101050003818d0030818902818100cba097c0854876f41338c
62598c658f545182cfa4acebce147aedf328181f9c4930f14498fd03c0af6b0cce25be99452a81d
f4fa30a53eddbb7bb7b203adf8764a0ccd9db6913a576d68d642d8fd47452590137869c25d9ff83
d68ebe6d616056a8425b85b52e69715b8b85ae807b84638d8f00e321b65e4c33acaf6469e18e302
03010001

recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100a070c82b34ae143cbe59b
3a2afde7186e9d5bc274955d8112d87a00256a35369acc4d0edfe65e8f9dc93fbd9ee74b9e7ea12
334da38c8c9900e6ced1c4ce93f86e06611e656521a1eab561892b7db0961b4f212d1fd5b5e49ae
09cf8c603a068f9b723aa8a651032ff6f24e5de00387e4d062375799742a359b8f22c5362e56502
03010001

value: 7.0

time: 2019-01-14 16:18:01.863932


sender:
30819f300d06092a864886f70d010101050003818d0030818902818100be93b516b28c6e674abe7
abdb11ce0fdf5bb728b75216b73f37a6432e4b402b3ad8139b8c0ba541a72c8add126b6e1a1308f
b98b727beb63c6060356bb177bb7d54b54dbe87aee7353d0a6baa9397704de625d1836d3f42c7ee
5683f6703259592cc24b09699376807f28fe0e00ff882974484d805f874260dfc2d1627473b9102
03010001

recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100a070c82b34ae143cbe59b
3a2afde7186e9d5bc274955d8112d87a00256a35369acc4d0edfe65e8f9dc93fbd9ee74b9e7ea12
334da38c8c9900e6ced1c4ce93f86e06611e656521a1eab561892b7db0961b4f212d1fd5b5e49ae
09cf8c603a068f9b723aa8a651032ff6f24e5de00387e4d062375799742a359b8f22c5362e56502
03010001

value: 3.0

time: 2019-01-14 16:18:01.865099


=====================================
block # 3
sender:
30819f300d06092a864886f70d010101050003818d0030818902818100a070c82b34ae143cbe59b
3a2afde7186e9d5bc274955d8112d87a00256a35369acc4d0edfe65e8f9dc93fbd9ee74b9e7ea12
334da38c8c9900e6ced1c4ce93f86e06611e656521a1eab561892b7db0961b4f212d1fd5b5e49ae
09cf8c603a068f9b723aa8a651032ff6f24e5de00387e4d062375799742a359b8f22c5362e56502
03010001

recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100bb064c99c492144a9f463
480273aba93ac1db1f0da3cb9f3c1f9d058cf499fd8e54d244da0a8dd6ddd329ec86794b04d773e
b4841c9f935ea4d9ccc2821c7a1082d23b6c928d59863407f52fa05d8b47e5157f8fe56c2ce3279
c657f9c6a80500073b0be8093f748aef667c03e64f04f84d311c4d866c12d79d3fc3034563dfb02
03010001

value: 8.0

time: 2019-01-14 16:18:01.866219


sender:
30819f300d06092a864886f70d010101050003818d0030818902818100a070c82b34ae143cbe59b
3a2afde7186e9d5bc274955d8112d87a00256a35369acc4d0edfe65e8f9dc93fbd9ee74b9e7ea12
334da38c8c9900e6ced1c4ce93f86e06611e656521a1eab561892b7db0961b4f212d1fd5b5e49ae
09cf8c603a068f9b723aa8a651032ff6f24e5de00387e4d062375799742a359b8f22c5362e56502
03010001

recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100be93b516b28c6e674abe7
abdb11ce0fdf5bb728b75216b73f37a6432e4b402b3ad8139b8c0ba541a72c8add126b6e1a1308f
b98b727beb63c6060356bb177bb7d54b54dbe87aee7353d0a6baa9397704de625d1836d3f42c7ee
5683f6703259592cc24b09699376807f28fe0e00ff882974484d805f874260dfc2d1627473b9102
03010001

value: 1.0

time: 2019-01-14 16:18:01.867223


sender:
30819f300d06092a864886f70d010101050003818d0030818902818100cba097c0854876f41338c
62598c658f545182cfa4acebce147aedf328181f9c4930f14498fd03c0af6b0cce25be99452a81d
f4fa30a53eddbb7bb7b203adf8764a0ccd9db6913a576d68d642d8fd47452590137869c25d9ff83
d68ebe6d616056a8425b85b52e69715b8b85ae807b84638d8f00e321b65e4c33acaf6469e18e302
03010001

recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100bb064c99c492144a9f463
480273aba93ac1db1f0da3cb9f3c1f9d058cf499fd8e54d244da0a8dd6ddd329ec86794b04d773e
b4841c9f935ea4d9ccc2821c7a1082d23b6c928d59863407f52fa05d8b47e5157f8fe56c2ce3279
c657f9c6a80500073b0be8093f748aef667c03e64f04f84d311c4d866c12d79d3fc3034563dfb02
03010001

value: 5.0

time: 2019-01-14 16:18:01.868241


=====================================

12. Geltungsbereich und Fazit

In diesem Tutorial haben wir gelernt, wie man ein Blockchain-Projekt in Python erstellt. Es gibt viele Bereiche, in denen Sie diesem Projekt weitere Funktionen hinzufügen müssen.

Sie müssen beispielsweise Funktionen zum Verwalten der Transaktionswarteschlange schreiben. Nachdem die Transaktionen abgebaut und der abgebaute Block vom System akzeptiert wurde, müssen sie nicht mehr gespeichert werden.

Außerdem würden die Miner sicherlich am liebsten die Transaktionen mit der höchsten Gebühr abholen. Gleichzeitig müssen Sie sicherstellen, dass die Transaktionen mit geringer oder keiner Gebühr für immer verhungern.

Sie müssen Algorithmen für die Verwaltung der Warteschlange entwickeln. Außerdem enthält das aktuelle Tutorial nicht den Clientschnittstellencode. Sie müssen dies sowohl für normale Kunden als auch für die Miner entwickeln. Das vollwertige Blockchain-Projekt würde mehrere weitere Codezeilen umfassen und würde den Rahmen dieses Tutorials sprengen. Der interessierte Leser kann die Quell-Bitcoin zum weiteren Studium.

Schlussfolgerungen

Dieses knackige Tutorial sollte Ihnen den Einstieg in die Erstellung Ihres eigenen Blockchain-Projekts erleichtern.

Für eine vollwertige Blockchain-Projektentwicklung können Sie mehr von der . erfahren Quell-Bitcoin .

Danke fürs Lesen. Wenn dir dieser Beitrag gefallen hat, teile ihn mit all deinen Programmierfreunden!

#python #blockchain #solidität #bitcoin #kryptowährung