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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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