diff --git a/bitcoin.pro b/bitcoin.pro
index b34f562fd..88b92bc6c 100644
--- a/bitcoin.pro
+++ b/bitcoin.pro
@@ -1,39 +1,40 @@
-######################################################################
-# Automatically generated by qmake (2.01a) Sat May 7 20:45:42 2011
-######################################################################
-
TEMPLATE = app
-TARGET =
+TARGET =
DEPENDPATH += .
-INCLUDEPATH += .
+INCLUDEPATH += gui/include lib/include
# Input
-HEADERS += bitcoingui.h \
- transactiontablemodel.h \
- addresstablemodel.h \
- optionsdialog.h \
- mainoptionspage.h \
- sendcoinsdialog.h \
- addressbookdialog.h \
- aboutdialog.h \
- editaddressdialog.h \
- bitcoinaddressvalidator.h
-SOURCES += bitcoin.cpp bitcoingui.cpp \
- transactiontablemodel.cpp \
- addresstablemodel.cpp \
- optionsdialog.cpp \
- mainoptionspage.cpp \
- sendcoinsdialog.cpp \
- addressbookdialog.cpp \
- aboutdialog.cpp \
- editaddressdialog.cpp \
- bitcoinaddressvalidator.cpp
+HEADERS += gui/include/bitcoingui.h \
+ gui/include/transactiontablemodel.h \
+ gui/include/addresstablemodel.h \
+ gui/include/optionsdialog.h \
+ gui/include/mainoptionspage.h \
+ gui/include/sendcoinsdialog.h \
+ gui/include/addressbookdialog.h \
+ gui/include/aboutdialog.h \
+ gui/include/editaddressdialog.h \
+ gui/include/bitcoinaddressvalidator.h \
+ lib/include/base58.h \
+ lib/include/bignum.h \
+ lib/include/util.h \
+ lib/include/uint256.h \
+ lib/include/serialize.h
+SOURCES += gui/src/bitcoin.cpp gui/src/bitcoingui.cpp \
+ gui/src/transactiontablemodel.cpp \
+ gui/src/addresstablemodel.cpp \
+ gui/src/optionsdialog.cpp \
+ gui/src/mainoptionspage.cpp \
+ gui/src/sendcoinsdialog.cpp \
+ gui/src/addressbookdialog.cpp \
+ gui/src/aboutdialog.cpp \
+ gui/src/editaddressdialog.cpp \
+ gui/src/bitcoinaddressvalidator.cpp
RESOURCES += \
- bitcoin.qrc
+ gui/bitcoin.qrc
FORMS += \
- sendcoinsdialog.ui \
- addressbookdialog.ui \
- aboutdialog.ui \
- editaddressdialog.ui
+ gui/forms/sendcoinsdialog.ui \
+ gui/forms/addressbookdialog.ui \
+ gui/forms/aboutdialog.ui \
+ gui/forms/editaddressdialog.ui
diff --git a/bitcoin.qrc b/gui/bitcoin.qrc
similarity index 100%
rename from bitcoin.qrc
rename to gui/bitcoin.qrc
diff --git a/aboutdialog.ui b/gui/forms/aboutdialog.ui
similarity index 97%
rename from aboutdialog.ui
rename to gui/forms/aboutdialog.ui
index 17a15dd07..88668d4da 100644
--- a/aboutdialog.ui
+++ b/gui/forms/aboutdialog.ui
@@ -26,7 +26,7 @@
- :/images/about
+ :/images/about
@@ -123,7 +123,7 @@ This product includes software developed by the OpenSSL Project for use in the O
-
+
diff --git a/addressbookdialog.ui b/gui/forms/addressbookdialog.ui
similarity index 100%
rename from addressbookdialog.ui
rename to gui/forms/addressbookdialog.ui
diff --git a/editaddressdialog.ui b/gui/forms/editaddressdialog.ui
similarity index 100%
rename from editaddressdialog.ui
rename to gui/forms/editaddressdialog.ui
diff --git a/sendcoinsdialog.ui b/gui/forms/sendcoinsdialog.ui
similarity index 98%
rename from sendcoinsdialog.ui
rename to gui/forms/sendcoinsdialog.ui
index f14ec2af1..31a0b99e2 100644
--- a/sendcoinsdialog.ui
+++ b/gui/forms/sendcoinsdialog.ui
@@ -121,7 +121,7 @@
&Send
-
+
:/icons/send:/icons/send
@@ -144,7 +144,7 @@
-
+
diff --git a/aboutdialog.h b/gui/include/aboutdialog.h
similarity index 100%
rename from aboutdialog.h
rename to gui/include/aboutdialog.h
diff --git a/addressbookdialog.h b/gui/include/addressbookdialog.h
similarity index 100%
rename from addressbookdialog.h
rename to gui/include/addressbookdialog.h
diff --git a/addresstablemodel.h b/gui/include/addresstablemodel.h
similarity index 100%
rename from addresstablemodel.h
rename to gui/include/addresstablemodel.h
diff --git a/bitcoinaddressvalidator.h b/gui/include/bitcoinaddressvalidator.h
similarity index 94%
rename from bitcoinaddressvalidator.h
rename to gui/include/bitcoinaddressvalidator.h
index f6a2ac02b..8b57a2471 100644
--- a/bitcoinaddressvalidator.h
+++ b/gui/include/bitcoinaddressvalidator.h
@@ -3,6 +3,8 @@
#include
+#include
+
class BitcoinAddressValidator : public QRegExpValidator
{
Q_OBJECT
diff --git a/bitcoingui.h b/gui/include/bitcoingui.h
similarity index 100%
rename from bitcoingui.h
rename to gui/include/bitcoingui.h
diff --git a/editaddressdialog.h b/gui/include/editaddressdialog.h
similarity index 100%
rename from editaddressdialog.h
rename to gui/include/editaddressdialog.h
diff --git a/mainoptionspage.h b/gui/include/mainoptionspage.h
similarity index 100%
rename from mainoptionspage.h
rename to gui/include/mainoptionspage.h
diff --git a/optionsdialog.h b/gui/include/optionsdialog.h
similarity index 100%
rename from optionsdialog.h
rename to gui/include/optionsdialog.h
diff --git a/sendcoinsdialog.h b/gui/include/sendcoinsdialog.h
similarity index 100%
rename from sendcoinsdialog.h
rename to gui/include/sendcoinsdialog.h
diff --git a/transactiontablemodel.h b/gui/include/transactiontablemodel.h
similarity index 100%
rename from transactiontablemodel.h
rename to gui/include/transactiontablemodel.h
diff --git a/res/icons/address-book.png b/gui/res/icons/address-book.png
similarity index 100%
rename from res/icons/address-book.png
rename to gui/res/icons/address-book.png
diff --git a/res/icons/bitcoin.png b/gui/res/icons/bitcoin.png
similarity index 100%
rename from res/icons/bitcoin.png
rename to gui/res/icons/bitcoin.png
diff --git a/res/icons/quit.png b/gui/res/icons/quit.png
similarity index 100%
rename from res/icons/quit.png
rename to gui/res/icons/quit.png
diff --git a/res/icons/send.png b/gui/res/icons/send.png
similarity index 100%
rename from res/icons/send.png
rename to gui/res/icons/send.png
diff --git a/res/icons/toolbar.png b/gui/res/icons/toolbar.png
similarity index 100%
rename from res/icons/toolbar.png
rename to gui/res/icons/toolbar.png
diff --git a/res/images/about.png b/gui/res/images/about.png
similarity index 100%
rename from res/images/about.png
rename to gui/res/images/about.png
diff --git a/aboutdialog.cpp b/gui/src/aboutdialog.cpp
similarity index 100%
rename from aboutdialog.cpp
rename to gui/src/aboutdialog.cpp
diff --git a/addressbookdialog.cpp b/gui/src/addressbookdialog.cpp
similarity index 100%
rename from addressbookdialog.cpp
rename to gui/src/addressbookdialog.cpp
diff --git a/addresstablemodel.cpp b/gui/src/addresstablemodel.cpp
similarity index 100%
rename from addresstablemodel.cpp
rename to gui/src/addresstablemodel.cpp
diff --git a/bitcoin.cpp b/gui/src/bitcoin.cpp
similarity index 100%
rename from bitcoin.cpp
rename to gui/src/bitcoin.cpp
diff --git a/bitcoinaddressvalidator.cpp b/gui/src/bitcoinaddressvalidator.cpp
similarity index 100%
rename from bitcoinaddressvalidator.cpp
rename to gui/src/bitcoinaddressvalidator.cpp
diff --git a/bitcoingui.cpp b/gui/src/bitcoingui.cpp
similarity index 100%
rename from bitcoingui.cpp
rename to gui/src/bitcoingui.cpp
diff --git a/editaddressdialog.cpp b/gui/src/editaddressdialog.cpp
similarity index 100%
rename from editaddressdialog.cpp
rename to gui/src/editaddressdialog.cpp
diff --git a/mainoptionspage.cpp b/gui/src/mainoptionspage.cpp
similarity index 100%
rename from mainoptionspage.cpp
rename to gui/src/mainoptionspage.cpp
diff --git a/optionsdialog.cpp b/gui/src/optionsdialog.cpp
similarity index 100%
rename from optionsdialog.cpp
rename to gui/src/optionsdialog.cpp
diff --git a/sendcoinsdialog.cpp b/gui/src/sendcoinsdialog.cpp
similarity index 100%
rename from sendcoinsdialog.cpp
rename to gui/src/sendcoinsdialog.cpp
diff --git a/transactiontablemodel.cpp b/gui/src/transactiontablemodel.cpp
similarity index 100%
rename from transactiontablemodel.cpp
rename to gui/src/transactiontablemodel.cpp
diff --git a/lib/include/base58.h b/lib/include/base58.h
new file mode 100644
index 000000000..7acdf63ae
--- /dev/null
+++ b/lib/include/base58.h
@@ -0,0 +1,208 @@
+// 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 std::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.
+//
+#ifndef BITCOIN_BASE58_H
+#define BITCOIN_BASE58_H
+
+#include
+#include
+#include "bignum.h"
+
+static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
+
+
+inline std::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
+ std::vector 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 std::string
+ std::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 std::string to big endian
+ reverse(str.begin(), str.end());
+ return str;
+}
+
+inline std::string EncodeBase58(const std::vector& vch)
+{
+ return EncodeBase58(&vch[0], &vch[0] + vch.size());
+}
+
+inline bool DecodeBase58(const char* psz, std::vector& vchRet)
+{
+ CAutoBN_CTX pctx;
+ vchRet.clear();
+ CBigNum bn58 = 58;
+ CBigNum bn = 0;
+ CBigNum bnChar;
+ while (isspace(*psz))
+ psz++;
+
+ // Convert big endian std::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
+ std::vector 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 std::string& str, std::vector& vchRet)
+{
+ return DecodeBase58(str.c_str(), vchRet);
+}
+
+
+
+
+
+inline std::string EncodeBase58Check(const std::vector& vchIn)
+{
+ // add 4-byte hash check to the end
+ std::vector 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, std::vector& 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 std::string& str, std::vector& vchRet)
+{
+ return DecodeBase58Check(str.c_str(), vchRet);
+}
+
+
+
+
+
+
+#define ADDRESSVERSION ((unsigned char)(fTestNet ? 111 : 0))
+
+inline std::string Hash160ToAddress(uint160 hash160)
+{
+ // add 1-byte version number to the front
+ std::vector vch(1, ADDRESSVERSION);
+ vch.insert(vch.end(), UBEGIN(hash160), UEND(hash160));
+ return EncodeBase58Check(vch);
+}
+
+inline bool AddressToHash160(const char* psz, uint160& hash160Ret)
+{
+ std::vector 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 std::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 std::string& str)
+{
+ return IsValidBitcoinAddress(str.c_str());
+}
+
+
+
+
+inline std::string PubKeyToAddress(const std::vector& vchPubKey)
+{
+ return Hash160ToAddress(Hash160(vchPubKey));
+}
+
+#endif
diff --git a/lib/include/bignum.h b/lib/include/bignum.h
new file mode 100644
index 000000000..e35353296
--- /dev/null
+++ b/lib/include/bignum.h
@@ -0,0 +1,537 @@
+// 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.
+#ifndef BITCOIN_BIGNUM_H
+#define BITCOIN_BIGNUM_H
+
+#include
+#include
+#include
+#include
+
+
+
+
+
+class bignum_error : public std::runtime_error
+{
+public:
+ explicit bignum_error(const std::string& str) : std::runtime_error(str) {}
+};
+
+
+
+class CAutoBN_CTX
+{
+protected:
+ BN_CTX* pctx;
+ BN_CTX* operator=(BN_CTX* pnew) { return pctx = pnew; }
+
+public:
+ CAutoBN_CTX()
+ {
+ pctx = BN_CTX_new();
+ if (pctx == NULL)
+ throw bignum_error("CAutoBN_CTX : BN_CTX_new() returned NULL");
+ }
+
+ ~CAutoBN_CTX()
+ {
+ if (pctx != NULL)
+ BN_CTX_free(pctx);
+ }
+
+ operator BN_CTX*() { return pctx; }
+ BN_CTX& operator*() { return *pctx; }
+ BN_CTX** operator&() { return &pctx; }
+ bool operator!() { return (pctx == NULL); }
+};
+
+
+
+class CBigNum : public BIGNUM
+{
+public:
+ CBigNum()
+ {
+ BN_init(this);
+ }
+
+ CBigNum(const CBigNum& b)
+ {
+ BN_init(this);
+ if (!BN_copy(this, &b))
+ {
+ BN_clear_free(this);
+ throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed");
+ }
+ }
+
+ CBigNum& operator=(const CBigNum& b)
+ {
+ if (!BN_copy(this, &b))
+ throw bignum_error("CBigNum::operator= : BN_copy failed");
+ return (*this);
+ }
+
+ ~CBigNum()
+ {
+ BN_clear_free(this);
+ }
+
+ CBigNum(char n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
+ CBigNum(short n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
+ CBigNum(int n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
+ CBigNum(long n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
+ CBigNum(int64 n) { BN_init(this); setint64(n); }
+ CBigNum(unsigned char n) { BN_init(this); setulong(n); }
+ CBigNum(unsigned short n) { BN_init(this); setulong(n); }
+ CBigNum(unsigned int n) { BN_init(this); setulong(n); }
+ CBigNum(unsigned long n) { BN_init(this); setulong(n); }
+ CBigNum(uint64 n) { BN_init(this); setuint64(n); }
+ explicit CBigNum(uint256 n) { BN_init(this); setuint256(n); }
+
+ explicit CBigNum(const std::vector& vch)
+ {
+ BN_init(this);
+ setvch(vch);
+ }
+
+ void setulong(unsigned long n)
+ {
+ if (!BN_set_word(this, n))
+ throw bignum_error("CBigNum conversion from unsigned long : BN_set_word failed");
+ }
+
+ unsigned long getulong() const
+ {
+ return BN_get_word(this);
+ }
+
+ unsigned int getuint() const
+ {
+ return BN_get_word(this);
+ }
+
+ int getint() const
+ {
+ unsigned long n = BN_get_word(this);
+ if (!BN_is_negative(this))
+ return (n > INT_MAX ? INT_MAX : n);
+ else
+ return (n > INT_MAX ? INT_MIN : -(int)n);
+ }
+
+ void setint64(int64 n)
+ {
+ unsigned char pch[sizeof(n) + 6];
+ unsigned char* p = pch + 4;
+ bool fNegative = false;
+ if (n < (int64)0)
+ {
+ n = -n;
+ fNegative = true;
+ }
+ bool fLeadingZeroes = true;
+ for (int i = 0; i < 8; i++)
+ {
+ unsigned char c = (n >> 56) & 0xff;
+ n <<= 8;
+ if (fLeadingZeroes)
+ {
+ if (c == 0)
+ continue;
+ if (c & 0x80)
+ *p++ = (fNegative ? 0x80 : 0);
+ else if (fNegative)
+ c |= 0x80;
+ fLeadingZeroes = false;
+ }
+ *p++ = c;
+ }
+ unsigned int nSize = p - (pch + 4);
+ pch[0] = (nSize >> 24) & 0xff;
+ pch[1] = (nSize >> 16) & 0xff;
+ pch[2] = (nSize >> 8) & 0xff;
+ pch[3] = (nSize) & 0xff;
+ BN_mpi2bn(pch, p - pch, this);
+ }
+
+ void setuint64(uint64 n)
+ {
+ unsigned char pch[sizeof(n) + 6];
+ unsigned char* p = pch + 4;
+ bool fLeadingZeroes = true;
+ for (int i = 0; i < 8; i++)
+ {
+ unsigned char c = (n >> 56) & 0xff;
+ n <<= 8;
+ if (fLeadingZeroes)
+ {
+ if (c == 0)
+ continue;
+ if (c & 0x80)
+ *p++ = 0;
+ fLeadingZeroes = false;
+ }
+ *p++ = c;
+ }
+ unsigned int nSize = p - (pch + 4);
+ pch[0] = (nSize >> 24) & 0xff;
+ pch[1] = (nSize >> 16) & 0xff;
+ pch[2] = (nSize >> 8) & 0xff;
+ pch[3] = (nSize) & 0xff;
+ BN_mpi2bn(pch, p - pch, this);
+ }
+
+ void setuint256(uint256 n)
+ {
+ unsigned char pch[sizeof(n) + 6];
+ unsigned char* p = pch + 4;
+ bool fLeadingZeroes = true;
+ unsigned char* pbegin = (unsigned char*)&n;
+ unsigned char* psrc = pbegin + sizeof(n);
+ while (psrc != pbegin)
+ {
+ unsigned char c = *(--psrc);
+ if (fLeadingZeroes)
+ {
+ if (c == 0)
+ continue;
+ if (c & 0x80)
+ *p++ = 0;
+ fLeadingZeroes = false;
+ }
+ *p++ = c;
+ }
+ unsigned int nSize = p - (pch + 4);
+ pch[0] = (nSize >> 24) & 0xff;
+ pch[1] = (nSize >> 16) & 0xff;
+ pch[2] = (nSize >> 8) & 0xff;
+ pch[3] = (nSize >> 0) & 0xff;
+ BN_mpi2bn(pch, p - pch, this);
+ }
+
+ uint256 getuint256()
+ {
+ unsigned int nSize = BN_bn2mpi(this, NULL);
+ if (nSize < 4)
+ return 0;
+ std::vector vch(nSize);
+ BN_bn2mpi(this, &vch[0]);
+ if (vch.size() > 4)
+ vch[4] &= 0x7f;
+ uint256 n = 0;
+ for (int i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--)
+ ((unsigned char*)&n)[i] = vch[j];
+ return n;
+ }
+
+ void setvch(const std::vector& vch)
+ {
+ std::vector vch2(vch.size() + 4);
+ unsigned int nSize = vch.size();
+ vch2[0] = (nSize >> 24) & 0xff;
+ vch2[1] = (nSize >> 16) & 0xff;
+ vch2[2] = (nSize >> 8) & 0xff;
+ vch2[3] = (nSize >> 0) & 0xff;
+ reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4);
+ BN_mpi2bn(&vch2[0], vch2.size(), this);
+ }
+
+ std::vector getvch() const
+ {
+ unsigned int nSize = BN_bn2mpi(this, NULL);
+ if (nSize < 4)
+ return std::vector();
+ std::vector vch(nSize);
+ BN_bn2mpi(this, &vch[0]);
+ vch.erase(vch.begin(), vch.begin() + 4);
+ reverse(vch.begin(), vch.end());
+ return vch;
+ }
+
+ CBigNum& SetCompact(unsigned int nCompact)
+ {
+ unsigned int nSize = nCompact >> 24;
+ std::vector vch(4 + nSize);
+ vch[3] = nSize;
+ if (nSize >= 1) vch[4] = (nCompact >> 16) & 0xff;
+ if (nSize >= 2) vch[5] = (nCompact >> 8) & 0xff;
+ if (nSize >= 3) vch[6] = (nCompact >> 0) & 0xff;
+ BN_mpi2bn(&vch[0], vch.size(), this);
+ return *this;
+ }
+
+ unsigned int GetCompact() const
+ {
+ unsigned int nSize = BN_bn2mpi(this, NULL);
+ std::vector vch(nSize);
+ nSize -= 4;
+ BN_bn2mpi(this, &vch[0]);
+ unsigned int nCompact = nSize << 24;
+ if (nSize >= 1) nCompact |= (vch[4] << 16);
+ if (nSize >= 2) nCompact |= (vch[5] << 8);
+ if (nSize >= 3) nCompact |= (vch[6] << 0);
+ return nCompact;
+ }
+
+ void SetHex(const std::string& str)
+ {
+ // skip 0x
+ const char* psz = str.c_str();
+ while (isspace(*psz))
+ psz++;
+ bool fNegative = false;
+ if (*psz == '-')
+ {
+ fNegative = true;
+ psz++;
+ }
+ if (psz[0] == '0' && tolower(psz[1]) == 'x')
+ psz += 2;
+ while (isspace(*psz))
+ psz++;
+
+ // hex string to bignum
+ static char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 };
+ *this = 0;
+ while (isxdigit(*psz))
+ {
+ *this <<= 4;
+ int n = phexdigit[*psz++];
+ *this += n;
+ }
+ if (fNegative)
+ *this = 0 - *this;
+ }
+
+ std::string ToString(int nBase=10) const
+ {
+ CAutoBN_CTX pctx;
+ CBigNum bnBase = nBase;
+ CBigNum bn0 = 0;
+ string str;
+ CBigNum bn = *this;
+ BN_set_negative(&bn, false);
+ CBigNum dv;
+ CBigNum rem;
+ if (BN_cmp(&bn, &bn0) == 0)
+ return "0";
+ while (BN_cmp(&bn, &bn0) > 0)
+ {
+ if (!BN_div(&dv, &rem, &bn, &bnBase, pctx))
+ throw bignum_error("CBigNum::ToString() : BN_div failed");
+ bn = dv;
+ unsigned int c = rem.getulong();
+ str += "0123456789abcdef"[c];
+ }
+ if (BN_is_negative(this))
+ str += "-";
+ reverse(str.begin(), str.end());
+ return str;
+ }
+
+ std::string GetHex() const
+ {
+ return ToString(16);
+ }
+
+ unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const
+ {
+ return ::GetSerializeSize(getvch(), nType, nVersion);
+ }
+
+ template
+ void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const
+ {
+ ::Serialize(s, getvch(), nType, nVersion);
+ }
+
+ template
+ void Unserialize(Stream& s, int nType=0, int nVersion=VERSION)
+ {
+ vector vch;
+ ::Unserialize(s, vch, nType, nVersion);
+ setvch(vch);
+ }
+
+
+ bool operator!() const
+ {
+ return BN_is_zero(this);
+ }
+
+ CBigNum& operator+=(const CBigNum& b)
+ {
+ if (!BN_add(this, this, &b))
+ throw bignum_error("CBigNum::operator+= : BN_add failed");
+ return *this;
+ }
+
+ CBigNum& operator-=(const CBigNum& b)
+ {
+ *this = *this - b;
+ return *this;
+ }
+
+ CBigNum& operator*=(const CBigNum& b)
+ {
+ CAutoBN_CTX pctx;
+ if (!BN_mul(this, this, &b, pctx))
+ throw bignum_error("CBigNum::operator*= : BN_mul failed");
+ return *this;
+ }
+
+ CBigNum& operator/=(const CBigNum& b)
+ {
+ *this = *this / b;
+ return *this;
+ }
+
+ CBigNum& operator%=(const CBigNum& b)
+ {
+ *this = *this % b;
+ return *this;
+ }
+
+ CBigNum& operator<<=(unsigned int shift)
+ {
+ if (!BN_lshift(this, this, shift))
+ throw bignum_error("CBigNum:operator<<= : BN_lshift failed");
+ return *this;
+ }
+
+ CBigNum& operator>>=(unsigned int shift)
+ {
+ // Note: BN_rshift segfaults on 64-bit if 2^shift is greater than the number
+ // if built on ubuntu 9.04 or 9.10, probably depends on version of openssl
+ CBigNum a = 1;
+ a <<= shift;
+ if (BN_cmp(&a, this) > 0)
+ {
+ *this = 0;
+ return *this;
+ }
+
+ if (!BN_rshift(this, this, shift))
+ throw bignum_error("CBigNum:operator>>= : BN_rshift failed");
+ return *this;
+ }
+
+
+ CBigNum& operator++()
+ {
+ // prefix operator
+ if (!BN_add(this, this, BN_value_one()))
+ throw bignum_error("CBigNum::operator++ : BN_add failed");
+ return *this;
+ }
+
+ const CBigNum operator++(int)
+ {
+ // postfix operator
+ const CBigNum ret = *this;
+ ++(*this);
+ return ret;
+ }
+
+ CBigNum& operator--()
+ {
+ // prefix operator
+ CBigNum r;
+ if (!BN_sub(&r, this, BN_value_one()))
+ throw bignum_error("CBigNum::operator-- : BN_sub failed");
+ *this = r;
+ return *this;
+ }
+
+ const CBigNum operator--(int)
+ {
+ // postfix operator
+ const CBigNum ret = *this;
+ --(*this);
+ return ret;
+ }
+
+
+ friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b);
+ friend inline const CBigNum operator/(const CBigNum& a, const CBigNum& b);
+ friend inline const CBigNum operator%(const CBigNum& a, const CBigNum& b);
+};
+
+
+
+inline const CBigNum operator+(const CBigNum& a, const CBigNum& b)
+{
+ CBigNum r;
+ if (!BN_add(&r, &a, &b))
+ throw bignum_error("CBigNum::operator+ : BN_add failed");
+ return r;
+}
+
+inline const CBigNum operator-(const CBigNum& a, const CBigNum& b)
+{
+ CBigNum r;
+ if (!BN_sub(&r, &a, &b))
+ throw bignum_error("CBigNum::operator- : BN_sub failed");
+ return r;
+}
+
+inline const CBigNum operator-(const CBigNum& a)
+{
+ CBigNum r(a);
+ BN_set_negative(&r, !BN_is_negative(&r));
+ return r;
+}
+
+inline const CBigNum operator*(const CBigNum& a, const CBigNum& b)
+{
+ CAutoBN_CTX pctx;
+ CBigNum r;
+ if (!BN_mul(&r, &a, &b, pctx))
+ throw bignum_error("CBigNum::operator* : BN_mul failed");
+ return r;
+}
+
+inline const CBigNum operator/(const CBigNum& a, const CBigNum& b)
+{
+ CAutoBN_CTX pctx;
+ CBigNum r;
+ if (!BN_div(&r, NULL, &a, &b, pctx))
+ throw bignum_error("CBigNum::operator/ : BN_div failed");
+ return r;
+}
+
+inline const CBigNum operator%(const CBigNum& a, const CBigNum& b)
+{
+ CAutoBN_CTX pctx;
+ CBigNum r;
+ if (!BN_mod(&r, &a, &b, pctx))
+ throw bignum_error("CBigNum::operator% : BN_div failed");
+ return r;
+}
+
+inline const CBigNum operator<<(const CBigNum& a, unsigned int shift)
+{
+ CBigNum r;
+ if (!BN_lshift(&r, &a, shift))
+ throw bignum_error("CBigNum:operator<< : BN_lshift failed");
+ return r;
+}
+
+inline const CBigNum operator>>(const CBigNum& a, unsigned int shift)
+{
+ CBigNum r = a;
+ r >>= shift;
+ return r;
+}
+
+inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) == 0); }
+inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) != 0); }
+inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) <= 0); }
+inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) >= 0); }
+inline bool operator<(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) < 0); }
+inline bool operator>(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) > 0); }
+
+#endif
diff --git a/lib/include/serialize.h b/lib/include/serialize.h
new file mode 100644
index 000000000..f810b339c
--- /dev/null
+++ b/lib/include/serialize.h
@@ -0,0 +1,1268 @@
+// 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.
+#ifndef BITCOIN_SERIALIZE_H
+#define BITCOIN_SERIALIZE_H
+
+#include
+#include
+#include