2020-05-01 15:28:51 +02:00
|
|
|
from binascii import unhexlify
|
2018-06-12 17:53:29 +02:00
|
|
|
|
2020-05-01 15:28:51 +02:00
|
|
|
from lbry.crypto.hash import hash160, double_sha256
|
2020-01-03 04:18:49 +01:00
|
|
|
from lbry.crypto.base58 import Base58
|
2020-05-01 15:28:51 +02:00
|
|
|
from lbry.conf import Config
|
|
|
|
from lbry.schema.url import URL
|
2020-01-03 04:18:49 +01:00
|
|
|
from .header import Headers, UnvalidatedHeaders
|
2020-04-02 20:31:03 +02:00
|
|
|
from .checkpoints import HASHES
|
2020-01-03 04:18:49 +01:00
|
|
|
|
|
|
|
|
2020-05-01 15:28:51 +02:00
|
|
|
class Ledger:
|
2018-06-12 17:53:29 +02:00
|
|
|
name = 'LBRY Credits'
|
|
|
|
symbol = 'LBC'
|
2018-06-14 06:53:38 +02:00
|
|
|
network_name = 'mainnet'
|
2018-06-12 17:53:29 +02:00
|
|
|
|
|
|
|
headers_class = Headers
|
2019-03-24 21:55:04 +01:00
|
|
|
|
2018-10-15 23:16:43 +02:00
|
|
|
secret_prefix = bytes((0x1c,))
|
|
|
|
pubkey_address_prefix = bytes((0x55,))
|
|
|
|
script_address_prefix = bytes((0x7a,))
|
2018-07-01 23:21:18 +02:00
|
|
|
extended_public_key_prefix = unhexlify('0488b21e')
|
|
|
|
extended_private_key_prefix = unhexlify('0488ade4')
|
2018-06-14 06:53:38 +02:00
|
|
|
|
|
|
|
max_target = 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
|
|
|
genesis_hash = '9c89283ba0f3227f6c03b70216b9f665f0118d5e0fa729cedf4fb34d6a34f463'
|
|
|
|
genesis_bits = 0x1f00ffff
|
|
|
|
target_timespan = 150
|
|
|
|
|
2020-05-01 15:28:51 +02:00
|
|
|
fee_per_byte = 50
|
|
|
|
fee_per_name_char = 200000
|
2018-06-12 17:53:29 +02:00
|
|
|
|
2020-04-02 20:31:03 +02:00
|
|
|
checkpoints = HASHES
|
|
|
|
|
2020-05-01 15:28:51 +02:00
|
|
|
def __init__(self, conf: Config = None):
|
|
|
|
self.conf = conf or Config.with_same_dir('/dev/null')
|
2020-01-03 04:18:49 +01:00
|
|
|
self.coin_selection_strategy = None
|
2018-08-28 02:03:08 +02:00
|
|
|
|
2020-01-03 04:18:49 +01:00
|
|
|
@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
|
2020-05-01 15:28:51 +02:00
|
|
|
def valid_address_or_error(cls, address):
|
2020-03-25 18:17:08 +01:00
|
|
|
try:
|
2020-05-01 15:28:51 +02:00
|
|
|
assert cls.is_valid_address(address)
|
|
|
|
except:
|
|
|
|
raise Exception(f"'{address}' is not a valid address")
|
2020-03-25 18:17:08 +01:00
|
|
|
|
2020-05-01 15:28:51 +02:00
|
|
|
@classmethod
|
|
|
|
def valid_channel_name_or_error(cls, name):
|
2019-05-22 19:08:22 +02:00
|
|
|
try:
|
2020-05-01 15:28:51 +02:00
|
|
|
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.")
|
2018-07-12 05:18:59 +02:00
|
|
|
|
2020-05-01 15:28:51 +02:00
|
|
|
@classmethod
|
|
|
|
def public_key_to_address(cls, public_key):
|
|
|
|
return cls.hash160_to_address(hash160(public_key))
|
2019-11-04 22:41:42 +01:00
|
|
|
|
2019-08-12 07:16:15 +02:00
|
|
|
@staticmethod
|
2020-05-01 15:28:51 +02:00
|
|
|
def private_key_to_wif(private_key):
|
|
|
|
return b'\x1c' + private_key + b'\x01'
|
2019-10-14 01:32:10 +02:00
|
|
|
|
2018-06-12 17:53:29 +02:00
|
|
|
|
2020-01-03 04:18:49 +01:00
|
|
|
class TestNetLedger(Ledger):
|
2018-06-12 17:53:29 +02:00
|
|
|
network_name = 'testnet'
|
2018-10-15 23:16:43 +02:00
|
|
|
pubkey_address_prefix = bytes((111,))
|
|
|
|
script_address_prefix = bytes((196,))
|
2018-06-12 17:53:29 +02:00
|
|
|
extended_public_key_prefix = unhexlify('043587cf')
|
|
|
|
extended_private_key_prefix = unhexlify('04358394')
|
2020-04-02 20:31:03 +02:00
|
|
|
checkpoints = {}
|
2018-04-30 09:04:52 +02:00
|
|
|
|
|
|
|
|
2020-01-03 04:18:49 +01:00
|
|
|
class RegTestLedger(Ledger):
|
2018-06-12 17:53:29 +02:00
|
|
|
network_name = 'regtest'
|
2018-08-16 07:38:28 +02:00
|
|
|
headers_class = UnvalidatedHeaders
|
2018-10-15 23:16:43 +02:00
|
|
|
pubkey_address_prefix = bytes((111,))
|
|
|
|
script_address_prefix = bytes((196,))
|
2018-06-12 17:53:29 +02:00
|
|
|
extended_public_key_prefix = unhexlify('043587cf')
|
|
|
|
extended_private_key_prefix = unhexlify('04358394')
|
2018-04-30 09:04:52 +02:00
|
|
|
|
|
|
|
max_target = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
|
|
|
genesis_hash = '6e3fcf1299d4ec5d79c3a4c91d624a4acf9e2e173d95a1a0504f677669687556'
|
|
|
|
genesis_bits = 0x207fffff
|
|
|
|
target_timespan = 1
|
2020-04-02 20:31:03 +02:00
|
|
|
checkpoints = {}
|