diff options
-rw-r--r-- | src/base58.cpp | 108 | ||||
-rw-r--r-- | src/base58.h | 65 | ||||
-rw-r--r-- | src/test/bip32_tests.cpp | 16 | ||||
-rw-r--r-- | src/wallet/rpcdump.cpp | 5 |
4 files changed, 56 insertions, 138 deletions
diff --git a/src/base58.cpp b/src/base58.cpp index 826fe630bc..b2c3161d14 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -152,67 +152,6 @@ bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRe return DecodeBase58Check(str.c_str(), vchRet); } -CBase58Data::CBase58Data() -{ - vchVersion.clear(); - vchData.clear(); -} - -void CBase58Data::SetData(const std::vector<unsigned char>& 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<unsigned char>& vchVersionIn, const unsigned char* pbegin, const unsigned char* pend) -{ - SetData(vchVersionIn, (void*)pbegin, pend - pbegin); -} - -bool CBase58Data::SetString(const char* psz, unsigned int nVersionBytes) -{ - std::vector<unsigned char> 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<unsigned char> 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<std::string> @@ -352,6 +291,53 @@ std::string EncodeSecret(const CKey& key) return ret; } +CExtPubKey DecodeExtPubKey(const std::string& str) +{ + CExtPubKey key; + std::vector<unsigned char> data; + if (DecodeBase58Check(str, data)) { + const std::vector<unsigned char>& 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<unsigned char> 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<unsigned char> data; + if (DecodeBase58Check(str, data)) { + const std::vector<unsigned char>& 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<unsigned char> 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 EncodeDestination(const CTxDestination& dest) { return boost::apply_visitor(DestinationEncoder(Params()), dest); diff --git a/src/base58.h b/src/base58.h index c3dea060b6..db33d0859c 100644 --- a/src/base58.h +++ b/src/base58.h @@ -64,70 +64,13 @@ inline bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRe */ inline bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet); -/** - * Base class for all base58-encoded data - */ -class CBase58Data -{ -protected: - //! the version byte(s) - std::vector<unsigned char> vchVersion; - - //! the actually encoded data - typedef std::vector<unsigned char, zero_after_free_allocator<unsigned char> > vector_uchar; - vector_uchar vchData; - - CBase58Data(); - void SetData(const std::vector<unsigned char> &vchVersionIn, const void* pdata, size_t nSize); - void SetData(const std::vector<unsigned char> &vchVersionIn, const unsigned char *pbegin, const unsigned char *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<typename K, int Size, CChainParams::Base58Type Type> class CBitcoinExtKeyBase : public CBase58Data -{ -public: - void SetKey(const K &key) { - unsigned char 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<CExtKey, BIP32_EXTKEY_SIZE, CChainParams::EXT_SECRET_KEY> CBitcoinExtKey; -typedef CBitcoinExtKeyBase<CExtPubKey, BIP32_EXTKEY_SIZE, CChainParams::EXT_PUBLIC_KEY> 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 EncodeDestination(const CTxDestination& dest); CTxDestination DecodeDestination(const std::string& str); diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp index 438ddc177d..d4c29b2635 100644 --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -99,20 +99,12 @@ void RunTest(const TestVector &test) { 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(); - assert(checkKey == key); //ensure a base58 decoded key also matches + BOOST_CHECK(EncodeExtKey(key) == derive.prv); + BOOST_CHECK(DecodeExtKey(derive.prv) == key); //ensure a base58 decoded key also matches // Test public key - CBitcoinExtPubKey b58pubkey; b58pubkey.SetKey(pubkey); - BOOST_CHECK(b58pubkey.ToString() == derive.pub); - - CBitcoinExtPubKey b58PubkeyDecodeCheck(derive.pub); - CExtPubKey checkPubKey = b58PubkeyDecodeCheck.GetKey(); - assert(checkPubKey == pubkey); //ensure a base58 decoded pubkey also matches + BOOST_CHECK(EncodeExtPubKey(pubkey) == derive.pub); + BOOST_CHECK(DecodeExtPubKey(derive.pub) == pubkey); //ensure a base58 decoded pubkey also matches // Derive new keys CExtKey keyNew; diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 502d49d0aa..bf6c0815fe 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -736,10 +736,7 @@ UniValue dumpwallet(const JSONRPCRequest& request) CExtKey masterKey; masterKey.SetMaster(key.begin(), key.size()); - CBitcoinExtKey b58extkey; - b58extkey.SetKey(masterKey); - - file << "# extended private masterkey: " << b58extkey.ToString() << "\n\n"; + file << "# extended private masterkey: " << EncodeExtKey(masterKey) << "\n\n"; } } for (std::vector<std::pair<int64_t, CKeyID> >::const_iterator it = vKeyBirth.begin(); it != vKeyBirth.end(); it++) { |