Mercurial > public > bitcaviar-plus
annotate src/block.py @ 5:1a8d94b500d8
finish basic parser
author | Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com> |
---|---|
date | Thu, 21 Oct 2021 18:52:54 +0200 |
parents | e7a84094bf07 |
children |
rev | line source |
---|---|
5
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
1 from src.helpers import __get_hash |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
2 from src.helpers import __get_variable_int |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
3 from src.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 |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
18 header_bytes = f.read(80) |
5
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
19 block.block_hash = __get_hash(header_bytes) |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
20 f.seek(8) |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
21 block.header = __get_header(f) |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
22 number_of_transactions = __get_variable_int(f) |
5
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
23 |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
24 transactions = [] |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
25 for transaction_number in range(number_of_transactions): |
5
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
26 transactions.append(__get_transaction(f)) |
0
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
27 |
5
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
28 block_dict = block.__dict__ |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
29 block_dict['transactions'] = transactions |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
30 |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
31 return block_dict |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
32 |
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 def __get_header(f): |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
35 """ |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
36 Get block header |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
37 :param f: buffer, required |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
38 :return: dict |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
39 """ |
0
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
40 |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
41 header = Header() |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
42 header.version = int.from_bytes(f.read(4), 'little') |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
43 header.previous_block_hash = f.read(32)[::-1].hex() |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
44 header.merkle_root = f.read(32)[::-1].hex() |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
45 header.timestamp = int.from_bytes(f.read(4), 'little') |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
46 header.bits = int.from_bytes(f.read(4), 'little') |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
47 header.nonce = int.from_bytes(f.read(4), 'little') |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
48 |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
49 return header.__dict__ |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
50 |
2
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
51 |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
52 def __get_transaction(f): |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
53 """ |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
54 Get transaction |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
55 :param f: buffer, required |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
56 :return: dict |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
57 """ |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
58 |
5
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
59 transaction_data_start = f.tell() |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
60 |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
61 transaction = Transaction() |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
62 transaction.version = int.from_bytes(f.read(4)[::-1], 'big') |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
63 number_of_inputs = __get_variable_int(f) |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
64 |
5
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
65 inputs = [] |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
66 for input_number in range(number_of_inputs): |
5
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
67 inputs.append(__get_input(f)) |
0
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
68 |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
69 number_of_outputs = __get_variable_int(f) |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
70 |
5
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
71 outputs = [] |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
72 for output_number in range(number_of_outputs): |
5
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
73 outputs.append(__get_outputs(f)) |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
74 |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
75 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
|
76 |
5
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
77 transaction_dict = transaction.__dict__ |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
78 transaction_dict['inputs'] = inputs |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
79 transaction_dict['outputs'] = outputs |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
80 |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
81 transaction_data_end = f.tell() |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
82 |
5
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
83 # Get transaction id |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
84 transaction_data_size = transaction_data_end - transaction_data_start |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
85 f.seek(transaction_data_start) |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
86 transaction_data = f.read(transaction_data_size) |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
87 transaction.id = __get_hash(transaction_data) |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
88 |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
89 return transaction_dict |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
90 |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
91 |
5
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
92 def __get_input(buffer): |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
93 """ |
5
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
94 Get input from transaction data |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
95 :param buffer: bytes, required |
5
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
96 :return: dict |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
97 """ |
2
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
98 |
5
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
99 transaction_input = TransactionInput() |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
100 transaction_input.id = buffer.read(32)[::-1].hex() |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
101 |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
102 if transaction_input.id == '0000000000000000000000000000000000000000000000000000000000000000': |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
103 transaction_input.is_coinbase = True |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
104 |
5
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
105 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
|
106 script_sig_size = __get_variable_int(buffer) |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
107 transaction_input.script_sig = buffer.read(script_sig_size).hex() |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
108 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
|
109 |
5
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
110 return transaction_input.__dict__ |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
111 |
2
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
112 |
5
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
113 def __get_outputs(buffer): |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
114 """ |
5
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
115 Get output from transaction data |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
116 :param buffer: bytes, required |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
117 :return: dict |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
118 """ |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
119 |
5
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
120 transaction_output = TransactionOutput() |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
121 transaction_output.value = float.fromhex(buffer.read(8)[::-1].hex()) |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
122 transaction_output.value /= 100000000 # Satoshis to BTC |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
123 script_pub_key_size = __get_variable_int(buffer) |
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
124 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
|
125 |
5
1a8d94b500d8
finish basic parser
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
4
diff
changeset
|
126 return transaction_output.__dict__ |