aboutsummaryrefslogtreecommitdiff
path: root/src/base58.cpp
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2017-08-25 19:55:52 -0700
committerPieter Wuille <pieter.wuille@gmail.com>2017-09-28 16:24:30 -0700
commitc091b99379b97cb314c9fa123beabdbc324cf7a4 (patch)
treef1cc720f195b18842831f964a3dd1fc71d29a4ff /src/base58.cpp
parentbd355b8db9ffaacaafd10eb14f6b74cf00d8fc06 (diff)
Implement BIP173 addresses and tests
Diffstat (limited to 'src/base58.cpp')
-rw-r--r--src/base58.cpp62
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