Better wording for transaction fee notification messages
[novacoin.git] / base58.h
index 98b8087..828f8d5 100644 (file)
--- a/base58.h
+++ b/base58.h
-// Copyright (c) 2009-2010 Satoshi Nakamoto\r
-// Distributed under the MIT/X11 software license, see the accompanying\r
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.\r
-\r
-\r
-//\r
-// Why base-58 instead of standard base-64 encoding?\r
-// - Don't want 0OIl characters that look the same in some fonts and\r
-//      could be used to create visually identical looking account numbers.\r
-// - A string with non-alphanumeric characters is not as easily accepted as an account number.\r
-// - E-mail usually won't line-break if there's no punctuation to break at.\r
-// - Doubleclicking selects the whole number as one word if it's all alphanumeric.\r
-//\r
-\r
-\r
-static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";\r
-\r
-\r
-inline string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)\r
-{\r
-    CAutoBN_CTX pctx;\r
-    CBigNum bn58 = 58;\r
-    CBigNum bn0 = 0;\r
-\r
-    // Convert big endian data to little endian\r
-    // Extra zero at the end make sure bignum will interpret as a positive number\r
-    vector<unsigned char> vchTmp(pend-pbegin+1, 0);\r
-    reverse_copy(pbegin, pend, vchTmp.begin());\r
-\r
-    // Convert little endian data to bignum\r
-    CBigNum bn;\r
-    bn.setvch(vchTmp);\r
-\r
-    // Convert bignum to string\r
-    string str;\r
-    str.reserve((pend - pbegin) * 138 / 100 + 1);\r
-    CBigNum dv;\r
-    CBigNum rem;\r
-    while (bn > bn0)\r
-    {\r
-        if (!BN_div(&dv, &rem, &bn, &bn58, pctx))\r
-            throw bignum_error("EncodeBase58 : BN_div failed");\r
-        bn = dv;\r
-        unsigned int c = rem.getulong();\r
-        str += pszBase58[c];\r
-    }\r
-\r
-    // Leading zeroes encoded as base58 zeros\r
-    for (const unsigned char* p = pbegin; p < pend && *p == 0; p++)\r
-        str += pszBase58[0];\r
-\r
-    // Convert little endian string to big endian\r
-    reverse(str.begin(), str.end());\r
-    return str;\r
-}\r
-\r
-inline string EncodeBase58(const vector<unsigned char>& vch)\r
-{\r
-    return EncodeBase58(&vch[0], &vch[0] + vch.size());\r
-}\r
-\r
-inline bool DecodeBase58(const char* psz, vector<unsigned char>& vchRet)\r
-{\r
-    CAutoBN_CTX pctx;\r
-    vchRet.clear();\r
-    CBigNum bn58 = 58;\r
-    CBigNum bn = 0;\r
-    CBigNum bnChar;\r
-    while (isspace(*psz))\r
-        psz++;\r
-\r
-    // Convert big endian string to bignum\r
-    for (const char* p = psz; *p; p++)\r
-    {\r
-        const char* p1 = strchr(pszBase58, *p);\r
-        if (p1 == NULL)\r
-        {\r
-            while (isspace(*p))\r
-                p++;\r
-            if (*p != '\0')\r
-                return false;\r
-            break;\r
-        }\r
-        bnChar.setulong(p1 - pszBase58);\r
-        if (!BN_mul(&bn, &bn, &bn58, pctx))\r
-            throw bignum_error("DecodeBase58 : BN_mul failed");\r
-        bn += bnChar;\r
-    }\r
-\r
-    // Get bignum as little endian data\r
-    vector<unsigned char> vchTmp = bn.getvch();\r
-\r
-    // Trim off sign byte if present\r
-    if (vchTmp.size() >= 2 && vchTmp.end()[-1] == 0 && vchTmp.end()[-2] >= 0x80)\r
-        vchTmp.erase(vchTmp.end()-1);\r
-\r
-    // Restore leading zeros\r
-    int nLeadingZeros = 0;\r
-    for (const char* p = psz; *p == pszBase58[0]; p++)\r
-        nLeadingZeros++;\r
-    vchRet.assign(nLeadingZeros + vchTmp.size(), 0);\r
-\r
-    // Convert little endian data to big endian\r
-    reverse_copy(vchTmp.begin(), vchTmp.end(), vchRet.end() - vchTmp.size());\r
-    return true;\r
-}\r
-\r
-inline bool DecodeBase58(const string& str, vector<unsigned char>& vchRet)\r
-{\r
-    return DecodeBase58(str.c_str(), vchRet);\r
-}\r
-\r
-\r
-\r
-\r
-\r
-inline string EncodeBase58Check(const vector<unsigned char>& vchIn)\r
-{\r
-    // add 4-byte hash check to the end\r
-    vector<unsigned char> vch(vchIn);\r
-    uint256 hash = Hash(vch.begin(), vch.end());\r
-    vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4);\r
-    return EncodeBase58(vch);\r
-}\r
-\r
-inline bool DecodeBase58Check(const char* psz, vector<unsigned char>& vchRet)\r
-{\r
-    if (!DecodeBase58(psz, vchRet))\r
-        return false;\r
-    if (vchRet.size() < 4)\r
-    {\r
-        vchRet.clear();\r
-        return false;\r
-    }\r
-    uint256 hash = Hash(vchRet.begin(), vchRet.end()-4);\r
-    if (memcmp(&hash, &vchRet.end()[-4], 4) != 0)\r
-    {\r
-        vchRet.clear();\r
-        return false;\r
-    }\r
-    vchRet.resize(vchRet.size()-4);\r
-    return true;\r
-}\r
-\r
-inline bool DecodeBase58Check(const string& str, vector<unsigned char>& vchRet)\r
-{\r
-    return DecodeBase58Check(str.c_str(), vchRet);\r
-}\r
-\r
-\r
-\r
-\r
-\r
-\r
-static const unsigned char ADDRESSVERSION = 0;\r
-\r
-inline string Hash160ToAddress(uint160 hash160)\r
-{\r
-    // add 1-byte version number to the front\r
-    vector<unsigned char> vch(1, ADDRESSVERSION);\r
-    vch.insert(vch.end(), UBEGIN(hash160), UEND(hash160));\r
-    return EncodeBase58Check(vch);\r
-}\r
-\r
-inline bool AddressToHash160(const char* psz, uint160& hash160Ret)\r
-{\r
-    vector<unsigned char> vch;\r
-    if (!DecodeBase58Check(psz, vch))\r
-        return false;\r
-    if (vch.empty())\r
-        return false;\r
-    unsigned char nVersion = vch[0];\r
-    if (vch.size() != sizeof(hash160Ret) + 1)\r
-        return false;\r
-    memcpy(&hash160Ret, &vch[1], sizeof(hash160Ret));\r
-    return (nVersion <= ADDRESSVERSION);\r
-}\r
-\r
-inline bool AddressToHash160(const string& str, uint160& hash160Ret)\r
-{\r
-    return AddressToHash160(str.c_str(), hash160Ret);\r
-}\r
-\r
-inline bool IsValidBitcoinAddress(const char* psz)\r
-{\r
-    uint160 hash160;\r
-    return AddressToHash160(psz, hash160);\r
-}\r
-\r
-inline bool IsValidBitcoinAddress(const string& str)\r
-{\r
-    return IsValidBitcoinAddress(str.c_str());\r
-}\r
-\r
-\r
-\r
-\r
-inline string PubKeyToAddress(const vector<unsigned char>& vchPubKey)\r
-{\r
-    return Hash160ToAddress(Hash160(vchPubKey));\r
-}\r
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Distributed under the MIT/X11 software license, see the accompanying
+// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+
+
+//
+// Why base-58 instead of standard base-64 encoding?
+// - Don't want 0OIl characters that look the same in some fonts and
+//      could be used to create visually identical looking account numbers.
+// - A string with non-alphanumeric characters is not as easily accepted as an account number.
+// - E-mail usually won't line-break if there's no punctuation to break at.
+// - Doubleclicking selects the whole number as one word if it's all alphanumeric.
+//
+
+
+static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
+
+
+inline string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
+{
+    CAutoBN_CTX pctx;
+    CBigNum bn58 = 58;
+    CBigNum bn0 = 0;
+
+    // Convert big endian data to little endian
+    // Extra zero at the end make sure bignum will interpret as a positive number
+    vector<unsigned char> vchTmp(pend-pbegin+1, 0);
+    reverse_copy(pbegin, pend, vchTmp.begin());
+
+    // Convert little endian data to bignum
+    CBigNum bn;
+    bn.setvch(vchTmp);
+
+    // Convert bignum to string
+    string str;
+    str.reserve((pend - pbegin) * 138 / 100 + 1);
+    CBigNum dv;
+    CBigNum rem;
+    while (bn > bn0)
+    {
+        if (!BN_div(&dv, &rem, &bn, &bn58, pctx))
+            throw bignum_error("EncodeBase58 : BN_div failed");
+        bn = dv;
+        unsigned int c = rem.getulong();
+        str += pszBase58[c];
+    }
+
+    // Leading zeroes encoded as base58 zeros
+    for (const unsigned char* p = pbegin; p < pend && *p == 0; p++)
+        str += pszBase58[0];
+
+    // Convert little endian string to big endian
+    reverse(str.begin(), str.end());
+    return str;
+}
+
+inline string EncodeBase58(const vector<unsigned char>& vch)
+{
+    return EncodeBase58(&vch[0], &vch[0] + vch.size());
+}
+
+inline bool DecodeBase58(const char* psz, vector<unsigned char>& vchRet)
+{
+    CAutoBN_CTX pctx;
+    vchRet.clear();
+    CBigNum bn58 = 58;
+    CBigNum bn = 0;
+    CBigNum bnChar;
+    while (isspace(*psz))
+        psz++;
+
+    // Convert big endian string to bignum
+    for (const char* p = psz; *p; p++)
+    {
+        const char* p1 = strchr(pszBase58, *p);
+        if (p1 == NULL)
+        {
+            while (isspace(*p))
+                p++;
+            if (*p != '\0')
+                return false;
+            break;
+        }
+        bnChar.setulong(p1 - pszBase58);
+        if (!BN_mul(&bn, &bn, &bn58, pctx))
+            throw bignum_error("DecodeBase58 : BN_mul failed");
+        bn += bnChar;
+    }
+
+    // Get bignum as little endian data
+    vector<unsigned char> vchTmp = bn.getvch();
+
+    // Trim off sign byte if present
+    if (vchTmp.size() >= 2 && vchTmp.end()[-1] == 0 && vchTmp.end()[-2] >= 0x80)
+        vchTmp.erase(vchTmp.end()-1);
+
+    // Restore leading zeros
+    int nLeadingZeros = 0;
+    for (const char* p = psz; *p == pszBase58[0]; p++)
+        nLeadingZeros++;
+    vchRet.assign(nLeadingZeros + vchTmp.size(), 0);
+
+    // Convert little endian data to big endian
+    reverse_copy(vchTmp.begin(), vchTmp.end(), vchRet.end() - vchTmp.size());
+    return true;
+}
+
+inline bool DecodeBase58(const string& str, vector<unsigned char>& vchRet)
+{
+    return DecodeBase58(str.c_str(), vchRet);
+}
+
+
+
+
+
+inline string EncodeBase58Check(const vector<unsigned char>& vchIn)
+{
+    // add 4-byte hash check to the end
+    vector<unsigned char> vch(vchIn);
+    uint256 hash = Hash(vch.begin(), vch.end());
+    vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4);
+    return EncodeBase58(vch);
+}
+
+inline bool DecodeBase58Check(const char* psz, vector<unsigned char>& vchRet)
+{
+    if (!DecodeBase58(psz, vchRet))
+        return false;
+    if (vchRet.size() < 4)
+    {
+        vchRet.clear();
+        return false;
+    }
+    uint256 hash = Hash(vchRet.begin(), vchRet.end()-4);
+    if (memcmp(&hash, &vchRet.end()[-4], 4) != 0)
+    {
+        vchRet.clear();
+        return false;
+    }
+    vchRet.resize(vchRet.size()-4);
+    return true;
+}
+
+inline bool DecodeBase58Check(const string& str, vector<unsigned char>& vchRet)
+{
+    return DecodeBase58Check(str.c_str(), vchRet);
+}
+
+
+
+
+
+
+#define ADDRESSVERSION   ((unsigned char)(fTestNet ? 111 : 0))
+
+inline string Hash160ToAddress(uint160 hash160)
+{
+    // add 1-byte version number to the front
+    vector<unsigned char> vch(1, ADDRESSVERSION);
+    vch.insert(vch.end(), UBEGIN(hash160), UEND(hash160));
+    return EncodeBase58Check(vch);
+}
+
+inline bool AddressToHash160(const char* psz, uint160& hash160Ret)
+{
+    vector<unsigned char> vch;
+    if (!DecodeBase58Check(psz, vch))
+        return false;
+    if (vch.empty())
+        return false;
+    unsigned char nVersion = vch[0];
+    if (vch.size() != sizeof(hash160Ret) + 1)
+        return false;
+    memcpy(&hash160Ret, &vch[1], sizeof(hash160Ret));
+    return (nVersion <= ADDRESSVERSION);
+}
+
+inline bool AddressToHash160(const string& str, uint160& hash160Ret)
+{
+    return AddressToHash160(str.c_str(), hash160Ret);
+}
+
+inline bool IsValidBitcoinAddress(const char* psz)
+{
+    uint160 hash160;
+    return AddressToHash160(psz, hash160);
+}
+
+inline bool IsValidBitcoinAddress(const string& str)
+{
+    return IsValidBitcoinAddress(str.c_str());
+}
+
+
+
+
+inline string PubKeyToAddress(const vector<unsigned char>& vchPubKey)
+{
+    return Hash160ToAddress(Hash160(vchPubKey));
+}