| 83 | }; |
| 84 | |
| 85 | CTxDestination DecodeDestination(const std::string& str, const CChainParams& params, std::string& error_str, std::vector<int>* error_locations) |
| 86 | { |
| 87 | std::vector<unsigned char> data; |
| 88 | uint160 hash; |
| 89 | error_str = ""; |
| 90 | |
| 91 | // Note this will be false if it is a valid Bech32 address for a different network |
| 92 | bool is_bech32 = (ToLower(str.substr(0, params.Bech32HRP().size())) == params.Bech32HRP()); |
| 93 | |
| 94 | if (!is_bech32 && DecodeBase58Check(str, data, 21)) { |
| 95 | // base58-encoded Bitcoin addresses. |
| 96 | // Public-key-hash-addresses have version 0 (or 111 testnet). |
| 97 | // The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key. |
| 98 | const std::vector<unsigned char>& pubkey_prefix = params.Base58Prefix(CChainParams::PUBKEY_ADDRESS); |
| 99 | if (data.size() == hash.size() + pubkey_prefix.size() && std::equal(pubkey_prefix.begin(), pubkey_prefix.end(), data.begin())) { |
| 100 | std::copy(data.begin() + pubkey_prefix.size(), data.end(), hash.begin()); |
| 101 | return PKHash(hash); |
| 102 | } |
| 103 | // Script-hash-addresses have version 5 (or 196 testnet). |
| 104 | // The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script. |
| 105 | const std::vector<unsigned char>& script_prefix = params.Base58Prefix(CChainParams::SCRIPT_ADDRESS); |
| 106 | if (data.size() == hash.size() + script_prefix.size() && std::equal(script_prefix.begin(), script_prefix.end(), data.begin())) { |
| 107 | std::copy(data.begin() + script_prefix.size(), data.end(), hash.begin()); |
| 108 | return ScriptHash(hash); |
| 109 | } |
| 110 | |
| 111 | // If the prefix of data matches either the script or pubkey prefix, the length must have been wrong |
| 112 | if ((data.size() >= script_prefix.size() && |
| 113 | std::equal(script_prefix.begin(), script_prefix.end(), data.begin())) || |
| 114 | (data.size() >= pubkey_prefix.size() && |
| 115 | std::equal(pubkey_prefix.begin(), pubkey_prefix.end(), data.begin()))) { |
| 116 | error_str = "Invalid length for Base58 address (P2PKH or P2SH)"; |
| 117 | } else { |
| 118 | error_str = "Invalid or unsupported Base58-encoded address."; |
| 119 | } |
| 120 | return CNoDestination(); |
| 121 | } else if (!is_bech32) { |
| 122 | // Try Base58 decoding without the checksum, using a much larger max length |
| 123 | if (!DecodeBase58(str, data, 100)) { |
| 124 | error_str = "Invalid or unsupported Segwit (Bech32) or Base58 encoding."; |
| 125 | } else { |
| 126 | error_str = "Invalid checksum or length of Base58 address (P2PKH or P2SH)"; |
| 127 | } |
| 128 | return CNoDestination(); |
| 129 | } |
| 130 | |
| 131 | data.clear(); |
| 132 | const auto dec = bech32::Decode(str); |
| 133 | if (dec.encoding == bech32::Encoding::BECH32 || dec.encoding == bech32::Encoding::BECH32M) { |
| 134 | if (dec.data.empty()) { |
| 135 | error_str = "Empty Bech32 data section"; |
| 136 | return CNoDestination(); |
| 137 | } |
| 138 | // Bech32 decoding |
| 139 | if (dec.hrp != params.Bech32HRP()) { |
| 140 | error_str = strprintf("Invalid or unsupported prefix for Segwit (Bech32) address (expected %s, got %s).", params.Bech32HRP(), dec.hrp); |
| 141 | return CNoDestination(); |
| 142 | } |