def output_derive_script(o: TxOutputType, coin: coininfo.CoinInfo, keychain: seed.Keychain) -> 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 scripts.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, keychain) 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 = addresses.decode_bech32_address(coin.bech32_prefix, o.address) return scripts.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 = scripts.output_script_p2pkh(pubkeyhash) if coin.bip115: script += scripts.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 = scripts.output_script_p2sh(scripthash) if coin.bip115: script += scripts.script_replay_protection_bip115( o.block_hash_bip115, o.block_height_bip115) return script raise SigningError(FailureType.DataError, "Invalid address type")
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")