Come creare la tua criptovaluta usando Python

Con l'attuale aumento delle criptovalute, la blockchain sta creando un ronzio nel mondo della tecnologia. Questa tecnologia ha attirato così tanta attenzione principalmente per la sua capacità di garantire la sicurezza, imporre il decentramento e accelerare i processi in diversi settori, in particolare nel settore finanziario.

In sostanza, una blockchain è un database pubblico che documenta e autentica in modo irreversibile il possesso e la trasmissione di risorse digitali. Le valute digitali, come Bitcoin ed Ethereum, si basano su questo concetto. Blockchain è una tecnologia entusiasmante che puoi utilizzare per trasformare le capacità delle tue applicazioni.

Ultimamente, abbiamo visto governi, organizzazioni e individui utilizzare la tecnologia blockchain per creare le proprie criptovalute ed evitare di essere lasciati indietro. In particolare, quando Facebook ha proposto la propria criptovaluta, chiamata Libra, l'annuncio ha agitato molte acque in tutto il mondo.

E se potessi anche seguire l'esempio e creare la tua versione di una criptovaluta?

Ci ho pensato e ho deciso di sviluppare un algoritmo che crea una crittografia.

Ho deciso di chiamare la criptovaluta fccCoin .

In questo tutorial, illustrerò il processo passo passo che ho usato per costruire la valuta digitale (ho usato i concetti orientati agli oggetti del linguaggio di programmazione Python).

Ecco il progetto di base dell'algoritmo blockchain per la creazione di 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] 

Ora, lascia che ti spieghi cosa sta succedendo ...

1. Costruire la prima classe Block

Una blockchain comprende diversi blocchi uniti tra loro (suona familiare, giusto?).

Il concatenamento dei blocchi avviene in modo tale che se un blocco viene manomesso, il resto della catena diventa non valido.

Nell'applicare il concetto di cui sopra, ho creato la seguente classe di blocco iniziale:

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) 

Come puoi vedere dal codice sopra, ho definito la funzione __init __ () , che verrà eseguita quando viene avviata la classe Block , proprio come in qualsiasi altra classe Python.

Ho fornito i seguenti parametri alla funzione di iniziazione:

  • self: si riferisce all'istanza della classe Block , rendendo possibile l'accesso ai metodi e agli attributi associati alla classe;
  • indice: tiene traccia della posizione del blocco all'interno della blockchain;
  • proof_no: questo è il numero prodotto durante la creazione di un nuovo blocco (chiamato mining);
  • prev_hash: si riferisce all'hash del blocco precedente all'interno della catena;
  • dati: questo fornisce una registrazione di tutte le transazioni completate, come la quantità acquistata;
  • timestamp: inserisce un timestamp per le transazioni.

Il secondo metodo della classe, calcolare_hash , genererà l'hash dei blocchi utilizzando i valori sopra. Il modulo SHA-256 viene importato nel progetto per facilitare l'ottenimento degli hash dei blocchi.

Dopo che i valori sono stati inseriti nell'algoritmo hash crittografico, la funzione restituirà una stringa a 256 bit che rappresenta il contenuto del blocco.

Questo è il modo in cui si ottiene la sicurezza nelle blockchain: ogni blocco avrà un hash e quell'hash si baserà sull'hash del blocco precedente.

Pertanto, se qualcuno cerca di compromettere un blocco della catena, gli altri blocchi avranno hash non validi, portando all'interruzione dell'intera rete blockchain.

Alla fine, un blocco sarà simile a questo:

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

2. Costruire la classe Blockchain

L'idea principale di una blockchain, proprio come suggerisce il nome, implica il "concatenamento" di più blocchi tra loro.

Pertanto, costruirò una classe Blockchain che sarà utile nella gestione del funzionamento dell'intera catena. È qui che si svolgerà la maggior parte dell'azione.

La classe Blockchain avrà vari metodi di supporto per completare varie attività nella blockchain.

Lascia che ti spieghi il ruolo di ciascuno dei metodi nella classe.

un. Metodo del costruttore

Questo metodo garantisce l'istanza della blockchain.

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

Ecco i ruoli dei suoi attributi:

  • self.chain: questa variabile mantiene tutti i blocchi;
  • self.current_data: questa variabile conserva tutte le transazioni completate nel blocco;
  • self.construct_genesis (): questo metodo si occuperà di costruire il blocco iniziale.

b. Costruire il blocco genesi

La blockchain richiede un metodo construct_genesis per costruire il blocco iniziale nella catena. Nella convenzione blockchain, questo blocco è speciale perché simboleggia l'inizio della blockchain.

In questo caso, costruiamolo semplicemente passando alcuni valori predefiniti al metodo construct_block .

Ho dato sia proof_no che prev_hash un valore pari a zero, sebbene tu possa fornire qualsiasi valore tu voglia.

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. Costruire nuovi blocchi

Il metodo construct_block viene utilizzato per creare nuovi blocchi nella blockchain.

Ecco cosa sta succedendo con i vari attributi di questo metodo:

  • indice: rappresenta la lunghezza della blockchain;
  • proof_nor & prev_hash: il metodo del chiamante li passa;
  • dati: contiene un record di tutte le transazioni che non sono incluse in alcun blocco sul nodo;
  • self.current_data—this is used to reset the transaction list on the node. If a block has been constructed and the transactions allocated to it, the list is reset to ensure that future transactions are added into this list. And, this process will take place continuously;
  • self.chain.append()—this method joins newly constructed blocks to the chain;
  • return—lastly, a constructed block object is returned.

d. Checking validity

The check_validity method is important in assessing the integrity of the blockchain and ensuring anomalies are absent.

As mentioned earlier, hashes are essential for the security of the blockchain as even the slightest change in the object will lead to the generation of a completely new hash.

Therefore, this check_validitymethod uses if statements to check whether the hash of every block is correct.

It also verifies if every block points to the right previous block, through comparing the value of their hashes. If everything is correct, it returns true; otherwise, it returns 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. Adding data of transactions

The new_data method is used for adding the data of transactions to a block. It’s a very simple method: it accepts three parameters (sender’s details, receiver’s details, and quantity) and append the transaction data to self.current_data list.

Anytime a new block is created, this list is allocated to that block and reset once more as explained in the construct_block method.

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!