annotate src/block.py @ 2:5b16e6df6a59

get txid hashing transaction data
author Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
date Sun, 17 Oct 2021 11:14:46 +0200
parents 2327b9eda10f
children 3d83609e12a1
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 = []
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
31
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
32 class Inputs:
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
33 pass
0
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
34
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
35
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
36 def read_block(file):
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
37 """
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
38 Deserialize block
2
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
39 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
40 :param file: <class '_io.BufferedReader'>, required
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
41 :return:
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
42 """
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
43
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
44 block = Block()
2
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
45 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
46 block.size = int.from_bytes(read_bytes(file, 4), 'big')
0
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 # Compute block hash
2
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
49 header_bytes = read_bytes(file, 80, 'forward')
0
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
50 block_hash = hashlib.sha256(header_bytes).digest()
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
51 block_hash = hashlib.sha256(block_hash).digest()
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
52
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
53 # Read block header
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
54 header = block.Header()
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
55 header.block_hash = block_hash[::-1].hex()
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
56 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
57 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
58 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
59 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
60 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
61 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
62
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
63 # Number of transactions (varInt)
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
64 block.number_of_transactions = get_variable_int(file)
0
2327b9eda10f first commit
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents:
diff changeset
65
2
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
66 # Compute transaction ID
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
67 # Get remaining bytes until the end of the block
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
68 transaction = Transaction()
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
69 bytes_read = file.tell()
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
70 whole_block_size = block.size + 8 # Plus magic number and block size
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
71 transaction_data_size = whole_block_size - bytes_read
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
72 transaction_data = file.read(transaction_data_size)
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
73 file.seek(bytes_read) # Set position to where 'transaction data' starts
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
74 transaction_id = hashlib.sha256(transaction_data).digest()
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
75 transaction_id = hashlib.sha256(transaction_id).digest()
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
76 transaction.id = transaction_id[::-1].hex()
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
77
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
78 transaction.version = int.from_bytes(read_bytes(file, 4), 'little')
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
79 transaction.number_of_inputs = get_variable_int(file)
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
80
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
81
5b16e6df6a59 get txid hashing transaction data
Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
parents: 0
diff changeset
82