1
1
import hashlib
2
2
import json
3
3
from time import time
4
+ from typing import Any , Dict , List , Optional
4
5
from urllib .parse import urlparse
5
6
from uuid import uuid4
6
7
7
8
import requests
8
9
from flask import Flask , jsonify , request
9
10
10
11
11
- class Blockchain ( object ) :
12
+ class Blockchain :
12
13
def __init__ (self ):
13
14
self .current_transactions = []
14
15
self .chain = []
15
16
self .nodes = set ()
16
17
17
18
# Create the genesis block
18
- self .new_block (previous_hash = 1 , proof = 100 )
19
+ self .new_block (previous_hash = '1' , proof = 100 )
19
20
20
- def register_node (self , address ) :
21
+ def register_node (self , address : str ) -> None :
21
22
"""
22
23
Add a new node to the list of nodes
23
24
24
- :param address: <str> Address of node. Eg. 'http://192.168.0.5:5000'
25
- :return: None
25
+ :param address: Address of node. Eg. 'http://192.168.0.5:5000'
26
26
"""
27
27
28
28
parsed_url = urlparse (address )
29
29
self .nodes .add (parsed_url .netloc )
30
30
31
- def valid_chain (self , chain ) :
31
+ def valid_chain (self , chain : List [ Dict [ str , Any ]]) -> bool :
32
32
"""
33
33
Determine if a given blockchain is valid
34
34
35
- :param chain: <list> A blockchain
36
- :return: <bool> True if valid, False if not
35
+ :param chain: A blockchain
36
+ :return: True if valid, False if not
37
37
"""
38
38
39
39
last_block = chain [0 ]
@@ -57,12 +57,12 @@ def valid_chain(self, chain):
57
57
58
58
return True
59
59
60
- def resolve_conflicts (self ):
60
+ def resolve_conflicts (self ) -> bool :
61
61
"""
62
62
This is our consensus algorithm, it resolves conflicts
63
63
by replacing our chain with the longest one in the network.
64
64
65
- :return: <bool> True if our chain was replaced, False if not
65
+ :return: True if our chain was replaced, False if not
66
66
"""
67
67
68
68
neighbours = self .nodes
@@ -91,13 +91,13 @@ def resolve_conflicts(self):
91
91
92
92
return False
93
93
94
- def new_block (self , proof , previous_hash = None ) :
94
+ def new_block (self , proof : int , previous_hash : Optional [ str ]) -> Dict [ str , Any ] :
95
95
"""
96
96
Create a new Block in the Blockchain
97
97
98
- :param proof: <int> The proof given by the Proof of Work algorithm
99
- :param previous_hash: (Optional) <str> Hash of previous Block
100
- :return: <dict> New Block
98
+ :param proof: The proof given by the Proof of Work algorithm
99
+ :param previous_hash: Hash of previous Block
100
+ :return: New Block
101
101
"""
102
102
103
103
block = {
@@ -114,14 +114,14 @@ def new_block(self, proof, previous_hash=None):
114
114
self .chain .append (block )
115
115
return block
116
116
117
- def new_transaction (self , sender , recipient , amount ) :
117
+ def new_transaction (self , sender : str , recipient : str , amount : int ) -> int :
118
118
"""
119
119
Creates a new transaction to go into the next mined Block
120
120
121
- :param sender: <str> Address of the Sender
122
- :param recipient: <str> Address of the Recipient
123
- :param amount: <int> Amount
124
- :return: <int> The index of the Block that will hold this transaction
121
+ :param sender: Address of the Sender
122
+ :param recipient: Address of the Recipient
123
+ :param amount: Amount
124
+ :return: The index of the Block that will hold this transaction
125
125
"""
126
126
self .current_transactions .append ({
127
127
'sender' : sender ,
@@ -132,30 +132,26 @@ def new_transaction(self, sender, recipient, amount):
132
132
return self .last_block ['index' ] + 1
133
133
134
134
@property
135
- def last_block (self ):
135
+ def last_block (self ) -> Dict [ str : Any ] :
136
136
return self .chain [- 1 ]
137
137
138
138
@staticmethod
139
- def hash (block ) :
139
+ def hash (block : Dict [ str , Any ]) -> str :
140
140
"""
141
141
Creates a SHA-256 hash of a Block
142
142
143
- :param block: <dict> Block
144
- :return: <str>
143
+ :param block: Block
145
144
"""
146
145
147
146
# We must make sure that the Dictionary is Ordered, or we'll have inconsistent hashes
148
147
block_string = json .dumps (block , sort_keys = True ).encode ()
149
148
return hashlib .sha256 (block_string ).hexdigest ()
150
149
151
- def proof_of_work (self , last_proof ) :
150
+ def proof_of_work (self , last_proof : int ) -> int :
152
151
"""
153
152
Simple Proof of Work Algorithm:
154
153
- Find a number p' such that hash(pp') contains leading 4 zeroes, where p is the previous p'
155
154
- p is the previous proof, and p' is the new proof
156
-
157
- :param last_proof: <int>
158
- :return: <int>
159
155
"""
160
156
161
157
proof = 0
@@ -165,13 +161,13 @@ def proof_of_work(self, last_proof):
165
161
return proof
166
162
167
163
@staticmethod
168
- def valid_proof (last_proof , proof ) :
164
+ def valid_proof (last_proof : int , proof : int ) -> bool :
169
165
"""
170
166
Validates the Proof
171
167
172
- :param last_proof: <int> Previous Proof
173
- :param proof: <int> Current Proof
174
- :return: <bool> True if correct, False if not.
168
+ :param last_proof: Previous Proof
169
+ :param proof: Current Proof
170
+ :return: True if correct, False if not.
175
171
"""
176
172
177
173
guess = f'{ last_proof } { proof } ' .encode ()
0 commit comments