From 9a6fcd541789228206cf068664ccda8a122efbf1 Mon Sep 17 00:00:00 2001 From: Anurag Singh <54910091+anurags10@users.noreply.github.com> Date: Thu, 3 Oct 2024 15:39:44 +0530 Subject: [PATCH] Update pow_algorithm.py --- blockchain/pow_algorithm.py | 82 ++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 42 deletions(-) diff --git a/blockchain/pow_algorithm.py b/blockchain/pow_algorithm.py index 139cb3648..65e2f59b6 100644 --- a/blockchain/pow_algorithm.py +++ b/blockchain/pow_algorithm.py @@ -1,17 +1,14 @@ -""" # 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 -difficulty is defined by the number of leading zeros required in the block hash. -""" +# 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, @@ -19,7 +16,7 @@ class Block: previous_hash: str, transactions: str, timestamp: float, - difficulty: int, + difficulty: int ) -> None: """ Initializes a Block object with the specified parameters. @@ -28,7 +25,8 @@ class Block: - 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). + - 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 @@ -42,9 +40,9 @@ class Block: 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. - + 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. """ @@ -57,21 +55,19 @@ class Block: 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: int) -> None: """ @@ -79,18 +75,18 @@ class Blockchain: Parameters: - difficulty (int): The difficulty level for mining blocks in this blockchain. - + Returns: - None """ - self.chain = [] + self.chain: list[Block] = [] # Adding type hint for the list of blocks self.difficulty = difficulty self.create_genesis_block() def create_genesis_block(self) -> None: """ Creates the first block in the blockchain (the Genesis block). - + Returns: - None """ @@ -104,24 +100,21 @@ class Blockchain: 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) -> 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: @@ -141,37 +134,42 @@ class Blockchain: return True - # Test cases - +## Test Case 1: Blockchain Initialization and Genesis Block +# This test verifies if the blockchain is correctly initialized with a Genesis block +# and if the block is successfully mined. 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) - # Add new blocks + ## Test Case 2: Add a block and verify the block is mined + # This test adds a new block with transactions and ensures it's mined according + # to the proof of work mechanism. blockchain.add_block("Transaction 1: Alice pays Bob 5 BTC") blockchain.add_block("Transaction 2: Bob pays Charlie 3 BTC") - # Verify the integrity of the blockchain + ## Test Case 3: Verify blockchain integrity + # This test checks that the blockchain remains valid after adding new blocks 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" + ## Test Case 4: Tampering with the blockchain + # This test simulates tampering with the blockchain and checks that the validation + # correctly detects the 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" + ## Test Case 5: Correct blockchain validation + # This test checks if the blockchain becomes invalid after tampering and verifies + # if the PoW still holds after tampering is done. + print("All test cases passed.") - if __name__ == "__main__": test_blockchain()