Blockchain technology is getting very popular these days but most people think it is used for buying or selling Bitcoins only. This is a common misconception as blockchain can be implemented in every field of life including healthcare, education, and on. We shall learn how to build our own cryptocurrency blockchain using python.
Build Your Own Chain Using Python
Note: This code presented in this article is for learning purposes only. Please do not use this code in a production environment as it could contain some vulnerabilities.
1- Creating The First Block (Block Class Constructor)
A block is a fundamental unit of a blockchain.
We will now create the first block. We will use the standard JSON format to store data in each block. The data in the block looks something like this:
{ “author”: “author_name”,
“timestamp”: “transaction_time”,
“data”: “transaction_data”
}
Now we will implement this in Python. The first step is to create a block class with the mentioned attributes. Also, make sure that each block is unique so that duplication does not occur.
class Block: def __init__(self, index, transactions, timestamp, previous_hash, nonce=0): self.index = index self.transactions = transactions self.timestamp = timestamp self.previous_hash = previous_hash self.nonce = nonce
from hashlib import sha256 import json class Block: def __init__(self, index, transactions, timestamp, previous_hash, nonce=0): self.index = index self.transactions = transactions self.timestamp = timestamp self.previous_hash = previous_hash self.nonce = nonce def compute_hash(self): block_string = json.dumps(self.__dict__, sort_keys=True) return sha256(block_string.encode()).hexdigest()
Hashing of each block ensures the security of each one separately, making it extremely difficult to tamper with the data which is within the blocks. The next step is to chain the block together.
2-Building Your Blockchain
A Series of interconnected blocks make a blockchain.
We shall use the approach of including the hash of the previous block within the current block. By this method, the entire data within each block ensures the integrity and protection of the entire chain. That’s the reason we use the “Previous_hash” variable in the block class.
Also, we need to initialize the blockchain, therefore we define the “create_genesis_block method”. This will create a starting block with the index of 0 and a previous hash of 0. Finally, we add this to the list “chain” so it will keep track of each block.
This will ensure the immutability of the entire blockchain
import time class Blockchain: def __init__(self): self.unconfirmed_transactions = [] self.chain = [] self.create_genesis_block() def create_genesis_block(self): genesis_block = Block(0, [], time.time(), "0") genesis_block.hash = genesis_block.compute_hash() self.chain.append(genesis_block) @property def last_block(self): return self.chain[-1]
3- Add A Proof Of Work Method
Adding the proof of work method makes it more difficult to perform the creation of a new block progressively. This means that if someone who changes or modifies a previous block would have to redo the work of the block and all of the blocks that follow it. Since the difficulty increases with each block, it will prevent users from modifying the previous blocks. In order to modify the previous block, you need to redo the following blocks to catch up with others. which is impossible.
To implement PoW, we can add a “Proof of Work” method in the blockchain class.
difficulty = 2 def proof_of_work(self, block): block.nonce = computed_hash = block.compute_hash() while not computed_hash.startswith('0' * Blockchain.difficulty): block.nonce += 1 computed_hash = block.compute_hash() return computed_hash
We shall initially store the data of each transaction in “Unconfirmed transactions“. Once it is valid proof according to the defined criteria, we add it to the chain. This process of computational work is known as mining. This ensures the security of the entire chain.
def add_block(self, block, proof): previous_hash = self.last_block.hash if previous_hash != block.previous_hash: return False if not self.is_valid_proof(block, proof): return False block.hash = proof self.chain.append(block) return True def is_valid_proof(self, block, block_hash): return (block_hash.startswith('0' * Blockchain.difficulty) and block_hash == block.compute_hash()) def add_new_transaction(self, transaction): self.unconfirmed_transactions.append(transaction) def mine(self): if not self.unconfirmed_transactions: return False last_block = self.last_block new_block = Block(index=last_block.index + 1, transactions=self.unconfirmed_transactions, timestamp=time.time(), previous_hash=last_block.hash) proof = self.proof_of_work(new_block) self.add_block(new_block, proof) self.unconfirmed_transactions = [] return new_block.index
4- Build An Interface/API
So now that we have defined a single block, developed a blockchain, implemented the Proof of work system, and defined a mining procedure, we need to build an interface with which users or nodes can interact with. For this, we will use Flask to create an API. This is a web application framework written for Python.
from flask import Flask, request import requests app = Flask(__name__) blockchain = Blockchain()
@app.route('/chain', methods=['GET']) def get_chain(): chain_data = [] for block in blockchain.chain: chain_data.append(block.__dict__) return json.dumps({"length": len(chain_data), "chain": chain_data}) app.run(debug=True, port=5000)
Now we will query this blockchain.
> python3 Blockchain.py > curl http://127.0.0.1:5000/chain The output shall contain all the information about the block chain.
Conclusion
In summary, the following steps are required to create the blockchain.
- Creation of a block class.
- Define the blockchain and encrypt each block with a cryptographic hash function
- Add proof of work method to ensure security and safe from hacks.
- Build an interface API that multiple users or nodes can be used to interact with the blockchain.