Mercurial > public > bitcaviar-plus
comparison 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 |
comparison
equal
deleted
inserted
replaced
1:8522a23c82f0 | 2:5b16e6df6a59 |
---|---|
1 import hashlib | 1 import hashlib |
2 from src.helpers import read_bytes | 2 from src.helpers import read_bytes |
3 from src.helpers import get_variable_int | |
3 | 4 |
4 | 5 |
5 class Block: | 6 class Block: |
6 """ | 7 """ |
7 Block structure | 8 Block structure |
8 """ | 9 """ |
9 | 10 |
10 block_hash = None | 11 block_hash = str() |
11 magic_number = None | 12 magic_number = int() |
12 size = None | 13 size = int() |
13 | 14 number_of_transactions = int() |
14 def __init__(self): | 15 transactions = [] |
15 # Init BlockHeader class | |
16 self.header = self.Header() | |
17 | 16 |
18 class Header: | 17 class Header: |
19 version = None | 18 version = int() |
20 previous_block_hash = None | 19 previous_block_hash = str() |
21 merkle_root = None | 20 merkle_root = str() |
22 timestamp = None | 21 timestamp = int() # Epoch Unix time |
23 difficult_target = None | 22 difficult_target = int() # Bits |
24 nonce = None | 23 nonce = int() |
24 | |
25 | |
26 class Transaction: | |
27 id = str() | |
28 version = int() | |
29 number_of_inputs = int() | |
30 inputs = [] | |
31 | |
32 class Inputs: | |
33 pass | |
25 | 34 |
26 | 35 |
27 def read_block(file): | 36 def read_block(file): |
28 """ | 37 """ |
29 Deserialize block | 38 Deserialize block |
39 More info about block structure: https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch09.asciidoc | |
30 :param file: <class '_io.BufferedReader'>, required | 40 :param file: <class '_io.BufferedReader'>, required |
31 :return: | 41 :return: |
32 """ | 42 """ |
33 | 43 |
34 block = Block() | 44 block = Block() |
35 block.magic_number = int(read_bytes(file, 4), 16) | 45 block.magic_number = int.from_bytes(read_bytes(file, 4), 'big') |
36 block.size = int(read_bytes(file, 4), 16) | 46 block.size = int.from_bytes(read_bytes(file, 4), 'big') |
37 | 47 |
38 # Compute block hash | 48 # Compute block hash |
39 header_bytes = file.read(80) | 49 header_bytes = read_bytes(file, 80, 'forward') |
40 block_hash = hashlib.sha256(header_bytes).digest() | 50 block_hash = hashlib.sha256(header_bytes).digest() |
41 block_hash = hashlib.sha256(block_hash).digest() | 51 block_hash = hashlib.sha256(block_hash).digest() |
42 | 52 |
43 # Read block header | 53 # Read block header |
44 header = block.Header() | 54 header = block.Header() |
45 header.block_hash = block_hash[::-1].hex() | 55 header.block_hash = block_hash[::-1].hex() |
46 header.version = int.from_bytes(header_bytes[:4], 'little') | 56 header.version = int.from_bytes(header_bytes[:4], 'little') |
47 header.previous_block_hash = header_bytes[4:32].hex() | 57 header.previous_block_hash = header_bytes[4:36][::-1].hex() |
58 header.merkle_root = header_bytes[36:68][::-1].hex() | |
59 header.timestamp = int.from_bytes(header_bytes[68:72], 'little') | |
60 header.difficult_target = int.from_bytes(header_bytes[72:76], 'little') | |
61 header.nonce = int.from_bytes(header_bytes[76:80], 'little') | |
48 | 62 |
63 # Number of transactions (varInt) | |
64 block.number_of_transactions = get_variable_int(file) | |
65 | |
66 # Compute transaction ID | |
67 # Get remaining bytes until the end of the block | |
68 transaction = Transaction() | |
69 bytes_read = file.tell() | |
70 whole_block_size = block.size + 8 # Plus magic number and block size | |
71 transaction_data_size = whole_block_size - bytes_read | |
72 transaction_data = file.read(transaction_data_size) | |
73 file.seek(bytes_read) # Set position to where 'transaction data' starts | |
74 transaction_id = hashlib.sha256(transaction_data).digest() | |
75 transaction_id = hashlib.sha256(transaction_id).digest() | |
76 transaction.id = transaction_id[::-1].hex() | |
77 | |
78 transaction.version = int.from_bytes(read_bytes(file, 4), 'little') | |
79 transaction.number_of_inputs = get_variable_int(file) | |
80 | |
81 | |
82 |