mirror of
https://github.com/TheAlgorithms/Python.git
synced 2025-04-02 20:06:50 +00:00
Update pow_algorithm.py
This commit is contained in:
parent
3d91445a57
commit
9a6fcd5417
@ -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()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user