# Path: electrumx/lib/hash.py
# def double_sha256(x):
#     '''SHA-256 of SHA-256, as used extensively in bitcoin.'''
#     return sha256(sha256(x))
# 
# def hash_to_hex_str(x):
#     '''Convert a big-endian binary hash to displayed hex string.
# 
#     Display form of a binary hash is reversed and converted to hex.
#     '''
#     return bytes(reversed(x)).hex()
# 
# Path: electrumx/lib/util.py
# class ConnectionLogger(logging.LoggerAdapter):
# class CompactFormatter(logging.Formatter):
# class cachedproperty(object):
# class LogicalFile(object):
#     def process(self, msg, kwargs):
#     def format(self, record):
# def make_logger(name, *, handler, level):
# def class_logger(path, classname):
#     def __init__(self, f):
#     def __get__(self, obj, type_):
# def formatted_time(t, sep=' '):
# def deep_getsizeof(obj):
#     def size(o):
# def subclasses(base_class, strict=True):
#     def select(obj):
# def chunks(items, size):
# def resolve_limit(limit):
# def bytes_to_int(be_bytes):
# def int_to_bytes(value):
# def increment_byte_string(bs):
#     def __init__(self, prefix, digits, file_size):
#     def read(self, start, size=-1):
#     def write(self, start, b):
#     def open_file(self, start, create):
# def open_file(filename, create=False):
# def open_truncate(filename):
# def address_string(address):
# def protocol_tuple(s):
# def version_string(ptuple):
# def protocol_version(client_req, min_tuple, max_tuple):
# def pack_varint(n):
# def pack_varbytes(data):


from collections import namedtuple
from electrumx.lib.hash import double_sha256, hash_to_hex_str
from electrumx.lib.util import (
    unpack_le_int32_from, unpack_le_int64_from, unpack_le_uint16_from,
    unpack_be_uint16_from,
    unpack_le_uint32_from, unpack_le_uint64_from, pack_le_int32, pack_varint,
    pack_le_uint32, pack_le_int64, pack_varbytes,
)
            pack_le_uint32(self.locktime)
        ))


class TxInput(namedtuple("TxInput", "prev_hash prev_idx script sequence")):
    '''Class representing a transaction input.'''
    def __str__(self):
        script = self.script.hex()
        prev_hash = hash_to_hex_str(self.prev_hash)
        return ("Input({}, {:d}, script={}, sequence={:d})"
                .format(prev_hash, self.prev_idx, script, self.sequence))

    def is_generation(self):
        '''Test if an input is generation/coinbase like'''
        return self.prev_idx == MINUS_1 and self.prev_hash == ZERO

    def serialize(self):
        return b''.join((
            self.prev_hash,
            pack_le_uint32(self.prev_idx),
            pack_varbytes(self.script),
            pack_le_uint32(self.sequence),
        ))


class TxOutput(namedtuple("TxOutput", "value pk_script")):

    def serialize(self):
        return b''.join((
            pack_le_int64(self.value),

# Path: electrumx/lib/hash.py
# def double_sha256(x):
#     '''SHA-256 of SHA-256, as used extensively in bitcoin.'''
#     return sha256(sha256(x))
# 
# def hash_to_hex_str(x):
#     '''Convert a big-endian binary hash to displayed hex string.
# 
#     Display form of a binary hash is reversed and converted to hex.
#     '''
#     return bytes(reversed(x)).hex()
# 
# Path: electrumx/lib/util.py
# class ConnectionLogger(logging.LoggerAdapter):
# class CompactFormatter(logging.Formatter):
# class cachedproperty(object):
# class LogicalFile(object):
#     def process(self, msg, kwargs):
#     def format(self, record):
# def make_logger(name, *, handler, level):
# def class_logger(path, classname):
#     def __init__(self, f):
#     def __get__(self, obj, type_):
# def formatted_time(t, sep=' '):
# def deep_getsizeof(obj):
#     def size(o):
# def subclasses(base_class, strict=True):
#     def select(obj):
# def chunks(items, size):
# def resolve_limit(limit):
# def bytes_to_int(be_bytes):
# def int_to_bytes(value):
# def increment_byte_string(bs):
#     def __init__(self, prefix, digits, file_size):
#     def read(self, start, size=-1):
#     def write(self, start, b):
#     def open_file(self, start, create):
# def open_file(filename, create=False):
# def open_truncate(filename):
# def address_string(address):
# def protocol_tuple(s):
# def version_string(ptuple):
# def protocol_version(client_req, min_tuple, max_tuple):
# def pack_varint(n):
# def pack_varbytes(data):


# Path: electrumx/lib/tx.py
from collections import namedtuple
from electrumx.lib.hash import double_sha256, hash_to_hex_str
from electrumx.lib.util import (
    unpack_le_int32_from, unpack_le_int64_from, unpack_le_uint16_from,
    unpack_be_uint16_from,
    unpack_le_uint32_from, unpack_le_uint64_from, pack_le_int32, pack_varint,
    pack_le_uint32, pack_le_int64, pack_varbytes,
)

            pack_le_uint32(self.locktime)
        ))


class TxInput(namedtuple("TxInput", "prev_hash prev_idx script sequence")):
    '''Class representing a transaction input.'''
    def __str__(self):
        script = self.script.hex()
        prev_hash = hash_to_hex_str(self.prev_hash)
        return ("Input({}, {:d}, script={}, sequence={:d})"
                .format(prev_hash, self.prev_idx, script, self.sequence))

    def is_generation(self):
        '''Test if an input is generation/coinbase like'''
        return self.prev_idx == MINUS_1 and self.prev_hash == ZERO

    def serialize(self):
        return b''.join((
            self.prev_hash,
            pack_le_uint32(self.prev_idx),
            pack_varbytes(self.script),
            pack_le_uint32(self.sequence),
        ))


class TxOutput(namedtuple("TxOutput", "value pk_script")):

    def serialize(self):
        return b''.join((
            pack_le_int64(self.value),

            pack_varbytes(self.pk_script),