예제 #1
0
def get_address(
    script_type: EnumTypeInputScriptType,
    coin: CoinInfo,
    node: bip32.HDNode,
    multisig: MultisigRedeemScriptType = None,
) -> str:

    if (
        script_type == InputScriptType.SPENDADDRESS
        or script_type == InputScriptType.SPENDMULTISIG
    ):
        if multisig:  # p2sh multisig
            pubkey = node.public_key()
            index = multisig_pubkey_index(multisig, pubkey)
            if index is None:
                raise wire.ProcessError("Public key not found")
            if coin.address_type_p2sh is None:
                raise wire.ProcessError("Multisig not enabled on this coin")

            pubkeys = multisig_get_pubkeys(multisig)
            address = address_multisig_p2sh(pubkeys, multisig.m, coin)
            if coin.cashaddr_prefix is not None:
                address = address_to_cashaddr(address, coin)
            return address
        if script_type == InputScriptType.SPENDMULTISIG:
            raise wire.ProcessError("Multisig details required")

        # p2pkh
        address = node.address(coin.address_type)
        if coin.cashaddr_prefix is not None:
            address = address_to_cashaddr(address, coin)
        return address

    elif script_type == InputScriptType.SPENDWITNESS:  # native p2wpkh or native p2wsh
        if not coin.segwit or not coin.bech32_prefix:
            raise wire.ProcessError("Segwit not enabled on this coin")
        # native p2wsh multisig
        if multisig is not None:
            pubkeys = multisig_get_pubkeys(multisig)
            return address_multisig_p2wsh(pubkeys, multisig.m, coin.bech32_prefix)

        # native p2wpkh
        return address_p2wpkh(node.public_key(), coin)

    elif (
        script_type == InputScriptType.SPENDP2SHWITNESS
    ):  # p2wpkh or p2wsh nested in p2sh
        if not coin.segwit or coin.address_type_p2sh is None:
            raise wire.ProcessError("Segwit not enabled on this coin")
        # p2wsh multisig nested in p2sh
        if multisig is not None:
            pubkeys = multisig_get_pubkeys(multisig)
            return address_multisig_p2wsh_in_p2sh(pubkeys, multisig.m, coin)

        # p2wpkh nested in p2sh
        return address_p2wpkh_in_p2sh(node.public_key(), coin)

    else:
        raise wire.ProcessError("Invalid script type")
예제 #2
0
def generate_proof(
    node: bip32.HDNode,
    script_type: EnumTypeInputScriptType,
    multisig: Optional[MultisigRedeemScriptType],
    coin: CoinInfo,
    user_confirmed: bool,
    ownership_ids: List[bytes],
    script_pubkey: bytes,
    commitment_data: bytes,
) -> Tuple[bytes, bytes]:
    flags = 0
    if user_confirmed:
        flags |= _FLAG_USER_CONFIRMED

    proof = empty_bytearray(4 + 1 + 1 + len(ownership_ids) * _OWNERSHIP_ID_LEN)

    write_bytes_fixed(proof, _VERSION_MAGIC, 4)
    write_uint8(proof, flags)
    write_bitcoin_varint(proof, len(ownership_ids))
    for ownership_id in ownership_ids:
        write_bytes_fixed(proof, ownership_id, _OWNERSHIP_ID_LEN)

    sighash = hashlib.sha256(proof)
    sighash.update(script_pubkey)
    sighash.update(commitment_data)
    signature = common.ecdsa_sign(node, sighash.digest())
    public_key = node.public_key()
    write_bip322_signature_proof(proof, script_type, multisig, coin,
                                 public_key, signature)

    return proof, signature
예제 #3
0
def generate_proof(
    node: bip32.HDNode,
    script_type: InputScriptType,
    multisig: MultisigRedeemScriptType | None,
    coin: CoinInfo,
    user_confirmed: bool,
    ownership_ids: list[bytes],
    script_pubkey: bytes,
    commitment_data: bytes,
) -> tuple[bytes, bytes]:
    flags = 0
    if user_confirmed:
        flags |= _FLAG_USER_CONFIRMED

    proof = utils.empty_bytearray(4 + 1 + 1 +
                                  len(ownership_ids) * _OWNERSHIP_ID_LEN)

    write_bytes_fixed(proof, _VERSION_MAGIC, 4)
    write_uint8(proof, flags)
    write_bitcoin_varint(proof, len(ownership_ids))
    for ownership_id in ownership_ids:
        write_bytes_fixed(proof, ownership_id, _OWNERSHIP_ID_LEN)

    sighash = HashWriter(sha256(proof))
    write_bytes_prefixed(sighash, script_pubkey)
    write_bytes_prefixed(sighash, commitment_data)
    if script_type in (
            InputScriptType.SPENDADDRESS,
            InputScriptType.SPENDMULTISIG,
            InputScriptType.SPENDWITNESS,
            InputScriptType.SPENDP2SHWITNESS,
    ):
        signature = common.ecdsa_sign(node, sighash.get_digest())
    elif script_type == InputScriptType.SPENDTAPROOT:
        signature = common.bip340_sign(node, sighash.get_digest())
    else:
        raise wire.DataError("Unsupported script type.")
    public_key = node.public_key()
    write_bip322_signature_proof(proof, script_type, multisig, coin,
                                 public_key, signature)

    return proof, signature
예제 #4
0
def _get_address_root(node: bip32.HDNode, address_attributes: dict) -> bytes:
    extpubkey = remove_ed25519_prefix(node.public_key()) + node.chain_code()
    return _address_hash([0, [0, extpubkey], address_attributes])
예제 #5
0
def get_address(
    script_type: InputScriptType,
    coin: CoinInfo,
    node: bip32.HDNode,
    multisig: MultisigRedeemScriptType | None = None,
) -> str:
    if multisig:
        # Ensure that our public key is included in the multisig.
        multisig_pubkey_index(multisig, node.public_key())

    if script_type in (InputScriptType.SPENDADDRESS,
                       InputScriptType.SPENDMULTISIG):
        if multisig:  # p2sh multisig
            if coin.address_type_p2sh is None:
                raise wire.ProcessError("Multisig not enabled on this coin")

            pubkeys = multisig_get_pubkeys(multisig)
            address = address_multisig_p2sh(pubkeys, multisig.m, coin)
            if coin.cashaddr_prefix is not None:
                address = address_to_cashaddr(address, coin)
            return address
        if script_type == InputScriptType.SPENDMULTISIG:
            raise wire.ProcessError("Multisig details required")

        # p2pkh
        address = node.address(coin.address_type)
        if coin.cashaddr_prefix is not None:
            address = address_to_cashaddr(address, coin)
        return address

    elif script_type == InputScriptType.SPENDWITNESS:  # native p2wpkh or native p2wsh
        if not coin.segwit or not coin.bech32_prefix:
            raise wire.ProcessError("Segwit not enabled on this coin")
        # native p2wsh multisig
        if multisig is not None:
            pubkeys = multisig_get_pubkeys(multisig)
            return address_multisig_p2wsh(pubkeys, multisig.m,
                                          coin.bech32_prefix)

        # native p2wpkh
        return address_p2wpkh(node.public_key(), coin)

    elif script_type == InputScriptType.SPENDTAPROOT:  # taproot
        if not coin.taproot or not coin.bech32_prefix:
            raise wire.ProcessError("Taproot not enabled on this coin")

        if multisig is not None:
            raise wire.ProcessError("Multisig not supported for taproot")

        return address_p2tr(node.public_key(), coin)

    elif (script_type == InputScriptType.SPENDP2SHWITNESS
          ):  # p2wpkh or p2wsh nested in p2sh
        if not coin.segwit or coin.address_type_p2sh is None:
            raise wire.ProcessError("Segwit not enabled on this coin")
        # p2wsh multisig nested in p2sh
        if multisig is not None:
            pubkeys = multisig_get_pubkeys(multisig)
            return address_multisig_p2wsh_in_p2sh(pubkeys, multisig.m, coin)

        # p2wpkh nested in p2sh
        return address_p2wpkh_in_p2sh(node.public_key(), coin)

    else:
        raise wire.ProcessError("Invalid script type")