changeset 6:5f6d1a28051a

add python package config files
author Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com>
date Sun, 24 Oct 2021 15:18:54 +0200
parents 1a8d94b500d8
children e4afde8d5a7e
files .gitignore .idea/puppy.iml main.py pyproject.toml setup.cfg src/__init__.py src/block.py src/block_structure.py src/helpers.py src/puppy/__init__.py src/puppy/block.py src/puppy/block_structure.py src/puppy/helpers.py test_block_0.json tests/__init__.py
diffstat 12 files changed, 240 insertions(+), 238 deletions(-) [+]
line wrap: on
line diff
--- a/.gitignore	Thu Oct 21 18:52:54 2021 +0200
+++ b/.gitignore	Sun Oct 24 15:18:54 2021 +0200
@@ -1,4 +1,3 @@
-
 # Created by https://www.toptal.com/developers/gitignore/api/macos,python,pycharm
 # Edit at https://www.toptal.com/developers/gitignore?templates=macos,python,pycharm
 
--- a/.idea/puppy.iml	Thu Oct 21 18:52:54 2021 +0200
+++ b/.idea/puppy.iml	Sun Oct 24 15:18:54 2021 +0200
@@ -2,7 +2,10 @@
 <module type="PYTHON_MODULE" version="4">
   <component name="NewModuleRootManager">
     <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
       <excludeFolder url="file://$MODULE_DIR$/venv" />
+      <excludeFolder url="file://$MODULE_DIR$/.idea/ZeppelinRemoteNotebooks" />
+      <excludeFolder url="file://$MODULE_DIR$/tests/output_files" />
     </content>
     <orderEntry type="inheritedJdk" />
     <orderEntry type="sourceFolder" forTests="false" />
--- a/main.py	Thu Oct 21 18:52:54 2021 +0200
+++ b/main.py	Sun Oct 24 15:18:54 2021 +0200
@@ -1,13 +1,15 @@
-import json
-from src.block import read_block
+import os
+from src.puppy.block import read_block
 
 
 def main():
-    with open('/Users/dennis/Bitcoin/blocks/blk00000.dat', 'rb') as f:
-        for i in range(1):
+    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)
-            with open('test_block_0.json', 'w') as f_test:
-                json.dump(block, f_test, ensure_ascii=False, indent=4)
 
 
 if __name__ == '__main__':
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pyproject.toml	Sun Oct 24 15:18:54 2021 +0200
@@ -0,0 +1,6 @@
+[build-system]
+requires = [
+    "setuptools>=42",
+    "wheel"
+]
+build-backend = "setuptools.build_meta"
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/setup.cfg	Sun Oct 24 15:18:54 2021 +0200
@@ -0,0 +1,24 @@
+[metadata]
+name = example-pkg-YOUR-USERNAME-HERE
+version = 0.0.1
+author = Example Author
+author_email = author@example.com
+description = A small example package
+long_description = file: README.md
+long_description_content_type = text/markdown
+url = https://github.com/pypa/sampleproject
+project_urls =
+    Bug Tracker = https://github.com/pypa/sampleproject/issues
+classifiers =
+    Programming Language :: Python :: 3
+    License :: OSI Approved :: MIT License
+    Operating System :: OS Independent
+
+[options]
+package_dir =
+    = src
+packages = find:
+python_requires = >=3.8
+
+[options.packages.find]
+where = src
\ No newline at end of file
--- a/src/block.py	Thu Oct 21 18:52:54 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-from src.helpers import __get_hash
-from src.helpers import __get_variable_int
-from src.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
-    header_bytes = f.read(80)
-    block.block_hash = __get_hash(header_bytes)
-    f.seek(8)
-    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 transaction id
-    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/block_structure.py	Thu Oct 21 18:52:54 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-class Block:
-    block_hash = str()  # Block hash
-    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/helpers.py	Thu Oct 21 18:52: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')
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/puppy/block.py	Sun Oct 24 15:18:54 2021 +0200
@@ -0,0 +1,127 @@
+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__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/puppy/block_structure.py	Sun Oct 24 15:18:54 2021 +0200
@@ -0,0 +1,31 @@
+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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/puppy/helpers.py	Sun Oct 24 15:18:54 2021 +0200
@@ -0,0 +1,41 @@
+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')
--- a/test_block_0.json	Thu Oct 21 18:52:54 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-{
-    "block_hash": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
-    "header": {
-        "version": 1,
-        "previous_block_hash": "0000000000000000000000000000000000000000000000000000000000000000",
-        "merkle_root": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
-        "timestamp": 1231006505,
-        "bits": 486604799,
-        "nonce": 2083236893
-    },
-    "transactions": [
-        {
-            "version": 1,
-            "lock_time": 0,
-            "inputs": [
-                {
-                    "id": "0000000000000000000000000000000000000000000000000000000000000000",
-                    "is_coinbase": true,
-                    "vout": 4294967295,
-                    "script_sig": "04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73",
-                    "sequence": 4294967295
-                }
-            ],
-            "outputs": [
-                {
-                    "value": 50.0,
-                    "script_pub_key": "4104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac"
-                }
-            ],
-            "id": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
-        }
-    ]
-}
\ No newline at end of file