1+ import time
2+
3+ from backend .util .crypto_hash import crypto_hash
4+ from backend .util .hex_to_binary import hex_to_binary
5+ from backend .config import MINE_RATE
6+
7+ GENESIS_DATA = {
8+ 'timestamp' : 1 ,
9+ 'last_hash' : 'genesis_last_hash' ,
10+ 'hash' : 'genesis_hash' ,
11+ 'data' : [],
12+ 'difficulty' : 3 ,
13+ 'nonce' : 'genesis_nonce'
14+ }
15+
16+ class Block :
17+ """
18+ Block: a unit of storage.
19+ Store transactions in a blockchain that supports a cryptocurrency.
20+ """
21+ def __init__ (self , timestamp , last_hash , hash , data , difficulty , nonce ):
22+ self .timestamp = timestamp
23+ self .last_hash = last_hash
24+ self .hash = hash
25+ self .data = data
26+ self .difficulty = difficulty
27+ self .nonce = nonce
28+
29+ def __repr__ (self ):
30+ return (
31+ 'Block('
32+ f'timestamp: { self .timestamp } , '
33+ f'last_hash: { self .last_hash } , '
34+ f'hash: { self .hash } , '
35+ f'data: { self .data } , '
36+ f'difficulty: { self .difficulty } , '
37+ f'nonce: { self .nonce } )'
38+ )
39+
40+ @staticmethod
41+ def mine_block (last_block , data ):
42+ """
43+ Mine a block based on the given last_block and data, until a block hash
44+ is found that meets the leading 0's proof of work requirement.
45+ """
46+ timestamp = time .time_ns ()
47+ last_hash = last_block .hash
48+ difficulty = Block .adjust_difficulty (last_block , timestamp )
49+ nonce = 0
50+ hash = crypto_hash (timestamp , last_hash , data , difficulty , nonce )
51+
52+ while hex_to_binary (hash )[0 :difficulty ] != '0' * difficulty :
53+ nonce += 1
54+ timestamp = time .time_ns ()
55+ difficulty = Block .adjust_difficulty (last_block , timestamp )
56+ hash = crypto_hash (timestamp , last_hash , data , difficulty , nonce )
57+
58+ return Block (timestamp , last_hash , hash , data , difficulty , nonce )
59+
60+ @staticmethod
61+ def genesis ():
62+ """
63+ Generate the genesis block.
64+ """
65+ return Block (** GENESIS_DATA )
66+
67+ @staticmethod
68+ def adjust_difficulty (last_block , new_timestamp ):
69+ """
70+ Calculate the adjusted difficulty according to the MINE_RATE.
71+ Increase the difficulty for slowly mined blocks.
72+ Decrease the difficulty for quickly mined blocks.
73+ """
74+ if (new_timestamp - last_block .timestamp ) < MINE_RATE :
75+ return last_block .difficulty + 1
76+
77+ if (last_block .difficulty - 1 ) > 0 :
78+ return last_block .difficulty - 1
79+
80+ return 1
81+
82+ def main ():
83+ genesis_block = Block .genesis ()
84+ block = Block .mine_block (genesis_block , 'foo' )
85+ print (block )
86+
87+ if __name__ == '__main__' :
88+ main ()
0 commit comments