Skip to content

Instantly share code, notes, and snippets.

@iamareebjamal
Created January 15, 2018 21: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 iamareebjamal/189c3b9e206ce3ebeeff9fb4a06cf656 to your computer and use it in GitHub Desktop.
Save iamareebjamal/189c3b9e206ce3ebeeff9fb4a06cf656 to your computer and use it in GitHub Desktop.
import time
import hashlib
class Block:
def __init__(self, index, data, previous_hash=None):
self.index = index
self.data = data
self.previous_hash = previous_hash
self.timestamp = time.time()
self.nonce = 0
self.hash = self.calculate_hash()
def calculate_hash(self):
m = hashlib.sha256()
m.update(str(self.index).encode('utf-8'))
m.update(str(self.timestamp).encode('utf-8'))
m.update(str(self.data).encode('utf-8'))
m.update(str(self.previous_hash).encode('utf-8'))
m.update(str(self.nonce).encode('utf-8'))
return m.hexdigest()
def mine_block(self, difficulty):
while self.hash[:difficulty] != '0'*difficulty:
self.nonce += 1
self.hash = self.calculate_hash()
print('Block Mined : {} in {} iterations'.format(self.hash, self.nonce))
def __str__(self):
return "(index: {}, data: {}, timestamp: {}, nonce: {}, hash: {}, previous_hash: {})".format(
self.index,
self.data,
self.timestamp,
self.nonce,
self.hash,
self.previous_hash)
class BlockChain:
def __init__(self, difficulty=2):
self.chain = [self.generate_genesis()]
self.difficulty = difficulty;
def generate_genesis(self):
return Block(0, "Genesis", "0")
def get_latest_block(self):
return self.chain[len(self.chain) - 1]
def add_block(self, data):
previous_block = self.get_latest_block()
new_block = Block(previous_block.index + 1, data, previous_block.hash)
new_block.mine_block(self.difficulty)
self.chain.append(new_block)
def is_valid(self):
for index, block in enumerate(self.chain[1:]):
previous_block = self.chain[index]
if (block.hash != block.calculate_hash()):
print('Block has changed')
return False
if (block.previous_hash != previous_block.hash):
print('Block link invalid')
return False
return True
def __str__(self):
return ' -> \n'.join([str(x) for x in self.chain])
current_milli_time = lambda: time.time() * 1000
start = current_milli_time()
blockchain = BlockChain(2)
print('Mining Block 1...')
blockchain.add_block({ 'amount': 40 })
print('Mining Block 2...')
blockchain.add_block({ 'amount': 548 })
print(blockchain)
print(blockchain.is_valid())
print('Completed in {} ms'.format(current_milli_time() - start))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment