from binascii import unhexlify from lbry.crypto.hash import hash160, double_sha256 from lbry.crypto.base58 import Base58 from lbry.conf import Config from lbry.schema.url import URL from .header import Headers, UnvalidatedHeaders from .checkpoints import HASHES class Ledger: name = 'LBRY Credits' symbol = 'LBC' network_name = 'mainnet' headers_class = Headers secret_prefix = bytes((0x1c,)) pubkey_address_prefix = bytes((0x55,)) script_address_prefix = bytes((0x7a,)) extended_public_key_prefix = unhexlify('0488b21e') extended_private_key_prefix = unhexlify('0488ade4') max_target = 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff genesis_hash = '9c89283ba0f3227f6c03b70216b9f665f0118d5e0fa729cedf4fb34d6a34f463' genesis_bits = 0x1f00ffff target_timespan = 150 fee_per_byte = 50 fee_per_name_char = 200000 checkpoints = HASHES def __init__(self, conf: Config = None): self.conf = conf or Config.with_same_dir('/dev/null') self.coin_selection_strategy = None @classmethod def get_id(cls): return '{}_{}'.format(cls.symbol.lower(), cls.network_name.lower()) @classmethod def hash160_to_address(cls, h160): raw_address = cls.pubkey_address_prefix + h160 return Base58.encode(bytearray(raw_address + double_sha256(raw_address)[0:4])) @staticmethod def address_to_hash160(address): return Base58.decode(address)[1:21] @classmethod def is_valid_address(cls, address): decoded = Base58.decode_check(address) return decoded[0] == cls.pubkey_address_prefix[0] @classmethod def valid_address_or_error(cls, address): try: assert cls.is_valid_address(address) except: raise Exception(f"'{address}' is not a valid address") @classmethod def valid_channel_name_or_error(cls, name): try: if not name: raise Exception( "Channel name cannot be blank." ) parsed = URL.parse(name) if not parsed.has_channel: raise Exception("Channel names must start with '@' symbol.") if parsed.channel.name != name: raise Exception("Channel name has invalid character") except (TypeError, ValueError): raise Exception("Invalid channel name.") @classmethod def public_key_to_address(cls, public_key): return cls.hash160_to_address(hash160(public_key)) @staticmethod def private_key_to_wif(private_key): return b'\x1c' + private_key + b'\x01' class TestNetLedger(Ledger): network_name = 'testnet' pubkey_address_prefix = bytes((111,)) script_address_prefix = bytes((196,)) extended_public_key_prefix = unhexlify('043587cf') extended_private_key_prefix = unhexlify('04358394') checkpoints = {} class RegTestLedger(Ledger): network_name = 'regtest' headers_class = UnvalidatedHeaders pubkey_address_prefix = bytes((111,)) script_address_prefix = bytes((196,)) extended_public_key_prefix = unhexlify('043587cf') extended_private_key_prefix = unhexlify('04358394') max_target = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff genesis_hash = '6e3fcf1299d4ec5d79c3a4c91d624a4acf9e2e173d95a1a0504f677669687556' genesis_bits = 0x207fffff target_timespan = 1 checkpoints = {}