Welcome. Without any further ado let us see how to create a blockchain with Python. Before that have a look at the basic terminologies of Blockchain.
Blockchain: Fixed and permanent record of transaction that is verified and thus appended ahead of each other.
Block: A single transaction that is appended to the blockchain.
Genesis Block: The initial most block that is hard coded into the block chain and has no previous hash is Genesis Block.
Contents of Block: A block consists of all the general information like Time of transaction, Hash Data Generated, Previous Hash and transaction data(sender/receiver information)
Python Code-Along
We will be using functions of datetime library and sha256 from hashlib that is famously used for password and in the case of Blockchain, for verifying transactions.
Step 1:Import the libraries discussed and create a Block class that resembles the conceptual creation of Linked List in ths manner
import datetime
from hashlib import sha256
class Block:
def __init__(self, transactions, previous_hash):
self.time_stamp = datetime.datetime.now()
self.transactions = transactions
self.previous_hash = previous_hash
self.nonce = 0
self.hash = self.generate_hash()
def generate_hash(self):
pass
def print_contents(self):
pass
We are done with creating the skeleton of our block, it is time to make it secure with our ultra-protected cipher.
Step 2:Completing the incomplete functions in our code.
import datetime
from hashlib import sha256
class Block:
def __init__(self, transactions, previous_hash):
self.time_stamp = datetime.datetime.now()
self.transactions = transactions
self.previous_hash = previous_hash
self.nonce = 0
self.hash = self.generate_hash()
def generate_hash(self):
block_header = str(self.time_stamp) + str(self.transactions) +str(self.previous_hash) + str(self.nonce)
block_hash = sha256(block_header.encode())
return block_hash.hexdigest()
def print_contents(self):
print("timestamp:", self.time_stamp)
print("transactions:", self.transactions)
print("current hash:", self.generate_hash())
print("previous hash:", self.previous_hash)
Voila, you are done with creating your own block that will generate a cryptographic hash and store all the relevant details of a transaction.
Step 3: We are in a new file altogether importing the block file in Blockchain file before hopping the endgame i.e main file. We will be doin git this way for better code reusability and optimization
from block import Block
class Blockchain:
def __init__(self):
self.chain = []
self.unconfirmed_transactions = []
self.genesis_block()
def genesis_block(self):
transactions = []
genesis_block = Block(transactions, "0")
genesis_block.generate_hash()
self.chain.append(genesis_block)
def add_block(self, transactions):
previous_hash = (self.chain[len(self.chain)-1]).hash
new_block = Block(transactions, previous_hash)
new_block.generate_hash()
# proof = proof_of_work(block)
self.chain.append(new_block)
def print_blocks(self):
for i in range(len(self.chain)):
current_block = self.chain[i]
print("Block {} {}".format(i, current_block))
current_block.print_contents()
The unconfirmed transactions lie in the mempool until they are done so by participants in the blockchain. Participant is responsible for their proof of work to authorize the transaction.
In case you need to know more about proof of work, Internet has sources for you in one go.
Step 4:
Creating the proof of work and validation of transaction method to make a fully-functioning blockchain.
from block import Block
class Blockchain:
def __init__(self):
self.chain = []
self.unconfirmed_transactions = []
self.genesis_block()
def genesis_block(self):
transactions = []
genesis_block = Block(transactions, "0")
genesis_block.generate_hash()
self.chain.append(genesis_block)
def add_block(self, transactions):
previous_hash = (self.chain[len(self.chain)-1]).hash
new_block = Block(transactions, previous_hash)
new_block.generate_hash()
# proof = proof_of_work(block)
self.chain.append(new_block)
def print_blocks(self):
for i in range(len(self.chain)):
current_block = self.chain[i]
print("Block {} {}".format(i, current_block))
current_block.print_contents()
def validate_chain(self):
for i in range(1, len(self.chain)):
current = self.chain[i]
previous = self.chain[i-1]
if(current.hash != current.generate_hash()):
print("Current hash does not equal generated hash")
return False
if(current.previous_hash != previous.generate_hash()):
print("Previous block's hash got changed")
return False
return True
def proof_of_work(self, block, difficulty=2):
proof = block.generate_hash()
while proof[:2] != "0"*difficulty:
block.nonce += 1
proof = block.generate_hash()
block.nonce = 0
return proof
The value in the generated hash will be starting with a character and go on until the length of nonce pipelined into the sha256 algorithm to check if a certain condition is met with verification done and that is the prototype on how proof of work works.
Proof of work also avoid attacks which is the reason it was introduced in working of Bitcoin in 2009.
Moving onto the last step by actually creating and testing our Blockchain.
Final Step
from blockchain import Blockchain
block_one_transactions = {"sender":"Alice", "receiver": "Bob", "amount":"50"}
block_two_transactions = {"sender": "Bob", "receiver":"Cole", "amount":"25"}
block_three_transactions = {"sender":"Alice", "receiver":"Cole", "amount":"35"}
fake_transactions = {"sender": "Bob", "receiver":"Cole, Alice", "amount":"25"}
local_blockchain = Blockchain()
local_blockchain.print_blocks()
local_blockchain.add_block(block_one_transactions)
local_blockchain.add_block(block_two_transactions)
local_blockchain.add_block(block_three_transactions)
local_blockchain.print_blocks()
local_blockchain.chain[2].transactions = fake_transactions
local_blockchain.validate_chain()
Top comments (0)