diff options
Diffstat (limited to 'src/base58.cpp')
-rw-r--r-- | src/base58.cpp | 62 |
1 files changed, 61 insertions, 1 deletions
diff --git a/src/base58.cpp b/src/base58.cpp index 0272711575..c2cc5d979f 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -4,9 +4,11 @@ #include "base58.h" +#include "bech32.h" #include "hash.h" #include "script/script.h" #include "uint256.h" +#include "utilstrencodings.h" #include <boost/variant/apply_visitor.hpp> #include <boost/variant/static_visitor.hpp> @@ -235,7 +237,31 @@ public: return EncodeBase58Check(data); } - std::string operator()(const CNoDestination& no) const { return ""; } + std::string operator()(const WitnessV0KeyHash& id) const + { + std::vector<unsigned char> data = {0}; + ConvertBits<8, 5, true>(data, id.begin(), id.end()); + return bech32::Encode(m_params.Bech32HRP(), data); + } + + std::string operator()(const WitnessV0ScriptHash& id) const + { + std::vector<unsigned char> data = {0}; + ConvertBits<8, 5, true>(data, id.begin(), id.end()); + return bech32::Encode(m_params.Bech32HRP(), data); + } + + std::string operator()(const WitnessUnknown& id) const + { + if (id.version < 1 || id.version > 16 || id.length < 2 || id.length > 40) { + return {}; + } + std::vector<unsigned char> data = {(unsigned char)id.version}; + ConvertBits<8, 5, true>(data, id.program, id.program + id.length); + return bech32::Encode(m_params.Bech32HRP(), data); + } + + std::string operator()(const CNoDestination& no) const { return {}; } }; CTxDestination DecodeDestination(const std::string& str, const CChainParams& params) @@ -259,6 +285,40 @@ CTxDestination DecodeDestination(const std::string& str, const CChainParams& par return CScriptID(hash); } } + data.clear(); + auto bech = bech32::Decode(str); + if (bech.second.size() > 0 && bech.first == params.Bech32HRP()) { + // Bech32 decoding + int version = bech.second[0]; // The first 5 bit symbol is the witness version (0-16) + // The rest of the symbols are converted witness program bytes. + if (ConvertBits<5, 8, false>(data, bech.second.begin() + 1, bech.second.end())) { + if (version == 0) { + { + WitnessV0KeyHash keyid; + if (data.size() == keyid.size()) { + std::copy(data.begin(), data.end(), keyid.begin()); + return keyid; + } + } + { + WitnessV0ScriptHash scriptid; + if (data.size() == scriptid.size()) { + std::copy(data.begin(), data.end(), scriptid.begin()); + return scriptid; + } + } + return CNoDestination(); + } + if (version > 16 || data.size() < 2 || data.size() > 40) { + return CNoDestination(); + } + WitnessUnknown unk; + unk.version = version; + std::copy(data.begin(), data.end(), unk.program); + unk.length = data.size(); + return unk; + } + } return CNoDestination(); } } // namespace |