Building a Blockchain in Python
Building a Blockchain is very easy and anyone can do this with basics of programming. In this example we're going to use Python to build own Blockchain that can be used to send and receive money.
Note: This Blockchain is not for production purpose, it is just an example to explain you the functioning of Blockchain.
Let's see what will be the features of this Blockchain
1. Mine Blocks
2. Proof-of-Work
3. Miner Rewards
4. Transaction
5. Get Balance of users
Let's start and build our Blockchain
Transactions
Let's first build how our transactions will be structured. So let's create a class called "Transaction".
class Transaction:
def __init__(self, from_address, to_address, amount):
self.from_address = from_address
self.to_address = to_address
self.amount = amount
def serialize(self):
return {
"from_address": self.from_address,
"to_address": self.to_address,
"amount": self.amount
}
This Transaction class will store
from_address: Address from which money is sent.
to_address: Address to which money is sent.
amount: Amount of coins that is sent.
Our transaction class will also contain a "serialize" function to serialize the transaction in to a dictionary.
Blocks
Before structuring our blocks, let's import three modules.
from datetime import datetime
from hashlib import sha256
import json
Now let's create a "Block" class.
class Block:
def __init__(self, timestamp, transactions, previous_hash):
self.timestamp = timestamp
self.transactions = transactions
self.previous_hash = previous_hash
self.nonce = 0
self.hash = self.calculate_hash()
def calculate_hash(self):
hashing_string = (self.previous_hash
+ str(self.timestamp)
+ json.dumps(self.transactions, separators=(',', ':'))
+ str(self.nonce)).encode('utf-8')
return sha256(hashing_string).hexdigest()
In our Block class we will store the following
timestamp: It will be used to record the time when the Block was created
transactions: It will be used to store which transactions are in the Block
previous_hash: It will store the hash of the previous block. Previous hash will be useful to calculate the order of blocks in our blockchain.
nonce: This is an arbitrary value which we will update when we will implement mining.
hash: This hash will be calculated using "calculate_hash" method. This method will create a string called "hash_string" which will contain all the data of the Block and run SHA256 algorithm on it to create our hash which will be unique for every block on our blockchain.
Now let's implement mining in our Block class. Add the following method in your Block class.
def mine_block(self, difficulty):
while not self.hash[:difficulty] == ("0"*difficulty):
self.nonce += 1
self.hash = self.calculate_hash()
This "mine_block" method will get first few characters of our hash whose length will be equal to "difficulty". And it will create a string containing zeros which will also be equal to "difficulty". And until those two strings will not be same it will change the nonce value which will change the hash of the block. And it will keep doing it until the hash begins with certain amount of zeros.
Blockchain
Now let's finally create our Blockchain class.
class Blockchain:
def __init__(self, difficulty, mining_reward):
self.chain = [self.create_genesis_block()]
self.pending_transactions = []
self.difficulty = difficulty
self.mining_reward = mining_reward
def create_genesis_block(self):
return Block(datetime.now(),
[Transaction(None, 'kartik', 1000).serialize()],
'0')
def get_latest_block(self):
return self.chain[len(self.chain) - 1]
def is_chain_valid(self):
if len(self.chain) == 1:
return True
for i in range(1, len(self.chain)):
current_block = self.chain[i]
previous_block = self.chain[i-1]
if not current_block.hash == current_block.calculate_hash():
return False
if not current_block.previous_hash == previous_block.hash:
return False
return True
def get_balance_of(self, address):
balance = 0
for block in self.chain:
for transaction in block.transactions:
if transaction['from_address'] == address:
balance -= transaction['amount']
if transaction['to_address'] == address:
balance += transaction['amount']
return balance
def create_transaction(self, transaction):
if self.get_balance_of(transaction.from_address) < transaction.amount:
print(transaction.from_address + ' doesn\'t have enough coins to send to ' + transaction.to_address + '.')
else:
self.pending_transactions.append(transaction.serialize())
print("Transaction created, "+str(transaction.amount)+" coints will be send from "+transaction.from_address+" to "+transaction.to_address)
def mine_pending_transactions(self, mining_reward_address):
if not len(self.pending_transactions) == 0:
pending_transactions = self.pending_transactions
pending_transactions.append(Transaction(None, mining_reward_address, self.mining_reward).serialize())
block = Block(datetime.now(), pending_transactions, self.get_latest_block().hash)
block.mine_block(self.difficulty)
self.chain.append(block)
print("Block Mined, "+"Hash: "+block.hash+"; "+mining_reward_address+" is rewarded with "+str(self.mining_reward)+" coins for mining the Block.")
self.pending_transactions = []
The blockchain class stores the following data:
chain: it contain the list of all the blocks in the blockchain.
pending_transactions: It contain the list of all the transactions that is not mined.
difficulty: It is the mining difficulty
mining_reward: It is the amount of coins that the miner will get for mining one block
The blockchain class contains the following functions
create_genesis_block: It creates the genesis block that needs to be created manually to initialize the blockchain.
get_latest_block: It returns the latest block that is in the block chain
is_chain_valid: It validates that all the blocks have correct hash and previous_hash
get_balance_of: It calculates balance of any particular address
create_transaction: It creates a transaction and put it in the pending_transaction list to be mined.
mine_pending_transaction: This method is run by the miner to mine all the pending transaction, and after mining it rewards the miner.
Let's test our blockchain
Add the following code to test our blockchain
chain = Blockchain(5, 100)
chain.create_transaction(Transaction('kartik', 'satoshi', 10))
chain.create_transaction(Transaction('kartik', 'ned', 10))
chain.mine_pending_transactions('miner')
print("Balance")
print("kartik: " + str(chain.get_balance_of('kartik')) + " coins")
print("satoshi: " + str(chain.get_balance_of('satoshi')) + " coins")
print("ned: " + str(chain.get_balance_of('ned')) + " coins")
print("miner: " + str(chain.get_balance_of('miner')) + " coins")
This code will create a blockchain with difficulty 5 and miner reward 100 and create two transactions and then mine those transaction and after that print the balance of all the addresses.
It should give an output something like this
Transaction created, 10 coints will be send from kartik to satoshi
Transaction created, 10 coints will be send from kartik to ned
Block Mined, Hash: 000002377f42855b2fcf511bb1fd308a8b6633f41c94b0e7f23baa740bad9a78; miner is rewarded with 100 coins for mining the Block.
Balance
kartik: 980 coins
satoshi: 10 coins
ned: 10 coins
miner: 100 coins
Store our Blockchain
We need a way to store and retrieve our blockchain so that all the data is preserved
To store the blockchain we need pickle, so to install it type pip install pickle
in terminal and import pickle in the python file by using import pickle
To store your blockchain use the following code
with open('chain.pkl', 'wb') as f:
pickle.dump(chain, f)
and to retrieve blockchain back use the following code
with open('chain.pkl', 'rb') as f:
chain = pickle.load(f)
Hope this was fun, and you enjoyed making your own blockchian
Thank You! Steemit Community
Just what i needed because i will soon take a programming course online to learn blockchain programming
Great, Wish you all the very best for learning blockchain programming.
Thanks so much:) I am really new to this, but i will take a chance
Good
Thank You!
Congratulations @kartik2085! You have completed some achievement on Steemit and have been rewarded with new badge(s) :
Award for the number of upvotes received
Click on any badge to view your own Board of Honor on SteemitBoard.
To support your work, I also upvoted your post!
For more information about SteemitBoard, click here
If you no longer want to receive notifications, reply to this comment with the word
STOP
This is very good bro. I have always read about the power of Python as programming language, I consider that the power is in the programmer and in the multitudes of things that can be done with this language. It is very good for future projects. Greetings.