9
9
import hashlib
10
10
import time
11
11
12
+
12
13
class Block :
13
14
def __init__ (
14
15
self ,
15
16
index : int ,
16
17
previous_hash : str ,
17
18
transactions : str ,
18
19
timestamp : float ,
19
- difficulty : int
20
+ difficulty : int ,
20
21
) -> None :
21
22
"""
22
23
Initializes a Block object with the specified parameters.
@@ -42,7 +43,7 @@ def compute_hash(self) -> str:
42
43
Generates the hash of the block content.
43
44
Combines index, previous hash, transactions, timestamp, and nonce into
44
45
a string, which is then hashed using SHA-256.
45
-
46
+
46
47
Returns:
47
48
- str: The hash of the block.
48
49
"""
@@ -57,25 +58,28 @@ def mine_block(self) -> None:
57
58
Performs Proof of Work by adjusting the nonce until a valid hash is found.
58
59
A valid hash has the required number of leading zeros based on the
59
60
difficulty level.
60
-
61
+
61
62
Returns:
62
63
- None
63
64
"""
64
- target = '0' * self .difficulty # Target hash should start with 'difficulty' zeros
65
- while self .hash [:self .difficulty ] != target :
65
+ target = (
66
+ "0" * self .difficulty
67
+ ) # Target hash should start with 'difficulty' zeros
68
+ while self .hash [: self .difficulty ] != target :
66
69
self .nonce += 1
67
70
self .hash = self .compute_hash ()
68
71
69
72
print (f"Block mined with nonce { self .nonce } , hash: { self .hash } " )
70
73
74
+
71
75
class Blockchain :
72
76
def __init__ (self , difficulty : int ) -> None :
73
77
"""
74
78
Initializes the blockchain with a given difficulty level.
75
79
76
80
Parameters:
77
81
- difficulty (int): The difficulty level for mining blocks in this blockchain.
78
-
82
+
79
83
Returns:
80
84
- None
81
85
"""
@@ -86,7 +90,7 @@ def __init__(self, difficulty: int) -> None:
86
90
def create_genesis_block (self ) -> None :
87
91
"""
88
92
Creates the first block in the blockchain (the Genesis block).
89
-
93
+
90
94
Returns:
91
95
- None
92
96
"""
@@ -100,21 +104,24 @@ def add_block(self, transactions: str) -> None:
100
104
101
105
Parameters:
102
106
- transactions (str): The list of transactions to be added in the new block.
103
-
107
+
104
108
Returns:
105
109
- None
106
110
"""
107
111
previous_block = self .chain [- 1 ]
108
112
new_block = Block (
109
- len (self .chain ), previous_block .hash , transactions , time .time (),
110
- self .difficulty
113
+ len (self .chain ),
114
+ previous_block .hash ,
115
+ transactions ,
116
+ time .time (),
117
+ self .difficulty ,
111
118
)
112
119
new_block .mine_block ()
113
120
self .chain .append (new_block )
114
121
115
122
def is_chain_valid (self ) -> bool :
116
123
"""
117
- Verifies the integrity of the blockchain by ensuring each block's previous
124
+ Verifies the integrity of the blockchain by ensuring each block's previous
118
125
hash matches and that all blocks meet the Proof of Work requirement.
119
126
120
127
Returns:
@@ -134,15 +141,17 @@ def is_chain_valid(self) -> bool:
134
141
135
142
return True
136
143
144
+
137
145
# Test cases
138
146
147
+
139
148
## Test Case 1: Blockchain Initialization and Genesis Block
140
149
# This test verifies if the blockchain is correctly initialized with a Genesis block
141
150
# and if the block is successfully mined.
142
151
def test_blockchain () -> None :
143
152
"""
144
153
Test cases for the Blockchain proof of work algorithm.
145
-
154
+
146
155
Returns:
147
156
- None
148
157
"""
@@ -162,14 +171,19 @@ def test_blockchain() -> None:
162
171
## Test Case 4: Tampering with the blockchain
163
172
# This test simulates tampering with the blockchain and checks that the validation
164
173
# 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"
174
+ blockchain .chain [
175
+ 1
176
+ ].transactions = "Transaction 1: Alice pays Bob 50 BTC" # Tampering
177
+ assert (
178
+ not blockchain .is_chain_valid ()
179
+ ), "Blockchain should be invalid due to tampering"
167
180
168
181
## Test Case 5: Correct blockchain validation
169
182
# This test checks if the blockchain becomes invalid after tampering and verifies
170
183
# if the PoW still holds after tampering is done.
171
-
184
+
172
185
print ("All test cases passed." )
173
186
187
+
174
188
if __name__ == "__main__" :
175
189
test_blockchain ()
0 commit comments