Update pow_algorithm.py

This commit is contained in:
Anurag Singh 2024-10-03 15:39:44 +05:30 committed by GitHub
parent 3d91445a57
commit 9a6fcd5417
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,17 +1,14 @@
"""
# Title: Proof of Work Algorithm for Blockchain # Title: Proof of Work Algorithm for Blockchain
## Algorithm Statement: ## Algorithm Statement:
The algorithm implements the Proof of Work (PoW) consensus mechanism used in # The algorithm implements the Proof of Work (PoW) consensus mechanism used in
blockchain to validate blocks. PoW ensures participants (miners) perform a # blockchain to validate blocks. PoW ensures participants (miners) perform a
computational task to create a valid block and add it to the blockchain. The # 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. # difficulty is defined by the number of leading zeros required in the block hash.
"""
import hashlib import hashlib
import time import time
class Block: class Block:
def __init__( def __init__(
self, self,
@ -19,7 +16,7 @@ class Block:
previous_hash: str, previous_hash: str,
transactions: str, transactions: str,
timestamp: float, timestamp: float,
difficulty: int, difficulty: int
) -> None: ) -> None:
""" """
Initializes a Block object with the specified parameters. Initializes a Block object with the specified parameters.
@ -28,7 +25,8 @@ class Block:
- index (int): The index of the block in the blockchain. - index (int): The index of the block in the blockchain.
- previous_hash (str): The hash of the previous block. - previous_hash (str): The hash of the previous block.
- transactions (str): The list of transactions in the 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. - difficulty (int): The difficulty level for mining this block.
""" """
self.index = index self.index = index
@ -42,9 +40,9 @@ class Block:
def compute_hash(self) -> str: def compute_hash(self) -> str:
""" """
Generates the hash of the block content. Generates the hash of the block content.
Combines index, previous hash, transactions, timestamp, and nonce into a string, Combines index, previous hash, transactions, timestamp, and nonce into
which is then hashed using SHA-256. a string, which is then hashed using SHA-256.
Returns: Returns:
- str: The hash of the block. - str: The hash of the block.
""" """
@ -57,21 +55,19 @@ class Block:
def mine_block(self) -> None: def mine_block(self) -> None:
""" """
Performs Proof of Work by adjusting the nonce until a valid hash is found. 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: Returns:
- None - None
""" """
target = ( target = '0' * self.difficulty # Target hash should start with 'difficulty' zeros
"0" * self.difficulty while self.hash[:self.difficulty] != target:
) # Target hash should start with 'difficulty' zeros
while self.hash[: self.difficulty] != target:
self.nonce += 1 self.nonce += 1
self.hash = self.compute_hash() self.hash = self.compute_hash()
print(f"Block mined with nonce {self.nonce}, hash: {self.hash}") print(f"Block mined with nonce {self.nonce}, hash: {self.hash}")
class Blockchain: class Blockchain:
def __init__(self, difficulty: int) -> None: def __init__(self, difficulty: int) -> None:
""" """
@ -79,18 +75,18 @@ class Blockchain:
Parameters: Parameters:
- difficulty (int): The difficulty level for mining blocks in this blockchain. - difficulty (int): The difficulty level for mining blocks in this blockchain.
Returns: Returns:
- None - None
""" """
self.chain = [] self.chain: list[Block] = [] # Adding type hint for the list of blocks
self.difficulty = difficulty self.difficulty = difficulty
self.create_genesis_block() self.create_genesis_block()
def create_genesis_block(self) -> None: def create_genesis_block(self) -> None:
""" """
Creates the first block in the blockchain (the Genesis block). Creates the first block in the blockchain (the Genesis block).
Returns: Returns:
- None - None
""" """
@ -104,24 +100,21 @@ class Blockchain:
Parameters: Parameters:
- transactions (str): The list of transactions to be added in the new block. - transactions (str): The list of transactions to be added in the new block.
Returns: Returns:
- None - None
""" """
previous_block = self.chain[-1] previous_block = self.chain[-1]
new_block = Block( new_block = Block(
len(self.chain), len(self.chain), previous_block.hash, transactions, time.time(),
previous_block.hash, self.difficulty
transactions,
time.time(),
self.difficulty,
) )
new_block.mine_block() new_block.mine_block()
self.chain.append(new_block) self.chain.append(new_block)
def is_chain_valid(self) -> bool: 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. hash matches and that all blocks meet the Proof of Work requirement.
Returns: Returns:
@ -141,37 +134,42 @@ class Blockchain:
return True return True
# Test cases # 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: def test_blockchain() -> None:
""" """
Test cases for the Blockchain proof of work algorithm. Test cases for the Blockchain proof of work algorithm.
Returns: Returns:
- None - None
""" """
# Create blockchain with difficulty level of 4 (hash should start with 4 zeros) # Create blockchain with difficulty level of 4 (hash should start with 4 zeros)
blockchain = Blockchain(difficulty=4) 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 1: Alice pays Bob 5 BTC")
blockchain.add_block("Transaction 2: Bob pays Charlie 3 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" assert blockchain.is_chain_valid(), "Blockchain should be valid"
# Tamper with the blockchain and check validation ## Test Case 4: Tampering with the blockchain
blockchain.chain[ # This test simulates tampering with the blockchain and checks that the validation
1 # correctly detects the tampering.
].transactions = "Transaction 1: Alice pays Bob 50 BTC" # Tampering blockchain.chain[1].transactions = "Transaction 1: Alice pays Bob 50 BTC" # Tampering
assert ( assert not blockchain.is_chain_valid(), "Blockchain should be invalid due to tampering"
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.") print("All test cases passed.")
if __name__ == "__main__": if __name__ == "__main__":
test_blockchain() test_blockchain()