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