changeset 7:e4afde8d5a7e

restart project
author Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
date Sun, 24 Oct 2021 15:19:56 +0200
parents 5f6d1a28051a
children 4d259e84160d
files main.py src/puppy/block.py src/puppy/block_structure.py src/puppy/helpers.py
diffstat 4 files changed, 1 insertions(+), 207 deletions(-) [+]
line wrap: on
line diff
--- a/main.py	Sun Oct 24 15:18:54 2021 +0200
+++ b/main.py	Sun Oct 24 15:19:56 2021 +0200
@@ -1,15 +1,8 @@
-import os
-from src.puppy.block import read_block
-
-
 def main():
     file_path = '/Users/dennis/Bitcoin/blocks/blk00000.dat'
 
     with open(file_path, 'rb') as f:
-        number_of_bytes_in_file = os.path.getsize(file_path)
-
-        while f.tell() < number_of_bytes_in_file:
-            block = read_block(f)
+        pass
 
 
 if __name__ == '__main__':
--- a/src/puppy/block.py	Sun Oct 24 15:18:54 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +0,0 @@
-from puppy.helpers import __get_hash
-from puppy.helpers import __get_variable_int
-from puppy.block_structure import *
-
-
-def read_block(f):
-    """
-    Deserialize block
-    More info about block structure: https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch09.asciidoc
-    More info about bytes order: https://en.wikipedia.org/wiki/Endianness
-    :param f: buffer, required
-    :return:
-    """
-
-    block = Block()
-    _ = f.read(4)  # Magic number
-    _ = f.read(4)[::-1]  # Block size
-    position_before_header = f.tell()
-    header_bytes = f.read(80)
-    block.block_hash = __get_hash(header_bytes)
-    f.seek(position_before_header)
-    block.header = __get_header(f)
-    number_of_transactions = __get_variable_int(f)
-
-    transactions = []
-    for transaction_number in range(number_of_transactions):
-        transactions.append(__get_transaction(f))
-
-    block_dict = block.__dict__
-    block_dict['transactions'] = transactions
-
-    return block_dict
-
-
-def __get_header(f):
-    """
-    Get block header
-    :param f: buffer, required
-    :return: dict
-    """
-
-    header = Header()
-    header.version = int.from_bytes(f.read(4), 'little')
-    header.previous_block_hash = f.read(32)[::-1].hex()
-    header.merkle_root = f.read(32)[::-1].hex()
-    header.timestamp = int.from_bytes(f.read(4), 'little')
-    header.bits = int.from_bytes(f.read(4), 'little')
-    header.nonce = int.from_bytes(f.read(4), 'little')
-
-    return header.__dict__
-
-
-def __get_transaction(f):
-    """
-    Get transaction
-    :param f: buffer, required
-    :return: dict
-    """
-
-    transaction_data_start = f.tell()
-
-    transaction = Transaction()
-    transaction.version = int.from_bytes(f.read(4)[::-1], 'big')
-    number_of_inputs = __get_variable_int(f)
-
-    inputs = []
-    for input_number in range(number_of_inputs):
-        inputs.append(__get_input(f))
-
-    number_of_outputs = __get_variable_int(f)
-
-    outputs = []
-    for output_number in range(number_of_outputs):
-        outputs.append(__get_outputs(f))
-
-    transaction.lock_time = int.from_bytes(f.read(4)[::-1], 'little')
-
-    transaction_dict = transaction.__dict__
-    transaction_dict['inputs'] = inputs
-    transaction_dict['outputs'] = outputs
-
-    transaction_data_end = f.tell()
-
-    # Get current transaction ID: https://learnmeabitcoin.com/technical/txid
-    transaction_data_size = transaction_data_end - transaction_data_start
-    f.seek(transaction_data_start)
-    transaction_data = f.read(transaction_data_size)
-    transaction.id = __get_hash(transaction_data)
-
-    return transaction_dict
-
-
-def __get_input(buffer):
-    """
-    Get input from transaction data
-    :param buffer: bytes, required
-    :return: dict
-    """
-
-    transaction_input = TransactionInput()
-    transaction_input.id = buffer.read(32)[::-1].hex()
-
-    if transaction_input.id == '0000000000000000000000000000000000000000000000000000000000000000':
-        transaction_input.is_coinbase = True
-
-    transaction_input.vout = int.from_bytes(buffer.read(4)[::-1], 'little')
-    script_sig_size = __get_variable_int(buffer)
-    transaction_input.script_sig = buffer.read(script_sig_size).hex()
-    transaction_input.sequence = int.from_bytes(buffer.read(4)[::-1], 'little')
-
-    return transaction_input.__dict__
-
-
-def __get_outputs(buffer):
-    """
-    Get output from transaction data
-    :param buffer: bytes, required
-    :return: dict
-    """
-
-    transaction_output = TransactionOutput()
-    transaction_output.value = float.fromhex(buffer.read(8)[::-1].hex())
-    transaction_output.value /= 100000000  # Satoshis to BTC
-    script_pub_key_size = __get_variable_int(buffer)
-    transaction_output.script_pub_key = buffer.read(script_pub_key_size).hex()
-
-    return transaction_output.__dict__
--- a/src/puppy/block_structure.py	Sun Oct 24 15:18:54 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-class Block:
-    block_hash = str()
-    header = dict()
-
-
-class Header:
-    version = int()
-    previous_block_hash = str()
-    merkle_root = str()
-    timestamp = int()
-    bits = int()
-    nonce = int()
-
-
-class Transaction:
-    id = str()
-    version = int()
-    lock_time = int()
-
-
-class TransactionInput:
-    is_coinbase = False
-    id = str()
-    vout = int()
-    script_sig = str()
-    sequence = int()
-
-
-class TransactionOutput:
-    value = float()
-    script_pub_key = str()
\ No newline at end of file
--- a/src/puppy/helpers.py	Sun Oct 24 15:18:54 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-import hashlib
-
-
-def __get_hash(buffer, bytes_order='backward'):
-    """
-    Compute hash from bytes
-    More info about bytes order: https://en.wikipedia.org/wiki/Endianness
-    :param buffer: bytes, required
-    :param bytes_order: string, 'backward' or 'forward', optional
-    :return: string
-    """
-
-    h = hashlib.sha256(buffer).digest()
-    h = hashlib.sha256(h).digest()
-
-    if bytes_order == 'backward':
-        h = h[::-1]
-
-    return h.hex()
-
-
-def __get_variable_int(f):
-    """
-    Get variable int from transaction data
-    More info: https://learnmeabitcoin.com/technical/varint
-    :param f: buffer, required
-    :return: int
-    """
-
-    first_byte = f.read(1)
-
-    if first_byte == b'\xfd':
-        variable_int_bytes = f.read(2)[::-1]
-    elif first_byte == b'\xfe':
-        variable_int_bytes = f.read(4)[::-1]
-    elif first_byte == b'\xff':
-        variable_int_bytes = f.read(8)[::-1]
-    else:
-        variable_int_bytes = first_byte
-
-    return int.from_bytes(variable_int_bytes, 'little')