Exemple #1
0
class AbosomMainnet(AbstractNet, StakeMixin):
    NAME = 'Abosom'
    NAME_LOWER = 'abosom'
    SHORT_CODE = 'ABOSOM'
    DATA_DIR = 'abosom'
    OPEN_ALIAS_PREFIX = 'abosom'
    PAYMENT_URI_SCHEME = 'abosom'
    PAYMENT_REQUEST_PKI_TYPE = "dnssec+abosom"
    APPLICATION_PAYMENT_REQUEST_TYPE = 'application/abosom-paymentrequest'
    APPLICATION_PAYMENT_TYPE = 'application/abosom-payment'
    APPLICATION_PAYMENT_ACK_TYPE = 'application/abosom-paymentack'
    BASE_UNITS = {'ABOSOM': 8, 'mABOSOM': 5, 'uABOSOM': 2, 'satoshi': 0}
    BASE_UNITS_INVERSE = inv_dict(BASE_UNITS)
    BASE_UNITS_LIST = ['ABOSOM', 'mABOSOM', 'uABOSOM', 'satoshi']
    TESTNET = False

    WIF_PREFIX = 0x80
    ADDRTYPE_P2PKH = 75
    ADDRTYPE_P2SH = 78
    XPRV_HEADERS = {
        'standard': 0x800001c8,
    }
    XPRV_HEADERS_INV = inv_dict(XPRV_HEADERS)
    XPUB_HEADERS = {
        'standard': 0x800001c8,
    }
    XPUB_HEADERS_INV = inv_dict(XPUB_HEADERS)
    BIP44_COIN_TYPE = 704

    GENESIS = "00000e8048ffa0a80549ed405640e95e01590e70baf4888ef594d87402635697"

    DEFAULT_PORTS = {'t': '50041', 's': '50042'}
    DEFAULT_SERVERS = read_json('servers/Abosom-Mainnet.json', {})
    CHECKPOINTS = read_json('checkpoints/Abosom-Mainnet.json', [])

    LN_REALM_BYTE = 0
    LN_DNS_SEEDS = []

    COINBASE_MATURITY = 8
    COIN = 1000000
    TOTAL_COIN_SUPPLY_LIMIT = 110000000
    SIGNED_MESSAGE_PREFIX = b"\x18Abosom Signed Message:\n"
Exemple #2
0
class BitcoinMainnet(AbstractNet):

    NAME = 'Bitcoin'
    NAME_LOWER = 'bitcoin'
    SHORT_CODE = 'BTC'
    TESTNET = False
    WIF_PREFIX = 0x80
    ADDRTYPE_P2PKH = 0
    ADDRTYPE_P2SH = 5
    SEGWIT_HRP = "bc"
    GENESIS = "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
    DEFAULT_PORTS = {'t': '50001', 's': '50002'}
    DEFAULT_SERVERS = read_json('servers/Bitcoin-Mainnet.json', {})
    CHECKPOINTS = read_json('checkpoints/Bitcoin-Mainnet.json', [])
    BLOCK_HEIGHT_FIRST_LIGHTNING_CHANNELS = 497000
    DATA_DIR = None
    DEV_FEE_ADDRESS = "3DY72R2mJUnFYUdgrAXLCWjy4gKyWHeuU4"
    XPRV_HEADERS = {
        'standard': 0x0488ade4,  # xprv
        'p2wpkh-p2sh': 0x049d7878,  # yprv
        'p2wsh-p2sh': 0x0295b005,  # Yprv
        'p2wpkh': 0x04b2430c,  # zprv
        'p2wsh': 0x02aa7a99,  # Zprv
    }
    XPRV_HEADERS_INV = inv_dict(XPRV_HEADERS)
    XPUB_HEADERS = {
        'standard': 0x0488b21e,  # xpub
        'p2wpkh-p2sh': 0x049d7cb2,  # ypub
        'p2wsh-p2sh': 0x0295b43f,  # Ypub
        'p2wpkh': 0x04b24746,  # zpub
        'p2wsh': 0x02aa7ed3,  # Zpub
    }
    XPUB_HEADERS_INV = inv_dict(XPUB_HEADERS)

    BIP44_COIN_TYPE = 0
    LN_REALM_BYTE = 0
    LN_DNS_SEEDS = [
        'nodes.lightning.directory.',
        'lseed.bitcoinstats.com.',
    ]

    APPLICATION_PAYMENT_REQUEST_TYPE = 'application/bitcoin-paymentrequest'
    APPLICATION_PAYMENT_TYPE = 'application/bitcoin-payment'
    APPLICATION_PAYMENT_ACK_TYPE = 'application/bitcoin-paymentack'
    OPEN_ALIAS_PREFIX = 'btc'
    PAYMENT_URI_SCHEME = 'bitcoin'
    PAYMENT_REQUEST_PKI_TYPE = "dnssec+btc"
    COINBASE_MATURITY = 100
    COIN = 100000000
    TOTAL_COIN_SUPPLY_LIMIT = 21000000
    SIGNED_MESSAGE_PREFIX = b"\x18Bitcoin Signed Message:\n"

    BASE_UNITS = {'BTC': 8, 'mBTC': 5, 'bits': 2, 'sat': 0}
    BASE_UNITS_INVERSE = inv_dict(BASE_UNITS)
    BASE_UNITS_LIST = ['BTC', 'mBTC', 'bits', 'sat']
    DECIMAL_POINT_DEFAULT = 5  # mBTC
    BLOCK_EXPLORERS = {
        'Bitupper Explorer': ('https://bitupper.com/en/explorer/bitcoin/', {
            'tx': 'transactions/',
            'addr': 'addresses/'
        }),
        'Bitflyer.jp': ('https://chainflyer.bitflyer.jp/', {
            'tx': 'Transaction/',
            'addr': 'Address/'
        }),
        'Blockchain.info': ('https://blockchain.com/btc/', {
            'tx': 'tx/',
            'addr': 'address/'
        }),
        'blockchainbdgpzk.onion': ('https://blockchainbdgpzk.onion/', {
            'tx': 'tx/',
            'addr': 'address/'
        }),
        'Blockstream.info': ('https://blockstream.info/', {
            'tx': 'tx/',
            'addr': 'address/'
        }),
        'Bitaps.com': ('https://btc.bitaps.com/', {
            'tx': '',
            'addr': ''
        }),
        'BTC.com': ('https://btc.com/', {
            'tx': '',
            'addr': ''
        }),
        'Chain.so': ('https://www.chain.so/', {
            'tx': 'tx/BTC/',
            'addr': 'address/BTC/'
        }),
        'Insight.is': ('https://insight.bitpay.com/', {
            'tx': 'tx/',
            'addr': 'address/'
        }),
        'TradeBlock.com': ('https://tradeblock.com/blockchain/', {
            'tx': 'tx/',
            'addr': 'address/'
        }),
        'BlockCypher.com': ('https://live.blockcypher.com/btc/', {
            'tx': 'tx/',
            'addr': 'address/'
        }),
        'Blockchair.com': ('https://blockchair.com/bitcoin/', {
            'tx': 'transaction/',
            'addr': 'address/'
        }),
        'blockonomics.co': ('https://www.blockonomics.co/', {
            'tx': 'api/tx?txid=',
            'addr': '#/search?q='
        }),
        'OXT.me': ('https://oxt.me/', {
            'tx': 'transaction/',
            'addr': 'address/'
        }),
        'smartbit.com.au': ('https://www.smartbit.com.au/', {
            'tx': 'tx/',
            'addr': 'address/'
        }),
        'mynode.local': ('http://mynode.local:3002/', {
            'tx': 'tx/',
            'addr': 'address/'
        }),
        'system default': ('blockchain:/', {
            'tx': 'tx/',
            'addr': 'address/'
        }),
    }

    TARGET_TIMESPAN = int(14 * 24 * 60 * 60)
    TARGET_SPACING = int(10 * 60)
    INTERVAL = int(TARGET_TIMESPAN / TARGET_SPACING)

    @classmethod
    def get_target(cls, height: int, blockchain) -> int:
        index = height // 2016 - 1

        if index == -1:
            return cls.MAX_TARGET

        if index < len(blockchain.checkpoints):
            h, t = blockchain.checkpoints[index]
            return t

        if not height % cls.INTERVAL == 0:
            # Get the first block of this retarget period
            last = blockchain.read_header(height - 1)
            if not last:
                raise MissingHeader()
            return blockchain.bits_to_target(last['bits'])

        # new target
        first = blockchain.read_header(height - cls.INTERVAL)
        last = blockchain.read_header(height - 1)
        if not first or not last:
            raise MissingHeader()

        bits = last.get('bits')
        target = blockchain.bits_to_target(bits)
        nActualTimespan = last.get('timestamp') - first.get('timestamp')
        nActualTimespan = max(nActualTimespan, cls.TARGET_TIMESPAN // 4)
        nActualTimespan = min(nActualTimespan, cls.TARGET_TIMESPAN * 4)
        new_target = min(cls.MAX_TARGET,
                         (target * nActualTimespan) // cls.TARGET_TIMESPAN)
        # not any target can be represented in 32 bits:
        new_target = blockchain.bits_to_target(
            blockchain.target_to_bits(new_target))
        return new_target
class ScalarisMainnet(AbstractNet, StakeMixin):

    NAME = 'Scalaris'
    NAME_LOWER = 'scalaris'
    SHORT_CODE = 'SCA'
    DATA_DIR = 'scalaris'
    OPEN_ALIAS_PREFIX = 'sca'
    PAYMENT_URI_SCHEME = 'scalaris'
    PAYMENT_REQUEST_PKI_TYPE = "dnssec+sca"
    APPLICATION_PAYMENT_REQUEST_TYPE = 'application/scalaris-paymentrequest'
    APPLICATION_PAYMENT_TYPE = 'application/scalaris-payment'
    APPLICATION_PAYMENT_ACK_TYPE = 'application/scalaris-paymentack'
    BASE_UNITS = {'SCA': 8, 'mSCA': 5, 'uSCA': 2, 'swartz': 0}
    BASE_UNITS_INVERSE = inv_dict(BASE_UNITS)
    BASE_UNITS_LIST = ['SCA', 'mSCA', 'uSCA', 'swartz']
    TESTNET = False

    WIF_PREFIX = 0x9a
    ADDRTYPE_P2PKH = 63
    ADDRTYPE_P2SH = 23
    XPRV_HEADERS = {
        'standard': 0x0488ade4,
    }
    XPRV_HEADERS_INV = inv_dict(XPRV_HEADERS)
    XPUB_HEADERS = {
        'standard': 0x0488b21e,
    }
    XPUB_HEADERS_INV = inv_dict(XPUB_HEADERS)
    BIP44_COIN_TYPE = 921

    GENESIS = "000003bf95cf7875987b333cc8e49a7c1a83583e5f5039b9af9555a92cb29651"

    DEFAULT_PORTS = {'t': '10001', 's': '10002'}
    DEFAULT_SERVERS = read_json('servers/Scalaris-Mainnet.json', {})
    CHECKPOINTS = read_json('checkpoints/Scalaris-Mainnet.json', [])

    LN_REALM_BYTE = 0
    LN_DNS_SEEDS = []

    COINBASE_MATURITY = 100
    COIN = 100000000
    TOTAL_COIN_SUPPLY_LIMIT = 999999999999
    SIGNED_MESSAGE_PREFIX = b"\x18Scalaris Signed Message:\n"

    DECIMAL_POINT_DEFAULT = 8  # SCA
    TARGET_SPACING = int(2 * 60)
    DGW_FORK_BLOCK = 0

    BLOCK_EXPLORERS = {
        'explorer.scalaris.info': ('https://explorer.scalaris.info', {
            'tx': '/tx/',
            'addr': '/address/'
        }),
        'openchains.info': ('https://openchains.info', {
            'tx': '/coin/scalaris/tx/',
            'addr': '/coin/scalaris/address/'
        }),
    }

    @classmethod
    def hash_raw_header(cls, header):
        import algomodule
        return hash_encode(algomodule._quark_hash(bfh(header)))

    @classmethod
    def get_target(cls, height: int, blockchain) -> int:
        index = height // 2016 - 1
        if index == -1:
            return cls.MAX_TARGET

        # Blockchain is PURE POS so we dont have the info needed to
        # calculate the targets required
        return 0
class DonuMainnet(AbstractNet, StakeMixin):
    NAME = 'Donu'
    NAME_LOWER = 'donu'
    SHORT_CODE = 'DONU'
    DATA_DIR = 'donu'
    OPEN_ALIAS_PREFIX = 'donu'
    PAYMENT_URI_SCHEME = 'donu'
    PAYMENT_REQUEST_PKI_TYPE = "dnssec+donu"
    APPLICATION_PAYMENT_REQUEST_TYPE = 'application/donu-paymentrequest'
    APPLICATION_PAYMENT_TYPE = 'application/donu-payment'
    APPLICATION_PAYMENT_ACK_TYPE = 'application/donu-paymentack'
    BASE_UNITS = {'DONU': 8, 'mDONU': 5, 'uDONU': 2, 'satoshi': 0}
    BASE_UNITS_INVERSE = inv_dict(BASE_UNITS)
    BASE_UNITS_LIST = ['DONU', 'mDONU', 'uDONU', 'satoshi']
    TESTNET = False

    WIF_PREFIX = 0x80
    ADDRTYPE_P2PKH = 53
    ADDRTYPE_P2SH = 5
    XPRV_HEADERS = {
        'standard': 0x0488ade4,
    }
    XPRV_HEADERS_INV = inv_dict(XPRV_HEADERS)
    XPUB_HEADERS = {
        'standard': 0x0488b21e,
    }
    XPUB_HEADERS_INV = inv_dict(XPUB_HEADERS)
    BIP44_COIN_TYPE = 405
    SEGWIT_HRP = "dn"

    GENESIS = "000000008507af1fdaaf3fed6173005b23b0febf72e7c2094f11f1d057692182"

    DEFAULT_PORTS = {'t': '50001', 's': '50002'}
    DEFAULT_SERVERS = read_json('servers/Donu-Mainnet.json', {})
    CHECKPOINTS = read_json('checkpoints/Donu-Mainnet.json', [])

    LN_REALM_BYTE = 0
    LN_DNS_SEEDS = []

    COINBASE_MATURITY = 100
    COIN = 1000000
    TOTAL_COIN_SUPPLY_LIMIT = 21000000
    SIGNED_MESSAGE_PREFIX = b"\x18Donu Signed Message:\n"

    DECIMAL_POINT_DEFAULT = 8  # DONU
    TARGET_SPACING = int(2 * 60)

    POS_START_HEIGHT = 0

    BLOCK_EXPLORERS = {
        'CryptoID.info': ('https://chainz.cryptoid.info/donu/', {
            'tx': 'tx.dws?',
            'addr': 'address.dws?'
        }),
        'system default': ('blockchain:/', {
            'tx': 'tx/',
            'addr': 'address/'
        }),
    }

    @classmethod
    def get_target(cls, height: int, blockchain) -> int:
        index = height // 2016 - 1
        if index == -1:
            return cls.MAX_TARGET

        # Blockchain is PURE POS so we dont have the info needed to
        # calculate the targets required
        return 0
class NamecoinMainnet(AbstractNet, AuxPowMixin):

    NAME = 'Namecoin'
    NAME_LOWER = 'namecoin'
    SHORT_CODE = 'NMC'
    TESTNET = False
    WIF_PREFIX = 180
    ADDRTYPE_P2PKH = 52
    ADDRTYPE_P2SH = 13
    SEGWIT_HRP = "nc"
    GENESIS = "000000000062b72c5e2ceb45fbc8587e807c155b0da735e6483dfba2f0a9c770"
    DEFAULT_PORTS = {'t': '50001', 's': '50002'}
    DEFAULT_SERVERS = read_json('servers/Namecoin-Mainnet.json', {})
    CHECKPOINTS = read_json('checkpoints/Namecoin-Mainnet.json', [])
    BLOCK_HEIGHT_FIRST_LIGHTNING_CHANNELS = 497000
    DATA_DIR = 'namecoin'

    XPRV_HEADERS = {
        'standard': 0x0488ade4,  # xprv
        'p2wpkh-p2sh': 0x049d7878,  # yprv
        'p2wsh-p2sh': 0x0295b005,  # Yprv
        'p2wpkh': 0x04b2430c,  # zprv
        'p2wsh': 0x02aa7a99,  # Zprv
    }
    XPRV_HEADERS_INV = inv_dict(XPRV_HEADERS)
    XPUB_HEADERS = {
        'standard': 0x0488b21e,  # xpub
        'p2wpkh-p2sh': 0x049d7cb2,  # ypub
        'p2wsh-p2sh': 0x0295b43f,  # Ypub
        'p2wpkh': 0x04b24746,  # zpub
        'p2wsh': 0x02aa7ed3,  # Zpub
    }
    XPUB_HEADERS_INV = inv_dict(XPUB_HEADERS)
    BIP44_COIN_TYPE = 7
    LN_REALM_BYTE = 0
    LN_DNS_SEEDS = []
    OPEN_ALIAS_PREFIX = 'nmc'
    PAYMENT_URI_SCHEME = 'namecoin'
    PAYMENT_REQUEST_PKI_TYPE = "dnssec+nmc"
    APPLICATION_PAYMENT_REQUEST_TYPE = 'application/namecoin-paymentrequest'
    APPLICATION_PAYMENT_TYPE = 'application/namecoin-payment'
    APPLICATION_PAYMENT_ACK_TYPE = 'application/namecoin-paymentack'
    COINBASE_MATURITY = 100
    COIN = 100000000
    TOTAL_COIN_SUPPLY_LIMIT = 21000000
    SIGNED_MESSAGE_PREFIX = b"\x18Namecoin Signed Message:\n"

    BASE_UNITS = {'NMC': 8, 'mNMC': 5, 'uNMC': 2, 'swartz': 0}
    BASE_UNITS_INVERSE = inv_dict(BASE_UNITS)
    BASE_UNITS_LIST = ['NMC', 'mNMC', 'uNMC', 'swartz']
    DECIMAL_POINT_DEFAULT = 5  # mNMC
    AUXPOW_CHAIN_ID = 0x0001
    AUXPOW_START_HEIGHT = 19200
    BLOCK_VERSION_AUXPOW_BIT = 0x100

    BLOCK_EXPLORERS = {
        'Cyphrs.com': ('https://namecoin.cyphrs.com/', {
            'tx': 'tx/',
            'addr': 'address/'
        }),
        'Namecha.in (non-libre; wiretapped by Cloudflare; discriminates against Tor)':
        ('https://namecha.in/', {
            'tx': 'tx/',
            'addr': 'address/'
        }),
        'Bchain.info (non-libre; no name support)':
        ('https://bchain.info/NMC/', {
            'tx': 'tx/',
            'addr': 'addr/'
        }),
        'BitInfoCharts.com (non-libre; wiretapped by Cloudflare; discriminates against Tor; no name support)':
        ('https://bitinfocharts.com/namecoin/', {
            'tx': 'tx/',
            'addr': 'address/'
        }),
        'mynode.local': ('http://mynode.local:3002/', {
            'tx': 'tx/',
            'addr': 'address/'
        }),
        'system default': ('blockchain:/', {
            'tx': 'tx/',
            'addr': 'address/'
        }),
    }

    # The default Bitcoin frame size limit of 1 MB doesn't work for AuxPoW-based
    # chains, because those chains' block headers have extra AuxPoW data.  A limit
    # of 10 MB works fine for Namecoin as of block height 418744 (5 MB fails after
    # height 155232); we set a limit of 20 MB so that we have extra wiggle room.
    MAX_INCOMING_MSG_SIZE = 20_000_000  # in bytes

    TARGET_TIMESPAN = int(14 * 24 * 60 * 60)
    TARGET_SPACING = int(10 * 60)
    INTERVAL = int(TARGET_TIMESPAN / TARGET_SPACING)

    @classmethod
    def get_target(cls, height: int, blockchain) -> int:
        index = height // 2016 - 1

        if index == -1:
            return cls.MAX_TARGET

        if index < len(blockchain.checkpoints):
            h, t = blockchain.checkpoints[index]
            return t

        if not height % cls.INTERVAL == 0:
            # Get the first block of this retarget period
            last = blockchain.read_header(height - 1)
            if not last:
                raise MissingHeader()
            return blockchain.bits_to_target(last['bits'])

        # new target
        if (index * 2016 + 2015 > 19200) and (index * 2016 + 2015 + 1 > 2016):
            # Namecoin: Apply retargeting hardfork after AuxPoW start
            first = blockchain.read_header(height - cls.INTERVAL - 1)
        else:
            first = blockchain.read_header(height - cls.INTERVAL)

        last = blockchain.read_header(height - 1)
        if not first or not last:
            raise MissingHeader()

        bits = last.get('bits')
        target = blockchain.bits_to_target(bits)
        nActualTimespan = last.get('timestamp') - first.get('timestamp')
        nActualTimespan = max(nActualTimespan, cls.TARGET_TIMESPAN // 4)
        nActualTimespan = min(nActualTimespan, cls.TARGET_TIMESPAN * 4)
        new_target = min(cls.MAX_TARGET,
                         (target * nActualTimespan) // cls.TARGET_TIMESPAN)
        # not any target can be represented in 32 bits:
        new_target = blockchain.bits_to_target(
            blockchain.target_to_bits(new_target))
        return new_target
class AbosomMainnet(AbstractNet, StakeMixin):
    NAME = 'Abosom'
    NAME_LOWER = 'abosom'
    SHORT_CODE = 'ABOSOM'
    DATA_DIR = 'abosom'
    OPEN_ALIAS_PREFIX = 'abosom'
    PAYMENT_URI_SCHEME = 'abosom'
    PAYMENT_REQUEST_PKI_TYPE = "dnssec+abosom"
    APPLICATION_PAYMENT_REQUEST_TYPE = 'application/abosom-paymentrequest'
    APPLICATION_PAYMENT_TYPE = 'application/abosom-payment'
    APPLICATION_PAYMENT_ACK_TYPE = 'application/abosom-paymentack'
    BASE_UNITS = {'ABOSOM': 8, 'mABOSOM': 5, 'uABOSOM': 2, 'satoshi': 0}
    BASE_UNITS_INVERSE = inv_dict(BASE_UNITS)
    BASE_UNITS_LIST = ['ABOSOM', 'mABOSOM', 'uABOSOM', 'satoshi']
    TESTNET = False

    WIF_PREFIX = 0x80
    ADDRTYPE_P2PKH = 75
    ADDRTYPE_P2SH = 78
    XPRV_HEADERS = {
        'standard': 0x800001c8,
    }
    XPRV_HEADERS_INV = inv_dict(XPRV_HEADERS)
    XPUB_HEADERS = {
        'standard': 0x800101c8,
    }
    XPUB_HEADERS_INV = inv_dict(XPUB_HEADERS)
    BIP44_COIN_TYPE = 704

    GENESIS = "00000e8048ffa0a80549ed405640e95e01590e70baf4888ef594d87402635697"

    DEFAULT_PORTS = {'t': '50041', 's': '50042'}
    DEFAULT_SERVERS = read_json('servers/Abosom-Mainnet.json', {})
    CHECKPOINTS = read_json('checkpoints/Abosom-Mainnet.json', [])

    LN_REALM_BYTE = 0
    LN_DNS_SEEDS = []

    COINBASE_MATURITY = 8
    COIN = 1000000
    TOTAL_COIN_SUPPLY_LIMIT = 110000000
    SIGNED_MESSAGE_PREFIX = b"\x18Abosom Signed Message:\n"
    DECIMAL_POINT_DEFAULT = 8  # CRW
    TARGET_TIMESPAN = int(24 * 60 * 60)
    TARGET_SPACING = int(60)
    INTERVAL = int(TARGET_TIMESPAN / TARGET_SPACING)

    POS_START_HEIGHT = 1
    BLOCK_EXPLORERS = {
        'system default': ('blockchain:/', {
            'tx': 'tx/',
            'addr': 'address/'
        }),
    }

    @classmethod
    def hash_raw_header(cls, header):
        import algomodule
        return hash_encode(algomodule._x11_hash(bfh(header)))

    @classmethod
    def is_pos_active(cls, header) -> bool:
        return True

    @classmethod
    def get_target(cls, height: int, blockchain) -> int:
        index = height // 2016 - 1
        if index == -1:
            return cls.MAX_TARGET

        if index < len(blockchain.checkpoints):
            h, t = blockchain.checkpoints[index]
            return t

        return cls.get_target_btc(height, blockchain)

    @classmethod
    def get_target_btc(cls, height: int, blockchain) -> int:
        if not height % cls.INTERVAL == 0:
            # Get the first block of this retarget period
            last = blockchain.read_header(height - 1)
            if not last:
                raise MissingHeader()
            return blockchain.bits_to_target(last['bits'])

        # new target
        first = blockchain.read_header(height - cls.INTERVAL)
        last = blockchain.read_header(height - 1)
        if not first or not last:
            raise MissingHeader()

        bits = last.get('bits')
        target = blockchain.bits_to_target(bits)
        nActualTimespan = last.get('timestamp') - first.get('timestamp')
        nActualTimespan = max(nActualTimespan, cls.TARGET_TIMESPAN // 4)
        nActualTimespan = min(nActualTimespan, cls.TARGET_TIMESPAN * 4)
        new_target = min(cls.MAX_TARGET,
                         (target * nActualTimespan) // cls.TARGET_TIMESPAN)
        # not any target can be represented in 32 bits:
        new_target = blockchain.bits_to_target(
            blockchain.target_to_bits(new_target))
        return new_target
class BitcoinTestnet(BitcoinMainnet):

    NAME = 'Bitcoin Testnet'
    NAME_LOWER = 'testnet bitcoin'
    TESTNET = True
    WIF_PREFIX = 0xef
    ADDRTYPE_P2PKH = 111
    ADDRTYPE_P2SH = 196
    SEGWIT_HRP = "tb"
    GENESIS = "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"
    DEFAULT_PORTS = {'t': '51001', 's': '51002'}
    DEFAULT_SERVERS = read_json('servers/Bitcoin-Testnet.json', {})
    CHECKPOINTS = read_json('checkpoints/Bitcoin-Testnet.json', [])
    DATA_DIR = 'testnet'

    XPRV_HEADERS = {
        'standard': 0x04358394,  # tprv
        'p2wpkh-p2sh': 0x044a4e28,  # uprv
        'p2wsh-p2sh': 0x024285b5,  # Uprv
        'p2wpkh': 0x045f18bc,  # vprv
        'p2wsh': 0x02575048,  # Vprv
    }
    XPRV_HEADERS_INV = inv_dict(XPRV_HEADERS)
    XPUB_HEADERS = {
        'standard': 0x043587cf,  # tpub
        'p2wpkh-p2sh': 0x044a5262,  # upub
        'p2wsh-p2sh': 0x024289ef,  # Upub
        'p2wpkh': 0x045f1cf6,  # vpub
        'p2wsh': 0x02575483,  # Vpub
    }
    XPUB_HEADERS_INV = inv_dict(XPUB_HEADERS)
    BIP44_COIN_TYPE = 1
    LN_REALM_BYTE = 1
    LN_DNS_SEEDS = [
        # TODO investigate this again
        # 'test.nodes.lightning.directory.',  # times out.
        # 'lseed.bitcoinstats.com.',  # ignores REALM byte and returns mainnet peers...
    ]
    BLOCK_EXPLORERS = {
        'Bitaps.com': ('https://tbtc.bitaps.com/', {
            'tx': '',
            'addr': ''
        }),
        'BlockCypher.com': ('https://live.blockcypher.com/btc-testnet/', {
            'tx': 'tx/',
            'addr': 'address/'
        }),
        'Blockchain.info': ('https://www.blockchain.com/btctest/', {
            'tx': 'tx/',
            'addr': 'address/'
        }),
        'Blockstream.info': ('https://blockstream.info/testnet/', {
            'tx': 'tx/',
            'addr': 'address/'
        }),
        'smartbit.com.au': ('https://testnet.smartbit.com.au/', {
            'tx': 'tx/',
            'addr': 'address/'
        }),
        'system default':
        ('blockchain://000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943/',
         {
             'tx': 'tx/',
             'addr': 'address/'
         }),
    }

    @classmethod
    def get_target(cls, height: int, blockchain) -> int:
        return 0
Exemple #8
0
class CrowncoinMainnet(AbstractNet, AuxPowMixin, StakeMixin):

    NAME = 'Crown'
    NAME_LOWER = 'crown'
    SHORT_CODE = 'CRW'
    DATA_DIR = 'crowncoin'
    OPEN_ALIAS_PREFIX = 'crw'
    PAYMENT_URI_SCHEME = 'crown'
    PAYMENT_REQUEST_PKI_TYPE = "dnssec+crw"
    APPLICATION_PAYMENT_REQUEST_TYPE = 'application/crowncoin-paymentrequest'
    APPLICATION_PAYMENT_TYPE = 'application/crowncoin-payment'
    APPLICATION_PAYMENT_ACK_TYPE = 'application/crowncoin-paymentack'
    BASE_UNITS = {'CRW': 8, 'mCRW': 5, 'uCRW': 2, 'swartz': 0}
    BASE_UNITS_INVERSE = inv_dict(BASE_UNITS)
    BASE_UNITS_LIST = ['CRW', 'mCRW', 'uCRW', 'swartz']
    TESTNET = False

    WIF_PREFIX = 0x80
    ADDRTYPE_P2PKH = bfh('017507')
    ADDRTYPE_P2SH = bfh('0174f1')
    XPRV_HEADERS = {
        'standard': 0x0488ade4,
    }
    XPRV_HEADERS_INV = inv_dict(XPRV_HEADERS)
    XPUB_HEADERS = {
        'standard': 0x0488b21e,
    }
    XPUB_HEADERS_INV = inv_dict(XPUB_HEADERS)
    BIP44_COIN_TYPE = 72

    GENESIS = "0000000085370d5e122f64f4ab19c68614ff3df78c8d13cb814fd7e69a1dc6da"

    DEFAULT_PORTS = {'t': '50001', 's': '50002'}
    DEFAULT_SERVERS = read_json('servers/Crowncoin-Mainnet.json', {})
    CHECKPOINTS = read_json('checkpoints/Crowncoin-Mainnet.json', [])

    LN_REALM_BYTE = 0
    LN_DNS_SEEDS = []

    COINBASE_MATURITY = 100
    COIN = 100000000
    TOTAL_COIN_SUPPLY_LIMIT = 21000000
    SIGNED_MESSAGE_PREFIX = b"\x18Crowncoin Signed Message:\n"

    DECIMAL_POINT_DEFAULT = 8 # CRW
    AUXPOW_CHAIN_ID = 0x14
    AUXPOW_START_HEIGHT = 45327
    BLOCK_VERSION_AUXPOW_BIT = 0x100
    DGW_FORK_BLOCK = 1059780
    TARGET_TIMESPAN = int(14 * 24 * 60 * 60)
    TARGET_SPACING = int(60)
    INTERVAL = int(TARGET_TIMESPAN / TARGET_SPACING)

    POS_START_HEIGHT = 2330000
    MIN_POS_WORK_LIMIT = 0x00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff

    BLOCK_EXPLORERS = {
        'CryptoID.info': ('https://chainz.cryptoid.info/crw/', {'tx': 'tx.dws?', 'addr': 'address.dws?'}),
        'system default': ('blockchain:/', {'tx': 'tx/', 'addr': 'address/'}),
    }

    # The default Bitcoin frame size limit of 1 MB doesn't work for AuxPoW-based
    # chains, because those chains' block headers have extra AuxPoW data.
    # we set a limit of 40 MB so that we have extra wiggle room.
    MAX_INCOMING_MSG_SIZE = 40_000_000  # in bytes


    @classmethod
    def get_target(cls, height: int, blockchain) -> int: 
        index = height // 2016 - 1
        if index == -1:
            return cls.MAX_TARGET

        if index < len(blockchain.checkpoints):
            h, t = blockchain.checkpoints[index]
            return t

        if height >= cls.DGW_FORK_BLOCK:
            return cls.get_target_dgw(height, blockchain)
        return cls.get_target_btc(height, blockchain)

    @classmethod
    def get_target_btc(cls, height: int, blockchain) -> int:
        if not height % cls.INTERVAL == 0:
            # Get the first block of this retarget period
            last = blockchain.read_header(height - 1)
            if not last:
                raise MissingHeader()
            return blockchain.bits_to_target(last['bits'])

        # new target
        first = blockchain.read_header(height - cls.INTERVAL)
        last = blockchain.read_header(height - 1)
        if not first or not last:
            raise MissingHeader()

        bits = last.get('bits')
        target = blockchain.bits_to_target(bits)
        nActualTimespan = last.get('timestamp') - first.get('timestamp')
        nActualTimespan = max(nActualTimespan, cls.TARGET_TIMESPAN // 4)
        nActualTimespan = min(nActualTimespan, cls.TARGET_TIMESPAN * 4)
        new_target = min(cls.MAX_TARGET, (target * nActualTimespan) // cls.TARGET_TIMESPAN)
        # not any target can be represented in 32 bits:
        new_target = blockchain.bits_to_target(blockchain.target_to_bits(new_target))
        return new_target

    @classmethod
    def get_target_dgw(cls, height: int, blockchain) -> int:       
        # get last solved header
        current = blockchain.read_header(height - 1)
        nActualTimespan = 0
        lastBlockTime = 0
        pastBlocksMin = 24
        pastBlocksMax = 24
        countBlocks = 0

        for i in range(pastBlocksMax):
            countBlocks += 1
            if not current:
                raise BaseException('header at height: %d is not stored in db' % (height - i - 1))

            bits = current.get('bits')
            if countBlocks <= pastBlocksMin:
                if countBlocks == 1:
                    past_difficulty_avg = blockchain.bits_to_target(bits)
                else:
                    past_difficulty_avg = (past_difficulty_avg_prev * countBlocks + blockchain.bits_to_target(bits)) // (countBlocks + 1)
                past_difficulty_avg_prev = past_difficulty_avg

            if lastBlockTime > 0:
                nActualTimespan += lastBlockTime - current.get('timestamp')
            lastBlockTime = current.get('timestamp')

            # get previous block
            current = blockchain.read_header(height - i - 2)

        target_timespan = countBlocks * cls.TARGET_SPACING
        nActualTimespan = max(nActualTimespan, target_timespan // 3)
        nActualTimespan = min(nActualTimespan, target_timespan * 3)
        new_target = min(cls.MAX_TARGET, (past_difficulty_avg * nActualTimespan) // target_timespan)
        return new_target

    @classmethod
    def hash160_to_b58_address(cls, h160: bytes, addrtype: int) -> str:
        s = addrtype + h160
        return base_encode(s+Hash(s)[0:4], base=58)

    @classmethod
    def b58_address_to_hash160(cls, addr):
        addr = to_bytes(addr, 'ascii')
        _bytes = base_decode(addr, length=27, base=58)
        return _bytes[0:3], _bytes[3:23]