1
- """
2
1
# Title: Proof of Work Algorithm for Blockchain
3
2
4
3
## Algorithm Statement:
5
- The algorithm implements the Proof of Work (PoW) consensus mechanism used in
6
- blockchain to validate blocks. PoW ensures participants (miners) perform a
7
- computational task to create a valid block and add it to the blockchain. The
8
- difficulty is defined by the number of leading zeros required in the block hash.
9
- """
4
+ # The algorithm implements the Proof of Work (PoW) consensus mechanism used in
5
+ # blockchain to validate blocks. PoW ensures participants (miners) perform a
6
+ # computational task to create a valid block and add it to the blockchain. The
7
+ # difficulty is defined by the number of leading zeros required in the block hash.
10
8
11
9
import hashlib
12
10
import time
13
11
14
-
15
12
class Block :
16
13
def __init__ (
17
14
self ,
18
15
index : int ,
19
16
previous_hash : str ,
20
17
transactions : str ,
21
18
timestamp : float ,
22
- difficulty : int ,
19
+ difficulty : int
23
20
) -> None :
24
21
"""
25
22
Initializes a Block object with the specified parameters.
@@ -28,7 +25,8 @@ def __init__(
28
25
- index (int): The index of the block in the blockchain.
29
26
- previous_hash (str): The hash of the previous block.
30
27
- transactions (str): The list of transactions in the block.
31
- - timestamp (float): The time when the block was created (in Unix timestamp format).
28
+ - timestamp (float): The time when the block was created
29
+ (in Unix timestamp format).
32
30
- difficulty (int): The difficulty level for mining this block.
33
31
"""
34
32
self .index = index
@@ -42,9 +40,9 @@ def __init__(
42
40
def compute_hash (self ) -> str :
43
41
"""
44
42
Generates the hash of the block content.
45
- Combines index, previous hash, transactions, timestamp, and nonce into a string,
46
- which is then hashed using SHA-256.
47
-
43
+ Combines index, previous hash, transactions, timestamp, and nonce into
44
+ a string, which is then hashed using SHA-256.
45
+
48
46
Returns:
49
47
- str: The hash of the block.
50
48
"""
@@ -57,40 +55,38 @@ def compute_hash(self) -> str:
57
55
def mine_block (self ) -> None :
58
56
"""
59
57
Performs Proof of Work by adjusting the nonce until a valid hash is found.
60
- A valid hash has the required number of leading zeros based on the difficulty level.
61
-
58
+ A valid hash has the required number of leading zeros based on the
59
+ difficulty level.
60
+
62
61
Returns:
63
62
- None
64
63
"""
65
- target = (
66
- "0" * self .difficulty
67
- ) # Target hash should start with 'difficulty' zeros
68
- while self .hash [: self .difficulty ] != target :
64
+ target = '0' * self .difficulty # Target hash should start with 'difficulty' zeros
65
+ while self .hash [:self .difficulty ] != target :
69
66
self .nonce += 1
70
67
self .hash = self .compute_hash ()
71
68
72
69
print (f"Block mined with nonce { self .nonce } , hash: { self .hash } " )
73
70
74
-
75
71
class Blockchain :
76
72
def __init__ (self , difficulty : int ) -> None :
77
73
"""
78
74
Initializes the blockchain with a given difficulty level.
79
75
80
76
Parameters:
81
77
- difficulty (int): The difficulty level for mining blocks in this blockchain.
82
-
78
+
83
79
Returns:
84
80
- None
85
81
"""
86
- self .chain = []
82
+ self .chain : list [ Block ] = [] # Adding type hint for the list of blocks
87
83
self .difficulty = difficulty
88
84
self .create_genesis_block ()
89
85
90
86
def create_genesis_block (self ) -> None :
91
87
"""
92
88
Creates the first block in the blockchain (the Genesis block).
93
-
89
+
94
90
Returns:
95
91
- None
96
92
"""
@@ -104,24 +100,21 @@ def add_block(self, transactions: str) -> None:
104
100
105
101
Parameters:
106
102
- transactions (str): The list of transactions to be added in the new block.
107
-
103
+
108
104
Returns:
109
105
- None
110
106
"""
111
107
previous_block = self .chain [- 1 ]
112
108
new_block = Block (
113
- len (self .chain ),
114
- previous_block .hash ,
115
- transactions ,
116
- time .time (),
117
- self .difficulty ,
109
+ len (self .chain ), previous_block .hash , transactions , time .time (),
110
+ self .difficulty
118
111
)
119
112
new_block .mine_block ()
120
113
self .chain .append (new_block )
121
114
122
115
def is_chain_valid (self ) -> bool :
123
116
"""
124
- Verifies the integrity of the blockchain by ensuring each block's previous
117
+ Verifies the integrity of the blockchain by ensuring each block's previous
125
118
hash matches and that all blocks meet the Proof of Work requirement.
126
119
127
120
Returns:
@@ -141,37 +134,42 @@ def is_chain_valid(self) -> bool:
141
134
142
135
return True
143
136
144
-
145
137
# Test cases
146
138
147
-
139
+ ## Test Case 1: Blockchain Initialization and Genesis Block
140
+ # This test verifies if the blockchain is correctly initialized with a Genesis block
141
+ # and if the block is successfully mined.
148
142
def test_blockchain () -> None :
149
143
"""
150
144
Test cases for the Blockchain proof of work algorithm.
151
-
145
+
152
146
Returns:
153
147
- None
154
148
"""
155
149
# Create blockchain with difficulty level of 4 (hash should start with 4 zeros)
156
150
blockchain = Blockchain (difficulty = 4 )
157
151
158
- # Add new blocks
152
+ ## Test Case 2: Add a block and verify the block is mined
153
+ # This test adds a new block with transactions and ensures it's mined according
154
+ # to the proof of work mechanism.
159
155
blockchain .add_block ("Transaction 1: Alice pays Bob 5 BTC" )
160
156
blockchain .add_block ("Transaction 2: Bob pays Charlie 3 BTC" )
161
157
162
- # Verify the integrity of the blockchain
158
+ ## Test Case 3: Verify blockchain integrity
159
+ # This test checks that the blockchain remains valid after adding new blocks
163
160
assert blockchain .is_chain_valid (), "Blockchain should be valid"
164
161
165
- # Tamper with the blockchain and check validation
166
- blockchain .chain [
167
- 1
168
- ].transactions = "Transaction 1: Alice pays Bob 50 BTC" # Tampering
169
- assert (
170
- not blockchain .is_chain_valid ()
171
- ), "Blockchain should be invalid due to tampering"
162
+ ## Test Case 4: Tampering with the blockchain
163
+ # This test simulates tampering with the blockchain and checks that the validation
164
+ # correctly detects the tampering.
165
+ blockchain .chain [1 ].transactions = "Transaction 1: Alice pays Bob 50 BTC" # Tampering
166
+ assert not blockchain .is_chain_valid (), "Blockchain should be invalid due to tampering"
172
167
168
+ ## Test Case 5: Correct blockchain validation
169
+ # This test checks if the blockchain becomes invalid after tampering and verifies
170
+ # if the PoW still holds after tampering is done.
171
+
173
172
print ("All test cases passed." )
174
173
175
-
176
174
if __name__ == "__main__" :
177
175
test_blockchain ()
0 commit comments