Last active
December 5, 2020 10:55
-
-
Save Divyosmi/8ad69d9f48427a47c0435c3dda1c587e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import hashlib | |
| import time | |
| class Block: | |
| def __init__(self, index, proof_no, prev_hash, data, timestamp=None): | |
| self.index = index | |
| self.proof_no = proof_no | |
| self.prev_hash = prev_hash | |
| self.data = data | |
| self.timestamp = timestamp or time.time() | |
| @property | |
| def calculate_hash(self): | |
| block_of_string = "{}{}{}{}{}".format(self.index, self.proof_no, | |
| self.prev_hash, self.data, | |
| self.timestamp) | |
| return hashlib.sha256(block_of_string.encode()).hexdigest() | |
| def __repr__(self): | |
| return "{} - {} - {} - {} - {}".format(self.index, self.proof_no, | |
| self.prev_hash, self.data, | |
| self.timestamp) | |
| class BlockChain: | |
| def __init__(self): | |
| self.chain = [] | |
| self.current_data = [] | |
| self.nodes = set() | |
| self.construct_genesis() | |
| def construct_genesis(self): | |
| self.construct_block(proof_no=0, prev_hash=0) | |
| def construct_block(self, proof_no, prev_hash): | |
| block = Block( | |
| index=len(self.chain), | |
| proof_no=proof_no, | |
| prev_hash=prev_hash, | |
| data=self.current_data) | |
| self.current_data = [] | |
| self.chain.append(block) | |
| return block | |
| @staticmethod | |
| def check_validity(block, prev_block): | |
| if prev_block.index + 1 != block.index: | |
| return False | |
| elif prev_block.calculate_hash != block.prev_hash: | |
| return False | |
| elif not BlockChain.verifying_proof(block.proof_no, | |
| prev_block.proof_no): | |
| return False | |
| elif block.timestamp <= prev_block.timestamp: | |
| return False | |
| return True | |
| def new_data(self, sender, recipient, quantity): | |
| self.current_data.append({ | |
| 'sender': sender, | |
| 'recipient': recipient, | |
| 'quantity': quantity | |
| }) | |
| return True | |
| @staticmethod | |
| def proof_of_work(last_proof): | |
| '''this simple algorithm identifies a number f' such that hash(ff') contain 4 leading zeroes | |
| f is the previous f' | |
| f' is the new proof | |
| ''' | |
| proof_no = 0 | |
| while BlockChain.verifying_proof(proof_no, last_proof) is False: | |
| proof_no += 1 | |
| return proof_no | |
| @staticmethod | |
| def verifying_proof(last_proof, proof): | |
| #verifying the proof: does hash(last_proof, proof) contain 4 leading zeroes? | |
| guess = f'{last_proof}{proof}'.encode() | |
| guess_hash = hashlib.sha256(guess).hexdigest() | |
| return guess_hash[:4] == "0000" | |
| @property | |
| def latest_block(self): | |
| return self.chain[-1] | |
| def block_mining(self, details_miner): | |
| self.new_data( | |
| sender="0", #it implies that this node has created a new block | |
| recipient=details_miner, | |
| quantity= | |
| 1, #creating a new block (or identifying the proof number) is awarded with 1 | |
| ) | |
| last_block = self.latest_block | |
| last_proof_no = last_block.proof_no | |
| proof_no = self.proof_of_work(last_proof_no) | |
| last_hash = last_block.calculate_hash | |
| block = self.construct_block(proof_no, last_hash) | |
| return vars(block) | |
| def create_node(self, address): | |
| self.nodes.add(address) | |
| return True | |
| @staticmethod | |
| def obtain_block_object(block_data): | |
| #obtains block object from the block data | |
| return Block( | |
| block_data['index'], | |
| block_data['proof_no'], | |
| block_data['prev_hash'], | |
| block_data['data'], | |
| timestamp=block_data['timestamp']) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment