Comment créer votre propre crypto-monnaie en utilisant Python

Avec la montée actuelle des crypto-monnaies, la blockchain crée un buzz dans le monde de la technologie. Cette technologie a attiré tellement d'attention principalement en raison de sa capacité à garantir la sécurité, à appliquer la décentralisation et à accélérer les processus dans plusieurs secteurs, en particulier dans le secteur financier.

Essentiellement, une blockchain est une base de données publique qui documente et authentifie de manière irréversible la possession et la transmission d'actifs numériques. Les monnaies numériques, comme Bitcoin et Ethereum, sont basées sur ce concept. La blockchain est une technologie passionnante que vous pouvez utiliser pour transformer les capacités de vos applications.

Récemment, nous avons vu des gouvernements, des organisations et des particuliers utiliser la technologie de la blockchain pour créer leurs propres crypto-monnaies et éviter d'être laissés pour compte. Notamment, lorsque Facebook a proposé sa propre crypto-monnaie, appelée Libra, l'annonce a remué de nombreuses eaux à travers le monde.

Et si vous pouviez également suivre et créer votre propre version d'une crypto-monnaie?

J'ai réfléchi à cela et j'ai décidé de développer un algorithme qui crée une crypto.

J'ai décidé d'appeler la crypto-monnaie fccCoin .

Dans ce tutoriel, je vais illustrer le processus étape par étape que j'ai utilisé pour créer la monnaie numérique (j'ai utilisé les concepts orientés objet du langage de programmation Python).

Voici le plan de base de l'algorithme de la blockchain pour créer le fccCoin :

class Block: def __init__(): #first block class pass def calculate_hash(): #calculates the cryptographic hash of every block class BlockChain: def __init__(self): # constructor method pass def construct_genesis(self): # constructs the initial block pass def construct_block(self, proof_no, prev_hash): # constructs a new block and adds it to the chain pass @staticmethod def check_validity(): # checks whether the blockchain is valid pass def new_data(self, sender, recipient, quantity): # adds a new transaction to the data of the transactions pass @staticmethod def construct_proof_of_work(prev_proof): # protects the blockchain from attack pass @property def last_block(self): # returns the last block in the chain return self.chain[-1] 

Maintenant, laissez-moi vous expliquer ce qui se passe…

1. Construire la première classe Block

Une blockchain comprend plusieurs blocs qui sont joints les uns aux autres (cela semble familier, non?).

Le chaînage des blocs a lieu de telle sorte que si un bloc est altéré, le reste de la chaîne devient invalide.

En appliquant le concept ci-dessus, j'ai créé la classe de bloc initiale suivante:

import hashlib import time class Block: def __init__(self, index, proof_no, prev_hash, data, timestamp=None): self.index = index self.proof_no = proof_no self.prev_hash = prev_hash self.data = data self.timestamp = timestamp or time.time() @property def calculate_hash(self): block_of_string = "{}{}{}{}{}".format(self.index, self.proof_no, self.prev_hash, self.data, self.timestamp) return hashlib.sha256(block_of_string.encode()).hexdigest() def __repr__(self): return "{} - {} - {} - {} - {}".format(self.index, self.proof_no, self.prev_hash, self.data, self.timestamp) 

Comme vous pouvez le voir dans le code ci-dessus, j'ai défini la fonction __init __ () , qui sera exécutée lorsque la classe Block est lancée, comme dans toute autre classe Python.

J'ai fourni les paramètres suivants à la fonction d'initiation:

  • self - cela fait référence à l'instance de la classe Block , ce qui permet d'accéder aux méthodes et attributs associés à la classe;
  • index - cela garde la trace de la position du bloc dans la blockchain;
  • proof_no - c'est le nombre produit lors de la création d'un nouveau bloc (appelé extraction);
  • prev_hash - cela fait référence au hachage du bloc précédent dans la chaîne;
  • données - cela donne un enregistrement de toutes les transactions effectuées, comme la quantité achetée;
  • horodatage - ceci place un horodatage pour les transactions.

La deuxième méthode de la classe, Calculate_hash , générera le hachage des blocs en utilisant les valeurs ci-dessus. Le module SHA-256 est importé dans le projet pour aider à obtenir les hachages des blocs.

Une fois que les valeurs ont été saisies dans l'algorithme de hachage cryptographique, la fonction renvoie une chaîne de 256 bits représentant le contenu du bloc.

C'est ainsi que la sécurité est assurée dans les blockchains - chaque bloc aura un hachage et ce hachage reposera sur le hachage du bloc précédent.

En tant que tel, si quelqu'un tente de compromettre un bloc de la chaîne, les autres blocs auront des hachages invalides, ce qui entraînera une perturbation de l'ensemble du réseau de la blockchain.

En fin de compte, un bloc ressemblera à ceci:

{ "index": 2, "proof": 21, "prev_hash": "6e27587e8a27d6fe376d4fd9b4edc96c8890346579e5cbf558252b24a8257823", "transactions": [ {'sender': '0', 'recipient': 'Quincy Larson', 'quantity': 1} ], "timestamp": 1521646442.4096143 } 

2. Construire la classe Blockchain

L'idée principale d'une blockchain, comme son nom l'indique, consiste à «enchaîner» plusieurs blocs les uns aux autres.

Par conséquent, je vais construire une classe Blockchain qui sera utile pour gérer le fonctionnement de toute la chaîne. C'est là que se déroulera l'essentiel de l'action.

La classe Blockchain aura diverses méthodes d'aide pour effectuer diverses tâches dans la blockchain.

Laissez-moi vous expliquer le rôle de chacune des méthodes de la classe.

une. Méthode constructeur

Cette méthode garantit que la blockchain est instanciée.

class BlockChain: def __init__(self): self.chain = [] self.current_data = [] self.nodes = set() self.construct_genesis() 

Voici les rôles de ses attributs:

  • self.chain - cette variable conserve tous les blocs;
  • self.current_data - cette variable conserve toutes les transactions terminées dans le bloc;
  • self.construct_genesis () - cette méthode se chargera de la construction du bloc initial.

b. Construire le bloc de genèse

La blockchain nécessite une méthode construct_genesis pour construire le bloc initial de la chaîne. Dans la convention blockchain, ce bloc est spécial car il symbolise le début de la blockchain.

Dans ce cas, construisons-le en passant simplement quelques valeurs par défaut à la méthode construct_block .

J'ai donné à la fois proof_no et prev_hash une valeur de zéro, bien que vous puissiez fournir la valeur de votre choix.

def construct_genesis(self): self.construct_block(proof_no=0, prev_hash=0) def construct_block(self, proof_no, prev_hash): block = Block( index=len(self.chain), proof_no=proof_no, prev_hash=prev_hash, data=self.current_data) self.current_data = [] self.chain.append(block) return block 

c. Construire de nouveaux blocs

La méthode construct_block est utilisée pour créer de nouveaux blocs dans la blockchain.

Voici ce qui se passe avec les différents attributs de cette méthode:

  • index - cela représente la longueur de la blockchain;
  • proof_nor & prev_hash - la méthode de l'appelant les transmet;
  • data - il contient un enregistrement de toutes les transactions qui ne sont incluses dans aucun bloc sur le nœud;
  • self.current_data - ceci est utilisé pour réinitialiser la liste des transactions sur le nœud. Si un bloc a été construit et que les transactions lui sont allouées, la liste est réinitialisée pour s'assurer que les futures transactions sont ajoutées à cette liste. Et, ce processus se déroulera en continu;
  • self.chain.append () - cette méthode joint les blocs nouvellement construits à la chaîne;
  • return - enfin, un objet bloc construit est renvoyé.

ré. Vérification de la validité

La méthode check_validity est importante pour évaluer l'intégrité de la blockchain et s'assurer que les anomalies sont absentes.

Comme mentionné précédemment, les hachages sont essentiels pour la sécurité de la blockchain car même le moindre changement dans l'objet conduira à la génération d'un hachage complètement nouveau.

Par conséquent, cette méthode check_validity utilise des instructions if pour vérifier si le hachage de chaque bloc est correct.

Il vérifie également si chaque bloc pointe vers le bloc précédent droit, en comparant la valeur de leurs hachages. Si tout est correct, il renvoie vrai; sinon, il renvoie false.

@staticmethod def check_validity(block, prev_block): if prev_block.index + 1 != block.index: return False elif prev_block.calculate_hash != block.prev_hash: return False elif not BlockChain.verifying_proof(block.proof_no, prev_block.proof_no): return False elif block.timestamp <= prev_block.timestamp: return False return True 

e. Ajout de données de transactions

La méthode new_data est utilisée pour ajouter les données des transactions à un bloc. C'est une méthode très simple: elle accepte trois paramètres (les détails de l'expéditeur, les détails du destinataire et la quantité) et ajoute les données de transaction à la liste self.current_data .

Chaque fois qu'un nouveau bloc est créé, cette liste est allouée à ce bloc et réinitialisée une fois de plus comme expliqué dans la méthode construct_block .

Once the transaction data has been added to the list, the index of the next block to be created is returned.

This index is calculated by adding 1 to the index of the current block (which is the last in the blockchain). The data will assist a user in submitting the transaction in future.

def new_data(self, sender, recipient, quantity): self.current_data.append({ 'sender': sender, 'recipient': recipient, 'quantity': quantity }) return True 

f. Adding proof of work

Proof of work is a concept that prevents the blockchain from abuse. Simply, its objective is to identify a number that solves a problem after a certain amount of computing work is done.

If the difficulty level of identifying the number is high, it discourages spamming and tampering with the blockchain.

In this case, we’ll use a simple algorithm that discourages people from mining blocks or creating blocks easily.

@staticmethod def proof_of_work(last_proof): '''this simple algorithm identifies a number f' such that hash(ff') contain 4 leading zeroes f is the previous f' f' is the new proof ''' proof_no = 0 while BlockChain.verifying_proof(proof_no, last_proof) is False: proof_no += 1 return proof_no @staticmethod def verifying_proof(last_proof, proof): #verifying the proof: does hash(last_proof, proof) contain 4 leading zeroes? guess = f'{last_proof}{proof}'.encode() guess_hash = hashlib.sha256(guess).hexdigest() return guess_hash[:4] == "0000" 

g. Getting the last block

Lastly, the latest_blockmethod is a helper method that assists in obtaining the last block in the blockchain. Remember that the last block is actually the current block in the chain.

@property def latest_block(self): return self.chain[-1] 

Let’s sum everything together

Here is the entire code for creating the fccCoin cryptocurrency.

You can also get the code on this GitHub repository.

import hashlib import time class Block: def __init__(self, index, proof_no, prev_hash, data, timestamp=None): self.index = index self.proof_no = proof_no self.prev_hash = prev_hash self.data = data self.timestamp = timestamp or time.time() @property def calculate_hash(self): block_of_string = "{}{}{}{}{}".format(self.index, self.proof_no, self.prev_hash, self.data, self.timestamp) return hashlib.sha256(block_of_string.encode()).hexdigest() def __repr__(self): return "{} - {} - {} - {} - {}".format(self.index, self.proof_no, self.prev_hash, self.data, self.timestamp) class BlockChain: def __init__(self): self.chain = [] self.current_data = [] self.nodes = set() self.construct_genesis() def construct_genesis(self): self.construct_block(proof_no=0, prev_hash=0) def construct_block(self, proof_no, prev_hash): block = Block( index=len(self.chain), proof_no=proof_no, prev_hash=prev_hash, data=self.current_data) self.current_data = [] self.chain.append(block) return block @staticmethod def check_validity(block, prev_block): if prev_block.index + 1 != block.index: return False elif prev_block.calculate_hash != block.prev_hash: return False elif not BlockChain.verifying_proof(block.proof_no, prev_block.proof_no): return False elif block.timestamp <= prev_block.timestamp: return False return True def new_data(self, sender, recipient, quantity): self.current_data.append({ 'sender': sender, 'recipient': recipient, 'quantity': quantity }) return True @staticmethod def proof_of_work(last_proof): '''this simple algorithm identifies a number f' such that hash(ff') contain 4 leading zeroes f is the previous f' f' is the new proof ''' proof_no = 0 while BlockChain.verifying_proof(proof_no, last_proof) is False: proof_no += 1 return proof_no @staticmethod def verifying_proof(last_proof, proof): #verifying the proof: does hash(last_proof, proof) contain 4 leading zeroes? guess = f'{last_proof}{proof}'.encode() guess_hash = hashlib.sha256(guess).hexdigest() return guess_hash[:4] == "0000" @property def latest_block(self): return self.chain[-1] def block_mining(self, details_miner): self.new_data( sender="0", #it implies that this node has created a new block receiver=details_miner, quantity= 1, #creating a new block (or identifying the proof number) is awarded with 1 ) last_block = self.latest_block last_proof_no = last_block.proof_no proof_no = self.proof_of_work(last_proof_no) last_hash = last_block.calculate_hash block = self.construct_block(proof_no, last_hash) return vars(block) def create_node(self, address): self.nodes.add(address) return True @staticmethod def obtain_block_object(block_data): #obtains block object from the block data return Block( block_data['index'], block_data['proof_no'], block_data['prev_hash'], block_data['data'], timestamp=block_data['timestamp']) 

Now, let’s test our code to see if it works.

blockchain = BlockChain() print("***Mining fccCoin about to start***") print(blockchain.chain) last_block = blockchain.latest_block last_proof_no = last_block.proof_no proof_no = blockchain.proof_of_work(last_proof_no) blockchain.new_data( sender="0", #it implies that this node has created a new block recipient="Quincy Larson", #let's send Quincy some coins! quantity= 1, #creating a new block (or identifying the proof number) is awarded with 1 ) last_hash = last_block.calculate_hash block = blockchain.construct_block(proof_no, last_hash) print("***Mining fccCoin has been successful***") print(blockchain.chain) 

It worked!

Here is the output of the mining process:

***Mining fccCoin about to start*** [0 - 0 - 0 - [] - 1566930640.2707076] ***Mining fccCoin has been successful*** [0 - 0 - 0 - [] - 1566930640.2707076, 1 - 88914 - a8d45cb77cddeac750a9439d629f394da442672e56edfe05827b5e41f4ba0138 - [{'sender': '0', 'recipient': 'Quincy Larson', 'quantity': 1}] - 1566930640.5363243] 

Conclusion

There you have it!

That’s how you could create your own blockchain using Python.

Let me say that this tutorial just demonstrates the basic concepts for getting your feet wet in the innovative blockchain technology.

If this coin were deployed as-is, it could not meet the present market demands for a stable, secure, and easy-to-use cryptocurrency.

Therefore, it can still be improved by adding additional features to enhance its capabilities for mining and sending financial transactions.

Nonetheless, it’s a good starting point if you decide to make your name known in the amazing world of cryptos.

If you have any comments or questions, please post them below.

Happy (crypto) coding!