Ejemplo n.º 1
0
def output_derive_script(address: str, coin: CoinInfo) -> bytes:
    if coin.bech32_prefix and address.startswith(coin.bech32_prefix):
        # p2wpkh or p2wsh
        witprog = common.decode_bech32_address(coin.bech32_prefix, address)
        return output_script_native_p2wpkh_or_p2wsh(witprog)

    if (not utils.BITCOIN_ONLY and coin.cashaddr_prefix is not None
            and address.startswith(coin.cashaddr_prefix + ":")):
        prefix, addr = address.split(":")
        version, data = cashaddr.decode(prefix, addr)
        if version == cashaddr.ADDRESS_TYPE_P2KH:
            version = coin.address_type
        elif version == cashaddr.ADDRESS_TYPE_P2SH:
            version = coin.address_type_p2sh
        else:
            raise wire.DataError("Unknown cashaddr address type")
        raw_address = bytes([version]) + data
    else:
        try:
            raw_address = base58.decode_check(address, coin.b58_hash)
        except ValueError:
            raise wire.DataError("Invalid address")

    if address_type.check(coin.address_type, raw_address):
        # p2pkh
        pubkeyhash = address_type.strip(coin.address_type, raw_address)
        script = output_script_p2pkh(pubkeyhash)
        return script
    elif address_type.check(coin.address_type_p2sh, raw_address):
        # p2sh
        scripthash = address_type.strip(coin.address_type_p2sh, raw_address)
        script = output_script_p2sh(scripthash)
        return script

    raise wire.DataError("Invalid address type")
Ejemplo n.º 2
0
def output_derive_script(o: TxOutputType, coin: CoinInfo, root: bip32.HDNode) -> bytes:

    if o.script_type == OutputScriptType.PAYTOOPRETURN:
        # op_return output
        if o.amount != 0:
            raise SigningError(
                FailureType.DataError, "OP_RETURN output with non-zero amount"
            )
        return output_script_paytoopreturn(o.op_return_data)

    if o.address_n:
        # change output
        if o.address:
            raise SigningError(FailureType.DataError, "Address in change output")
        o.address = get_address_for_change(o, coin, root)
    else:
        if not o.address:
            raise SigningError(FailureType.DataError, "Missing address")

    if coin.bech32_prefix and o.address.startswith(coin.bech32_prefix):
        # p2wpkh or p2wsh
        witprog = decode_bech32_address(coin.bech32_prefix, o.address)
        return output_script_native_p2wpkh_or_p2wsh(witprog)

    if coin.cashaddr_prefix is not None and o.address.startswith(
        coin.cashaddr_prefix + ":"
    ):
        prefix, addr = o.address.split(":")
        version, data = cashaddr.decode(prefix, addr)
        if version == cashaddr.ADDRESS_TYPE_P2KH:
            version = coin.address_type
        elif version == cashaddr.ADDRESS_TYPE_P2SH:
            version = coin.address_type_p2sh
        else:
            raise ValueError("Unknown cashaddr address type")
        raw_address = bytes([version]) + data
    else:
        raw_address = base58.decode_check(o.address, coin.b58_hash)

    if address_type.check(coin.address_type, raw_address):
        # p2pkh
        pubkeyhash = address_type.strip(coin.address_type, raw_address)
        script = output_script_p2pkh(pubkeyhash)
        if coin.bip115:
            script += script_replay_protection_bip115(
                o.block_hash_bip115, o.block_height_bip115
            )
        return script

    elif address_type.check(coin.address_type_p2sh, raw_address):
        # p2sh
        scripthash = address_type.strip(coin.address_type_p2sh, raw_address)
        script = output_script_p2sh(scripthash)
        if coin.bip115:
            script += script_replay_protection_bip115(
                o.block_hash_bip115, o.block_height_bip115
            )
        return script

    raise SigningError(FailureType.DataError, "Invalid address type")
Ejemplo n.º 3
0
def output_derive_script(o: TxOutputType, coin: CoinType, root) -> bytes:

    if o.script_type == OutputScriptType.PAYTOOPRETURN:
        if o.amount != 0:
            raise SigningError(FailureType.DataError,
                               'OP_RETURN output with non-zero amount')
        return output_script_paytoopreturn(o.op_return_data)

    if o.address_n:  # change output
        if o.address:
            raise SigningError(FailureType.DataError,
                               'Address in change output')
        o.address = get_address_for_change(o, coin, root)
    else:
        if not o.address:
            raise SigningError(FailureType.DataError, 'Missing address')

    if coin.bech32_prefix and o.address.startswith(
            coin.bech32_prefix):  # p2wpkh or p2wsh
        witprog = decode_bech32_address(coin.bech32_prefix, o.address)
        return output_script_native_p2wpkh_or_p2wsh(witprog)

    raw_address = base58.decode_check(o.address)

    if address_type.check(coin.address_type, raw_address):  # p2pkh
        pubkeyhash = address_type.strip(coin.address_type, raw_address)
        return output_script_p2pkh(pubkeyhash)

    elif address_type.check(coin.address_type_p2sh, raw_address):  # p2sh
        scripthash = address_type.strip(coin.address_type_p2sh, raw_address)
        return output_script_p2sh(scripthash)

    raise SigningError(FailureType.DataError, 'Invalid address type')
Ejemplo n.º 4
0
def address_to_script_type(address: str, coin: CoinInfo) -> InputScriptType:
    # Determines the script type from a non-multisig address.

    if coin.bech32_prefix and address.startswith(coin.bech32_prefix):
        witver, _ = common.decode_bech32_address(coin.bech32_prefix, address)
        if witver == 0:
            return InputScriptType.SPENDWITNESS
        elif witver == 1:
            return InputScriptType.SPENDTAPROOT
        else:
            raise wire.DataError("Invalid address")

    if (not utils.BITCOIN_ONLY and coin.cashaddr_prefix is not None
            and address.startswith(coin.cashaddr_prefix + ":")):
        return InputScriptType.SPENDADDRESS

    try:
        raw_address = base58.decode_check(address, coin.b58_hash)
    except ValueError:
        raise wire.DataError("Invalid address")

    if address_type.check(coin.address_type, raw_address):
        # p2pkh
        return InputScriptType.SPENDADDRESS
    elif address_type.check(coin.address_type_p2sh, raw_address):
        # p2sh
        return InputScriptType.SPENDP2SHWITNESS

    raise wire.DataError("Invalid address")
Ejemplo n.º 5
0
def output_derive_script(
    o: TxOutputType, coin: coininfo.CoinInfo, keychain: seed.Keychain
) -> bytes:

    if o.script_type == OutputScriptType.PAYTOOPRETURN:
        return scripts.output_script_paytoopreturn(o.op_return_data)

    if o.address_n:
        # change output
        o.address = get_address_for_change(o, coin, keychain)

    if coin.bech32_prefix and o.address.startswith(coin.bech32_prefix):
        # p2wpkh or p2wsh
        witprog = addresses.decode_bech32_address(coin.bech32_prefix, o.address)
        return scripts.output_script_native_p2wpkh_or_p2wsh(witprog)

    if (
        not utils.BITCOIN_ONLY
        and coin.cashaddr_prefix is not None
        and o.address.startswith(coin.cashaddr_prefix + ":")
    ):
        prefix, addr = o.address.split(":")
        version, data = cashaddr.decode(prefix, addr)
        if version == cashaddr.ADDRESS_TYPE_P2KH:
            version = coin.address_type
        elif version == cashaddr.ADDRESS_TYPE_P2SH:
            version = coin.address_type_p2sh
        else:
            raise SigningError("Unknown cashaddr address type")
        raw_address = bytes([version]) + data
    else:
        try:
            raw_address = base58.decode_check(o.address, coin.b58_hash)
        except ValueError:
            raise SigningError(FailureType.DataError, "Invalid address")

    if address_type.check(coin.address_type, raw_address):
        # p2pkh
        pubkeyhash = address_type.strip(coin.address_type, raw_address)
        script = scripts.output_script_p2pkh(pubkeyhash)
        return script

    elif address_type.check(coin.address_type_p2sh, raw_address):
        # p2sh
        scripthash = address_type.strip(coin.address_type_p2sh, raw_address)
        script = scripts.output_script_p2sh(scripthash)
        return script

    raise SigningError(FailureType.DataError, "Invalid address type")
Ejemplo n.º 6
0
def output_paytoaddress_extract_raw_address(
        o: TxOutputType, coin: CoinType, root, p2sh: bool=False) -> bytes:
    addr_type = coin.address_type_p2sh if p2sh else coin.address_type
    # TODO: dont encode/decode more then necessary
    if o.address_n is not None:
        node = node_derive(root, o.address_n)
        address = node.address(addr_type)
        return base58.decode_check(address)
    if o.address:
        raw = base58.decode_check(o.address)
        if not address_type.check(addr_type, raw):
            raise SigningError(FailureType.SyntaxError,
                               'Invalid address type')
        return raw
    raise SigningError(FailureType.SyntaxError,
                       'Missing address')