Mercurial > public > bitcaviar-plus
annotate src/block.py @ 3:3d83609e12a1
get value in output
author | Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com> |
---|---|
date | Sun, 17 Oct 2021 17:33:26 +0200 |
parents | 5b16e6df6a59 |
children | e7a84094bf07 |
rev | line source |
---|---|
0
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
1 import hashlib |
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
2 from src.helpers import read_bytes |
2
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
3 from src.helpers import get_variable_int |
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 |
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
6 class Block: |
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 Block structure |
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
9 """ |
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
10 |
2
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
11 block_hash = str() |
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
12 magic_number = int() |
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
13 size = int() |
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
14 number_of_transactions = int() |
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
15 transactions = [] |
0
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
16 |
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
17 class Header: |
2
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
18 version = int() |
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
19 previous_block_hash = str() |
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
20 merkle_root = str() |
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
21 timestamp = int() # Epoch Unix time |
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
22 difficult_target = int() # Bits |
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
23 nonce = int() |
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
24 |
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
25 |
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
26 class Transaction: |
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
27 id = str() |
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
28 version = int() |
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
29 number_of_inputs = int() |
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
30 inputs = [] |
3
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
31 number_of_outputs = int() |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
32 outputs = [] |
2
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
33 |
3
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
34 class TransactionInput: |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
35 id = str() |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
36 is_coinbase = False |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
37 vout = int() |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
38 script_sig_size = int() |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
39 script_sig = str() |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
40 sequence = int() |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
41 |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
42 class TransactionOutput: |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
43 value = float() |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
44 script_pub_key_size = int() |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
45 script_pub_key = str() |
0
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
46 |
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
47 |
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
48 def read_block(file): |
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
49 """ |
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
50 Deserialize block |
2
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
51 More info about block structure: https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch09.asciidoc |
0
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
52 :param file: <class '_io.BufferedReader'>, required |
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
53 :return: |
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
54 """ |
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
55 |
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
56 block = Block() |
2
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
57 block.magic_number = int.from_bytes(read_bytes(file, 4), 'big') |
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
58 block.size = int.from_bytes(read_bytes(file, 4), 'big') |
0
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
59 |
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
60 # Compute block hash |
2
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
61 header_bytes = read_bytes(file, 80, 'forward') |
0
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
62 block_hash = hashlib.sha256(header_bytes).digest() |
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
63 block_hash = hashlib.sha256(block_hash).digest() |
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
64 |
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
65 # Read block header |
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
66 header = block.Header() |
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
67 header.block_hash = block_hash[::-1].hex() |
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
68 header.version = int.from_bytes(header_bytes[:4], 'little') |
2
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
69 header.previous_block_hash = header_bytes[4:36][::-1].hex() |
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
70 header.merkle_root = header_bytes[36:68][::-1].hex() |
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
71 header.timestamp = int.from_bytes(header_bytes[68:72], 'little') |
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
72 header.difficult_target = int.from_bytes(header_bytes[72:76], 'little') |
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
73 header.nonce = int.from_bytes(header_bytes[76:80], 'little') |
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
74 |
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
75 # Number of transactions (varInt) |
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
76 block.number_of_transactions = get_variable_int(file) |
0
2327b9eda10f
first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff
changeset
|
77 |
3
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
78 for transaction_number in range(block.number_of_transactions): |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
79 transaction = Transaction() |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
80 transaction.version = int.from_bytes(read_bytes(file, 4), 'big') |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
81 transaction.number_of_inputs = get_variable_int(file) |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
82 |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
83 for input_number in range(transaction.number_of_inputs): |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
84 transaction_input = transaction.TransactionInput() |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
85 transaction_input.id = read_bytes(file, 32).hex() |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
86 if transaction_input.id == '0000000000000000000000000000000000000000000000000000000000000000': |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
87 transaction_input.is_coinbase = True |
2
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
88 |
3
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
89 transaction_input.vout = int.from_bytes(read_bytes(file, 4), 'little') |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
90 transaction_input.script_sig_size = get_variable_int(file) |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
91 transaction_input.script_sig = read_bytes(file, transaction_input.script_sig_size, 'forward').hex() |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
92 transaction_input.sequence = int.from_bytes(read_bytes(file, 4), 'little') |
2
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
93 |
3
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
94 transaction.number_of_outputs = get_variable_int(file) |
2
5b16e6df6a59
get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
0
diff
changeset
|
95 |
3
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
96 for output_number in range(transaction.number_of_outputs): |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
97 transaction_output = transaction.TransactionOutput() |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
98 transaction_output.value = float.fromhex(read_bytes(file, 8).hex()) |
3d83609e12a1
get value in output
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
2
diff
changeset
|
99 transaction_output.value /= 100000000 # Satoshis to BTC |