Comment créer une blockchain avec Python ?

Publié: 2021-11-03

Saviez-vous que Bitcoin est construit sur Blockchain ? Aujourd'hui, nous allons créer une Blockchain avec Python à partir de zéro.

Qu'est-ce que la blockchain ?

En 2008, le document Bitcoin a été publié par un individu ou un groupe inconnu nommé Satoshi Nakamoto. Bitcoin est sorti comme une version peer-to-peer de la monnaie électronique qui permettait des transactions sans passer par des institutions centralisées (banques). La plupart des gens ne savent pas que dans ce même article, Satoshi a défini un moyen distribué de stocker des informations, aujourd'hui connu sous le nom de Blockchain.

Technologie blockchain
Technologie blockchain

Pour faire simple, Blockchain est un grand livre numérique partagé et immuable qui stocke les transactions sur un réseau décentralisé d'ordinateurs.

Nous pouvons diviser Blockchain en deux termes simples :

  • Block : Un espace où nous stockons les transactions
  • Chaîne : un ensemble d'enregistrements liés

Cela définit Blockchain comme une chaîne de blocs liés, où chaque bloc stocke une transaction effectuée avec des paramètres spécifiques.

Chaque bloc est construit sur un autre bloc, créant une chaîne irréversible de blocs. En d'autres termes, chaque bloc dépend d'un autre. Cela s'avère être un système robuste et immuable dans lequel toute personne disposant des autorisations appropriées peut vérifier l'intégrité.

Blockchain introduit un ensemble intéressant de fonctionnalités :

  • Immuabilité de l'histoire
  • Persistance des informations
  • Aucune erreur avec les données stockées

De nombreux systèmes reposent actuellement sur Blockchain, tels que les crypto-monnaies, le transfert d'actifs (NFT) et peut-être dans un avenir proche, le vote.

Il convient de mentionner qu'une Blockchain Python ne doit pas être un programme complexe avec des milliers de lignes de code. À la base, il s'agirait d'une liste de transactions liées les unes aux autres.

Bien sûr, c'était une brève explication, mais si vous voulez un guide complet, nous avons produit un tutoriel complet sur Blockchain pour les débutants. Assurez-vous de le vérifier.

Sans plus tarder, construisons une Blockchain simple avec Python.

Construire une blockchain avec Python

Avant de commencer, définissons ce que nous allons faire dans ce tutoriel :

  • Construire un système Blockchain simple écrit en Python
  • Utilisez notre Blockchain avec des transactions préétablies représentées sous forme de chaînes
  • Testez l'immuabilité de notre Blockchain

Nous n'allons pas utiliser JSON mais des listes Python. Cela nous permettra de simplifier le processus et de nous concentrer sur l'application des concepts clés d'une blockchain.

Ce dont vous aurez besoin pour suivre ce tutoriel :

  • Compréhension des classes et des méthodes en Python
  • Utilisation de base de la ligne de commande

Création de la classe Block

Ouvrez votre éditeur de code préféré et créez un fichier main.py. Ce sera le fichier avec lequel nous travaillerons.

Maintenant, importez hashlib, un module qui nous permet de créer des messages cryptés à sens unique. Les techniques de cryptographie comme le hachage font que Blockchain crée des transactions sécurisées.

Une fonction de hachage est un algorithme qui prend des données (généralement une chaîne encodée) et renvoie un identifiant unique, souvent nommé « condensé » ou « signature ». Cette dernière partie est vitale ; avec une fonction de hachage, une légère différence dans l'entrée produit un identifiant radicalement différent en sortie. Nous verrons cela en action plus tard.

Pour l'instant, importez simplement le module intégré hashlib :

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

Ce module comprend la plupart des algorithmes de hachage dont vous aurez besoin. N'oubliez pas que nous utiliserons la fonction hashlib.sha256() .

Passons maintenant au GeekCoinBlock, notre nom de blockchain totalement original.

 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()

Je sais que cela peut entraîner un morceau de code maladroit. Décomposons chaque partie dans la section suivante.

Explication GeekCoinBlock

Tout d'abord, nous créons une classe nommée GeekCoinBlock , un wrapper pour les objets qui auront certaines caractéristiques (attributs) et comportements (méthodes).

Ensuite, nous définissons la méthode __ init__ (également nommée constructeur), qui est invoquée à chaque fois qu'un objet GeekCoinBlock est créé.

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 de transactions effectuées dans le bloc actuel).

Nous stockons la liste de hachage et de transaction précédente et créons une variable d'instance block_data sous forme de chaîne. Cela ne se produit pas avec les vraies crypto-monnaies, dans lesquelles nous stockons ce type de données sous forme d'un autre hachage, mais pour des raisons de simplicité, nous stockerons chaque bloc de données sous forme de chaîne.

Enfin, nous créons le block_hash , que les autres blocs utiliseront pour continuer la chaîne. Voici où hashlib est utile; au lieu de créer une fonction de hachage personnalisée, nous pouvons utiliser le sha256 pré-construit pour créer des blocs immuables.

Cette fonction reçoit des chaînes encodées (ou octets) comme paramètres. C'est pourquoi nous utilisons la méthode block_data.encode() . Après cela, nous appelons hexdigest() pour renvoyer les données encodées au format hexadécimal.

Je sais que tout cela peut être écrasant, alors jouons avec hashlib sur un shell Python.

 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'

Comme vous pouvez le voir, un léger changement dans l'entrée comme « Python est génial » en « Python n'est pas génial » peut produire un hachage totalement différent. Tout cela a à voir avec l'intégrité de la Blockchain. Si vous introduisez quelques petits changements dans une blockchain, son hachage changera radicalement. C'est la raison pour laquelle le dicton « Vous ne pouvez pas corrompre une blockchain » est vrai.

Utiliser notre Block Class

Nous construirons une classe Blockchain entière plus tard, mais pour l'instant, utilisons notre classe Block pour créer une chaîne de blocs (Blockchain).

Dans le même fichier, créez quelques transactions composées de chaînes simples stockées dans des variables, par exemple :

 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"

Bien sûr, GC fait référence à GeekCoin

Maintenant, construisez le premier bloc de notre Blockchain en utilisant la classe GeekCoinBlock et imprimez ses attributs. Tenez compte du fait que le paramètre previous_hash du bloc genesis (premier bloc qui précède les autres blocs) sera toujours une chaîne ou un hachage arbitraire, dans ce cas, "firstblock".

 block1 = GeekCoinBlock('firstblock', [t1, t2]) print(f"Block 1 data: {block1.block_data}") print(f"Block 1 hash: {block1.block_hash}")

Ensuite, nous faisons de même avec le deuxième bloc, mais en passant le hachage du premier bloc comme 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}")

Exécutons et analysons la sortie que nous obtenons de ce morceau de code. Encore une fois, tapez dans votre terminal :

 ❯ 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

Pour l'instant, vous ne voyez que du texte et quelques hachages de 64 caractères, mais cela reprend à peu près le mécanisme d'une Blockchain.

Vous commencez avec un bloc de genèse, la base de tous les autres blocs.

N'importe qui peut valider l'intégrité de la chaîne, et c'est pourquoi une Blockchain est un système si sécurisé. Par exemple, si nous modifions légèrement le contenu d'une transaction, disons :

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

Nous voyons un changement spectaculaire dans le hachage des blocs.

 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

Vous pouvez voir le projet en cours sur ce référentiel GitHub.

Codage d'une blockchain

Il n'est pas si intelligent de baser l'intégrité de notre système sur des variables codées à la main, nous avons donc besoin d'une autre approche.

Nous avons les blocs. Il est temps de créer une classe qui les rejoint dans une Blockchain.

Commençons par supprimer nos précédentes transactions et objets de blocage, puis en utilisant 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", ['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]

C'est encore un énorme morceau de code. Décomposons chaque partie :

  • self.chain — La liste où tous les blocs sont enregistrés. Nous pouvons accéder à chaque bloc via des index de liste.
  • generate_genesis_block — Ajoute la genèse ou le premier bloc à la chaîne. Le hachage précédent du bloc est « 0 » et la liste des transactions est simplement « Bloc Genesis ».
  • create_block_from_transaction — Cela nous permet d'ajouter des blocs à la chaîne avec juste une liste de transactions. Il serait très ennuyeux de créer un bloc manuellement à chaque fois que l'on veut enregistrer une transaction
  • display_chain — Affiche la chaîne de blocs avec une boucle for
  • last_block — Une propriété qui nous permet d'accéder au dernier élément de la chaîne. Nous l'avons utilisé sur la méthode create_block_from_transaction .

Testons cette Blockchain.

 # 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()

Maintenant, exécutez le fichier main.py.

 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

Toutes nos félicitations! Vous venez de créer une simple blockchain Python à partir de zéro.

Vous pouvez désormais renforcer l'immuabilité de la Blockchain en utilisant des getters et des setters et implémenter d'autres fonctionnalités telles que la preuve de travail, l'exploitation minière ou tout autre concept que nous avons expliqué dans l'article sur les fondamentaux de Bitcoin Mining.

Conclusion

Blockchain est la technologie derrière Bitcoin, Etherium et toutes les autres crypto-monnaies. Dans cet article, vous avez appris à créer une Blockchain avec Python en utilisant des algorithmes de hachage tels que sha256 , des classes et des objets.

Votre défi est 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 grâce aux crypto-monnaies. Imaginez ce que vous pourriez faire si vous en créiez un vous-même.

Continuez à coder !