experimental-genesis 1
experimental-genesis 2
experimental-genesis 3
experimental-genesis 4
experimental-genesis 5
experimental-genesis 6
experimental-genesis 7
experimental-genesis 8
experimental-genesis 9
experimental-genesis 10
experimental-genesis 11
experimental-genesis 12
experimental-genesis 13
experimental-genesis 14
experimental-genesis 15
experimental-genesis 16
experimental-genesis 17
experimental-genesis 18
experimental-genesis 19
experimental-genesis 20
experimental-genesis 21
experimental-genesis 22
experimental-genesis 23
experimental-genesis 24
experimental-genesis 25
experimental-genesis 26
experimental-genesis 27
experimental-genesis 28
experimental-genesis 29
experimental-genesis 30
experimental-genesis 31
experimental-genesis 32
experimental-genesis 33
experimental-genesis 34
experimental-genesis 35
experimental-genesis 36
experimental-genesis 37
experimental-genesis 38
experimental-genesis 39
experimental-genesis 40
experimental-genesis 41
experimental-genesis 42
experimental-genesis 43
experimental-genesis 44
experimental-genesis 45
experimental-genesis 46 #ifndef BITCOIN_BASE58_H
experimental-genesis 47 #define BITCOIN_BASE58_H
experimental-genesis 48
experimental-genesis 49 #include <string>
experimental-genesis 50 #include <vector>
experimental-genesis 51 #include "bignum.h"
experimental-genesis 52
experimental-genesis 53 static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
experimental-genesis 54
experimental-genesis 55
experimental-genesis 56 inline std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
experimental-genesis 57 {
experimental-genesis 58 CAutoBN_CTX pctx;
experimental-genesis 59 CBigNum bn58 = 58;
experimental-genesis 60 CBigNum bn0 = 0;
experimental-genesis 61
experimental-genesis 62
experimental-genesis 63
experimental-genesis 64 std::vector<unsigned char> vchTmp(pend-pbegin+1, 0);
experimental-genesis 65 reverse_copy(pbegin, pend, vchTmp.begin());
experimental-genesis 66
experimental-genesis 67
experimental-genesis 68 CBigNum bn;
experimental-genesis 69 bn.setvch(vchTmp);
experimental-genesis 70
experimental-genesis 71
experimental-genesis 72 std::string str;
experimental-genesis 73
experimental-genesis 74
experimental-genesis 75 str.reserve((pend - pbegin) * 138 / 100 + 1);
experimental-genesis 76 CBigNum dv;
experimental-genesis 77 CBigNum rem;
experimental-genesis 78 while (bn > bn0)
experimental-genesis 79 {
experimental-genesis 80 if (!BN_div(&dv, &rem, &bn, &bn58, pctx))
experimental-genesis 81 throw bignum_error("EncodeBase58 : BN_div failed");
experimental-genesis 82 bn = dv;
experimental-genesis 83 unsigned int c = rem.getulong();
experimental-genesis 84 str += pszBase58[c];
experimental-genesis 85 }
experimental-genesis 86
experimental-genesis 87
experimental-genesis 88 for (const unsigned char* p = pbegin; p < pend && *p == 0; p++)
experimental-genesis 89 str += pszBase58[0];
experimental-genesis 90
experimental-genesis 91
experimental-genesis 92 reverse(str.begin(), str.end());
experimental-genesis 93 return str;
experimental-genesis 94 }
experimental-genesis 95
experimental-genesis 96
experimental-genesis 97 inline std::string EncodeBase58(const std::vector<unsigned char>& vch)
experimental-genesis 98 {
experimental-genesis 99 return EncodeBase58(&vch[0], &vch[0] + vch.size());
experimental-genesis 100 }
experimental-genesis 101
experimental-genesis 102
experimental-genesis 103
experimental-genesis 104 inline bool DecodeBase58(const char* psz, std::vector<unsigned char>& vchRet)
experimental-genesis 105 {
experimental-genesis 106 CAutoBN_CTX pctx;
experimental-genesis 107 vchRet.clear();
experimental-genesis 108 CBigNum bn58 = 58;
experimental-genesis 109 CBigNum bn = 0;
experimental-genesis 110 CBigNum bnChar;
experimental-genesis 111 while (isspace(*psz))
experimental-genesis 112 psz++;
experimental-genesis 113
experimental-genesis 114
experimental-genesis 115 for (const char* p = psz; *p; p++)
experimental-genesis 116 {
experimental-genesis 117 const char* p1 = strchr(pszBase58, *p);
experimental-genesis 118 if (p1 == NULL)
experimental-genesis 119 {
experimental-genesis 120 while (isspace(*p))
experimental-genesis 121 p++;
experimental-genesis 122 if (*p != '\0')
experimental-genesis 123 return false;
experimental-genesis 124 break;
experimental-genesis 125 }
experimental-genesis 126 bnChar.setulong(p1 - pszBase58);
experimental-genesis 127 if (!BN_mul(&bn, &bn, &bn58, pctx))
experimental-genesis 128 throw bignum_error("DecodeBase58 : BN_mul failed");
experimental-genesis 129 bn += bnChar;
experimental-genesis 130 }
experimental-genesis 131
experimental-genesis 132
experimental-genesis 133 std::vector<unsigned char> vchTmp = bn.getvch();
experimental-genesis 134
experimental-genesis 135
experimental-genesis 136 if (vchTmp.size() >= 2 && vchTmp.end()[-1] == 0 && vchTmp.end()[-2] >= 0x80)
experimental-genesis 137 vchTmp.erase(vchTmp.end()-1);
experimental-genesis 138
experimental-genesis 139
experimental-genesis 140 int nLeadingZeros = 0;
experimental-genesis 141 for (const char* p = psz; *p == pszBase58[0]; p++)
experimental-genesis 142 nLeadingZeros++;
experimental-genesis 143 vchRet.assign(nLeadingZeros + vchTmp.size(), 0);
experimental-genesis 144
experimental-genesis 145
experimental-genesis 146 reverse_copy(vchTmp.begin(), vchTmp.end(), vchRet.end() - vchTmp.size());
experimental-genesis 147 return true;
experimental-genesis 148 }
experimental-genesis 149
experimental-genesis 150
experimental-genesis 151
experimental-genesis 152 inline bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet)
experimental-genesis 153 {
experimental-genesis 154 return DecodeBase58(str.c_str(), vchRet);
experimental-genesis 155 }
experimental-genesis 156
experimental-genesis 157
experimental-genesis 158
experimental-genesis 159
experimental-genesis 160
experimental-genesis 161 inline std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn)
experimental-genesis 162 {
experimental-genesis 163
experimental-genesis 164 std::vector<unsigned char> vch(vchIn);
experimental-genesis 165 uint256 hash = Hash(vch.begin(), vch.end());
experimental-genesis 166 vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4);
experimental-genesis 167 return EncodeBase58(vch);
experimental-genesis 168 }
experimental-genesis 169
experimental-genesis 170
experimental-genesis 171
experimental-genesis 172 inline bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet)
experimental-genesis 173 {
experimental-genesis 174 if (!DecodeBase58(psz, vchRet))
experimental-genesis 175 return false;
experimental-genesis 176 if (vchRet.size() < 4)
experimental-genesis 177 {
experimental-genesis 178 vchRet.clear();
experimental-genesis 179 return false;
experimental-genesis 180 }
experimental-genesis 181 uint256 hash = Hash(vchRet.begin(), vchRet.end()-4);
experimental-genesis 182 if (memcmp(&hash, &vchRet.end()[-4], 4) != 0)
experimental-genesis 183 {
experimental-genesis 184 vchRet.clear();
experimental-genesis 185 return false;
experimental-genesis 186 }
experimental-genesis 187 vchRet.resize(vchRet.size()-4);
experimental-genesis 188 return true;
experimental-genesis 189 }
experimental-genesis 190
experimental-genesis 191
experimental-genesis 192
experimental-genesis 193 inline bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet)
experimental-genesis 194 {
experimental-genesis 195 return DecodeBase58Check(str.c_str(), vchRet);
experimental-genesis 196 }
experimental-genesis 197
experimental-genesis 198
experimental-genesis 199
experimental-genesis 200
experimental-genesis 201
experimental-genesis 202
experimental-genesis 203 class CBase58Data
experimental-genesis 204 {
experimental-genesis 205 protected:
experimental-genesis 206
experimental-genesis 207 unsigned char nVersion;
experimental-genesis 208
experimental-genesis 209
experimental-genesis 210 std::vector<unsigned char> vchData;
experimental-genesis 211
experimental-genesis 212 CBase58Data()
experimental-genesis 213 {
experimental-genesis 214 nVersion = 0;
experimental-genesis 215 vchData.clear();
experimental-genesis 216 }
experimental-genesis 217
experimental-genesis 218 ~CBase58Data()
experimental-genesis 219 {
experimental-genesis 220
experimental-genesis 221 if (!vchData.empty())
experimental-genesis 222 memset(&vchData[0], 0, vchData.size());
experimental-genesis 223 }
experimental-genesis 224
experimental-genesis 225 void SetData(int nVersionIn, const void* pdata, size_t nSize)
experimental-genesis 226 {
experimental-genesis 227 nVersion = nVersionIn;
experimental-genesis 228 vchData.resize(nSize);
experimental-genesis 229 if (!vchData.empty())
experimental-genesis 230 memcpy(&vchData[0], pdata, nSize);
experimental-genesis 231 }
experimental-genesis 232
experimental-genesis 233 void SetData(int nVersionIn, const unsigned char *pbegin, const unsigned char *pend)
experimental-genesis 234 {
experimental-genesis 235 SetData(nVersionIn, (void*)pbegin, pend - pbegin);
experimental-genesis 236 }
experimental-genesis 237
experimental-genesis 238 public:
experimental-genesis 239 bool SetString(const char* psz)
experimental-genesis 240 {
experimental-genesis 241 std::vector<unsigned char> vchTemp;
experimental-genesis 242 DecodeBase58Check(psz, vchTemp);
experimental-genesis 243 if (vchTemp.empty())
experimental-genesis 244 {
experimental-genesis 245 vchData.clear();
experimental-genesis 246 nVersion = 0;
experimental-genesis 247 return false;
experimental-genesis 248 }
experimental-genesis 249 nVersion = vchTemp[0];
experimental-genesis 250 vchData.resize(vchTemp.size() - 1);
experimental-genesis 251 if (!vchData.empty())
experimental-genesis 252 memcpy(&vchData[0], &vchTemp[1], vchData.size());
experimental-genesis 253 memset(&vchTemp[0], 0, vchTemp.size());
experimental-genesis 254 return true;
experimental-genesis 255 }
experimental-genesis 256
experimental-genesis 257 bool SetString(const std::string& str)
experimental-genesis 258 {
experimental-genesis 259 return SetString(str.c_str());
experimental-genesis 260 }
experimental-genesis 261
experimental-genesis 262 std::string ToString() const
experimental-genesis 263 {
experimental-genesis 264 std::vector<unsigned char> vch(1, nVersion);
experimental-genesis 265 vch.insert(vch.end(), vchData.begin(), vchData.end());
experimental-genesis 266 return EncodeBase58Check(vch);
experimental-genesis 267 }
experimental-genesis 268
experimental-genesis 269 int CompareTo(const CBase58Data& b58) const
experimental-genesis 270 {
experimental-genesis 271 if (nVersion < b58.nVersion) return -1;
experimental-genesis 272 if (nVersion > b58.nVersion) return 1;
experimental-genesis 273 if (vchData < b58.vchData) return -1;
experimental-genesis 274 if (vchData > b58.vchData) return 1;
experimental-genesis 275 return 0;
experimental-genesis 276 }
experimental-genesis 277
experimental-genesis 278 bool operator==(const CBase58Data& b58) const { return CompareTo(b58) == 0; }
experimental-genesis 279 bool operator<=(const CBase58Data& b58) const { return CompareTo(b58) <= 0; }
experimental-genesis 280 bool operator>=(const CBase58Data& b58) const { return CompareTo(b58) >= 0; }
experimental-genesis 281 bool operator< (const CBase58Data& b58) const { return CompareTo(b58) < 0; }
experimental-genesis 282 bool operator> (const CBase58Data& b58) const { return CompareTo(b58) > 0; }
experimental-genesis 283 };
experimental-genesis 284
experimental-genesis 285
experimental-genesis 286
experimental-genesis 287
experimental-genesis 288 class CBitcoinAddress : public CBase58Data
experimental-genesis 289 {
experimental-genesis 290 public:
experimental-genesis 291 bool SetHash160(const uint160& hash160)
experimental-genesis 292 {
experimental-genesis 293 SetData(fTestNet ? 111 : 0, &hash160, 20);
experimental-genesis 294 return true;
experimental-genesis 295 }
experimental-genesis 296
experimental-genesis 297 bool SetPubKey(const std::vector<unsigned char>& vchPubKey)
experimental-genesis 298 {
experimental-genesis 299 return SetHash160(Hash160(vchPubKey));
experimental-genesis 300 }
experimental-genesis 301
experimental-genesis 302 bool IsValid() const
experimental-genesis 303 {
experimental-genesis 304 int nExpectedSize = 20;
experimental-genesis 305 bool fExpectTestNet = false;
experimental-genesis 306 switch(nVersion)
experimental-genesis 307 {
experimental-genesis 308 case 0:
experimental-genesis 309 break;
experimental-genesis 310
experimental-genesis 311 case 111:
experimental-genesis 312 fExpectTestNet = true;
experimental-genesis 313 break;
experimental-genesis 314
experimental-genesis 315 default:
experimental-genesis 316 return false;
experimental-genesis 317 }
experimental-genesis 318 return fExpectTestNet == fTestNet && vchData.size() == nExpectedSize;
experimental-genesis 319 }
experimental-genesis 320
experimental-genesis 321 CBitcoinAddress()
experimental-genesis 322 {
experimental-genesis 323 }
experimental-genesis 324
experimental-genesis 325 CBitcoinAddress(uint160 hash160In)
experimental-genesis 326 {
experimental-genesis 327 SetHash160(hash160In);
experimental-genesis 328 }
experimental-genesis 329
experimental-genesis 330 CBitcoinAddress(const std::vector<unsigned char>& vchPubKey)
experimental-genesis 331 {
experimental-genesis 332 SetPubKey(vchPubKey);
experimental-genesis 333 }
experimental-genesis 334
experimental-genesis 335 CBitcoinAddress(const std::string& strAddress)
experimental-genesis 336 {
experimental-genesis 337 SetString(strAddress);
experimental-genesis 338 }
experimental-genesis 339
experimental-genesis 340 CBitcoinAddress(const char* pszAddress)
experimental-genesis 341 {
experimental-genesis 342 SetString(pszAddress);
experimental-genesis 343 }
experimental-genesis 344
experimental-genesis 345 uint160 GetHash160() const
experimental-genesis 346 {
experimental-genesis 347 assert(vchData.size() == 20);
experimental-genesis 348 uint160 hash160;
experimental-genesis 349 memcpy(&hash160, &vchData[0], 20);
experimental-genesis 350 return hash160;
experimental-genesis 351 }
experimental-genesis 352 };
experimental-genesis 353
experimental-genesis 354 #endif