11import time
22
33from backend .util .crypto_hash import crypto_hash
4+ from backend .config import MINE_RATE
45
56GENESIS_DATA = {
67 'timestamp' : 1 ,
78 'last_hash' : 'genesis_last_hash' ,
89 'hash' : 'genesis_hash' ,
9- 'data' : []
10+ 'data' : [],
11+ 'difficulty' : 3 ,
12+ 'nonce' : 'genesis_nonce'
1013}
1114
1215class Block :
1316 """
1417 Block: a unit of storage.
1518 Store transactions in a blockchain that supports a cryptocurrency.
1619 """
17- def __init__ (self , timestamp , last_hash , hash , data ):
20+ def __init__ (self , timestamp , last_hash , hash , data , difficulty , nonce ):
1821 self .timestamp = timestamp
1922 self .last_hash = last_hash
2023 self .hash = hash
2124 self .data = data
25+ self .difficulty = difficulty
26+ self .nonce = nonce
2227
2328 def add_block (self , data ):
2429 self .chain .append (Block (data ))
@@ -29,33 +34,53 @@ def __repr__(self):
2934 f'timestamp: { self .timestamp } , '
3035 f'last_hash: { self .last_hash } , '
3136 f'hash: { self .hash } , '
32- f'data: { self .data } )'
37+ f'data: { self .data } , '
38+ f'difficulty: { self .difficulty } , '
39+ f'nonce: { self .nonce } )'
3340 )
3441
3542 @staticmethod
3643 def mine_block (last_block , data ):
3744 """
38- Mine a block based on the given last_block and data.
45+ Mine a block based on the given last_block and data, until a block hash
46+ is found that meets the leading 0's proof of work requirement.
3947 """
4048 timestamp = time .time_ns ()
4149 last_hash = last_block .hash
42- hash = crypto_hash (timestamp , last_hash , data )
50+ difficulty = Block .adjust_difficulty (last_block , timestamp )
51+ nonce = 0
52+ hash = crypto_hash (timestamp , last_hash , data , difficulty , nonce )
4353
44- return Block (timestamp , last_hash , hash , data )
54+ while hash [0 :difficulty ] != '0' * difficulty :
55+ nonce += 1
56+ timestamp = time .time_ns ()
57+ difficulty = Block .adjust_difficulty (last_block , timestamp )
58+ hash = crypto_hash (timestamp , last_hash , data , difficulty , nonce )
59+
60+ return Block (timestamp , last_hash , hash , data , difficulty , nonce )
4561
4662 @staticmethod
4763 def genesis ():
4864 """
4965 Generate the genesis block.
5066 """
51- # return Block(
52- # timestamp=GENESIS_DATA['timestamp'],
53- # last_hash=GENESIS_DATA['last_hash'],
54- # hash=GENESIS_DATA['hash'],
55- # data=GENESIS_DATA['data']
56- # )
5767 return Block (** GENESIS_DATA )
5868
69+ @staticmethod
70+ def adjust_difficulty (last_block , new_timestamp ):
71+ """
72+ Calculate the adjusted difficulty according to the MINE_RATE.
73+ Increase the difficulty for slowly mined blocks.
74+ Decrease the difficulty for slowly mined blocks.
75+ """
76+ if (new_timestamp - last_block .timestamp ) < MINE_RATE :
77+ return last_block .difficulty + 1
78+
79+ if (last_block .difficulty - 1 ) > 0 :
80+ return last_block .difficulty - 1
81+
82+ return 1
83+
5984def main ():
6085 genesis_block = Block .genesis ()
6186 block = Block .mine_block (genesis_block , 'foo' )
0 commit comments