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