Skip to content

Instantly share code, notes, and snippets.

@roychowdhuryrohit-dev
Created February 28, 2018 16:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save roychowdhuryrohit-dev/1fee318dfedb417b64c8c8287b945fa1 to your computer and use it in GitHub Desktop.
Save roychowdhuryrohit-dev/1fee318dfedb417b64c8c8287b945fa1 to your computer and use it in GitHub Desktop.
from hashlib import sha256
import time
from json import dumps
# to define each blocks
class Block:
def __init__(self, data, prevHash=None):
self.data = data
# timestamp of block creation
self.time = time.time()
# to help in guessing the target during mining
self.nonce = 0
# hash key of previous block
self.prevHash = prevHash
self.hash = self.calc_hash()
def calc_hash(self):
hash_object = None
input = self.data+str(self.time)+str(self.nonce)
if self.prevHash is not None:
input += self.prevHash
# to produce 256 bit hex digest using SHA algorithm
hash_object = sha256(input.encode('utf-8'))
digest = hash_object.hexdigest()
return digest
# to mine current block as proof-of-work
def mine_block(self):
# to mine until target is reached
while self.hash[:BlockChain.mining_difficulty] != BlockChain.target:
self.nonce += 1
self.hash = self.calc_hash()
print("Block mined : {0} Nonce : {1}".format(self.hash, self.nonce))
# to define block chain
class BlockChain:
# mining difficulty. For Bitcoin it is around 3,007,383,866,430
mining_difficulty = 5
target = "0"*mining_difficulty
def __init__(self, data):
self.block_chain = list()
# genesis block
gen_block = Block(data)
self.block_chain.append(gen_block)
# to check if the blockchain is valid
def checkChainValid(self):
i = 1
while i < len(self.block_chain):
prev_block = self.block_chain[i-1]
cur_block = self.block_chain[i]
if cur_block.hash != cur_block.calc_hash():
print("Current hash mismatch !")
return False
elif cur_block.prevHash != prev_block.hash:
print("Previous hash mismatch !")
return False
elif cur_block.hash[:BlockChain.mining_difficulty] != BlockChain.target:
print("Current block {0} is not mined !".format(
cur_block.hash))
return False
i += 1
return True
def getBlockChain(self):
return self.block_chain
# driver/test code
block_chain_obj = BlockChain("Genesis block")
block_chain = block_chain_obj.getBlockChain()
print("Mining block #0")
block_chain[0].mine_block()
block_chain.append(Block("Hello world", block_chain[0].hash))
print("Mining block #1")
# block_chain[1].mine_block()
block_chain.append(Block("I am a block", block_chain[1].hash))
print("Mining block #2")
block_chain[2].mine_block()
if block_chain_obj.checkChainValid():
# produce json dump of valid blockchain
print(dumps([block.__dict__ for block in block_chain],
indent=4, sort_keys=True))
else:
print("BlockChain is invalid !")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment