Skip to content

Commit 37549d5

Browse files
authored
Create PoWAlgorithm.py
1 parent 18e367f commit 37549d5

File tree

1 file changed

+129
-0
lines changed

1 file changed

+129
-0
lines changed

blockchain/PoWAlgorithm.py

+129
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
"""
2+
# Title: Proof of Work Algorithm for Blockchain
3+
4+
## Algorithm Statement:
5+
The algorithm implements the Proof of Work (PoW) consensus mechanism used in blockchain to validate blocks. PoW is used to ensure that participants (miners) must perform a computational task to create a valid block and add it to the blockchain. The difficulty of the task is defined by the number of leading zeros required in the hash of the block.
6+
7+
## Approach:
8+
1. Each block contains a list of transactions, a previous block's hash, a timestamp, and a nonce (random value).
9+
2. The block is hashed using the SHA-256 cryptographic hash function.
10+
3. The miner's goal is to find a nonce such that the resulting hash has a certain number of leading zeros, which defines the difficulty level.
11+
4. The difficulty is adjustable. The more leading zeros required, the harder it is to find a valid nonce.
12+
5. This process is repeated until a valid hash is found, which demonstrates that computational work has been done (Proof of Work).
13+
14+
## Steps:
15+
1. Create a `Block` class to hold block details (transactions, previous hash, timestamp, and nonce).
16+
2. Implement a `Blockchain` class that adds new blocks to the chain by solving the PoW problem.
17+
3. Implement the hashing function using SHA-256.
18+
4. Adjust the difficulty by varying the number of leading zeros required in the hash.
19+
5. Use test cases to validate the PoW algorithm.
20+
"""
21+
22+
import hashlib
23+
import time
24+
25+
class Block:
26+
def __init__(self, index, previous_hash, transactions, timestamp, difficulty):
27+
self.index = index
28+
self.previous_hash = previous_hash
29+
self.transactions = transactions
30+
self.timestamp = timestamp
31+
self.nonce = 0 # Start with nonce 0
32+
self.difficulty = difficulty
33+
self.hash = self.compute_hash()
34+
35+
def compute_hash(self):
36+
"""
37+
Generates the hash of the block content.
38+
Combines index, previous hash, transactions, timestamp, and nonce into a string,
39+
which is then hashed using SHA-256.
40+
"""
41+
block_string = f"{self.index}{self.previous_hash}{self.transactions}{self.timestamp}{self.nonce}"
42+
return hashlib.sha256(block_string.encode()).hexdigest()
43+
44+
def mine_block(self):
45+
"""
46+
Performs Proof of Work by adjusting the nonce until a valid hash is found.
47+
A valid hash has the required number of leading zeros based on the difficulty level.
48+
"""
49+
target = '0' * self.difficulty # Target hash should start with 'difficulty' number of zeros
50+
while self.hash[:self.difficulty] != target:
51+
self.nonce += 1
52+
self.hash = self.compute_hash()
53+
54+
print(f"Block mined with nonce {self.nonce}, hash: {self.hash}")
55+
56+
class Blockchain:
57+
def __init__(self, difficulty):
58+
self.chain = []
59+
self.difficulty = difficulty
60+
self.create_genesis_block()
61+
62+
def create_genesis_block(self):
63+
"""
64+
Creates the first block in the blockchain (the Genesis block).
65+
"""
66+
genesis_block = Block(0, "0", "Genesis Block", time.time(), self.difficulty)
67+
genesis_block.mine_block()
68+
self.chain.append(genesis_block)
69+
70+
def add_block(self, transactions):
71+
"""
72+
Adds a new block to the blockchain after performing Proof of Work.
73+
"""
74+
previous_block = self.chain[-1]
75+
new_block = Block(len(self.chain), previous_block.hash, transactions, time.time(), self.difficulty)
76+
new_block.mine_block()
77+
self.chain.append(new_block)
78+
79+
def is_chain_valid(self):
80+
"""
81+
Verifies the integrity of the blockchain by ensuring each block's previous hash matches
82+
and that all blocks meet the Proof of Work requirement.
83+
"""
84+
for i in range(1, len(self.chain)):
85+
current_block = self.chain[i]
86+
previous_block = self.chain[i - 1]
87+
88+
if current_block.hash != current_block.compute_hash():
89+
print(f"Invalid block at index {i}. Hash mismatch.")
90+
return False
91+
92+
if current_block.previous_hash != previous_block.hash:
93+
print(f"Invalid chain at index {i}. Previous hash mismatch.")
94+
return False
95+
96+
return True
97+
98+
# Test cases
99+
100+
def test_blockchain():
101+
"""
102+
Test cases for the Blockchain proof of work algorithm.
103+
"""
104+
# Create blockchain with difficulty level of 4 (hash should start with 4 zeros)
105+
blockchain = Blockchain(difficulty=4)
106+
107+
# Add new blocks
108+
blockchain.add_block("Transaction 1: Alice pays Bob 5 BTC")
109+
blockchain.add_block("Transaction 2: Bob pays Charlie 3 BTC")
110+
111+
# Verify the integrity of the blockchain
112+
assert blockchain.is_chain_valid() == True, "Blockchain should be valid"
113+
114+
# Tamper with the blockchain and check validation
115+
blockchain.chain[1].transactions = "Transaction 1: Alice pays Bob 50 BTC" # Tampering the transaction
116+
assert blockchain.is_chain_valid() == False, "Blockchain should be invalid due to tampering"
117+
118+
print("All test cases passed.")
119+
120+
if __name__ == "__main__":
121+
test_blockchain()
122+
123+
"""
124+
# Output:
125+
- Block mined with nonce X, hash: 0000abcd...
126+
- Block mined with nonce Y, hash: 0000xyz...
127+
- Block mined with nonce Z, hash: 0000pqrs...
128+
- All test cases passed.
129+
"""

0 commit comments

Comments
 (0)