|
4 | 4 |
|
5 | 5 | #include <base58.h> |
6 | 6 |
|
7 | | -#include <bech32.h> |
8 | 7 | #include <hash.h> |
9 | | -#include <script/script.h> |
10 | 8 | #include <uint256.h> |
11 | | -#include <utilstrencodings.h> |
12 | 9 |
|
13 | | -#include <boost/variant/apply_visitor.hpp> |
14 | | -#include <boost/variant/static_visitor.hpp> |
15 | | - |
16 | | -#include <algorithm> |
17 | 10 | #include <assert.h> |
18 | 11 | #include <string.h> |
19 | 12 |
|
20 | | - |
21 | 13 | /** All alphanumeric characters except for "0", "I", "O", and "l" */ |
22 | 14 | static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; |
23 | 15 |
|
@@ -151,209 +143,3 @@ bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRe |
151 | 143 | { |
152 | 144 | return DecodeBase58Check(str.c_str(), vchRet); |
153 | 145 | } |
154 | | - |
155 | | -namespace |
156 | | -{ |
157 | | -class DestinationEncoder : public boost::static_visitor<std::string> |
158 | | -{ |
159 | | -private: |
160 | | - const CChainParams& m_params; |
161 | | - |
162 | | -public: |
163 | | - DestinationEncoder(const CChainParams& params) : m_params(params) {} |
164 | | - |
165 | | - std::string operator()(const CKeyID& id) const |
166 | | - { |
167 | | - std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::PUBKEY_ADDRESS); |
168 | | - data.insert(data.end(), id.begin(), id.end()); |
169 | | - return EncodeBase58Check(data); |
170 | | - } |
171 | | - |
172 | | - std::string operator()(const CScriptID& id) const |
173 | | - { |
174 | | - std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::SCRIPT_ADDRESS); |
175 | | - data.insert(data.end(), id.begin(), id.end()); |
176 | | - return EncodeBase58Check(data); |
177 | | - } |
178 | | - |
179 | | - std::string operator()(const WitnessV0KeyHash& id) const |
180 | | - { |
181 | | - std::vector<unsigned char> data = {0}; |
182 | | - ConvertBits<8, 5, true>(data, id.begin(), id.end()); |
183 | | - return bech32::Encode(m_params.Bech32HRP(), data); |
184 | | - } |
185 | | - |
186 | | - std::string operator()(const WitnessV0ScriptHash& id) const |
187 | | - { |
188 | | - std::vector<unsigned char> data = {0}; |
189 | | - ConvertBits<8, 5, true>(data, id.begin(), id.end()); |
190 | | - return bech32::Encode(m_params.Bech32HRP(), data); |
191 | | - } |
192 | | - |
193 | | - std::string operator()(const WitnessUnknown& id) const |
194 | | - { |
195 | | - if (id.version < 1 || id.version > 16 || id.length < 2 || id.length > 40) { |
196 | | - return {}; |
197 | | - } |
198 | | - std::vector<unsigned char> data = {(unsigned char)id.version}; |
199 | | - ConvertBits<8, 5, true>(data, id.program, id.program + id.length); |
200 | | - return bech32::Encode(m_params.Bech32HRP(), data); |
201 | | - } |
202 | | - |
203 | | - std::string operator()(const CNoDestination& no) const { return {}; } |
204 | | -}; |
205 | | - |
206 | | -CTxDestination DecodeDestination(const std::string& str, const CChainParams& params) |
207 | | -{ |
208 | | - std::vector<unsigned char> data; |
209 | | - uint160 hash; |
210 | | - if (DecodeBase58Check(str, data)) { |
211 | | - // base58-encoded Bitcoin addresses. |
212 | | - // Public-key-hash-addresses have version 0 (or 111 testnet). |
213 | | - // The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key. |
214 | | - const std::vector<unsigned char>& pubkey_prefix = params.Base58Prefix(CChainParams::PUBKEY_ADDRESS); |
215 | | - if (data.size() == hash.size() + pubkey_prefix.size() && std::equal(pubkey_prefix.begin(), pubkey_prefix.end(), data.begin())) { |
216 | | - std::copy(data.begin() + pubkey_prefix.size(), data.end(), hash.begin()); |
217 | | - return CKeyID(hash); |
218 | | - } |
219 | | - // Script-hash-addresses have version 5 (or 196 testnet). |
220 | | - // The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script. |
221 | | - const std::vector<unsigned char>& script_prefix = params.Base58Prefix(CChainParams::SCRIPT_ADDRESS); |
222 | | - if (data.size() == hash.size() + script_prefix.size() && std::equal(script_prefix.begin(), script_prefix.end(), data.begin())) { |
223 | | - std::copy(data.begin() + script_prefix.size(), data.end(), hash.begin()); |
224 | | - return CScriptID(hash); |
225 | | - } |
226 | | - } |
227 | | - data.clear(); |
228 | | - auto bech = bech32::Decode(str); |
229 | | - if (bech.second.size() > 0 && bech.first == params.Bech32HRP()) { |
230 | | - // Bech32 decoding |
231 | | - int version = bech.second[0]; // The first 5 bit symbol is the witness version (0-16) |
232 | | - // The rest of the symbols are converted witness program bytes. |
233 | | - if (ConvertBits<5, 8, false>(data, bech.second.begin() + 1, bech.second.end())) { |
234 | | - if (version == 0) { |
235 | | - { |
236 | | - WitnessV0KeyHash keyid; |
237 | | - if (data.size() == keyid.size()) { |
238 | | - std::copy(data.begin(), data.end(), keyid.begin()); |
239 | | - return keyid; |
240 | | - } |
241 | | - } |
242 | | - { |
243 | | - WitnessV0ScriptHash scriptid; |
244 | | - if (data.size() == scriptid.size()) { |
245 | | - std::copy(data.begin(), data.end(), scriptid.begin()); |
246 | | - return scriptid; |
247 | | - } |
248 | | - } |
249 | | - return CNoDestination(); |
250 | | - } |
251 | | - if (version > 16 || data.size() < 2 || data.size() > 40) { |
252 | | - return CNoDestination(); |
253 | | - } |
254 | | - WitnessUnknown unk; |
255 | | - unk.version = version; |
256 | | - std::copy(data.begin(), data.end(), unk.program); |
257 | | - unk.length = data.size(); |
258 | | - return unk; |
259 | | - } |
260 | | - } |
261 | | - return CNoDestination(); |
262 | | -} |
263 | | -} // namespace |
264 | | - |
265 | | -CKey DecodeSecret(const std::string& str) |
266 | | -{ |
267 | | - CKey key; |
268 | | - std::vector<unsigned char> data; |
269 | | - if (DecodeBase58Check(str, data)) { |
270 | | - const std::vector<unsigned char>& privkey_prefix = Params().Base58Prefix(CChainParams::SECRET_KEY); |
271 | | - if ((data.size() == 32 + privkey_prefix.size() || (data.size() == 33 + privkey_prefix.size() && data.back() == 1)) && |
272 | | - std::equal(privkey_prefix.begin(), privkey_prefix.end(), data.begin())) { |
273 | | - bool compressed = data.size() == 33 + privkey_prefix.size(); |
274 | | - key.Set(data.begin() + privkey_prefix.size(), data.begin() + privkey_prefix.size() + 32, compressed); |
275 | | - } |
276 | | - } |
277 | | - memory_cleanse(data.data(), data.size()); |
278 | | - return key; |
279 | | -} |
280 | | - |
281 | | -std::string EncodeSecret(const CKey& key) |
282 | | -{ |
283 | | - assert(key.IsValid()); |
284 | | - std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::SECRET_KEY); |
285 | | - data.insert(data.end(), key.begin(), key.end()); |
286 | | - if (key.IsCompressed()) { |
287 | | - data.push_back(1); |
288 | | - } |
289 | | - std::string ret = EncodeBase58Check(data); |
290 | | - memory_cleanse(data.data(), data.size()); |
291 | | - return ret; |
292 | | -} |
293 | | - |
294 | | -CExtPubKey DecodeExtPubKey(const std::string& str) |
295 | | -{ |
296 | | - CExtPubKey key; |
297 | | - std::vector<unsigned char> data; |
298 | | - if (DecodeBase58Check(str, data)) { |
299 | | - const std::vector<unsigned char>& prefix = Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY); |
300 | | - if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && std::equal(prefix.begin(), prefix.end(), data.begin())) { |
301 | | - key.Decode(data.data() + prefix.size()); |
302 | | - } |
303 | | - } |
304 | | - return key; |
305 | | -} |
306 | | - |
307 | | -std::string EncodeExtPubKey(const CExtPubKey& key) |
308 | | -{ |
309 | | - std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY); |
310 | | - size_t size = data.size(); |
311 | | - data.resize(size + BIP32_EXTKEY_SIZE); |
312 | | - key.Encode(data.data() + size); |
313 | | - std::string ret = EncodeBase58Check(data); |
314 | | - return ret; |
315 | | -} |
316 | | - |
317 | | -CExtKey DecodeExtKey(const std::string& str) |
318 | | -{ |
319 | | - CExtKey key; |
320 | | - std::vector<unsigned char> data; |
321 | | - if (DecodeBase58Check(str, data)) { |
322 | | - const std::vector<unsigned char>& prefix = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY); |
323 | | - if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && std::equal(prefix.begin(), prefix.end(), data.begin())) { |
324 | | - key.Decode(data.data() + prefix.size()); |
325 | | - } |
326 | | - } |
327 | | - return key; |
328 | | -} |
329 | | - |
330 | | -std::string EncodeExtKey(const CExtKey& key) |
331 | | -{ |
332 | | - std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY); |
333 | | - size_t size = data.size(); |
334 | | - data.resize(size + BIP32_EXTKEY_SIZE); |
335 | | - key.Encode(data.data() + size); |
336 | | - std::string ret = EncodeBase58Check(data); |
337 | | - memory_cleanse(data.data(), data.size()); |
338 | | - return ret; |
339 | | -} |
340 | | - |
341 | | -std::string EncodeDestination(const CTxDestination& dest) |
342 | | -{ |
343 | | - return boost::apply_visitor(DestinationEncoder(Params()), dest); |
344 | | -} |
345 | | - |
346 | | -CTxDestination DecodeDestination(const std::string& str) |
347 | | -{ |
348 | | - return DecodeDestination(str, Params()); |
349 | | -} |
350 | | - |
351 | | -bool IsValidDestinationString(const std::string& str, const CChainParams& params) |
352 | | -{ |
353 | | - return IsValidDestination(DecodeDestination(str, params)); |
354 | | -} |
355 | | - |
356 | | -bool IsValidDestinationString(const std::string& str) |
357 | | -{ |
358 | | - return IsValidDestinationString(str, Params()); |
359 | | -} |
0 commit comments