annotate src/puppy/block.py @ 6:5f6d1a28051a

add python package config files
author Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
date Sun, 24 Oct 2021 15:18:54 +0200
parents src/block.py@1a8d94b500d8
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6
5f6d1a28051a add python package config files
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 5
diff changeset
1 from puppy.helpers import __get_hash
5f6d1a28051a add python package config files
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 5
diff changeset
2 from puppy.helpers import __get_variable_int
5f6d1a28051a add python package config files
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 5
diff changeset
3 from puppy.block_structure import *
0
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
4
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
5
4
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
6 def read_block(f):
0
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
7 """
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
8 Deserialize block
2
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
9 More info about block structure: https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch09.asciidoc
4
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
10 More info about bytes order: https://en.wikipedia.org/wiki/Endianness
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
11 :param f: buffer, required
0
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
12 :return:
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
13 """
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
14
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
15 block = Block()
4
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
16 _ = f.read(4) # Magic number
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
17 _ = f.read(4)[::-1] # Block size
6
5f6d1a28051a add python package config files
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 5
diff changeset
18 position_before_header = f.tell()
4
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
19 header_bytes = f.read(80)
5
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
20 block.block_hash = __get_hash(header_bytes)
6
5f6d1a28051a add python package config files
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 5
diff changeset
21 f.seek(position_before_header)
4
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
22 block.header = __get_header(f)
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
23 number_of_transactions = __get_variable_int(f)
5
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
24
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
25 transactions = []
4
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
26 for transaction_number in range(number_of_transactions):
5
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
27 transactions.append(__get_transaction(f))
0
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
28
5
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
29 block_dict = block.__dict__
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
30 block_dict['transactions'] = transactions
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
31
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
32 return block_dict
4
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
33
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
34
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
35 def __get_header(f):
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
36 """
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
37 Get block header
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
38 :param f: buffer, required
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
39 :return: dict
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
40 """
0
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
41
4
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
42 header = Header()
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
43 header.version = int.from_bytes(f.read(4), 'little')
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
44 header.previous_block_hash = f.read(32)[::-1].hex()
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
45 header.merkle_root = f.read(32)[::-1].hex()
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
46 header.timestamp = int.from_bytes(f.read(4), 'little')
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
47 header.bits = int.from_bytes(f.read(4), 'little')
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
48 header.nonce = int.from_bytes(f.read(4), 'little')
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
49
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
50 return header.__dict__
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
51
2
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
52
4
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
53 def __get_transaction(f):
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
54 """
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
55 Get transaction
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
56 :param f: buffer, required
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
57 :return: dict
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
58 """
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
59
5
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
60 transaction_data_start = f.tell()
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
61
4
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
62 transaction = Transaction()
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
63 transaction.version = int.from_bytes(f.read(4)[::-1], 'big')
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
64 number_of_inputs = __get_variable_int(f)
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
65
5
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
66 inputs = []
4
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
67 for input_number in range(number_of_inputs):
5
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
68 inputs.append(__get_input(f))
0
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
69
4
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
70 number_of_outputs = __get_variable_int(f)
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
71
5
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
72 outputs = []
4
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
73 for output_number in range(number_of_outputs):
5
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
74 outputs.append(__get_outputs(f))
4
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
75
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
76 transaction.lock_time = int.from_bytes(f.read(4)[::-1], 'little')
3
3d83609e12a1 get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 2
diff changeset
77
5
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
78 transaction_dict = transaction.__dict__
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
79 transaction_dict['inputs'] = inputs
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
80 transaction_dict['outputs'] = outputs
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
81
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
82 transaction_data_end = f.tell()
4
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
83
6
5f6d1a28051a add python package config files
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 5
diff changeset
84 # Get current transaction ID: https://learnmeabitcoin.com/technical/txid
5
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
85 transaction_data_size = transaction_data_end - transaction_data_start
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
86 f.seek(transaction_data_start)
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
87 transaction_data = f.read(transaction_data_size)
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
88 transaction.id = __get_hash(transaction_data)
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
89
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
90 return transaction_dict
4
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
91
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
92
5
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
93 def __get_input(buffer):
4
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
94 """
5
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
95 Get input from transaction data
4
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
96 :param buffer: bytes, required
5
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
97 :return: dict
4
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
98 """
2
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
99
5
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
100 transaction_input = TransactionInput()
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
101 transaction_input.id = buffer.read(32)[::-1].hex()
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
102
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
103 if transaction_input.id == '0000000000000000000000000000000000000000000000000000000000000000':
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
104 transaction_input.is_coinbase = True
4
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
105
5
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
106 transaction_input.vout = int.from_bytes(buffer.read(4)[::-1], 'little')
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
107 script_sig_size = __get_variable_int(buffer)
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
108 transaction_input.script_sig = buffer.read(script_sig_size).hex()
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
109 transaction_input.sequence = int.from_bytes(buffer.read(4)[::-1], 'little')
4
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
110
5
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
111 return transaction_input.__dict__
4
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
112
2
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
113
5
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
114 def __get_outputs(buffer):
4
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
115 """
5
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
116 Get output from transaction data
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
117 :param buffer: bytes, required
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
118 :return: dict
4
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
119 """
e7a84094bf07 refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 3
diff changeset
120
5
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
121 transaction_output = TransactionOutput()
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
122 transaction_output.value = float.fromhex(buffer.read(8)[::-1].hex())
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
123 transaction_output.value /= 100000000 # Satoshis to BTC
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
124 script_pub_key_size = __get_variable_int(buffer)
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
125 transaction_output.script_pub_key = buffer.read(script_pub_key_size).hex()
2
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
126
5
1a8d94b500d8 finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 4
diff changeset
127 return transaction_output.__dict__