diff --git a/src/base58.h b/src/base58.h --- a/src/base58.h +++ b/src/base58.h @@ -67,81 +67,13 @@ inline bool DecodeBase58Check(const std::string &str, std::vector &vchRet); -/** - * Base class for all base58-encoded data - */ -class CBase58Data { -protected: - //! the version byte(s) - std::vector vchVersion; - - //! the actually encoded data - typedef std::vector> - vector_uchar; - vector_uchar vchData; - - CBase58Data(); - void SetData(const std::vector &vchVersionIn, const void *pdata, - size_t nSize); - void SetData(const std::vector &vchVersionIn, - const uint8_t *pbegin, const uint8_t *pend); - -public: - bool SetString(const char *psz, unsigned int nVersionBytes = 1); - bool SetString(const std::string &str); - std::string ToString() const; - int CompareTo(const CBase58Data &b58) const; - - bool operator==(const CBase58Data &b58) const { - return CompareTo(b58) == 0; - } - bool operator<=(const CBase58Data &b58) const { - return CompareTo(b58) <= 0; - } - bool operator>=(const CBase58Data &b58) const { - return CompareTo(b58) >= 0; - } - bool operator<(const CBase58Data &b58) const { return CompareTo(b58) < 0; } - bool operator>(const CBase58Data &b58) const { return CompareTo(b58) > 0; } -}; - CKey DecodeSecret(const std::string &str); std::string EncodeSecret(const CKey &key); -template -class CBitcoinExtKeyBase : public CBase58Data { -public: - void SetKey(const K &key) { - uint8_t vch[Size]; - key.Encode(vch); - SetData(Params().Base58Prefix(Type), vch, vch + Size); - } - - K GetKey() { - K ret; - if (vchData.size() == Size) { - // If base58 encoded data does not hold an ext key, return a - // !IsValid() key - ret.Decode(vchData.data()); - } - return ret; - } - - CBitcoinExtKeyBase(const K &key) { SetKey(key); } - - CBitcoinExtKeyBase(const std::string &strBase58c) { - SetString(strBase58c.c_str(), Params().Base58Prefix(Type).size()); - } - - CBitcoinExtKeyBase() {} -}; - -typedef CBitcoinExtKeyBase - CBitcoinExtKey; -typedef CBitcoinExtKeyBase - CBitcoinExtPubKey; +CExtKey DecodeExtKey(const std::string &str); +std::string EncodeExtKey(const CExtKey &extkey); +CExtPubKey DecodeExtPubKey(const std::string &str); +std::string EncodeExtPubKey(const CExtPubKey &extpubkey); std::string EncodeLegacyAddr(const CTxDestination &dest, const CChainParams &); CTxDestination DecodeLegacyAddr(const std::string &str, diff --git a/src/base58.cpp b/src/base58.cpp --- a/src/base58.cpp +++ b/src/base58.cpp @@ -156,60 +156,6 @@ return DecodeBase58Check(str.c_str(), vchRet); } -CBase58Data::CBase58Data() { - vchVersion.clear(); - vchData.clear(); -} - -void CBase58Data::SetData(const std::vector &vchVersionIn, - const void *pdata, size_t nSize) { - vchVersion = vchVersionIn; - vchData.resize(nSize); - if (!vchData.empty()) { - memcpy(vchData.data(), pdata, nSize); - } -} - -void CBase58Data::SetData(const std::vector &vchVersionIn, - const uint8_t *pbegin, const uint8_t *pend) { - SetData(vchVersionIn, (void *)pbegin, pend - pbegin); -} - -bool CBase58Data::SetString(const char *psz, unsigned int nVersionBytes) { - std::vector vchTemp; - bool rc58 = DecodeBase58Check(psz, vchTemp); - if ((!rc58) || (vchTemp.size() < nVersionBytes)) { - vchData.clear(); - vchVersion.clear(); - return false; - } - vchVersion.assign(vchTemp.begin(), vchTemp.begin() + nVersionBytes); - vchData.resize(vchTemp.size() - nVersionBytes); - if (!vchData.empty()) { - memcpy(vchData.data(), vchTemp.data() + nVersionBytes, vchData.size()); - } - memory_cleanse(vchTemp.data(), vchTemp.size()); - return true; -} - -bool CBase58Data::SetString(const std::string &str) { - return SetString(str.c_str()); -} - -std::string CBase58Data::ToString() const { - std::vector vch = vchVersion; - vch.insert(vch.end(), vchData.begin(), vchData.end()); - return EncodeBase58Check(vch); -} - -int CBase58Data::CompareTo(const CBase58Data &b58) const { - if (vchVersion < b58.vchVersion) return -1; - if (vchVersion > b58.vchVersion) return 1; - if (vchData < b58.vchData) return -1; - if (vchData > b58.vchData) return 1; - return 0; -} - namespace { class DestinationEncoder : public boost::static_visitor { private: @@ -264,9 +210,9 @@ CKey DecodeSecret(const std::string &str) { CKey key; - std::vector data; + std::vector data; if (DecodeBase58Check(str, data)) { - const std::vector &privkey_prefix = + const std::vector &privkey_prefix = Params().Base58Prefix(CChainParams::SECRET_KEY); if ((data.size() == 32 + privkey_prefix.size() || (data.size() == 33 + privkey_prefix.size() && data.back() == 1)) && @@ -283,8 +229,7 @@ std::string EncodeSecret(const CKey &key) { assert(key.IsValid()); - std::vector data = - Params().Base58Prefix(CChainParams::SECRET_KEY); + std::vector data = Params().Base58Prefix(CChainParams::SECRET_KEY); data.insert(data.end(), key.begin(), key.end()); if (key.IsCompressed()) { data.push_back(1); @@ -294,6 +239,55 @@ return ret; } +CExtPubKey DecodeExtPubKey(const std::string &str) { + CExtPubKey key; + std::vector data; + if (DecodeBase58Check(str, data)) { + const std::vector &prefix = + Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY); + if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && + std::equal(prefix.begin(), prefix.end(), data.begin())) { + key.Decode(data.data() + prefix.size()); + } + } + return key; +} + +std::string EncodeExtPubKey(const CExtPubKey &key) { + std::vector data = + Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY); + size_t size = data.size(); + data.resize(size + BIP32_EXTKEY_SIZE); + key.Encode(data.data() + size); + std::string ret = EncodeBase58Check(data); + return ret; +} + +CExtKey DecodeExtKey(const std::string &str) { + CExtKey key; + std::vector data; + if (DecodeBase58Check(str, data)) { + const std::vector &prefix = + Params().Base58Prefix(CChainParams::EXT_SECRET_KEY); + if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && + std::equal(prefix.begin(), prefix.end(), data.begin())) { + key.Decode(data.data() + prefix.size()); + } + } + return key; +} + +std::string EncodeExtKey(const CExtKey &key) { + std::vector data = + Params().Base58Prefix(CChainParams::EXT_SECRET_KEY); + size_t size = data.size(); + data.resize(size + BIP32_EXTKEY_SIZE); + key.Encode(data.data() + size); + std::string ret = EncodeBase58Check(data); + memory_cleanse(data.data(), data.size()); + return ret; +} + std::string EncodeLegacyAddr(const CTxDestination &dest, const CChainParams ¶ms) { return boost::apply_visitor(DestinationEncoder(params), dest); diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -106,24 +106,14 @@ pubkey.Encode(data); // Test private key - CBitcoinExtKey b58key; - b58key.SetKey(key); - BOOST_CHECK(b58key.ToString() == derive.prv); - - CBitcoinExtKey b58keyDecodeCheck(derive.prv); - CExtKey checkKey = b58keyDecodeCheck.GetKey(); - // ensure a base58 decoded key also matches - assert(checkKey == key); + BOOST_CHECK(EncodeExtKey(key) == derive.prv); + // Ensure a base58 decoded key also matches + BOOST_CHECK(DecodeExtKey(derive.prv) == key); // Test public key - CBitcoinExtPubKey b58pubkey; - b58pubkey.SetKey(pubkey); - BOOST_CHECK(b58pubkey.ToString() == derive.pub); - - CBitcoinExtPubKey b58PubkeyDecodeCheck(derive.pub); - CExtPubKey checkPubKey = b58PubkeyDecodeCheck.GetKey(); - // ensure a base58 decoded pubkey also matches - assert(checkPubKey == pubkey); + BOOST_CHECK(EncodeExtPubKey(pubkey) == derive.pub); + // Ensure a base58 decoded pubkey also matches + BOOST_CHECK(DecodeExtPubKey(derive.pub) == pubkey); // Derive new keys CExtKey keyNew; diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -839,10 +839,7 @@ CExtKey masterKey; masterKey.SetMaster(key.begin(), key.size()); - CBitcoinExtKey b58extkey; - b58extkey.SetKey(masterKey); - - file << "# extended private masterkey: " << b58extkey.ToString() + file << "# extended private masterkey: " << EncodeExtKey(masterKey) << "\n\n"; } }