diff --git a/blockchain/pow_algorithm.py b/blockchain/pow_algorithm.py index 69fa58948..44e35baec 100644 --- a/blockchain/pow_algorithm.py +++ b/blockchain/pow_algorithm.py @@ -2,18 +2,34 @@ # Title: Proof of Work Algorithm for Blockchain ## Algorithm Statement: -The algorithm implements the Proof of Work (PoW) consensus mechanism used in -blockchain to validate blocks. PoW ensures participants (miners) perform a -computational task to create a valid block and add it to the blockchain. The +The algorithm implements the Proof of Work (PoW) consensus mechanism used in +blockchain to validate blocks. PoW ensures participants (miners) perform a +computational task to create a valid block and add it to the blockchain. The difficulty is defined by the number of leading zeros required in the block hash. """ import hashlib import time - class Block: - def __init__(self, index, previous_hash, transactions, timestamp, difficulty): + def __init__( + self, + index: int, + previous_hash: str, + transactions: str, + timestamp: float, + difficulty: int + ) -> None: + """ + Initializes a Block object with the specified parameters. + + Parameters: + - index (int): The index of the block in the blockchain. + - previous_hash (str): The hash of the previous block. + - transactions (str): The list of transactions in the block. + - timestamp (float): The time when the block was created (in Unix timestamp format). + - difficulty (int): The difficulty level for mining this block. + """ self.index = index self.previous_hash = previous_hash self.transactions = transactions @@ -22,11 +38,14 @@ class Block: self.difficulty = difficulty self.hash = self.compute_hash() - def compute_hash(self): + def compute_hash(self) -> str: """ Generates the hash of the block content. Combines index, previous hash, transactions, timestamp, and nonce into a string, which is then hashed using SHA-256. + + Returns: + - str: The hash of the block. """ block_string = ( f"{self.index}{self.previous_hash}{self.transactions}{self.timestamp}" @@ -34,55 +53,72 @@ class Block: ) return hashlib.sha256(block_string.encode()).hexdigest() - def mine_block(self): + def mine_block(self) -> None: """ Performs Proof of Work by adjusting the nonce until a valid hash is found. - A valid hash has the required number of leading zeros based on the difficulty - level. + A valid hash has the required number of leading zeros based on the difficulty level. + + Returns: + - None """ - target = ( - "0" * self.difficulty - ) # Target hash should start with 'difficulty' zeros - while self.hash[: self.difficulty] != target: + target = '0' * self.difficulty # Target hash should start with 'difficulty' zeros + while self.hash[:self.difficulty] != target: self.nonce += 1 self.hash = self.compute_hash() print(f"Block mined with nonce {self.nonce}, hash: {self.hash}") - class Blockchain: - def __init__(self, difficulty): + def __init__(self, difficulty: int) -> None: + """ + Initializes the blockchain with a given difficulty level. + + Parameters: + - difficulty (int): The difficulty level for mining blocks in this blockchain. + + Returns: + - None + """ self.chain = [] self.difficulty = difficulty self.create_genesis_block() - def create_genesis_block(self): + def create_genesis_block(self) -> None: """ Creates the first block in the blockchain (the Genesis block). + + Returns: + - None """ genesis_block = Block(0, "0", "Genesis Block", time.time(), self.difficulty) genesis_block.mine_block() self.chain.append(genesis_block) - def add_block(self, transactions): + def add_block(self, transactions: str) -> None: """ Adds a new block to the blockchain after performing Proof of Work. + + Parameters: + - transactions (str): The list of transactions to be added in the new block. + + Returns: + - None """ previous_block = self.chain[-1] new_block = Block( - len(self.chain), - previous_block.hash, - transactions, - time.time(), - self.difficulty, + len(self.chain), previous_block.hash, transactions, time.time(), + self.difficulty ) new_block.mine_block() self.chain.append(new_block) - def is_chain_valid(self): + def is_chain_valid(self) -> bool: """ - Verifies the integrity of the blockchain by ensuring each block's previous + Verifies the integrity of the blockchain by ensuring each block's previous hash matches and that all blocks meet the Proof of Work requirement. + + Returns: + - bool: True if the blockchain is valid, False otherwise. """ for i in range(1, len(self.chain)): current_block = self.chain[i] @@ -98,13 +134,14 @@ class Blockchain: return True - # Test cases - -def test_blockchain(): +def test_blockchain() -> None: """ Test cases for the Blockchain proof of work algorithm. + + Returns: + - None """ # Create blockchain with difficulty level of 4 (hash should start with 4 zeros) blockchain = Blockchain(difficulty=4) @@ -117,23 +154,10 @@ def test_blockchain(): assert blockchain.is_chain_valid(), "Blockchain should be valid" # Tamper with the blockchain and check validation - blockchain.chain[ - 1 - ].transactions = "Transaction 1: Alice pays Bob 50 BTC" # Tampering - assert ( - not blockchain.is_chain_valid() - ), "Blockchain should be invalid due to tampering" + blockchain.chain[1].transactions = "Transaction 1: Alice pays Bob 50 BTC" # Tampering + assert not blockchain.is_chain_valid(), "Blockchain should be invalid due to tampering" print("All test cases passed.") - if __name__ == "__main__": test_blockchain() - -""" -# Output: -- Block mined with nonce X, hash: 0000abcd... -- Block mined with nonce Y, hash: 0000xyz... -- Block mined with nonce Z, hash: 0000pqrs... -- All test cases passed. -"""