Mercurial > public > bitcaviar-plus
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 |
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__ |