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")
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")
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')
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")
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")
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')