// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2011 The Bitcoin Developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
-
+// Encode a byte sequence as a base58-encoded string
inline std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
{
CAutoBN_CTX pctx;
return str;
}
+// Encode a byte vector as a base58-encoded string
inline std::string EncodeBase58(const std::vector<unsigned char>& vch)
{
return EncodeBase58(&vch[0], &vch[0] + vch.size());
}
+// Decode a base58-encoded string psz into byte vector vchRet
+// returns true if decoding is succesful
inline bool DecodeBase58(const char* psz, std::vector<unsigned char>& vchRet)
{
CAutoBN_CTX pctx;
return true;
}
+// Decode a base58-encoded string str into byte vector vchRet
+// returns true if decoding is succesful
inline bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet)
{
return DecodeBase58(str.c_str(), vchRet);
-
+// Encode a byte vector to a base58-encoded string, including checksum
inline std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn)
{
// add 4-byte hash check to the end
return EncodeBase58(vch);
}
+// Decode a base58-encoded string psz that includes a checksum, into byte vector vchRet
+// returns true if decoding is succesful
inline bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet)
{
if (!DecodeBase58(psz, vchRet))
return true;
}
+// Decode a base58-encoded string str that includes a checksum, into byte vector vchRet
+// returns true if decoding is succesful
inline bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet)
{
return DecodeBase58Check(str.c_str(), vchRet);
-
-class CBitcoinAddress
+// Base class for all base58-encoded data
+class CBase58Data
{
protected:
+ // the version byte
unsigned char nVersion;
+
+ // the actually encoded data
std::vector<unsigned char> vchData;
-public:
- bool SetAddress(const uint160& hash160)
+ CBase58Data()
{
- nVersion = fTestNet ? 111 : 0;
- vchData.resize(20);
- memcpy(&vchData[0], &hash160, 20);
- return true;
+ nVersion = 0;
+ vchData.clear();
+ }
+
+ ~CBase58Data()
+ {
+ // zero the memory, as it may contain sensitive data
+ if (!vchData.empty())
+ memset(&vchData[0], 0, vchData.size());
+ }
+
+ void SetData(int nVersionIn, const void* pdata, size_t nSize)
+ {
+ nVersion = nVersionIn;
+ vchData.resize(nSize);
+ if (!vchData.empty())
+ memcpy(&vchData[0], pdata, nSize);
}
- bool SetAddress(const char* pszAddress)
+ void SetData(int nVersionIn, const unsigned char *pbegin, const unsigned char *pend)
+ {
+ SetData(nVersionIn, (void*)pbegin, pend - pbegin);
+ }
+
+public:
+ bool SetString(const char* psz)
{
std::vector<unsigned char> vchTemp;
- DecodeBase58Check(pszAddress, vchTemp);
+ DecodeBase58Check(psz, vchTemp);
if (vchTemp.empty())
{
vchData.clear();
}
nVersion = vchTemp[0];
vchData.resize(vchTemp.size() - 1);
- memcpy(&vchData[0], &vchTemp[1], vchData.size());
+ if (!vchData.empty())
+ memcpy(&vchData[0], &vchTemp[1], vchData.size());
+ memset(&vchTemp[0], 0, vchTemp.size());
return true;
}
- bool SetAddress(const std::string& strAddress)
+ bool SetString(const std::string& str)
{
- return SetAddress(strAddress.c_str());
+ return SetString(str.c_str());
}
- bool SetAddress(const std::vector<unsigned char>& vchPubKey)
+ std::string ToString() const
{
- return SetAddress(Hash160(vchPubKey));
+ std::vector<unsigned char> vch(1, nVersion);
+ vch.insert(vch.end(), vchData.begin(), vchData.end());
+ return EncodeBase58Check(vch);
+ }
+
+ int CompareTo(const CBase58Data& b58) const
+ {
+ if (nVersion < b58.nVersion) return -1;
+ if (nVersion > b58.nVersion) return 1;
+ if (vchData < b58.vchData) return -1;
+ if (vchData > b58.vchData) return 1;
+ return 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; }
+ bool operator> (const CBase58Data& b58) const { return CompareTo(b58) > 0; }
+};
+
+// base58-encoded bitcoin addresses
+// Addresses have version 0 or 111 (testnet)
+// The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key
+class CBitcoinAddress : public CBase58Data
+{
+public:
+ bool SetHash160(const uint160& hash160)
+ {
+ SetData(fTestNet ? 111 : 0, &hash160, 20);
+ return true;
+ }
+
+ bool SetPubKey(const std::vector<unsigned char>& vchPubKey)
+ {
+ return SetHash160(Hash160(vchPubKey));
}
bool IsValid() const
{
- int nExpectedSize = 20;
+ unsigned int nExpectedSize = 20;
bool fExpectTestNet = false;
switch(nVersion)
{
CBitcoinAddress()
{
- nVersion = 0;
- vchData.clear();
}
CBitcoinAddress(uint160 hash160In)
{
- SetAddress(hash160In);
+ SetHash160(hash160In);
}
CBitcoinAddress(const std::vector<unsigned char>& vchPubKey)
{
- SetAddress(vchPubKey);
+ SetPubKey(vchPubKey);
}
CBitcoinAddress(const std::string& strAddress)
{
- SetAddress(strAddress);
+ SetString(strAddress);
}
CBitcoinAddress(const char* pszAddress)
{
- SetAddress(pszAddress);
- }
-
- std::string ToString() const
- {
- std::vector<unsigned char> vch(1, nVersion);
- vch.insert(vch.end(), vchData.begin(), vchData.end());
- return EncodeBase58Check(vch);
+ SetString(pszAddress);
}
uint160 GetHash160() const
memcpy(&hash160, &vchData[0], 20);
return hash160;
}
-
- int CompareTo(const CBitcoinAddress& address) const
- {
- if (nVersion < address.nVersion) return -1;
- if (nVersion < address.nVersion) return 1;
- if (vchData < address.vchData) return -1;
- if (vchData > address.vchData) return 1;
- return 0;
- }
-
- bool operator==(const CBitcoinAddress& address) const { return CompareTo(address) == 0; }
- bool operator<=(const CBitcoinAddress& address) const { return CompareTo(address) <= 0; }
- bool operator>=(const CBitcoinAddress& address) const { return CompareTo(address) >= 0; }
- bool operator< (const CBitcoinAddress& address) const { return CompareTo(address) < 0; }
- bool operator> (const CBitcoinAddress& address) const { return CompareTo(address) > 0; }
};
#endif