File indexing completed on 2020-06-25 15:54:26
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef BITCOIN_BASE58_H
0016 #define BITCOIN_BASE58_H
0017
0018 #include <string>
0019 #include <vector>
0020 #include "bignum.h"
0021
0022 static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
0023
0024
0025 inline std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
0026 {
0027 CAutoBN_CTX pctx;
0028 CBigNum bn58 = 58;
0029 CBigNum bn0 = 0;
0030
0031
0032
0033 std::vector<unsigned char> vchTmp(pend-pbegin+1, 0);
0034 reverse_copy(pbegin, pend, vchTmp.begin());
0035
0036
0037 CBigNum bn;
0038 bn.setvch(vchTmp);
0039
0040
0041 std::string str;
0042
0043
0044 str.reserve((pend - pbegin) * 138 / 100 + 1);
0045 CBigNum dv;
0046 CBigNum rem;
0047 while (bn > bn0)
0048 {
0049 if (!BN_div(&dv, &rem, &bn, &bn58, pctx))
0050 throw bignum_error("EncodeBase58 : BN_div failed");
0051 bn = dv;
0052 unsigned int c = rem.getulong();
0053 str += pszBase58[c];
0054 }
0055
0056
0057 for (const unsigned char* p = pbegin; p < pend && *p == 0; p++)
0058 str += pszBase58[0];
0059
0060
0061 reverse(str.begin(), str.end());
0062 return str;
0063 }
0064
0065
0066 inline std::string EncodeBase58(const std::vector<unsigned char>& vch)
0067 {
0068 return EncodeBase58(&vch[0], &vch[0] + vch.size());
0069 }
0070
0071
0072
0073 inline bool DecodeBase58(const char* psz, std::vector<unsigned char>& vchRet)
0074 {
0075 CAutoBN_CTX pctx;
0076 vchRet.clear();
0077 CBigNum bn58 = 58;
0078 CBigNum bn = 0;
0079 CBigNum bnChar;
0080 while (isspace(*psz))
0081 psz++;
0082
0083
0084 for (const char* p = psz; *p; p++)
0085 {
0086 const char* p1 = strchr(pszBase58, *p);
0087 if (p1 == NULL)
0088 {
0089 while (isspace(*p))
0090 p++;
0091 if (*p != '\0')
0092 return false;
0093 break;
0094 }
0095 bnChar.setulong(p1 - pszBase58);
0096 if (!BN_mul(&bn, &bn, &bn58, pctx))
0097 throw bignum_error("DecodeBase58 : BN_mul failed");
0098 bn += bnChar;
0099 }
0100
0101
0102 std::vector<unsigned char> vchTmp = bn.getvch();
0103
0104
0105 if (vchTmp.size() >= 2 && vchTmp.end()[-1] == 0 && vchTmp.end()[-2] >= 0x80)
0106 vchTmp.erase(vchTmp.end()-1);
0107
0108
0109 int nLeadingZeros = 0;
0110 for (const char* p = psz; *p == pszBase58[0]; p++)
0111 nLeadingZeros++;
0112 vchRet.assign(nLeadingZeros + vchTmp.size(), 0);
0113
0114
0115 reverse_copy(vchTmp.begin(), vchTmp.end(), vchRet.end() - vchTmp.size());
0116 return true;
0117 }
0118
0119
0120
0121 inline bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet)
0122 {
0123 return DecodeBase58(str.c_str(), vchRet);
0124 }
0125
0126
0127
0128
0129
0130 inline std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn)
0131 {
0132
0133 std::vector<unsigned char> vch(vchIn);
0134 uint256 hash = Hash(vch.begin(), vch.end());
0135 vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4);
0136 return EncodeBase58(vch);
0137 }
0138
0139
0140
0141 inline bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet)
0142 {
0143 if (!DecodeBase58(psz, vchRet))
0144 return false;
0145 if (vchRet.size() < 4)
0146 {
0147 vchRet.clear();
0148 return false;
0149 }
0150 uint256 hash = Hash(vchRet.begin(), vchRet.end()-4);
0151 if (memcmp(&hash, &vchRet.end()[-4], 4) != 0)
0152 {
0153 vchRet.clear();
0154 return false;
0155 }
0156 vchRet.resize(vchRet.size()-4);
0157 return true;
0158 }
0159
0160
0161
0162 inline bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet)
0163 {
0164 return DecodeBase58Check(str.c_str(), vchRet);
0165 }
0166
0167
0168
0169
0170
0171
0172 class CBase58Data
0173 {
0174 protected:
0175
0176 unsigned char nVersion;
0177
0178
0179 std::vector<unsigned char> vchData;
0180
0181 CBase58Data()
0182 {
0183 nVersion = 0;
0184 vchData.clear();
0185 }
0186
0187 ~CBase58Data()
0188 {
0189
0190 if (!vchData.empty())
0191 memset(&vchData[0], 0, vchData.size());
0192 }
0193
0194 void SetData(int nVersionIn, const void* pdata, size_t nSize)
0195 {
0196 nVersion = nVersionIn;
0197 vchData.resize(nSize);
0198 if (!vchData.empty())
0199 memcpy(&vchData[0], pdata, nSize);
0200 }
0201
0202 void SetData(int nVersionIn, const unsigned char *pbegin, const unsigned char *pend)
0203 {
0204 SetData(nVersionIn, (void*)pbegin, pend - pbegin);
0205 }
0206
0207 public:
0208 bool SetString(const char* psz)
0209 {
0210 std::vector<unsigned char> vchTemp;
0211 DecodeBase58Check(psz, vchTemp);
0212 if (vchTemp.empty())
0213 {
0214 vchData.clear();
0215 nVersion = 0;
0216 return false;
0217 }
0218 nVersion = vchTemp[0];
0219 vchData.resize(vchTemp.size() - 1);
0220 if (!vchData.empty())
0221 memcpy(&vchData[0], &vchTemp[1], vchData.size());
0222 memset(&vchTemp[0], 0, vchTemp.size());
0223 return true;
0224 }
0225
0226 bool SetString(const std::string& str)
0227 {
0228 return SetString(str.c_str());
0229 }
0230
0231 std::string ToString() const
0232 {
0233 std::vector<unsigned char> vch(1, nVersion);
0234 vch.insert(vch.end(), vchData.begin(), vchData.end());
0235 return EncodeBase58Check(vch);
0236 }
0237
0238 int CompareTo(const CBase58Data& b58) const
0239 {
0240 if (nVersion < b58.nVersion) return -1;
0241 if (nVersion > b58.nVersion) return 1;
0242 if (vchData < b58.vchData) return -1;
0243 if (vchData > b58.vchData) return 1;
0244 return 0;
0245 }
0246
0247 bool operator==(const CBase58Data& b58) const { return CompareTo(b58) == 0; }
0248 bool operator<=(const CBase58Data& b58) const { return CompareTo(b58) <= 0; }
0249 bool operator>=(const CBase58Data& b58) const { return CompareTo(b58) >= 0; }
0250 bool operator< (const CBase58Data& b58) const { return CompareTo(b58) < 0; }
0251 bool operator> (const CBase58Data& b58) const { return CompareTo(b58) > 0; }
0252 };
0253
0254
0255
0256
0257 class CBitcoinAddress : public CBase58Data
0258 {
0259 public:
0260 bool SetHash160(const uint160& hash160)
0261 {
0262 SetData(fTestNet ? 111 : 0, &hash160, 20);
0263 return true;
0264 }
0265
0266 bool SetPubKey(const std::vector<unsigned char>& vchPubKey)
0267 {
0268 return SetHash160(Hash160(vchPubKey));
0269 }
0270
0271 bool IsValid() const
0272 {
0273 int nExpectedSize = 20;
0274 bool fExpectTestNet = false;
0275 switch(nVersion)
0276 {
0277 case 0:
0278 break;
0279
0280 case 111:
0281 fExpectTestNet = true;
0282 break;
0283
0284 default:
0285 return false;
0286 }
0287 return fExpectTestNet == fTestNet && vchData.size() == nExpectedSize;
0288 }
0289
0290 CBitcoinAddress()
0291 {
0292 }
0293
0294 CBitcoinAddress(uint160 hash160In)
0295 {
0296 SetHash160(hash160In);
0297 }
0298
0299 CBitcoinAddress(const std::vector<unsigned char>& vchPubKey)
0300 {
0301 SetPubKey(vchPubKey);
0302 }
0303
0304 CBitcoinAddress(const std::string& strAddress)
0305 {
0306 SetString(strAddress);
0307 }
0308
0309 CBitcoinAddress(const char* pszAddress)
0310 {
0311 SetString(pszAddress);
0312 }
0313
0314 uint160 GetHash160() const
0315 {
0316 assert(vchData.size() == 20);
0317 uint160 hash160;
0318 memcpy(&hash160, &vchData[0], 20);
0319 return hash160;
0320 }
0321 };
0322
0323 #endif