Mercurial > public > bitcaviar-plus
annotate src/block.py @ 4:e7a84094bf07
refactor code
author | Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com> |
---|---|
date | Wed, 20 Oct 2021 19:36:39 +0200 |
parents | 3d83609e12a1 |
children | 1a8d94b500d8 |
rev | line source |
---|---|
0
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
1 import hashlib |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
2 from src.block_structure import * |
0
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
3 |
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
4 |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
5 def read_block(f): |
0
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
6 """ |
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
7 Deserialize block |
2
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
8 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
|
9 More info about bytes order: https://en.wikipedia.org/wiki/Endianness |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
10 :param f: buffer, required |
0
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
11 :return: |
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
12 """ |
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 block = Block() |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
15 _ = f.read(4) # Magic number |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
16 _ = f.read(4)[::-1] # Block size |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
17 header_bytes = f.read(80) |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
18 block.h = __get_hash(header_bytes) |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
19 f.seek(8) |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
20 block.header = __get_header(f) |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
21 number_of_transactions = __get_variable_int(f) |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
22 for transaction_number in range(number_of_transactions): |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
23 block.transactions.append(__get_transaction(f)) |
0
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
24 |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
25 return block.__dict__ |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
26 |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
27 |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
28 def __get_header(f): |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
29 """ |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
30 Get block header |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
31 :param f: buffer, required |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
32 :return: dict |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
33 """ |
0
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
34 |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
35 header = Header() |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
36 header.version = int.from_bytes(f.read(4), 'little') |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
37 header.previous_block_hash = f.read(32)[::-1].hex() |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
38 header.merkle_root = f.read(32)[::-1].hex() |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
39 header.timestamp = int.from_bytes(f.read(4), 'little') |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
40 header.bits = int.from_bytes(f.read(4), 'little') |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
41 header.nonce = int.from_bytes(f.read(4), 'little') |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
42 |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
43 return header.__dict__ |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
44 |
2
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
45 |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
46 def __get_transaction(f): |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
47 """ |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
48 Get transaction |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
49 :param f: buffer, required |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
50 :return: dict |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
51 """ |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
52 |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
53 transaction = Transaction() |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
54 transaction.version = int.from_bytes(f.read(4)[::-1], 'big') |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
55 number_of_inputs = __get_variable_int(f) |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
56 |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
57 for input_number in range(number_of_inputs): |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
58 transaction_input = TransactionInput() |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
59 transaction_input.id = f.read(32)[::-1].hex() |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
60 |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
61 if transaction_input.id == '0000000000000000000000000000000000000000000000000000000000000000': |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
62 transaction_input.is_coinbase = True |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
63 |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
64 transaction_input.vout = int.from_bytes(f.read(4)[::-1], 'little') |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
65 script_sig_size = __get_variable_int(f) |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
66 transaction_input.script_sig = f.read(script_sig_size).hex() |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
67 transaction_input.sequence = int.from_bytes(f.read(4)[::-1], 'little') |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
68 transaction.inputs.append(transaction_input.__dict__) |
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 |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
72 for output_number in range(number_of_outputs): |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
73 transaction_output = TransactionOutput() |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
74 transaction_output.value = float.fromhex(f.read(8)[::-1].hex()) |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
75 transaction_output.value /= 100000000 # Satoshis to BTC |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
76 script_pub_key_size = __get_variable_int(f) |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
77 transaction_output.script_pub_key = f.read(script_pub_key_size) |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
78 transaction.outputs.append(transaction_output.__dict__) |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
79 |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
80 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
|
81 |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
82 print(transaction.outputs) |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
83 print(transaction.inputs) |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
84 print(transaction.__dict__) |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
85 |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
86 return transaction.__dict__ |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
87 |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
88 |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
89 def __get_hash(buffer, bytes_order='backward'): |
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 Compute hash from bytes |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
92 More info about bytes order: https://en.wikipedia.org/wiki/Endianness |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
93 :param buffer: bytes, required |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
94 :param bytes_order: string, 'backward' or 'forward', optional |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
95 :return: string |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
96 """ |
2
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
97 |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
98 h = hashlib.sha256(buffer).digest() |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
99 h = hashlib.sha256(h).digest() |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
100 |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
101 if bytes_order == 'backward': |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
102 h = h[::-1] |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
103 |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
104 return h.hex() |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
105 |
2
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
106 |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
107 def __get_variable_int(f): |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
108 """ |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
109 Get variable int from transaction data |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
110 More info: https://learnmeabitcoin.com/technical/varint |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
111 :param f: buffer, required |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
112 :return: int |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
113 """ |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
114 |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
115 first_byte = f.read(1) |
2
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
116 |
4
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
117 if first_byte == b'\xfd': |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
118 variable_int_bytes = f.read(2)[::-1] |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
119 elif first_byte == b'\xfe': |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
120 variable_int_bytes = f.read(4)[::-1] |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
121 elif first_byte == b'\xff': |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
122 variable_int_bytes = f.read(8)[::-1] |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
123 else: |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
124 variable_int_bytes = first_byte |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
125 |
e7a84094bf07
refactor code
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
3
diff
changeset
|
126 return int.from_bytes(variable_int_bytes, 'little') |