Simple Blockchain Demo With Python

Blockchain, is a growing list of records, called blocks, which are linked using cryptography. Each block contains a cryptographic hash of the previous block, a timestamp, and transaction data (generally represented as a merkle tree root hash). In this post we will no discuss about fundamentals of Blockchain as it was discussed in previous blog. Also there is a nice Visualization of Blockchain by Anders Brownworth at Github.

Basically we will just implement Block, Basic Blockchain Architecture, and very simple Blockchain Network.

import hashlib


class Block:
# Defining Block Structure
def __init__ (self, no, nonce, data, hashcode, prev):
self.no = no
self.nonce = nonce
self.data = data
self.hashcode = hashcode
self.prev = prev

def getStringVal (self):
return self.no, self.nonce, self.data, self.hashcode, self.prev


class BlockChain:
# Defining simple Blockchain structure, adding blocks and chaining them together
def __init__(self):
self.chain = []
self.prefix = "0000"

def addNewBlock (self, data):
no, nonce, prev = len(self.chain), 0 , "0" if len(self.chain)==0 else self.chain[-1].hashcode
myHash = hashlib.sha256(str(data).encode('utf-8')).hexdigest()
block = Block (no,nonce,data,myHash,prev)
self.chain.append (block)

def printBlockChain(self) :
chaintDict = {}
for no in range (len(self.chain)) :
chaintDict[no] = self.chain[no].getStringVal()
print (chaintDict)

def mineChain(self) :
brokenLink = self.checkIfBroken()
if (brokenLink==None):
pass
else:
for block in self.chain[brokenLink.no:]:
print ("Mining Block", block.getStringVal())
self.mineBlock(block)

def mineBlock (self, block) :
nonce = 0
myHash = hashlib.sha256(str(str(nonce)+str(block.data)).encode('utf-8')).hexdigest()
while myHash[0:4]!=self.prefix :
myHash = hashlib.sha256(str(str(nonce)+str(block.data)).encode('utf-8')).hexdigest()
nonce = nonce + 1
else:
print("nonce",nonce)
print ("new hash", myHash)
self.chain[block.no].hashcode = myHash
self.chain[block.no].nonce = nonce
if (block.no<len(self.chain)-1) :
self.chain[block.no+1].prev = myHash

# checking if the chain is broken
def checkIfBroken(self):
for no in range (len(self.chain)) :
if (self.chain[no].hashcode[0:4]== self.prefix):
pass
else:
return self.chain[no]
return None

def changeData(self, no, data):
self.chain[no].data = data
self.chain[no].hashcode = hashlib.sha256(str(str(self.chain[no].nonce)+str(self.chain[no].data)).encode('utf-8')).hexdigest()

def checkChain (self) :
lastPointer = "0"

for b in self.chain:
if (b.prev != lastPointer ):
print ("Chaincode broken at: ",b.getStringVal())
return
else:
lastPointer = b.hashcode

class BlockChainNetwork:
# Comparing Blockchain network
def compareBlockChains (self, bc1, *bchains):
for bchain in bchains:
if len(bc1.chain)!=len(bchain.chain) :
print ("Network is broken")
for bno in range(len(bc1.chain)) :
if bc1.chain[bno].hashcode!=bchain.chain[bno].hashcode :
print ("Network is Broken in Chain")
Image for post
#First We define a block structure with class Block: that has block and getstring value methods
#Basic Block has number, nonce, data, hash and previous hash arguments

# Class Blockchain is defining Blockchain structure
# that includes adding new blocks, mining chain and blocks.
# We also check if the chain is broken with checkifbroken function.
# Last we compare networks with simple Class BlockchainNetwork

class Block(builtins.object)
| Block(no, nonce, data, hashcode, prev)
|
| Methods defined here:
|
| __init__(self, no, nonce, data, hashcode, prev)
| Initialize self. See help(type(self)) for accurate signature.
|
| getStringVal(self)
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)

class BlockChain(builtins.object)

| Methods defined here:
|
| __init__(self)
| Initialize self. See help(type(self)) for accurate signature.
|
| addNewBlock(self, data)
|
| changeData(self, no, data)
|
| checkChain(self)
|
| checkIfBroken(self)
|
| mineBlock(self, block)
|
| mineChain(self)
|
| printBlockChain(self)
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)

class BlockChainNetwork(builtins.object)
| Methods defined here:
|
| compareBlockChains(self, bc1, *bchains)
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
# You can run Blockchain Demo (BlockDemo.py) at the Python Shell
>>> from BlockDemo import *
>>> b = BlockChain()
>>> b.addNewBlock("Hello")
>>> b.printBlockChain()
{0: (0, 0, 'Hello', '185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969', '0')}
>>> b.addNewBlock("World")
>>> b.printBlockChain()
{0: (0, 0, 'Hello', **'185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969', '0'), 1: (1, 0, 'World', '78ae647dc5544d227130a0682a51e30bc7777fbb6d8a8f17007463a3ecd1d524', '185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969')}
>>> b.mineChain()
Mining Block (0, 0, 'Hello', '185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969', '0')
nonce 24947
new hash 0000cf38af6f0bc77e243c63f177889f2640386adae15e90d048f7ff0cba7692
Mining Block (1, 0, 'World', '78ae647dc5544d227130a0682a51e30bc7777fbb6d8a8f17007463a3ecd1d524', '0000cf38af6f0bc77e243c63f177889f2640386adae15e90d048f7ff0cba7692')
nonce 35146
new hash 00001f1bce3b87d18ce1714fda928c8993bb05a9b839c9e83c2740ccd641699b
>>>
>>> b.changeData(1, "Hello Blockchain World")
>>> b.printBlockChain()
{0: (0, 24947, 'Hello', '0000cf38af6f0bc77e243c63f177889f2640386adae15e90d048f7ff0cba7692', '0'), 1: (1, 35146, 'Hello Blockchain World', 'c46d4260d2ed14e402388ab45c592a46d9371544b68bdea821237679d767a8d6', '0000cf38af6f0bc77e243c63f177889f2640386adae15e90d048f7ff0cba7692')}
>>> b.mineChain()
Mining Block (1, 35146, 'Hello Blockchain World', 'c46d4260d2ed14e402388ab45c592a46d9371544b68bdea821237679d767a8d6', '0000cf38af6f0bc77e243c63f177889f2640386adae15e90d048f7ff0cba7692')
nonce 98449
new hash 00000ff9285ae017d7ca04bf8bf2a843af32a8e6761437729880fbc7f8c0d727
>>>
>>> b1 = BlockChain()
>>> b2 = BlockChain()
>>> b3 = BlockChain()
>>> b1.addNewBlock("Hello")
>>> b1.addNewBlock("World")
>>> b1.mineChain()
Mining Block (0, 0, 'Hello', '185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969', '0')
nonce 24947
new hash 0000cf38af6f0bc77e243c63f177889f2640386adae15e90d048f7ff0cba7692
Mining Block (1, 0, 'World', '78ae647dc5544d227130a0682a51e30bc7777fbb6d8a8f17007463a3ecd1d524', '0000cf38af6f0bc77e243c63f177889f2640386adae15e90d048f7ff0cba7692')
nonce 35146
new hash 00001f1bce3b87d18ce1714fda928c8993bb05a9b839c9e83c2740ccd641699b
>>> b2.addNewBlock("Hello")
>>> b2.addNewBlock("World")
>>> b2.mineChain()
Mining Block (0, 0, 'Hello', '185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969', '0')
nonce 24947
new hash 0000cf38af6f0bc77e243c63f177889f2640386adae15e90d048f7ff0cba7692
Mining Block (1, 0, 'World', '78ae647dc5544d227130a0682a51e30bc7777fbb6d8a8f17007463a3ecd1d524', '0000cf38af6f0bc77e243c63f177889f2640386adae15e90d048f7ff0cba7692')
nonce 35146
new hash 00001f1bce3b87d18ce1714fda928c8993bb05a9b839c9e83c2740ccd641699b
>>> b3.addNewBlock("Hello")
>>> b3.addNewBlock("World")
>>> b3.mineChain()
Mining Block (0, 0, 'Hello', '185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969', '0')
nonce 24947
new hash 0000cf38af6f0bc77e243c63f177889f2640386adae15e90d048f7ff0cba7692
Mining Block (1, 0, 'World', '78ae647dc5544d227130a0682a51e30bc7777fbb6d8a8f17007463a3ecd1d524', '0000cf38af6f0bc77e243c63f177889f2640386adae15e90d048f7ff0cba7692')
nonce 35146
new hash 00001f1bce3b87d18ce1714fda928c8993bb05a9b839c9e83c2740ccd641699b
>>> bcn = BlockChainNetwork()
>>> bcn.compareBlockChains(b1,b3)
>>> bcn.compareBlockChains(b1,b2,b3)
>>> bcn.compareBlockChains(b,b1,b2,b3)
Network is Broken in Chain
Network is Broken in Chain
Network is Broken in Chain
>>> bcn.compareBlockChains(b,b1,b2)
Network is Broken in Chain
Network is Broken in Chain
>>> bcn.compareBlockChains(b1,b2)

BlockDemo.py resides at github.

Thanks to Anders Brownworth and Parth Joshi

Originally published at www.linkedin.com.

Written by

I am passionate about Technology, Cloud Computing, Machine Learning and Blockchain

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store