Comment créer une Blockchain avec Python ?
Bitcoin, cette monnaie numérique révolutionnaire, repose sur une technologie fascinante : la Blockchain. Aujourd'hui, nous allons explorer cette base technologique en construisant notre propre Blockchain, de A à Z, en utilisant Python.
La Blockchain : une introduction
En 2008, un mystérieux individu ou groupe, connu sous le nom de Satoshi Nakamoto, a publié le document fondateur de Bitcoin. Ce document présentait Bitcoin comme une version décentralisée de la monnaie électronique, permettant des échanges directs sans intervention d'organismes financiers traditionnels. Ce que beaucoup ignorent, c'est que ce même texte introduisait une nouvelle manière de stocker des informations : la Blockchain.
La technologie de la chaîne de blocs
Pour faire simple, la Blockchain est un registre numérique partagé et inviolable, qui enregistre les transactions sur un réseau informatique décentralisé.
Le terme Blockchain se décompose en deux éléments principaux :
- Bloc : Un conteneur où sont regroupées des transactions.
- Chaîne : Une séquence de blocs liés les uns aux autres.
Ainsi, la Blockchain est une série de blocs connectés, chaque bloc conservant un ensemble spécifique de transactions.
Chaque bloc est construit sur le bloc précédent, créant une chaîne de blocs irréversible. Cette interdépendance assure un système robuste et immuable, où l'intégrité des données peut être vérifiée par toute personne autorisée.
La Blockchain offre un ensemble de caractéristiques intéressantes :
- Inaltérabilité de l'historique des transactions.
- Conservation durable des informations.
- Absence d'erreurs dans les données stockées.
Aujourd'hui, la Blockchain est utilisée dans de nombreux systèmes, comme les cryptomonnaies, les transferts d'actifs (NFT) et potentiellement, les systèmes de vote du futur.
Il est important de noter qu'une Blockchain en Python ne requiert pas un code complexe de milliers de lignes. À sa base, il s'agit d'une simple liste de transactions liées entre elles.
Cette explication est un résumé, mais pour une compréhension plus approfondie, n'hésitez pas à consulter notre guide complet sur la Blockchain pour débutants.
Passons maintenant à la pratique : construisons une Blockchain simple avec Python.
Développer une Blockchain en Python
Avant de commencer, définissons les objectifs de ce tutoriel :
- Créer un système Blockchain de base en Python.
- Utiliser notre Blockchain avec des transactions sous forme de chaînes de caractères.
- Vérifier l'immuabilité de notre Blockchain.
Nous n'utiliserons pas de JSON, mais des listes Python, pour simplifier le processus et nous concentrer sur les principes essentiels de la Blockchain.
Voici ce dont vous aurez besoin pour suivre ce tutoriel :
Création de la classe Block
Ouvrez votre éditeur de code favori et créez un fichier nommé main.py. C'est le fichier que nous allons utiliser.
Importez ensuite le module hashlib. Ce module nous permet de générer des codes cryptographiques à sens unique. Les techniques de cryptographie, comme le hachage, sont essentielles à la sécurité des transactions dans la Blockchain.
Une fonction de hachage est un algorithme qui prend des données d'entrée et renvoie un identifiant unique, appelé "résumé" ou "empreinte". Une petite modification dans les données d'entrée entraîne une modification significative de l'identifiant de sortie. Nous verrons cela en pratique par la suite.
Pour le moment, importez simplement le module intégré hashlib :
# main.py file """ Une Blockchain simple en Python """ import hashlib
Ce module inclut les principaux algorithmes de hachage nécessaires. Nous utiliserons la fonction hashlib.sha256().
Passons maintenant à la définition de notre classe GeekCoinBlock, le bloc de notre Blockchain.
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()
Ce code peut sembler complexe au premier abord. Analysons chaque partie dans la section suivante.
Explication de GeekCoinBlock
Tout d'abord, nous créons une classe nommée GeekCoinBlock, qui servira de modèle pour nos blocs, avec leurs propriétés (attributs) et comportements (méthodes).
Ensuite, nous définissons la méthode __init__ (le constructeur), qui est appelée à chaque création d'un objet GeekCoinBlock.
Cette méthode a trois paramètres :
self(l'instance de chaque objet)previous_block_hash(une référence au bloc précédent)transaction_list(une liste des transactions du bloc actuel).
Nous stockons le hachage du bloc précédent et la liste de transactions. Nous créons également une variable d'instance block_data sous forme de chaîne de caractères. Dans les véritables cryptomonnaies, ces informations seraient stockées sous forme de hachage, mais nous utilisons ici une chaîne pour simplifier.
Enfin, nous créons le block_hash, que les blocs suivants utiliseront pour se connecter à la chaîne. C'est ici que hashlib intervient : au lieu de créer une fonction de hachage personnalisée, nous utilisons la fonction sha256 pour garantir l'immuabilité de nos blocs.
Cette fonction prend en paramètres des chaînes encodées (ou des octets). C'est pourquoi nous utilisons la méthode block_data.encode(). Après cela, nous appelons hexdigest() pour obtenir les données encodées sous forme hexadécimale.
Pour mieux comprendre, expérimentons avec hashlib dans un interpréteur Python.
In [1]: import hashlib In [2]: message = "Python est génial" 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 n'est pas génial") In [7]: h2 Out[7]: <sha256 ... object @ 0x7efcd55bfc90> In [8]: h2.hexdigest() Out[8]: 'fefe510a6a ... 97e010c0ea34'
Comme vous pouvez le constater, une petite modification dans l'entrée ("Python est génial" à "Python n'est pas génial") génère un hachage complètement différent. C'est la clé de l'intégrité de la Blockchain. Si vous modifiez une partie de la Blockchain, son hachage sera radicalement altéré. C'est pourquoi on dit souvent qu'une Blockchain est "incorruptible".
Utilisation de notre classe Block
Nous allons créer une classe Blockchain complète plus tard, mais pour l'instant, utilisons notre classe Block pour créer une chaîne de blocs.
Dans le même fichier, créez deux transactions représentées par des chaînes de caractères, par exemple :
class GeekCoinBlock:
...
t1 = "Noé envoie 5 GC à Marc"
t2 = "Marc envoie 2.3 GC à James"
t3 = "James envoie 4.2 GC à Alisson"
t4 = "Alisson envoie 1.1 GC à Noé"
Ici, GC signifie GeekCoin.
Maintenant, construisons le premier bloc de notre Blockchain avec la classe GeekCoinBlock et affichons ses attributs. Le paramètre previous_hash du bloc genèse (le premier bloc) sera une chaîne arbitraire ou un hachage. Dans ce cas, nous utilisons "firstblock".
block1 = GeekCoinBlock('firstblock', [t1, t2])
print(f"Données du bloc 1: {block1.block_data}")
print(f"Hash du bloc 1: {block1.block_hash}")
Ensuite, nous faisons la même chose pour le second bloc, mais en utilisant le hachage du premier bloc comme paramètre previous_hash.
block2 = GeekCoinBlock(block1.block_hash, [t3, t4])
print(f"Données du bloc 2: {block2.block_data}")
print(f"Hash du bloc 2: {block2.block_hash}")
Exécutez ce code et analysons les résultats. Dans votre terminal, entrez :
❯ python main.py Données du bloc 1: Noé envoie 5 GC à Marc - Marc envoie 2.3 GC à James - firstblock Hash du bloc 1: 01e4e15242a9601725f4a86ca01fbddaaec7105b442955bb0efcadbfc759806d Données du bloc 2: James envoie 4.2 GC à Alisson - Alisson envoie 1.1 GC à Noé - 01e4e15242a9601725f4a86ca01fbddaaec7105b442955bb0efcadbfc759806d Hash du bloc 2: 448c4306caf7f6937b0307f92f27fbea3bb73b3470363dee5026a1209dadcfa8
Pour l'instant, vous ne voyez que du texte et des hachages de 64 caractères, mais c'est le mécanisme de base d'une Blockchain.
Tout commence avec un bloc genèse, la base de tous les autres blocs.
N'importe qui peut vérifier l'intégrité de la chaîne, ce qui fait de la Blockchain un système sécurisé. Par exemple, si nous modifions légèrement une transaction :
t2 = "Marc envoie 2.3 GC à James" -> t2 = "Marc envoie 3.2 GC à James"
Nous observons une modification radicale dans les hachages des blocs.
Données du bloc 1: Noé envoie 5 GC à Marc - Marc envoie 3.2 GC à James - firstblock Hash du bloc 1: 7a990bf1d70230bf2dad6160496c0b3046da7a17b1281fd1d4c63d4eac58e78c Données du bloc 2: James envoie 4.2 GC à Alisson - Alisson envoie 1.1 GC à Noé - 7a990bf1d70230bf2dad6160496c0b3046da7a17b1281fd1d4c63d4eac58e78c Hash du bloc 2: 569b977306ce88b53e001dca7ba00c03a51c60d6df4650e7657dcd136f2da0ac
Vous pouvez retrouver le projet en cours sur ce dépôt GitHub.
Coder une Blockchain
Il n'est pas optimal de baser l'intégrité de notre système sur des variables codées en dur. Il nous faut une autre approche.
Nous avons les blocs. Il est temps de créer une classe qui les connecte en une Blockchain.
Commençons par supprimer nos transactions et objets de bloc précédents et utilisons le code ci-dessous.
# main.py
class Blockchain:
def __init__(self):
self.chain = []
self.generate_genesis_block()
def generate_genesis_block(self):
self.chain.append(GeekCoinBlock("0", ['Bloc Genèse']))
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"Données {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]
C'est encore une fois un bloc de code important. Analysons chaque partie :
self.chain: La liste où sont stockés tous les blocs. Nous accédons aux blocs via les index de liste.generate_genesis_block: Ajoute le bloc genèse (le premier bloc) à la chaîne. Le hachage précédent est "0" et la liste des transactions est simplement "Bloc Genèse".create_block_from_transaction: Permet d'ajouter des blocs à la chaîne en utilisant une liste de transactions. Il serait fastidieux de créer manuellement un bloc à chaque transaction.display_chain: Affiche la chaîne de blocs avec une bouclefor.last_block: Une propriété qui permet d'accéder au dernier élément de la chaîne. Nous l'avons utilisée dans la méthodecreate_block_from_transaction.
Testons cette Blockchain.
# main.py
import hashlib
class GeekCoinBlock:
...
class Blockchain:
...
t1 = "Georges envoie 3.1 GC à Joe"
t2 = "Joe envoie 2.5 GC à Adam"
t3 = "Adam envoie 1.2 GC à Bob"
t4 = "Bob envoie 0.5 GC à Charlie"
t5 = "Charlie envoie 0.2 GC à David"
t6 = "David envoie 0.1 GC à 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()
Exécutez le fichier main.py.
Data 1: Bloc Genèse - 0 Hash 1: 39331a6a2ea1cf31a5014b2a7c9e8dfad82df0b0666e81ce04cf8173cc5aed3e Data 2: Georges envoie 3.1 GC à Joe - Joe envoie 2.5 GC à Adam - 39331a6a2ea1cf31a5014b2a7c9e8dfad82df0b0666e81ce04cf8173cc5aed3e Hash 2: 98cf363aecb33989aea0425a3c1287268bd86f63851bc08c0734a31db08506d5 Data 3: Adam envoie 1.2 GC à Bob - Bob envoie 0.5 GC à Charlie - 98cf363aecb33989aea0425a3c1287268bd86f63851bc08c0734a31db08506d5 Hash 3: 6f1cfcc3082488b97db8fdf8ed33f9ac7519be3e285a37a6fcc2f1904f373589 Data 4: Charlie envoie 0.2 GC à David - David envoie 0.1 GC à Eric - 6f1cfcc3082488b97db8fdf8ed33f9ac7519be3e285a37a6fcc2f1904f373589 Hash 4: 869df2f03c9860767d35b30a46233fbeea89a3000ae5019d1491e3829d1ab929
Félicitations ! 🙌 Vous venez de créer une Blockchain simple en Python, de zéro.
Vous pouvez maintenant renforcer l'immuabilité de la Blockchain en utilisant des getters et des setters et implémenter d'autres fonctionnalités comme la preuve de travail, le minage, ou tout autre concept expliqué dans notre article sur les bases du minage de Bitcoin.
Conclusion
La Blockchain est la technologie derrière Bitcoin, Ethereum et toutes les autres cryptomonnaies. Dans cet article, vous avez appris à créer une Blockchain avec Python en utilisant des algorithmes de hachage comme sha256, des classes et des objets.
Votre défi est maintenant de créer un système de minage et pourquoi pas, de l'implémenter avec une API REST en utilisant des frameworks comme Django ou Flask.
Beaucoup de gens font fortune avec les cryptomonnaies. Imaginez ce que vous pourriez faire en créant la vôtre. 🤑
Continuez à coder ! 👨💻