First commit

This commit is contained in:
sirius-m 2009-08-30 03:46:39 +00:00
commit 4405b78d60
45 changed files with 32239 additions and 0 deletions

201
base58.h Normal file
View file

@ -0,0 +1,201 @@
// Copyright (c) 2009 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);
}
static const unsigned char ADDRESSVERSION = 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));
}

498
bignum.h Normal file
View file

@ -0,0 +1,498 @@
// Copyright (c) 2009 Satoshi Nakamoto
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#include <stdexcept>
#include <vector>
#include <openssl/bn.h>
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");
}
}
explicit CBigNum(const std::string& str)
{
BN_init(this);
SetHex(str);
}
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<unsigned char>& 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<unsigned char> 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<unsigned char>& vch)
{
std::vector<unsigned char> 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<unsigned char> getvch() const
{
unsigned int nSize = BN_bn2mpi(this, NULL);
if (nSize < 4)
return std::vector<unsigned char>();
std::vector<unsigned char> 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<unsigned char> 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<unsigned char> 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;
}
unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const
{
return ::GetSerializeSize(getvch(), nType, nVersion);
}
template<typename Stream>
void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const
{
::Serialize(s, getvch(), nType, nVersion);
}
template<typename Stream>
void Unserialize(Stream& s, int nType=0, int nVersion=VERSION)
{
vector<unsigned char> 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)
{
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;
if (!BN_rshift(&r, &a, shift))
throw bignum_error("CBigNum:operator>> : BN_rshift failed");
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); }

614
db.cpp Normal file
View file

@ -0,0 +1,614 @@
// Copyright (c) 2009 Satoshi Nakamoto
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#include "headers.h"
//
// CDB
//
static CCriticalSection cs_db;
static bool fDbEnvInit = false;
DbEnv dbenv(0);
static map<string, int> mapFileUseCount;
class CDBInit
{
public:
CDBInit()
{
}
~CDBInit()
{
if (fDbEnvInit)
{
dbenv.close(0);
fDbEnvInit = false;
}
}
}
instance_of_cdbinit;
CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL)
{
int ret;
if (pszFile == NULL)
return;
bool fCreate = strchr(pszMode, 'c');
bool fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
unsigned int nFlags = DB_THREAD;
if (fCreate)
nFlags |= DB_CREATE;
else if (fReadOnly)
nFlags |= DB_RDONLY;
if (!fReadOnly || fTxn)
nFlags |= DB_AUTO_COMMIT;
CRITICAL_BLOCK(cs_db)
{
if (!fDbEnvInit)
{
string strAppDir = GetAppDir();
string strLogDir = strAppDir + "\\database";
_mkdir(strLogDir.c_str());
printf("dbenv.open strAppDir=%s\n", strAppDir.c_str());
dbenv.set_lg_dir(strLogDir.c_str());
dbenv.set_lg_max(10000000);
dbenv.set_lk_max_locks(10000);
dbenv.set_lk_max_objects(10000);
dbenv.set_errfile(fopen("db.log", "a")); /// debug
///dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1); /// causes corruption
ret = dbenv.open(strAppDir.c_str(),
DB_CREATE |
DB_INIT_LOCK |
DB_INIT_LOG |
DB_INIT_MPOOL |
DB_INIT_TXN |
DB_THREAD |
DB_PRIVATE |
DB_RECOVER,
0);
if (ret > 0)
throw runtime_error(strprintf("CDB() : error %d opening database environment\n", ret));
fDbEnvInit = true;
}
strFile = pszFile;
++mapFileUseCount[strFile];
}
pdb = new Db(&dbenv, 0);
ret = pdb->open(NULL, // Txn pointer
pszFile, // Filename
"main", // Logical db name
DB_BTREE, // Database type
nFlags, // Flags
0);
if (ret > 0)
{
delete pdb;
pdb = NULL;
CRITICAL_BLOCK(cs_db)
--mapFileUseCount[strFile];
strFile = "";
throw runtime_error(strprintf("CDB() : can't open database file %s, error %d\n", pszFile, ret));
}
if (fCreate && !Exists(string("version")))
WriteVersion(VERSION);
RandAddSeed();
}
void CDB::Close()
{
if (!pdb)
return;
if (!vTxn.empty())
vTxn.front()->abort();
vTxn.clear();
pdb->close(0);
delete pdb;
pdb = NULL;
dbenv.txn_checkpoint(0, 0, 0);
CRITICAL_BLOCK(cs_db)
--mapFileUseCount[strFile];
RandAddSeed();
}
void DBFlush(bool fShutdown)
{
// Flush log data to the actual data file
// on all files that are not in use
printf("DBFlush(%s)\n", fShutdown ? "true" : "false");
CRITICAL_BLOCK(cs_db)
{
dbenv.txn_checkpoint(0, 0, 0);
map<string, int>::iterator mi = mapFileUseCount.begin();
while (mi != mapFileUseCount.end())
{
string strFile = (*mi).first;
int nRefCount = (*mi).second;
if (nRefCount == 0)
{
dbenv.lsn_reset(strFile.c_str(), 0);
mapFileUseCount.erase(mi++);
}
else
mi++;
}
if (fShutdown)
{
char** listp;
if (mapFileUseCount.empty())
dbenv.log_archive(&listp, DB_ARCH_REMOVE);
dbenv.close(0);
fDbEnvInit = false;
}
}
}
//
// CTxDB
//
bool CTxDB::ReadTxIndex(uint256 hash, CTxIndex& txindex)
{
assert(!fClient);
txindex.SetNull();
return Read(make_pair(string("tx"), hash), txindex);
}
bool CTxDB::UpdateTxIndex(uint256 hash, const CTxIndex& txindex)
{
assert(!fClient);
return Write(make_pair(string("tx"), hash), txindex);
}
bool CTxDB::AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight)
{
assert(!fClient);
// Add to tx index
uint256 hash = tx.GetHash();
CTxIndex txindex(pos, tx.vout.size());
return Write(make_pair(string("tx"), hash), txindex);
}
bool CTxDB::EraseTxIndex(const CTransaction& tx)
{
assert(!fClient);
uint256 hash = tx.GetHash();
return Erase(make_pair(string("tx"), hash));
}
bool CTxDB::ContainsTx(uint256 hash)
{
assert(!fClient);
return Exists(make_pair(string("tx"), hash));
}
bool CTxDB::ReadOwnerTxes(uint160 hash160, int nMinHeight, vector<CTransaction>& vtx)
{
assert(!fClient);
vtx.clear();
// Get cursor
Dbc* pcursor = GetCursor();
if (!pcursor)
return false;
unsigned int fFlags = DB_SET_RANGE;
loop
{
// Read next record
CDataStream ssKey;
if (fFlags == DB_SET_RANGE)
ssKey << string("owner") << hash160 << CDiskTxPos(0, 0, 0);
CDataStream ssValue;
int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags);
fFlags = DB_NEXT;
if (ret == DB_NOTFOUND)
break;
else if (ret != 0)
return false;
// Unserialize
string strType;
uint160 hashItem;
CDiskTxPos pos;
ssKey >> strType >> hashItem >> pos;
int nItemHeight;
ssValue >> nItemHeight;
// Read transaction
if (strType != "owner" || hashItem != hash160)
break;
if (nItemHeight >= nMinHeight)
{
vtx.resize(vtx.size()+1);
if (!vtx.back().ReadFromDisk(pos))
return false;
}
}
return true;
}
bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex)
{
assert(!fClient);
tx.SetNull();
if (!ReadTxIndex(hash, txindex))
return false;
return (tx.ReadFromDisk(txindex.pos));
}
bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx)
{
CTxIndex txindex;
return ReadDiskTx(hash, tx, txindex);
}
bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex)
{
return ReadDiskTx(outpoint.hash, tx, txindex);
}
bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx)
{
CTxIndex txindex;
return ReadDiskTx(outpoint.hash, tx, txindex);
}
bool CTxDB::WriteBlockIndex(const CDiskBlockIndex& blockindex)
{
return Write(make_pair(string("blockindex"), blockindex.GetBlockHash()), blockindex);
}
bool CTxDB::EraseBlockIndex(uint256 hash)
{
return Erase(make_pair(string("blockindex"), hash));
}
bool CTxDB::ReadHashBestChain(uint256& hashBestChain)
{
return Read(string("hashBestChain"), hashBestChain);
}
bool CTxDB::WriteHashBestChain(uint256 hashBestChain)
{
return Write(string("hashBestChain"), hashBestChain);
}
CBlockIndex* InsertBlockIndex(uint256 hash)
{
if (hash == 0)
return NULL;
// Return existing
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
if (mi != mapBlockIndex.end())
return (*mi).second;
// Create new
CBlockIndex* pindexNew = new CBlockIndex();
if (!pindexNew)
throw runtime_error("LoadBlockIndex() : new CBlockIndex failed");
mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
pindexNew->phashBlock = &((*mi).first);
return pindexNew;
}
bool CTxDB::LoadBlockIndex()
{
// Get cursor
Dbc* pcursor = GetCursor();
if (!pcursor)
return false;
unsigned int fFlags = DB_SET_RANGE;
loop
{
// Read next record
CDataStream ssKey;
if (fFlags == DB_SET_RANGE)
ssKey << make_pair(string("blockindex"), uint256(0));
CDataStream ssValue;
int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags);
fFlags = DB_NEXT;
if (ret == DB_NOTFOUND)
break;
else if (ret != 0)
return false;
// Unserialize
string strType;
ssKey >> strType;
if (strType == "blockindex")
{
CDiskBlockIndex diskindex;
ssValue >> diskindex;
// Construct block index object
CBlockIndex* pindexNew = InsertBlockIndex(diskindex.GetBlockHash());
pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev);
pindexNew->pnext = InsertBlockIndex(diskindex.hashNext);
pindexNew->nFile = diskindex.nFile;
pindexNew->nBlockPos = diskindex.nBlockPos;
pindexNew->nHeight = diskindex.nHeight;
pindexNew->nVersion = diskindex.nVersion;
pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot;
pindexNew->nTime = diskindex.nTime;
pindexNew->nBits = diskindex.nBits;
pindexNew->nNonce = diskindex.nNonce;
// Watch for genesis block and best block
if (pindexGenesisBlock == NULL && diskindex.GetBlockHash() == hashGenesisBlock)
pindexGenesisBlock = pindexNew;
}
else
{
break;
}
}
if (!ReadHashBestChain(hashBestChain))
{
if (pindexGenesisBlock == NULL)
return true;
return error("CTxDB::LoadBlockIndex() : hashBestChain not found\n");
}
if (!mapBlockIndex.count(hashBestChain))
return error("CTxDB::LoadBlockIndex() : blockindex for hashBestChain not found\n");
pindexBest = mapBlockIndex[hashBestChain];
nBestHeight = pindexBest->nHeight;
printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,14).c_str(), nBestHeight);
return true;
}
//
// CAddrDB
//
bool CAddrDB::WriteAddress(const CAddress& addr)
{
return Write(make_pair(string("addr"), addr.GetKey()), addr);
}
bool CAddrDB::LoadAddresses()
{
CRITICAL_BLOCK(cs_mapIRCAddresses)
CRITICAL_BLOCK(cs_mapAddresses)
{
// Load user provided addresses
CAutoFile filein = fopen("addr.txt", "rt");
if (filein)
{
try
{
char psz[1000];
while (fgets(psz, sizeof(psz), filein))
{
CAddress addr(psz, NODE_NETWORK);
if (addr.ip != 0)
{
AddAddress(*this, addr);
mapIRCAddresses.insert(make_pair(addr.GetKey(), addr));
}
}
}
catch (...) { }
}
// Get cursor
Dbc* pcursor = GetCursor();
if (!pcursor)
return false;
loop
{
// Read next record
CDataStream ssKey;
CDataStream ssValue;
int ret = ReadAtCursor(pcursor, ssKey, ssValue);
if (ret == DB_NOTFOUND)
break;
else if (ret != 0)
return false;
// Unserialize
string strType;
ssKey >> strType;
if (strType == "addr")
{
CAddress addr;
ssValue >> addr;
mapAddresses.insert(make_pair(addr.GetKey(), addr));
}
}
//// debug print
printf("mapAddresses:\n");
foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
item.second.print();
printf("-----\n");
// Fix for possible bug that manifests in mapAddresses.count in irc.cpp,
// just need to call count here and it doesn't happen there. The bug was the
// pack pragma in irc.cpp and has been fixed, but I'm not in a hurry to delete this.
mapAddresses.count(vector<unsigned char>(18));
}
return true;
}
bool LoadAddresses()
{
return CAddrDB("cr+").LoadAddresses();
}
//
// CReviewDB
//
bool CReviewDB::ReadReviews(uint256 hash, vector<CReview>& vReviews)
{
vReviews.size(); // msvc workaround, just need to do anything with vReviews
return Read(make_pair(string("reviews"), hash), vReviews);
}
bool CReviewDB::WriteReviews(uint256 hash, const vector<CReview>& vReviews)
{
return Write(make_pair(string("reviews"), hash), vReviews);
}
//
// CWalletDB
//
bool CWalletDB::LoadWallet(vector<unsigned char>& vchDefaultKeyRet)
{
vchDefaultKeyRet.clear();
//// todo: shouldn't we catch exceptions and try to recover and continue?
CRITICAL_BLOCK(cs_mapKeys)
CRITICAL_BLOCK(cs_mapWallet)
{
// Get cursor
Dbc* pcursor = GetCursor();
if (!pcursor)
return false;
loop
{
// Read next record
CDataStream ssKey;
CDataStream ssValue;
int ret = ReadAtCursor(pcursor, ssKey, ssValue);
if (ret == DB_NOTFOUND)
break;
else if (ret != 0)
return false;
// Unserialize
// Taking advantage of the fact that pair serialization
// is just the two items serialized one after the other
string strType;
ssKey >> strType;
if (strType == "name")
{
string strAddress;
ssKey >> strAddress;
ssValue >> mapAddressBook[strAddress];
}
else if (strType == "tx")
{
uint256 hash;
ssKey >> hash;
CWalletTx& wtx = mapWallet[hash];
ssValue >> wtx;
if (wtx.GetHash() != hash)
printf("Error in wallet.dat, hash mismatch\n");
//// debug print
//printf("LoadWallet %s\n", wtx.GetHash().ToString().c_str());
//printf(" %12I64d %s %s %s\n",
// wtx.vout[0].nValue,
// DateTimeStr(wtx.nTime).c_str(),
// wtx.hashBlock.ToString().substr(0,14).c_str(),
// wtx.mapValue["message"].c_str());
}
else if (strType == "key")
{
vector<unsigned char> vchPubKey;
ssKey >> vchPubKey;
CPrivKey vchPrivKey;
ssValue >> vchPrivKey;
mapKeys[vchPubKey] = vchPrivKey;
mapPubKeys[Hash160(vchPubKey)] = vchPubKey;
}
else if (strType == "defaultkey")
{
ssValue >> vchDefaultKeyRet;
}
else if (strType == "setting") /// or settings or option or options or config?
{
string strKey;
ssKey >> strKey;
if (strKey == "fGenerateBitcoins") ssValue >> fGenerateBitcoins;
if (strKey == "nTransactionFee") ssValue >> nTransactionFee;
if (strKey == "addrIncoming") ssValue >> addrIncoming;
}
}
}
printf("fGenerateBitcoins = %d\n", fGenerateBitcoins);
printf("nTransactionFee = %I64d\n", nTransactionFee);
printf("addrIncoming = %s\n", addrIncoming.ToString().c_str());
return true;
}
bool LoadWallet()
{
vector<unsigned char> vchDefaultKey;
if (!CWalletDB("cr").LoadWallet(vchDefaultKey))
return false;
if (mapKeys.count(vchDefaultKey))
{
// Set keyUser
keyUser.SetPubKey(vchDefaultKey);
keyUser.SetPrivKey(mapKeys[vchDefaultKey]);
}
else
{
// Create new keyUser and set as default key
RandAddSeed(true);
keyUser.MakeNewKey();
if (!AddKey(keyUser))
return false;
if (!SetAddressBookName(PubKeyToAddress(keyUser.GetPubKey()), "Your Address"))
return false;
CWalletDB().WriteDefaultKey(keyUser.GetPubKey());
}
return true;
}

420
db.h Normal file
View file

@ -0,0 +1,420 @@
// Copyright (c) 2009 Satoshi Nakamoto
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#include <db_cxx.h>
class CTransaction;
class CTxIndex;
class CDiskBlockIndex;
class CDiskTxPos;
class COutPoint;
class CUser;
class CReview;
class CAddress;
class CWalletTx;
extern map<string, string> mapAddressBook;
extern bool fClient;
extern DbEnv dbenv;
extern void DBFlush(bool fShutdown);
class CDB
{
protected:
Db* pdb;
string strFile;
vector<DbTxn*> vTxn;
explicit CDB(const char* pszFile, const char* pszMode="r+", bool fTxn=false);
~CDB() { Close(); }
public:
void Close();
private:
CDB(const CDB&);
void operator=(const CDB&);
protected:
template<typename K, typename T>
bool Read(const K& key, T& value)
{
if (!pdb)
return false;
// Key
CDataStream ssKey(SER_DISK);
ssKey.reserve(1000);
ssKey << key;
Dbt datKey(&ssKey[0], ssKey.size());
// Read
Dbt datValue;
datValue.set_flags(DB_DBT_MALLOC);
int ret = pdb->get(GetTxn(), &datKey, &datValue, 0);
memset(datKey.get_data(), 0, datKey.get_size());
if (datValue.get_data() == NULL)
return false;
// Unserialize value
CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK);
ssValue >> value;
// Clear and free memory
memset(datValue.get_data(), 0, datValue.get_size());
free(datValue.get_data());
return (ret == 0);
}
template<typename K, typename T>
bool Write(const K& key, const T& value, bool fOverwrite=true)
{
if (!pdb)
return false;
// Key
CDataStream ssKey(SER_DISK);
ssKey.reserve(1000);
ssKey << key;
Dbt datKey(&ssKey[0], ssKey.size());
// Value
CDataStream ssValue(SER_DISK);
ssValue.reserve(10000);
ssValue << value;
Dbt datValue(&ssValue[0], ssValue.size());
// Write
int ret = pdb->put(GetTxn(), &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE));
// Clear memory in case it was a private key
memset(datKey.get_data(), 0, datKey.get_size());
memset(datValue.get_data(), 0, datValue.get_size());
return (ret == 0);
}
template<typename K>
bool Erase(const K& key)
{
if (!pdb)
return false;
// Key
CDataStream ssKey(SER_DISK);
ssKey.reserve(1000);
ssKey << key;
Dbt datKey(&ssKey[0], ssKey.size());
// Erase
int ret = pdb->del(GetTxn(), &datKey, 0);
// Clear memory
memset(datKey.get_data(), 0, datKey.get_size());
return (ret == 0 || ret == DB_NOTFOUND);
}
template<typename K>
bool Exists(const K& key)
{
if (!pdb)
return false;
// Key
CDataStream ssKey(SER_DISK);
ssKey.reserve(1000);
ssKey << key;
Dbt datKey(&ssKey[0], ssKey.size());
// Exists
int ret = pdb->exists(GetTxn(), &datKey, 0);
// Clear memory
memset(datKey.get_data(), 0, datKey.get_size());
return (ret == 0);
}
Dbc* GetCursor()
{
if (!pdb)
return NULL;
Dbc* pcursor = NULL;
int ret = pdb->cursor(NULL, &pcursor, 0);
if (ret != 0)
return NULL;
return pcursor;
}
int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags=DB_NEXT)
{
// Read at cursor
Dbt datKey;
if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
{
datKey.set_data(&ssKey[0]);
datKey.set_size(ssKey.size());
}
Dbt datValue;
if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
{
datValue.set_data(&ssValue[0]);
datValue.set_size(ssValue.size());
}
datKey.set_flags(DB_DBT_MALLOC);
datValue.set_flags(DB_DBT_MALLOC);
int ret = pcursor->get(&datKey, &datValue, fFlags);
if (ret != 0)
return ret;
else if (datKey.get_data() == NULL || datValue.get_data() == NULL)
return 99999;
// Convert to streams
ssKey.SetType(SER_DISK);
ssKey.clear();
ssKey.write((char*)datKey.get_data(), datKey.get_size());
ssValue.SetType(SER_DISK);
ssValue.clear();
ssValue.write((char*)datValue.get_data(), datValue.get_size());
// Clear and free memory
memset(datKey.get_data(), 0, datKey.get_size());
memset(datValue.get_data(), 0, datValue.get_size());
free(datKey.get_data());
free(datValue.get_data());
return 0;
}
DbTxn* GetTxn()
{
if (!vTxn.empty())
return vTxn.back();
else
return NULL;
}
public:
bool TxnBegin()
{
if (!pdb)
return false;
DbTxn* ptxn = NULL;
int ret = dbenv.txn_begin(GetTxn(), &ptxn, 0);
if (!ptxn || ret != 0)
return false;
vTxn.push_back(ptxn);
return true;
}
bool TxnCommit()
{
if (!pdb)
return false;
if (vTxn.empty())
return false;
int ret = vTxn.back()->commit(0);
vTxn.pop_back();
return (ret == 0);
}
bool TxnAbort()
{
if (!pdb)
return false;
if (vTxn.empty())
return false;
int ret = vTxn.back()->abort();
vTxn.pop_back();
return (ret == 0);
}
bool ReadVersion(int& nVersion)
{
nVersion = 0;
return Read(string("version"), nVersion);
}
bool WriteVersion(int nVersion)
{
return Write(string("version"), nVersion);
}
};
class CTxDB : public CDB
{
public:
CTxDB(const char* pszMode="r+", bool fTxn=false) : CDB(!fClient ? "blkindex.dat" : NULL, pszMode, fTxn) { }
private:
CTxDB(const CTxDB&);
void operator=(const CTxDB&);
public:
bool ReadTxIndex(uint256 hash, CTxIndex& txindex);
bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex);
bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight);
bool EraseTxIndex(const CTransaction& tx);
bool ContainsTx(uint256 hash);
bool ReadOwnerTxes(uint160 hash160, int nHeight, vector<CTransaction>& vtx);
bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex);
bool ReadDiskTx(uint256 hash, CTransaction& tx);
bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex);
bool ReadDiskTx(COutPoint outpoint, CTransaction& tx);
bool WriteBlockIndex(const CDiskBlockIndex& blockindex);
bool EraseBlockIndex(uint256 hash);
bool ReadHashBestChain(uint256& hashBestChain);
bool WriteHashBestChain(uint256 hashBestChain);
bool LoadBlockIndex();
};
class CReviewDB : public CDB
{
public:
CReviewDB(const char* pszMode="r+", bool fTxn=false) : CDB("reviews.dat", pszMode, fTxn) { }
private:
CReviewDB(const CReviewDB&);
void operator=(const CReviewDB&);
public:
bool ReadUser(uint256 hash, CUser& user)
{
return Read(make_pair(string("user"), hash), user);
}
bool WriteUser(uint256 hash, const CUser& user)
{
return Write(make_pair(string("user"), hash), user);
}
bool ReadReviews(uint256 hash, vector<CReview>& vReviews);
bool WriteReviews(uint256 hash, const vector<CReview>& vReviews);
};
class CMarketDB : public CDB
{
public:
CMarketDB(const char* pszMode="r+", bool fTxn=false) : CDB("market.dat", pszMode, fTxn) { }
private:
CMarketDB(const CMarketDB&);
void operator=(const CMarketDB&);
};
class CAddrDB : public CDB
{
public:
CAddrDB(const char* pszMode="r+", bool fTxn=false) : CDB("addr.dat", pszMode, fTxn) { }
private:
CAddrDB(const CAddrDB&);
void operator=(const CAddrDB&);
public:
bool WriteAddress(const CAddress& addr);
bool LoadAddresses();
};
bool LoadAddresses();
class CWalletDB : public CDB
{
public:
CWalletDB(const char* pszMode="r+", bool fTxn=false) : CDB("wallet.dat", pszMode, fTxn) { }
private:
CWalletDB(const CWalletDB&);
void operator=(const CWalletDB&);
public:
bool ReadName(const string& strAddress, string& strName)
{
strName = "";
return Read(make_pair(string("name"), strAddress), strName);
}
bool WriteName(const string& strAddress, const string& strName)
{
mapAddressBook[strAddress] = strName;
return Write(make_pair(string("name"), strAddress), strName);
}
bool EraseName(const string& strAddress)
{
mapAddressBook.erase(strAddress);
return Erase(make_pair(string("name"), strAddress));
}
bool ReadTx(uint256 hash, CWalletTx& wtx)
{
return Read(make_pair(string("tx"), hash), wtx);
}
bool WriteTx(uint256 hash, const CWalletTx& wtx)
{
return Write(make_pair(string("tx"), hash), wtx);
}
bool EraseTx(uint256 hash)
{
return Erase(make_pair(string("tx"), hash));
}
bool ReadKey(const vector<unsigned char>& vchPubKey, CPrivKey& vchPrivKey)
{
vchPrivKey.clear();
return Read(make_pair(string("key"), vchPubKey), vchPrivKey);
}
bool WriteKey(const vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey)
{
return Write(make_pair(string("key"), vchPubKey), vchPrivKey, false);
}
bool ReadDefaultKey(vector<unsigned char>& vchPubKey)
{
vchPubKey.clear();
return Read(string("defaultkey"), vchPubKey);
}
bool WriteDefaultKey(const vector<unsigned char>& vchPubKey)
{
return Write(string("defaultkey"), vchPubKey);
}
template<typename T>
bool ReadSetting(const string& strKey, T& value)
{
return Read(make_pair(string("setting"), strKey), value);
}
template<typename T>
bool WriteSetting(const string& strKey, const T& value)
{
return Write(make_pair(string("setting"), strKey), value);
}
bool LoadWallet(vector<unsigned char>& vchDefaultKeyRet);
};
bool LoadWallet();
inline bool SetAddressBookName(const string& strAddress, const string& strName)
{
return CWalletDB().WriteName(strAddress, strName);
}

71
headers.h Normal file
View file

@ -0,0 +1,71 @@
// Copyright (c) 2009 Satoshi Nakamoto
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#ifdef _MSC_VER
#pragma warning(disable:4786)
#pragma warning(disable:4804)
#pragma warning(disable:4717)
#endif
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT 0x0400
#define WIN32_LEAN_AND_MEAN 1
#include <wx/wx.h>
#include <wx/clipbrd.h>
#include <wx/snglinst.h>
#include <openssl/ecdsa.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/sha.h>
#include <openssl/ripemd.h>
#include <windows.h>
#include <winsock2.h>
#include <mswsock.h>
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <math.h>
#include <limits.h>
#include <float.h>
#include <assert.h>
#include <process.h>
#include <malloc.h>
#include <memory>
#define BOUNDSCHECK 1
#include <sstream>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <map>
#include <set>
#include <algorithm>
#include <numeric>
#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_comparison.hpp>
#include <boost/tuple/tuple_io.hpp>
#include <boost/array.hpp>
#pragma hdrstop
using namespace std;
using namespace boost;
#include "serialize.h"
#include "uint256.h"
#include "util.h"
#include "key.h"
#include "bignum.h"
#include "base58.h"
#include "script.h"
#include "db.h"
#include "net.h"
#include "irc.h"
#include "main.h"
#include "market.h"
#include "uibase.h"
#include "ui.h"

314
irc.cpp Normal file
View file

@ -0,0 +1,314 @@
// Copyright (c) 2009 Satoshi Nakamoto
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#include "headers.h"
map<vector<unsigned char>, CAddress> mapIRCAddresses;
CCriticalSection cs_mapIRCAddresses;
#pragma pack(push, 1)
struct ircaddr
{
int ip;
short port;
};
#pragma pack(pop)
string EncodeAddress(const CAddress& addr)
{
struct ircaddr tmp;
tmp.ip = addr.ip;
tmp.port = addr.port;
vector<unsigned char> vch(UBEGIN(tmp), UEND(tmp));
return string("u") + EncodeBase58Check(vch);
}
bool DecodeAddress(string str, CAddress& addr)
{
vector<unsigned char> vch;
if (!DecodeBase58Check(str.substr(1), vch))
return false;
struct ircaddr tmp;
if (vch.size() != sizeof(tmp))
return false;
memcpy(&tmp, &vch[0], sizeof(tmp));
addr = CAddress(tmp.ip, tmp.port);
return true;
}
static bool Send(SOCKET hSocket, const char* pszSend)
{
if (strstr(pszSend, "PONG") != pszSend)
printf("SENDING: %s\n", pszSend);
const char* psz = pszSend;
const char* pszEnd = psz + strlen(psz);
while (psz < pszEnd)
{
int ret = send(hSocket, psz, pszEnd - psz, 0);
if (ret < 0)
return false;
psz += ret;
}
return true;
}
bool RecvLine(SOCKET hSocket, string& strLine)
{
strLine = "";
loop
{
char c;
int nBytes = recv(hSocket, &c, 1, 0);
if (nBytes > 0)
{
if (c == '\n')
continue;
if (c == '\r')
return true;
strLine += c;
}
else if (nBytes <= 0)
{
if (!strLine.empty())
return true;
// socket closed
printf("IRC socket closed\n");
return false;
}
else
{
// socket error
int nErr = WSAGetLastError();
if (nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
{
printf("IRC recv failed: %d\n", nErr);
return false;
}
}
}
}
bool RecvLineIRC(SOCKET hSocket, string& strLine)
{
loop
{
bool fRet = RecvLine(hSocket, strLine);
if (fRet)
{
if (fShutdown)
return false;
vector<string> vWords;
ParseString(strLine, ' ', vWords);
if (vWords[0] == "PING")
{
strLine[1] = 'O';
strLine += '\r';
Send(hSocket, strLine.c_str());
continue;
}
}
return fRet;
}
}
bool RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const char* psz3=NULL)
{
loop
{
string strLine;
if (!RecvLineIRC(hSocket, strLine))
return false;
printf("IRC %s\n", strLine.c_str());
if (psz1 && strLine.find(psz1) != -1)
return true;
if (psz2 && strLine.find(psz2) != -1)
return true;
if (psz3 && strLine.find(psz3) != -1)
return true;
}
}
bool Wait(int nSeconds)
{
if (fShutdown)
return false;
printf("Waiting %d seconds to reconnect to IRC\n", nSeconds);
for (int i = 0; i < nSeconds; i++)
{
if (fShutdown)
return false;
Sleep(1000);
}
return true;
}
void ThreadIRCSeed(void* parg)
{
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
int nErrorWait = 10;
int nRetryWait = 10;
while (!fShutdown)
{
CAddress addrConnect("216.155.130.130:6667");
struct hostent* phostent = gethostbyname("chat.freenode.net");
if (phostent && phostent->h_addr_list && phostent->h_addr_list[0])
addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(6667));
SOCKET hSocket;
if (!ConnectSocket(addrConnect, hSocket))
{
printf("IRC connect failed\n");
nErrorWait = nErrorWait * 11 / 10;
if (Wait(nErrorWait += 60))
continue;
else
return;
}
if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname"))
{
closesocket(hSocket);
nErrorWait = nErrorWait * 11 / 10;
if (Wait(nErrorWait += 60))
continue;
else
return;
}
string strMyName = EncodeAddress(addrLocalHost);
if (!addrLocalHost.IsRoutable())
strMyName = strprintf("x%u", GetRand(1000000000));
Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str());
Send(hSocket, strprintf("USER %s 8 * : %s\r", strMyName.c_str(), strMyName.c_str()).c_str());
if (!RecvUntil(hSocket, " 004 "))
{
closesocket(hSocket);
nErrorWait = nErrorWait * 11 / 10;
if (Wait(nErrorWait += 60))
continue;
else
return;
}
Sleep(500);
Send(hSocket, "JOIN #bitcoin\r");
Send(hSocket, "WHO #bitcoin\r");
int64 nStart = GetTime();
string strLine;
while (!fShutdown && RecvLineIRC(hSocket, strLine))
{
if (strLine.empty() || strLine.size() > 900 || strLine[0] != ':')
continue;
printf("IRC %s\n", strLine.c_str());
vector<string> vWords;
ParseString(strLine, ' ', vWords);
if (vWords.size() < 2)
continue;
char pszName[10000];
pszName[0] = '\0';
if (vWords[1] == "352" && vWords.size() >= 8)
{
// index 7 is limited to 16 characters
// could get full length name at index 10, but would be different from join messages
strcpy(pszName, vWords[7].c_str());
printf("GOT WHO: [%s] ", pszName);
}
if (vWords[1] == "JOIN" && vWords[0].size() > 1)
{
// :username!username@50000007.F000000B.90000002.IP JOIN :#channelname
strcpy(pszName, vWords[0].c_str() + 1);
if (strchr(pszName, '!'))
*strchr(pszName, '!') = '\0';
printf("GOT JOIN: [%s] ", pszName);
}
if (pszName[0] == 'u')
{
CAddress addr;
if (DecodeAddress(pszName, addr))
{
CAddrDB addrdb;
if (AddAddress(addrdb, addr))
printf("new ");
else
{
// make it try connecting again
CRITICAL_BLOCK(cs_mapAddresses)
if (mapAddresses.count(addr.GetKey()))
mapAddresses[addr.GetKey()].nLastFailed = 0;
}
addr.print();
CRITICAL_BLOCK(cs_mapIRCAddresses)
mapIRCAddresses.insert(make_pair(addr.GetKey(), addr));
}
else
{
printf("decode failed\n");
}
}
}
closesocket(hSocket);
if (GetTime() - nStart > 20 * 60)
{
nErrorWait /= 3;
nRetryWait /= 3;
}
nRetryWait = nRetryWait * 11 / 10;
if (!Wait(nRetryWait += 60))
return;
}
}
#ifdef TEST
int main(int argc, char *argv[])
{
WSADATA wsadata;
if (WSAStartup(MAKEWORD(2,2), &wsadata) != NO_ERROR)
{
printf("Error at WSAStartup()\n");
return false;
}
ThreadIRCSeed(NULL);
WSACleanup();
return 0;
}
#endif

10
irc.h Normal file
View file

@ -0,0 +1,10 @@
// Copyright (c) 2009 Satoshi Nakamoto
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
extern bool RecvLine(SOCKET hSocket, string& strLine);
extern void ThreadIRCSeed(void* parg);
extern bool fRestartIRCSeed;
extern map<vector<unsigned char>, CAddress> mapIRCAddresses;
extern CCriticalSection cs_mapIRCAddresses;

156
key.h Normal file
View file

@ -0,0 +1,156 @@
// Copyright (c) 2009 Satoshi Nakamoto
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
// secp160k1
// const unsigned int PRIVATE_KEY_SIZE = 192;
// const unsigned int PUBLIC_KEY_SIZE = 41;
// const unsigned int SIGNATURE_SIZE = 48;
//
// secp192k1
// const unsigned int PRIVATE_KEY_SIZE = 222;
// const unsigned int PUBLIC_KEY_SIZE = 49;
// const unsigned int SIGNATURE_SIZE = 57;
//
// secp224k1
// const unsigned int PRIVATE_KEY_SIZE = 250;
// const unsigned int PUBLIC_KEY_SIZE = 57;
// const unsigned int SIGNATURE_SIZE = 66;
//
// secp256k1:
// const unsigned int PRIVATE_KEY_SIZE = 279;
// const unsigned int PUBLIC_KEY_SIZE = 65;
// const unsigned int SIGNATURE_SIZE = 72;
//
// see www.keylength.com
// script supports up to 75 for single byte push
class key_error : public std::runtime_error
{
public:
explicit key_error(const std::string& str) : std::runtime_error(str) {}
};
// secure_allocator is defined is serialize.h
typedef vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
class CKey
{
protected:
EC_KEY* pkey;
public:
CKey()
{
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
if (pkey == NULL)
throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");
}
CKey(const CKey& b)
{
pkey = EC_KEY_dup(b.pkey);
if (pkey == NULL)
throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed");
}
CKey& operator=(const CKey& b)
{
if (!EC_KEY_copy(pkey, b.pkey))
throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed");
return (*this);
}
~CKey()
{
EC_KEY_free(pkey);
}
void MakeNewKey()
{
if (!EC_KEY_generate_key(pkey))
throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
}
bool SetPrivKey(const CPrivKey& vchPrivKey)
{
const unsigned char* pbegin = &vchPrivKey[0];
if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size()))
return false;
return true;
}
CPrivKey GetPrivKey() const
{
unsigned int nSize = i2d_ECPrivateKey(pkey, NULL);
if (!nSize)
throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");
CPrivKey vchPrivKey(nSize, 0);
unsigned char* pbegin = &vchPrivKey[0];
if (i2d_ECPrivateKey(pkey, &pbegin) != nSize)
throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size");
return vchPrivKey;
}
bool SetPubKey(const vector<unsigned char>& vchPubKey)
{
const unsigned char* pbegin = &vchPubKey[0];
if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size()))
return false;
return true;
}
vector<unsigned char> GetPubKey() const
{
unsigned int nSize = i2o_ECPublicKey(pkey, NULL);
if (!nSize)
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
vector<unsigned char> vchPubKey(nSize, 0);
unsigned char* pbegin = &vchPubKey[0];
if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
return vchPubKey;
}
bool Sign(uint256 hash, vector<unsigned char>& vchSig)
{
vchSig.clear();
unsigned char pchSig[10000];
unsigned int nSize = 0;
if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey))
return false;
vchSig.resize(nSize);
memcpy(&vchSig[0], pchSig, nSize);
return true;
}
bool Verify(uint256 hash, const vector<unsigned char>& vchSig)
{
// -1 = error, 0 = bad sig, 1 = good
if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)
return false;
return true;
}
static bool Sign(const CPrivKey& vchPrivKey, uint256 hash, vector<unsigned char>& vchSig)
{
CKey key;
if (!key.SetPrivKey(vchPrivKey))
return false;
return key.Sign(hash, vchSig);
}
static bool Verify(const vector<unsigned char>& vchPubKey, uint256 hash, const vector<unsigned char>& vchSig)
{
CKey key;
if (!key.SetPubKey(vchPubKey))
return false;
return key.Verify(hash, vchSig);
}
};

BIN
libeay32.dll Normal file

Binary file not shown.

19
license.txt Normal file
View file

@ -0,0 +1,19 @@
Copyright (c) 2009 Satoshi Nakamoto
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

2692
main.cpp Normal file

File diff suppressed because it is too large Load diff

1329
main.h Normal file

File diff suppressed because it is too large Load diff

83
makefile Normal file
View file

@ -0,0 +1,83 @@
# Copyright (c) 2009 Satoshi Nakamoto
# Distributed under the MIT/X11 software license, see the accompanying
# file license.txt or http://www.opensource.org/licenses/mit-license.php.
ifneq "$(BUILD)" "debug"
ifneq "$(BUILD)" "release"
BUILD=debug
endif
endif
ifeq "$(BUILD)" "debug"
D=d
# note: gcc 3.x profile doesn't work
#DEBUGFLAGS=-O0 -g -pg -D__WXDEBUG__
DEBUGFLAGS=-g -D__WXDEBUG__
endif
INCLUDEPATHS=-I"/boost" -I"/DB/build_unix" -I"/OpenSSL/include" -I"/wxWidgets/lib/vc_lib/mswd" -I"/wxWidgets/include"
LIBPATHS=-L"/DB/build_unix" -L"/OpenSSL/out" -L"/wxWidgets/lib/gcc_lib"
LIBS= \
-l db_cxx \
-l eay32 \
-l wxmsw28$(D)_richtext -l wxmsw28$(D)_html -l wxmsw28$(D)_core -l wxbase28$(D) -l wxtiff$(D) -l wxjpeg$(D) -l wxpng$(D) -l wxzlib$(D) -l wxregex$(D) -l wxexpat$(D) \
-l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32
WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH
CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h
all: bitcoin.exe
headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h
g++ -c $(CFLAGS) -o $@ $<
obj/util.o: util.cpp $(HEADERS)
g++ -c $(CFLAGS) -o $@ $<
obj/script.o: script.cpp $(HEADERS)
g++ -c $(CFLAGS) -o $@ $<
obj/db.o: db.cpp $(HEADERS) market.h
g++ -c $(CFLAGS) -o $@ $<
obj/net.o: net.cpp $(HEADERS) net.h
g++ -c $(CFLAGS) -o $@ $<
obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h
g++ -c $(CFLAGS) -o $@ $<
obj/market.o: market.cpp $(HEADERS) market.h
g++ -c $(CFLAGS) -o $@ $<
obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h
g++ -c $(CFLAGS) -o $@ $<
obj/uibase.o: uibase.cpp uibase.h
g++ -c $(CFLAGS) -o $@ $<
obj/sha.o: sha.cpp sha.h
g++ -c $(CFLAGS) -O3 -o $@ $<
obj/irc.o: irc.cpp $(HEADERS)
g++ -c $(CFLAGS) -o $@ $<
obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp
windres $(WXDEFS) $(INCLUDEPATHS) -o $@ -i $<
OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \
obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ui_res.o
bitcoin.exe: headers.h.gch $(OBJS)
-kill /f bitcoin.exe
g++ $(CFLAGS) -mwindows -Wl,--subsystem,windows -o $@ $(LIBPATHS) $(OBJS) $(LIBS)
clean:
-del /Q obj\*
-del /Q headers.h.gch

77
makefile.vc Normal file
View file

@ -0,0 +1,77 @@
# Copyright (c) 2009 Satoshi Nakamoto
# Distributed under the MIT/X11 software license, see the accompanying
# file license.txt or http://www.opensource.org/licenses/mit-license.php.
!IF "$(BUILD)" != "debug" && "$(BUILD)" != "release"
BUILD=debug
!ENDIF
!IF "$(BUILD)" == "debug"
D=d
DEBUGFLAGS=/Zi /Od /D__WXDEBUG__
!ENDIF
INCLUDEPATHS=/I"/boost" /I"/DB/build_windows" /I"/OpenSSL/include" /I"/wxWidgets/lib/vc_lib/mswd" /I"/wxWidgets/include"
LIBPATHS=/LIBPATH:"/DB/build_windows/$(BUILD)" /LIBPATH:"/OpenSSL/out" /LIBPATH:"/wxWidgets/lib/vc_lib"
LIBS= \
libdb47s$(D).lib \
libeay32.lib \
wxmsw28$(D)_richtext.lib wxmsw28$(D)_html.lib wxmsw28$(D)_core.lib wxbase28$(D).lib wxtiff$(D).lib wxjpeg$(D).lib wxpng$(D).lib wxzlib$(D).lib wxregex$(D).lib wxexpat$(D).lib \
kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib ws2_32.lib
WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH
CFLAGS=/c /nologo /Ob0 /MD$(D) /EHsc /GR /Zm300 /YX /Fpobj/headers.pch $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h
all: bitcoin.exe
obj\util.obj: util.cpp $(HEADERS)
cl $(CFLAGS) /Fo$@ %s
obj\script.obj: script.cpp $(HEADERS)
cl $(CFLAGS) /Fo$@ %s
obj\db.obj: db.cpp $(HEADERS) market.h
cl $(CFLAGS) /Fo$@ %s
obj\net.obj: net.cpp $(HEADERS) net.h
cl $(CFLAGS) /Fo$@ %s
obj\main.obj: main.cpp $(HEADERS) net.h market.h
cl $(CFLAGS) /Fo$@ %s
obj\market.obj: market.cpp $(HEADERS) market.h
cl $(CFLAGS) /Fo$@ %s
obj\ui.obj: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h
cl $(CFLAGS) /Fo$@ %s
obj\uibase.obj: uibase.cpp uibase.h
cl $(CFLAGS) /Fo$@ %s
obj\sha.obj: sha.cpp sha.h
cl $(CFLAGS) /O2 /Fo$@ %s
obj\irc.obj: irc.cpp $(HEADERS)
cl $(CFLAGS) /Fo$@ %s
obj\ui.res: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp
rc $(INCLUDEPATHS) $(WXDEFS) /Fo$@ %s
OBJS=obj\util.obj obj\script.obj obj\db.obj obj\net.obj obj\main.obj obj\market.obj \
obj\ui.obj obj\uibase.obj obj\sha.obj obj\irc.obj obj\ui.res
bitcoin.exe: $(OBJS)
-kill /f bitcoin.exe & sleep 1
link /nologo /DEBUG /SUBSYSTEM:WINDOWS /OUT:$@ $(LIBPATHS) $** $(LIBS)
clean:
-del /Q obj\*
-del *.ilk
-del *.pdb

264
market.cpp Normal file
View file

@ -0,0 +1,264 @@
// Copyright (c) 2009 Satoshi Nakamoto
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#include "headers.h"
//
// Global state variables
//
//// later figure out how these are persisted
map<uint256, CProduct> mapMyProducts;
map<uint256, CProduct> mapProducts;
CCriticalSection cs_mapProducts;
bool AdvertInsert(const CProduct& product)
{
uint256 hash = product.GetHash();
bool fNew = false;
bool fUpdated = false;
CRITICAL_BLOCK(cs_mapProducts)
{
// Insert or find existing product
pair<map<uint256, CProduct>::iterator, bool> item = mapProducts.insert(make_pair(hash, product));
CProduct* pproduct = &(*(item.first)).second;
fNew = item.second;
// Update if newer
if (product.nSequence > pproduct->nSequence)
{
*pproduct = product;
fUpdated = true;
}
}
//if (fNew)
// NotifyProductAdded(hash);
//else if (fUpdated)
// NotifyProductUpdated(hash);
return (fNew || fUpdated);
}
void AdvertErase(const CProduct& product)
{
uint256 hash = product.GetHash();
CRITICAL_BLOCK(cs_mapProducts)
mapProducts.erase(hash);
//NotifyProductDeleted(hash);
}
template<typename T>
unsigned int Union(T& v1, T& v2)
{
// v1 = v1 union v2
// v1 and v2 must be sorted
// returns the number of elements added to v1
///// need to check that this is equivalent, then delete this comment
//vector<unsigned short> vUnion(v1.size() + v2.size());
//vUnion.erase(set_union(v1.begin(), v1.end(),
// v2.begin(), v2.end(),
// vUnion.begin()),
// vUnion.end());
T vUnion;
vUnion.reserve(v1.size() + v2.size());
set_union(v1.begin(), v1.end(),
v2.begin(), v2.end(),
back_inserter(vUnion));
unsigned int nAdded = vUnion.size() - v1.size();
if (nAdded > 0)
v1 = vUnion;
return nAdded;
}
void CUser::AddAtom(unsigned short nAtom, bool fOrigin)
{
// Ignore duplicates
if (binary_search(vAtomsIn.begin(), vAtomsIn.end(), nAtom) ||
find(vAtomsNew.begin(), vAtomsNew.end(), nAtom) != vAtomsNew.end())
return;
//// instead of zero atom, should change to free atom that propagates,
//// limited to lower than a certain value like 5 so conflicts quickly
// The zero atom never propagates,
// new atoms always propagate through the user that created them
if (nAtom == 0 || fOrigin)
{
vector<unsigned short> vTmp(1, nAtom);
Union(vAtomsIn, vTmp);
if (fOrigin)
vAtomsOut.push_back(nAtom);
return;
}
vAtomsNew.push_back(nAtom);
if (vAtomsNew.size() >= nFlowthroughRate || vAtomsOut.empty())
{
// Select atom to flow through to vAtomsOut
vAtomsOut.push_back(vAtomsNew[GetRand(vAtomsNew.size())]);
// Merge vAtomsNew into vAtomsIn
sort(vAtomsNew.begin(), vAtomsNew.end());
Union(vAtomsIn, vAtomsNew);
vAtomsNew.clear();
}
}
bool AddAtomsAndPropagate(uint256 hashUserStart, const vector<unsigned short>& vAtoms, bool fOrigin)
{
CReviewDB reviewdb;
map<uint256, vector<unsigned short> > pmapPropagate[2];
pmapPropagate[0][hashUserStart] = vAtoms;
for (int side = 0; !pmapPropagate[side].empty(); side = 1 - side)
{
map<uint256, vector<unsigned short> >& mapFrom = pmapPropagate[side];
map<uint256, vector<unsigned short> >& mapTo = pmapPropagate[1 - side];
for (map<uint256, vector<unsigned short> >::iterator mi = mapFrom.begin(); mi != mapFrom.end(); ++mi)
{
const uint256& hashUser = (*mi).first;
const vector<unsigned short>& vReceived = (*mi).second;
///// this would be a lot easier on the database if it put the new atom at the beginning of the list,
///// so the change would be right next to the vector size.
// Read user
CUser user;
reviewdb.ReadUser(hashUser, user);
unsigned int nIn = user.vAtomsIn.size();
unsigned int nNew = user.vAtomsNew.size();
unsigned int nOut = user.vAtomsOut.size();
// Add atoms received
foreach(unsigned short nAtom, vReceived)
user.AddAtom(nAtom, fOrigin);
fOrigin = false;
// Don't bother writing to disk if no changes
if (user.vAtomsIn.size() == nIn && user.vAtomsNew.size() == nNew)
continue;
// Propagate
if (user.vAtomsOut.size() > nOut)
foreach(const uint256& hash, user.vLinksOut)
mapTo[hash].insert(mapTo[hash].end(), user.vAtomsOut.begin() + nOut, user.vAtomsOut.end());
// Write back
if (!reviewdb.WriteUser(hashUser, user))
return false;
}
mapFrom.clear();
}
return true;
}
bool CReview::AcceptReview()
{
// Timestamp
nTime = GetTime();
// Check signature
if (!CKey::Verify(vchPubKeyFrom, GetSigHash(), vchSig))
return false;
CReviewDB reviewdb;
// Add review text to recipient
vector<CReview> vReviews;
reviewdb.ReadReviews(hashTo, vReviews);
vReviews.push_back(*this);
if (!reviewdb.WriteReviews(hashTo, vReviews))
return false;
// Add link from sender
CUser user;
uint256 hashFrom = Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end());
reviewdb.ReadUser(hashFrom, user);
user.vLinksOut.push_back(hashTo);
if (!reviewdb.WriteUser(hashFrom, user))
return false;
reviewdb.Close();
// Propagate atoms to recipient
vector<unsigned short> vZeroAtom(1, 0);
if (!AddAtomsAndPropagate(hashTo, user.vAtomsOut.size() ? user.vAtomsOut : vZeroAtom, false))
return false;
return true;
}
bool CProduct::CheckSignature()
{
return (CKey::Verify(vchPubKeyFrom, GetSigHash(), vchSig));
}
bool CProduct::CheckProduct()
{
if (!CheckSignature())
return false;
// Make sure it's a summary product
if (!mapDetails.empty() || !vOrderForm.empty())
return false;
// Look up seller's atom count
CReviewDB reviewdb("r");
CUser user;
reviewdb.ReadUser(GetUserHash(), user);
nAtoms = user.GetAtomCount();
reviewdb.Close();
////// delme, this is now done by AdvertInsert
//// Store to memory
//CRITICAL_BLOCK(cs_mapProducts)
// mapProducts[GetHash()] = *this;
return true;
}

182
market.h Normal file
View file

@ -0,0 +1,182 @@
// Copyright (c) 2009 Satoshi Nakamoto
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
class CUser;
class CReview;
class CProduct;
static const unsigned int nFlowthroughRate = 2;
bool AdvertInsert(const CProduct& product);
void AdvertErase(const CProduct& product);
bool AddAtomsAndPropagate(uint256 hashUserStart, const vector<unsigned short>& vAtoms, bool fOrigin);
class CUser
{
public:
vector<unsigned short> vAtomsIn;
vector<unsigned short> vAtomsNew;
vector<unsigned short> vAtomsOut;
vector<uint256> vLinksOut;
CUser()
{
}
IMPLEMENT_SERIALIZE
(
if (!(nType & SER_GETHASH))
READWRITE(nVersion);
READWRITE(vAtomsIn);
READWRITE(vAtomsNew);
READWRITE(vAtomsOut);
READWRITE(vLinksOut);
)
void SetNull()
{
vAtomsIn.clear();
vAtomsNew.clear();
vAtomsOut.clear();
vLinksOut.clear();
}
uint256 GetHash() const { return SerializeHash(*this); }
int GetAtomCount() const
{
return (vAtomsIn.size() + vAtomsNew.size());
}
void AddAtom(unsigned short nAtom, bool fOrigin);
};
class CReview
{
public:
int nVersion;
uint256 hashTo;
map<string, string> mapValue;
vector<unsigned char> vchPubKeyFrom;
vector<unsigned char> vchSig;
// memory only
unsigned int nTime;
int nAtoms;
CReview()
{
nVersion = 1;
hashTo = 0;
nTime = 0;
nAtoms = 0;
}
IMPLEMENT_SERIALIZE
(
READWRITE(this->nVersion);
nVersion = this->nVersion;
if (!(nType & SER_DISK))
READWRITE(hashTo);
READWRITE(mapValue);
READWRITE(vchPubKeyFrom);
if (!(nType & SER_GETHASH))
READWRITE(vchSig);
)
uint256 GetHash() const { return SerializeHash(*this); }
uint256 GetSigHash() const { return SerializeHash(*this, SER_GETHASH|SER_SKIPSIG); }
uint256 GetUserHash() const { return Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); }
bool AcceptReview();
};
class CProduct
{
public:
int nVersion;
CAddress addr;
map<string, string> mapValue;
map<string, string> mapDetails;
vector<pair<string, string> > vOrderForm;
unsigned int nSequence;
vector<unsigned char> vchPubKeyFrom;
vector<unsigned char> vchSig;
// disk only
int nAtoms;
// memory only
set<unsigned int> setSources;
CProduct()
{
nVersion = 1;
nAtoms = 0;
nSequence = 0;
}
IMPLEMENT_SERIALIZE
(
READWRITE(this->nVersion);
nVersion = this->nVersion;
READWRITE(addr);
READWRITE(mapValue);
if (!(nType & SER_GETHASH))
{
READWRITE(mapDetails);
READWRITE(vOrderForm);
READWRITE(nSequence);
}
READWRITE(vchPubKeyFrom);
if (!(nType & SER_GETHASH))
READWRITE(vchSig);
if (nType & SER_DISK)
READWRITE(nAtoms);
)
uint256 GetHash() const { return SerializeHash(*this); }
uint256 GetSigHash() const { return SerializeHash(*this, SER_GETHASH|SER_SKIPSIG); }
uint256 GetUserHash() const { return Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); }
bool CheckSignature();
bool CheckProduct();
};
extern map<uint256, CProduct> mapProducts;
extern CCriticalSection cs_mapProducts;
extern map<uint256, CProduct> mapMyProducts;

BIN
mingwm10.dll Normal file

Binary file not shown.

1100
net.cpp Normal file

File diff suppressed because it is too large Load diff

856
net.h Normal file
View file

@ -0,0 +1,856 @@
// Copyright (c) 2009 Satoshi Nakamoto
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
class CMessageHeader;
class CAddress;
class CInv;
class CRequestTracker;
class CNode;
static const unsigned short DEFAULT_PORT = htons(8333);
static const unsigned int PUBLISH_HOPS = 5;
enum
{
NODE_NETWORK = (1 << 0),
};
bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet);
bool GetMyExternalIP(unsigned int& ipRet);
bool AddAddress(CAddrDB& addrdb, const CAddress& addr);
CNode* FindNode(unsigned int ip);
CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0);
void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1);
bool AnySubscribed(unsigned int nChannel);
void ThreadBitcoinMiner(void* parg);
bool StartNode(string& strError=REF(string()));
bool StopNode();
void CheckForShutdown(int n);
//
// Message header
// (4) message start
// (12) command
// (4) size
// The message start string is designed to be unlikely to occur in normal data.
// The characters are rarely used upper ascii, not valid as UTF-8, and produce
// a large 4-byte int at any alignment.
static const char pchMessageStart[4] = { 0xf9, 0xbe, 0xb4, 0xd9 };
class CMessageHeader
{
public:
enum { COMMAND_SIZE=12 };
char pchMessageStart[sizeof(::pchMessageStart)];
char pchCommand[COMMAND_SIZE];
unsigned int nMessageSize;
CMessageHeader()
{
memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart));
memset(pchCommand, 0, sizeof(pchCommand));
pchCommand[1] = 1;
nMessageSize = -1;
}
CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn)
{
memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart));
strncpy(pchCommand, pszCommand, COMMAND_SIZE);
nMessageSize = nMessageSizeIn;
}
IMPLEMENT_SERIALIZE
(
READWRITE(FLATDATA(pchMessageStart));
READWRITE(FLATDATA(pchCommand));
READWRITE(nMessageSize);
)
string GetCommand()
{
if (pchCommand[COMMAND_SIZE-1] == 0)
return string(pchCommand, pchCommand + strlen(pchCommand));
else
return string(pchCommand, pchCommand + COMMAND_SIZE);
}
bool IsValid()
{
// Check start string
if (memcmp(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)) != 0)
return false;
// Check the command string for errors
for (char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++)
{
if (*p1 == 0)
{
// Must be all zeros after the first zero
for (; p1 < pchCommand + COMMAND_SIZE; p1++)
if (*p1 != 0)
return false;
}
else if (*p1 < ' ' || *p1 > 0x7E)
return false;
}
// Message size
if (nMessageSize > 0x10000000)
{
printf("CMessageHeader::IsValid() : nMessageSize too large %u\n", nMessageSize);
return false;
}
return true;
}
};
static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
class CAddress
{
public:
uint64 nServices;
unsigned char pchReserved[12];
unsigned int ip;
unsigned short port;
// disk only
unsigned int nTime;
// memory only
unsigned int nLastFailed;
CAddress()
{
nServices = 0;
memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
ip = 0;
port = DEFAULT_PORT;
nTime = GetAdjustedTime();
nLastFailed = 0;
}
CAddress(unsigned int ipIn, unsigned short portIn=DEFAULT_PORT, uint64 nServicesIn=0)
{
nServices = nServicesIn;
memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
ip = ipIn;
port = portIn;
nTime = GetAdjustedTime();
nLastFailed = 0;
}
explicit CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn=0)
{
nServices = nServicesIn;
memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
ip = sockaddr.sin_addr.s_addr;
port = sockaddr.sin_port;
nTime = GetAdjustedTime();
nLastFailed = 0;
}
explicit CAddress(const char* pszIn, uint64 nServicesIn=0)
{
nServices = nServicesIn;
memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
ip = 0;
port = DEFAULT_PORT;
nTime = GetAdjustedTime();
nLastFailed = 0;
char psz[100];
if (strlen(pszIn) > ARRAYLEN(psz)-1)
return;
strcpy(psz, pszIn);
unsigned int a, b, c, d, e;
if (sscanf(psz, "%u.%u.%u.%u:%u", &a, &b, &c, &d, &e) < 4)
return;
char* pszPort = strchr(psz, ':');
if (pszPort)
{
*pszPort++ = '\0';
port = htons(atoi(pszPort));
}
ip = inet_addr(psz);
}
IMPLEMENT_SERIALIZE
(
if (nType & SER_DISK)
{
READWRITE(nVersion);
READWRITE(nTime);
}
READWRITE(nServices);
READWRITE(FLATDATA(pchReserved));
READWRITE(ip);
READWRITE(port);
)
friend inline bool operator==(const CAddress& a, const CAddress& b)
{
return (memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved)) == 0 &&
a.ip == b.ip &&
a.port == b.port);
}
friend inline bool operator<(const CAddress& a, const CAddress& b)
{
int ret = memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved));
if (ret < 0)
return true;
else if (ret == 0)
{
if (ntohl(a.ip) < ntohl(b.ip))
return true;
else if (a.ip == b.ip)
return ntohs(a.port) < ntohs(b.port);
}
return false;
}
vector<unsigned char> GetKey() const
{
CDataStream ss;
ss.reserve(18);
ss << FLATDATA(pchReserved) << ip << port;
#if defined(_MSC_VER) && _MSC_VER < 1300
return vector<unsigned char>((unsigned char*)&ss.begin()[0], (unsigned char*)&ss.end()[0]);
#else
return vector<unsigned char>(ss.begin(), ss.end());
#endif
}
struct sockaddr_in GetSockAddr() const
{
struct sockaddr_in sockaddr;
sockaddr.sin_family = AF_INET;
sockaddr.sin_addr.s_addr = ip;
sockaddr.sin_port = port;
return sockaddr;
}
bool IsIPv4() const
{
return (memcmp(pchReserved, pchIPv4, sizeof(pchIPv4)) == 0);
}
bool IsRoutable() const
{
return !(GetByte(3) == 10 || (GetByte(3) == 192 && GetByte(2) == 168) || GetByte(3) == 127 || GetByte(3) == 0);
}
unsigned char GetByte(int n) const
{
return ((unsigned char*)&ip)[3-n];
}
string ToStringIPPort() const
{
return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port));
}
string ToStringIP() const
{
return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
}
string ToString() const
{
return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port));
//return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
}
void print() const
{
printf("CAddress(%s)\n", ToString().c_str());
}
};
enum
{
MSG_TX = 1,
MSG_BLOCK,
MSG_REVIEW,
MSG_PRODUCT,
MSG_TABLE,
};
static const char* ppszTypeName[] =
{
"ERROR",
"tx",
"block",
"review",
"product",
"table",
};
class CInv
{
public:
int type;
uint256 hash;
CInv()
{
type = 0;
hash = 0;
}
CInv(int typeIn, const uint256& hashIn)
{
type = typeIn;
hash = hashIn;
}
CInv(const string& strType, const uint256& hashIn)
{
int i;
for (i = 1; i < ARRAYLEN(ppszTypeName); i++)
{
if (strType == ppszTypeName[i])
{
type = i;
break;
}
}
if (i == ARRAYLEN(ppszTypeName))
throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType.c_str()));
hash = hashIn;
}
IMPLEMENT_SERIALIZE
(
READWRITE(type);
READWRITE(hash);
)
friend inline bool operator<(const CInv& a, const CInv& b)
{
return (a.type < b.type || (a.type == b.type && a.hash < b.hash));
}
bool IsKnownType() const
{
return (type >= 1 && type < ARRAYLEN(ppszTypeName));
}
const char* GetCommand() const
{
if (!IsKnownType())
throw std::out_of_range(strprintf("CInv::GetCommand() : type=% unknown type", type));
return ppszTypeName[type];
}
string ToString() const
{
return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,14).c_str());
}
void print() const
{
printf("CInv(%s)\n", ToString().c_str());
}
};
class CRequestTracker
{
public:
void (*fn)(void*, CDataStream&);
void* param1;
explicit CRequestTracker(void (*fnIn)(void*, CDataStream&)=NULL, void* param1In=NULL)
{
fn = fnIn;
param1 = param1In;
}
bool IsNull()
{
return fn == NULL;
}
};
extern bool fClient;
extern uint64 nLocalServices;
extern CAddress addrLocalHost;
extern CNode* pnodeLocalHost;
extern bool fShutdown;
extern array<bool, 10> vfThreadRunning;
extern vector<CNode*> vNodes;
extern CCriticalSection cs_vNodes;
extern map<vector<unsigned char>, CAddress> mapAddresses;
extern CCriticalSection cs_mapAddresses;
extern map<CInv, CDataStream> mapRelay;
extern deque<pair<int64, CInv> > vRelayExpiration;
extern CCriticalSection cs_mapRelay;
extern map<CInv, int64> mapAlreadyAskedFor;
extern CAddress addrProxy;
class CNode
{
public:
// socket
uint64 nServices;
SOCKET hSocket;
CDataStream vSend;
CDataStream vRecv;
CCriticalSection cs_vSend;
CCriticalSection cs_vRecv;
unsigned int nPushPos;
CAddress addr;
int nVersion;
bool fClient;
bool fInbound;
bool fNetworkNode;
bool fDisconnect;
protected:
int nRefCount;
public:
int64 nReleaseTime;
map<uint256, CRequestTracker> mapRequests;
CCriticalSection cs_mapRequests;
// flood
vector<CAddress> vAddrToSend;
set<CAddress> setAddrKnown;
// inventory based relay
set<CInv> setInventoryKnown;
set<CInv> setInventoryKnown2;
vector<CInv> vInventoryToSend;
CCriticalSection cs_inventory;
multimap<int64, CInv> mapAskFor;
// publish and subscription
vector<char> vfSubscribe;
CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false)
{
nServices = 0;
hSocket = hSocketIn;
vSend.SetType(SER_NETWORK);
vRecv.SetType(SER_NETWORK);
nPushPos = -1;
addr = addrIn;
nVersion = 0;
fClient = false; // set by version message
fInbound = fInboundIn;
fNetworkNode = false;
fDisconnect = false;
nRefCount = 0;
nReleaseTime = 0;
vfSubscribe.assign(256, false);
// Push a version message
/// when NTP implemented, change to just nTime = GetAdjustedTime()
int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
PushMessage("version", VERSION, nLocalServices, nTime, addr);
}
~CNode()
{
if (hSocket != INVALID_SOCKET)
closesocket(hSocket);
}
private:
CNode(const CNode&);
void operator=(const CNode&);
public:
bool ReadyToDisconnect()
{
return fDisconnect || GetRefCount() <= 0;
}
int GetRefCount()
{
return max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0);
}
void AddRef(int64 nTimeout=0)
{
if (nTimeout != 0)
nReleaseTime = max(nReleaseTime, GetTime() + nTimeout);
else
nRefCount++;
}
void Release()
{
nRefCount--;
}
void AddInventoryKnown(const CInv& inv)
{
CRITICAL_BLOCK(cs_inventory)
setInventoryKnown.insert(inv);
}
void PushInventory(const CInv& inv)
{
CRITICAL_BLOCK(cs_inventory)
if (!setInventoryKnown.count(inv))
vInventoryToSend.push_back(inv);
}
void AskFor(const CInv& inv)
{
// We're using mapAskFor as a priority queue,
// the key is the earliest time the request can be sent
int64& nRequestTime = mapAlreadyAskedFor[inv];
printf("askfor %s %I64d\n", inv.ToString().c_str(), nRequestTime);
// Make sure not to reuse time indexes to keep things in the same order
int64 nNow = (GetTime() - 1) * 1000000;
static int64 nLastTime;
nLastTime = nNow = max(nNow, ++nLastTime);
// Each retry is 2 minutes after the last
nRequestTime = max(nRequestTime + 2 * 60 * 1000000, nNow);
mapAskFor.insert(make_pair(nRequestTime, inv));
}
void BeginMessage(const char* pszCommand)
{
EnterCriticalSection(&cs_vSend);
if (nPushPos != -1)
AbortMessage();
nPushPos = vSend.size();
vSend << CMessageHeader(pszCommand, 0);
printf("sending: %-12s ", pszCommand);
}
void AbortMessage()
{
if (nPushPos == -1)
return;
vSend.resize(nPushPos);
nPushPos = -1;
LeaveCriticalSection(&cs_vSend);
printf("(aborted)\n");
}
void EndMessage()
{
extern int nDropMessagesTest;
if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0)
{
printf("dropmessages DROPPING SEND MESSAGE\n");
AbortMessage();
return;
}
if (nPushPos == -1)
return;
// Patch in the size
unsigned int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader);
memcpy((char*)&vSend[nPushPos] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize));
printf("(%d bytes) ", nSize);
//for (int i = nPushPos+sizeof(CMessageHeader); i < min(vSend.size(), nPushPos+sizeof(CMessageHeader)+20U); i++)
// printf("%02x ", vSend[i] & 0xff);
printf("\n");
nPushPos = -1;
LeaveCriticalSection(&cs_vSend);
}
void EndMessageAbortIfEmpty()
{
if (nPushPos == -1)
return;
int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader);
if (nSize > 0)
EndMessage();
else
AbortMessage();
}
const char* GetMessageCommand() const
{
if (nPushPos == -1)
return "";
return &vSend[nPushPos] + offsetof(CMessageHeader, pchCommand);
}
void PushMessage(const char* pszCommand)
{
try
{
BeginMessage(pszCommand);
EndMessage();
}
catch (...)
{
AbortMessage();
throw;
}
}
template<typename T1>
void PushMessage(const char* pszCommand, const T1& a1)
{
try
{
BeginMessage(pszCommand);
vSend << a1;
EndMessage();
}
catch (...)
{
AbortMessage();
throw;
}
}
template<typename T1, typename T2>
void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)
{
try
{
BeginMessage(pszCommand);
vSend << a1 << a2;
EndMessage();
}
catch (...)
{
AbortMessage();
throw;
}
}
template<typename T1, typename T2, typename T3>
void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)
{
try
{
BeginMessage(pszCommand);
vSend << a1 << a2 << a3;
EndMessage();
}
catch (...)
{
AbortMessage();
throw;
}
}
template<typename T1, typename T2, typename T3, typename T4>
void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4)
{
try
{
BeginMessage(pszCommand);
vSend << a1 << a2 << a3 << a4;
EndMessage();
}
catch (...)
{
AbortMessage();
throw;
}
}
void PushRequest(const char* pszCommand,
void (*fn)(void*, CDataStream&), void* param1)
{
uint256 hashReply;
RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
CRITICAL_BLOCK(cs_mapRequests)
mapRequests[hashReply] = CRequestTracker(fn, param1);
PushMessage(pszCommand, hashReply);
}
template<typename T1>
void PushRequest(const char* pszCommand, const T1& a1,
void (*fn)(void*, CDataStream&), void* param1)
{
uint256 hashReply;
RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
CRITICAL_BLOCK(cs_mapRequests)
mapRequests[hashReply] = CRequestTracker(fn, param1);
PushMessage(pszCommand, hashReply, a1);
}
template<typename T1, typename T2>
void PushRequest(const char* pszCommand, const T1& a1, const T2& a2,
void (*fn)(void*, CDataStream&), void* param1)
{
uint256 hashReply;
RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
CRITICAL_BLOCK(cs_mapRequests)
mapRequests[hashReply] = CRequestTracker(fn, param1);
PushMessage(pszCommand, hashReply, a1, a2);
}
bool IsSubscribed(unsigned int nChannel);
void Subscribe(unsigned int nChannel, unsigned int nHops=0);
void CancelSubscribe(unsigned int nChannel);
void Disconnect();
};
inline void RelayInventory(const CInv& inv)
{
// Put on lists to offer to the other nodes
CRITICAL_BLOCK(cs_vNodes)
foreach(CNode* pnode, vNodes)
pnode->PushInventory(inv);
}
template<typename T>
void RelayMessage(const CInv& inv, const T& a)
{
CDataStream ss(SER_NETWORK);
ss.reserve(10000);
ss << a;
RelayMessage(inv, ss);
}
template<>
inline void RelayMessage<>(const CInv& inv, const CDataStream& ss)
{
CRITICAL_BLOCK(cs_mapRelay)
{
// Expire old relay messages
while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
{
mapRelay.erase(vRelayExpiration.front().second);
vRelayExpiration.pop_front();
}
// Save original serialized message so newer versions are preserved
mapRelay[inv] = ss;
vRelayExpiration.push_back(make_pair(GetTime() + 15 * 60, inv));
}
RelayInventory(inv);
}
//
// Templates for the publish and subscription system.
// The object being published as T& obj needs to have:
// a set<unsigned int> setSources member
// specializations of AdvertInsert and AdvertErase
// Currently implemented for CTable and CProduct.
//
template<typename T>
void AdvertStartPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
{
// Add to sources
obj.setSources.insert(pfrom->addr.ip);
if (!AdvertInsert(obj))
return;
// Relay
CRITICAL_BLOCK(cs_vNodes)
foreach(CNode* pnode, vNodes)
if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel)))
pnode->PushMessage("publish", nChannel, nHops, obj);
}
template<typename T>
void AdvertStopPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
{
uint256 hash = obj.GetHash();
CRITICAL_BLOCK(cs_vNodes)
foreach(CNode* pnode, vNodes)
if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel)))
pnode->PushMessage("pub-cancel", nChannel, nHops, hash);
AdvertErase(obj);
}
template<typename T>
void AdvertRemoveSource(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
{
// Remove a source
obj.setSources.erase(pfrom->addr.ip);
// If no longer supported by any sources, cancel it
if (obj.setSources.empty())
AdvertStopPublish(pfrom, nChannel, nHops, obj);
}

BIN
rc/addressbook16.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
rc/addressbook16mask.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 B

BIN
rc/addressbook20.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
rc/addressbook20mask.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 B

BIN
rc/bitcoin.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
rc/check.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

BIN
rc/send16.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
rc/send16mask.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 B

BIN
rc/send16masknoshadow.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 B

BIN
rc/send20.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
rc/send20mask.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 B

76
readme.txt Normal file
View file

@ -0,0 +1,76 @@
BitCoin v0.1.5 ALPHA
Copyright (c) 2009 Satoshi Nakamoto
Distributed under the MIT/X11 software license, see the accompanying
file license.txt or http://www.opensource.org/licenses/mit-license.php.
This product includes software developed by the OpenSSL Project for use in
the OpenSSL Toolkit (http://www.openssl.org/). This product includes
cryptographic software written by Eric Young (eay@cryptsoft.com).
Compilers Supported
-------------------
MinGW GCC (v3.4.5)
Microsoft Visual C++ 6.0 SP6
Dependencies
------------
Libraries you need to obtain separately to build:
default path download
wxWidgets \wxWidgets http://www.wxwidgets.org/downloads/
OpenSSL \OpenSSL http://www.openssl.org/source/
Berkeley DB \DB http://www.oracle.com/technology/software/products/berkeley-db/index.html
Boost \Boost http://www.boost.org/users/download/
Their licenses:
wxWidgets LGPL 2.1 with very liberal exceptions
OpenSSL Old BSD license with the problematic advertising requirement
Berkeley DB New BSD license with additional requirement that linked software must be free open source
Boost MIT-like license
OpenSSL
-------
Bitcoin does not use any encryption. If you want to do a no-everything
build of OpenSSL to exclude encryption routines, a few patches are required.
(OpenSSL v0.9.8h)
Edit engines\e_gmp.c and put this #ifndef around #include <openssl/rsa.h>
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
Add this to crypto\err\err_all.c before the ERR_load_crypto_strings line:
void ERR_load_RSA_strings(void) { }
Edit ms\mingw32.bat and replace the Configure line's parameters with this
no-everything list. You have to put this in the batch file because batch
files can't handle more than 9 parameters.
perl Configure mingw threads no-rc2 no-rc4 no-rc5 no-idea no-des no-bf no-cast no-aes no-camellia no-seed no-rsa no-dh
Also REM out the following line in ms\mingw32.bat. The build fails after it's
already finished building libeay32, which is all we care about, but the
failure aborts the script before it runs dllwrap to generate libeay32.dll.
REM if errorlevel 1 goto end
Build
ms\mingw32.bat
If you want to use it with MSVC, generate the .lib file
lib /machine:i386 /def:ms\libeay32.def /out:out\libeay32.lib
Berkeley DB
-----------
MinGW with MSYS:
cd \DB\build_unix
sh ../dist/configure --enable-mingw --enable-cxx
make
Boost
-----
You may need Boost version 1.35 to build with MSVC 6.0. I couldn't get
version 1.37 to compile with MSVC 6.0.

1127
script.cpp Normal file

File diff suppressed because it is too large Load diff

597
script.h Normal file
View file

@ -0,0 +1,597 @@
// Copyright (c) 2009 Satoshi Nakamoto
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
class CTransaction;
enum
{
SIGHASH_ALL = 1,
SIGHASH_NONE = 2,
SIGHASH_SINGLE = 3,
SIGHASH_ANYONECANPAY = 0x80,
};
enum opcodetype
{
// push value
OP_0=0,
OP_FALSE=OP_0,
OP_PUSHDATA1=76,
OP_PUSHDATA2,
OP_PUSHDATA4,
OP_1NEGATE,
OP_RESERVED,
OP_1,
OP_TRUE=OP_1,
OP_2,
OP_3,
OP_4,
OP_5,
OP_6,
OP_7,
OP_8,
OP_9,
OP_10,
OP_11,
OP_12,
OP_13,
OP_14,
OP_15,
OP_16,
// control
OP_NOP,
OP_VER,
OP_IF,
OP_NOTIF,
OP_VERIF,
OP_VERNOTIF,
OP_ELSE,
OP_ENDIF,
OP_VERIFY,
OP_RETURN,
// stack ops
OP_TOALTSTACK,
OP_FROMALTSTACK,
OP_2DROP,
OP_2DUP,
OP_3DUP,
OP_2OVER,
OP_2ROT,
OP_2SWAP,
OP_IFDUP,
OP_DEPTH,
OP_DROP,
OP_DUP,
OP_NIP,
OP_OVER,
OP_PICK,
OP_ROLL,
OP_ROT,
OP_SWAP,
OP_TUCK,
// splice ops
OP_CAT,
OP_SUBSTR,
OP_LEFT,
OP_RIGHT,
OP_SIZE,
// bit logic
OP_INVERT,
OP_AND,
OP_OR,
OP_XOR,
OP_EQUAL,
OP_EQUALVERIFY,
OP_RESERVED1,
OP_RESERVED2,
// numeric
OP_1ADD,
OP_1SUB,
OP_2MUL,
OP_2DIV,
OP_NEGATE,
OP_ABS,
OP_NOT,
OP_0NOTEQUAL,
OP_ADD,
OP_SUB,
OP_MUL,
OP_DIV,
OP_MOD,
OP_LSHIFT,
OP_RSHIFT,
OP_BOOLAND,
OP_BOOLOR,
OP_NUMEQUAL,
OP_NUMEQUALVERIFY,
OP_NUMNOTEQUAL,
OP_LESSTHAN,
OP_GREATERTHAN,
OP_LESSTHANOREQUAL,
OP_GREATERTHANOREQUAL,
OP_MIN,
OP_MAX,
OP_WITHIN,
// crypto
OP_RIPEMD160,
OP_SHA1,
OP_SHA256,
OP_HASH160,
OP_HASH256,
OP_CODESEPARATOR,
OP_CHECKSIG,
OP_CHECKSIGVERIFY,
OP_CHECKMULTISIG,
OP_CHECKMULTISIGVERIFY,
// multi-byte opcodes
OP_SINGLEBYTE_END = 0xF0,
OP_DOUBLEBYTE_BEGIN = 0xF000,
// template matching params
OP_PUBKEY,
OP_PUBKEYHASH,
OP_INVALIDOPCODE = 0xFFFF,
};
inline const char* GetOpName(opcodetype opcode)
{
switch (opcode)
{
// push value
case OP_0 : return "0";
case OP_PUSHDATA1 : return "OP_PUSHDATA1";
case OP_PUSHDATA2 : return "OP_PUSHDATA2";
case OP_PUSHDATA4 : return "OP_PUSHDATA4";
case OP_1NEGATE : return "-1";
case OP_RESERVED : return "OP_RESERVED";
case OP_1 : return "1";
case OP_2 : return "2";
case OP_3 : return "3";
case OP_4 : return "4";
case OP_5 : return "5";
case OP_6 : return "6";
case OP_7 : return "7";
case OP_8 : return "8";
case OP_9 : return "9";
case OP_10 : return "10";
case OP_11 : return "11";
case OP_12 : return "12";
case OP_13 : return "13";
case OP_14 : return "14";
case OP_15 : return "15";
case OP_16 : return "16";
// control
case OP_NOP : return "OP_NOP";
case OP_VER : return "OP_VER";
case OP_IF : return "OP_IF";
case OP_NOTIF : return "OP_NOTIF";
case OP_VERIF : return "OP_VERIF";
case OP_VERNOTIF : return "OP_VERNOTIF";
case OP_ELSE : return "OP_ELSE";
case OP_ENDIF : return "OP_ENDIF";
case OP_VERIFY : return "OP_VERIFY";
case OP_RETURN : return "OP_RETURN";
// stack ops
case OP_TOALTSTACK : return "OP_TOALTSTACK";
case OP_FROMALTSTACK : return "OP_FROMALTSTACK";
case OP_2DROP : return "OP_2DROP";
case OP_2DUP : return "OP_2DUP";
case OP_3DUP : return "OP_3DUP";
case OP_2OVER : return "OP_2OVER";
case OP_2ROT : return "OP_2ROT";
case OP_2SWAP : return "OP_2SWAP";
case OP_IFDUP : return "OP_IFDUP";
case OP_DEPTH : return "OP_DEPTH";
case OP_DROP : return "OP_DROP";
case OP_DUP : return "OP_DUP";
case OP_NIP : return "OP_NIP";
case OP_OVER : return "OP_OVER";
case OP_PICK : return "OP_PICK";
case OP_ROLL : return "OP_ROLL";
case OP_ROT : return "OP_ROT";
case OP_SWAP : return "OP_SWAP";
case OP_TUCK : return "OP_TUCK";
// splice ops
case OP_CAT : return "OP_CAT";
case OP_SUBSTR : return "OP_SUBSTR";
case OP_LEFT : return "OP_LEFT";
case OP_RIGHT : return "OP_RIGHT";
case OP_SIZE : return "OP_SIZE";
// bit logic
case OP_INVERT : return "OP_INVERT";
case OP_AND : return "OP_AND";
case OP_OR : return "OP_OR";
case OP_XOR : return "OP_XOR";
case OP_EQUAL : return "OP_EQUAL";
case OP_EQUALVERIFY : return "OP_EQUALVERIFY";
case OP_RESERVED1 : return "OP_RESERVED1";
case OP_RESERVED2 : return "OP_RESERVED2";
// numeric
case OP_1ADD : return "OP_1ADD";
case OP_1SUB : return "OP_1SUB";
case OP_2MUL : return "OP_2MUL";
case OP_2DIV : return "OP_2DIV";
case OP_NEGATE : return "OP_NEGATE";
case OP_ABS : return "OP_ABS";
case OP_NOT : return "OP_NOT";
case OP_0NOTEQUAL : return "OP_0NOTEQUAL";
case OP_ADD : return "OP_ADD";
case OP_SUB : return "OP_SUB";
case OP_MUL : return "OP_MUL";
case OP_DIV : return "OP_DIV";
case OP_MOD : return "OP_MOD";
case OP_LSHIFT : return "OP_LSHIFT";
case OP_RSHIFT : return "OP_RSHIFT";
case OP_BOOLAND : return "OP_BOOLAND";
case OP_BOOLOR : return "OP_BOOLOR";
case OP_NUMEQUAL : return "OP_NUMEQUAL";
case OP_NUMEQUALVERIFY : return "OP_NUMEQUALVERIFY";
case OP_NUMNOTEQUAL : return "OP_NUMNOTEQUAL";
case OP_LESSTHAN : return "OP_LESSTHAN";
case OP_GREATERTHAN : return "OP_GREATERTHAN";
case OP_LESSTHANOREQUAL : return "OP_LESSTHANOREQUAL";
case OP_GREATERTHANOREQUAL : return "OP_GREATERTHANOREQUAL";
case OP_MIN : return "OP_MIN";
case OP_MAX : return "OP_MAX";
case OP_WITHIN : return "OP_WITHIN";
// crypto
case OP_RIPEMD160 : return "OP_RIPEMD160";
case OP_SHA1 : return "OP_SHA1";
case OP_SHA256 : return "OP_SHA256";
case OP_HASH160 : return "OP_HASH160";
case OP_HASH256 : return "OP_HASH256";
case OP_CODESEPARATOR : return "OP_CODESEPARATOR";
case OP_CHECKSIG : return "OP_CHECKSIG";
case OP_CHECKSIGVERIFY : return "OP_CHECKSIGVERIFY";
case OP_CHECKMULTISIG : return "OP_CHECKMULTISIG";
case OP_CHECKMULTISIGVERIFY : return "OP_CHECKMULTISIGVERIFY";
// multi-byte opcodes
case OP_SINGLEBYTE_END : return "OP_SINGLEBYTE_END";
case OP_DOUBLEBYTE_BEGIN : return "OP_DOUBLEBYTE_BEGIN";
case OP_PUBKEY : return "OP_PUBKEY";
case OP_PUBKEYHASH : return "OP_PUBKEYHASH";
case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE";
default:
return "UNKNOWN_OPCODE";
}
};
inline string ValueString(const vector<unsigned char>& vch)
{
if (vch.size() <= 4)
return strprintf("%d", CBigNum(vch).getint());
else
return HexNumStr(vch.begin(), vch.end());
//return string("(") + HexStr(vch.begin(), vch.end()) + string(")");
}
inline string StackString(const vector<vector<unsigned char> >& vStack)
{
string str;
foreach(const vector<unsigned char>& vch, vStack)
{
if (!str.empty())
str += " ";
str += ValueString(vch);
}
return str;
}
class CScript : public vector<unsigned char>
{
protected:
CScript& push_int64(int64 n)
{
if (n == -1 || (n >= 1 && n <= 16))
{
push_back(n + (OP_1 - 1));
}
else
{
CBigNum bn(n);
*this << bn.getvch();
}
return (*this);
}
CScript& push_uint64(uint64 n)
{
if (n == -1 || (n >= 1 && n <= 16))
{
push_back(n + (OP_1 - 1));
}
else
{
CBigNum bn(n);
*this << bn.getvch();
}
return (*this);
}
public:
CScript() { }
CScript(const CScript& b) : vector<unsigned char>(b.begin(), b.end()) { }
CScript(const_iterator pbegin, const_iterator pend) : vector<unsigned char>(pbegin, pend) { }
#ifndef _MSC_VER
CScript(const unsigned char* pbegin, const unsigned char* pend) : vector<unsigned char>(pbegin, pend) { }
#endif
CScript& operator+=(const CScript& b)
{
insert(end(), b.begin(), b.end());
return *this;
}
friend CScript operator+(const CScript& a, const CScript& b)
{
CScript ret = a;
ret += b;
return (ret);
}
explicit CScript(char b) { operator<<(b); }
explicit CScript(short b) { operator<<(b); }
explicit CScript(int b) { operator<<(b); }
explicit CScript(long b) { operator<<(b); }
explicit CScript(int64 b) { operator<<(b); }
explicit CScript(unsigned char b) { operator<<(b); }
explicit CScript(unsigned int b) { operator<<(b); }
explicit CScript(unsigned short b) { operator<<(b); }
explicit CScript(unsigned long b) { operator<<(b); }
explicit CScript(uint64 b) { operator<<(b); }
explicit CScript(opcodetype b) { operator<<(b); }
explicit CScript(const uint256& b) { operator<<(b); }
explicit CScript(const CBigNum& b) { operator<<(b); }
explicit CScript(const vector<unsigned char>& b) { operator<<(b); }
CScript& operator<<(char b) { return (push_int64(b)); }
CScript& operator<<(short b) { return (push_int64(b)); }
CScript& operator<<(int b) { return (push_int64(b)); }
CScript& operator<<(long b) { return (push_int64(b)); }
CScript& operator<<(int64 b) { return (push_int64(b)); }
CScript& operator<<(unsigned char b) { return (push_uint64(b)); }
CScript& operator<<(unsigned int b) { return (push_uint64(b)); }
CScript& operator<<(unsigned short b) { return (push_uint64(b)); }
CScript& operator<<(unsigned long b) { return (push_uint64(b)); }
CScript& operator<<(uint64 b) { return (push_uint64(b)); }
CScript& operator<<(opcodetype opcode)
{
if (opcode <= OP_SINGLEBYTE_END)
{
insert(end(), (unsigned char)opcode);
}
else
{
assert(opcode >= OP_DOUBLEBYTE_BEGIN);
insert(end(), (unsigned char)(opcode >> 8));
insert(end(), (unsigned char)(opcode & 0xFF));
}
return (*this);
}
CScript& operator<<(const uint160& b)
{
insert(end(), sizeof(b));
insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b));
return (*this);
}
CScript& operator<<(const uint256& b)
{
insert(end(), sizeof(b));
insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b));
return (*this);
}
CScript& operator<<(const CBigNum& b)
{
*this << b.getvch();
return (*this);
}
CScript& operator<<(const vector<unsigned char>& b)
{
if (b.size() < OP_PUSHDATA1)
{
insert(end(), (unsigned char)b.size());
}
else if (b.size() <= 0xff)
{
insert(end(), OP_PUSHDATA1);
insert(end(), (unsigned char)b.size());
}
else
{
insert(end(), OP_PUSHDATA2);
unsigned short nSize = b.size();
insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize));
}
insert(end(), b.begin(), b.end());
return (*this);
}
CScript& operator<<(const CScript& b)
{
// I'm not sure if this should push the script or concatenate scripts.
// If there's ever a use for pushing a script onto a script, delete this member fn
assert(("warning: pushing a CScript onto a CScript with << is probably not intended, use + to concatenate", false));
return (*this);
}
bool GetOp(iterator& pc, opcodetype& opcodeRet, vector<unsigned char>& vchRet)
{
// This is why people hate C++
const_iterator pc2 = pc;
bool fRet = GetOp(pc2, opcodeRet, vchRet);
pc = begin() + (pc2 - begin());
return fRet;
}
bool GetOp(const_iterator& pc, opcodetype& opcodeRet, vector<unsigned char>& vchRet) const
{
opcodeRet = OP_INVALIDOPCODE;
vchRet.clear();
if (pc >= end())
return false;
// Read instruction
unsigned int opcode = *pc++;
if (opcode >= OP_SINGLEBYTE_END)
{
if (pc + 1 > end())
return false;
opcode <<= 8;
opcode |= *pc++;
}
// Immediate operand
if (opcode <= OP_PUSHDATA4)
{
unsigned int nSize = opcode;
if (opcode == OP_PUSHDATA1)
{
if (pc + 1 > end())
return false;
nSize = *pc++;
}
else if (opcode == OP_PUSHDATA2)
{
if (pc + 2 > end())
return false;
nSize = 0;
memcpy(&nSize, &pc[0], 2);
pc += 2;
}
else if (opcode == OP_PUSHDATA4)
{
if (pc + 4 > end())
return false;
memcpy(&nSize, &pc[0], 4);
pc += 4;
}
if (pc + nSize > end())
return false;
vchRet.assign(pc, pc + nSize);
pc += nSize;
}
opcodeRet = (opcodetype)opcode;
return true;
}
void FindAndDelete(const CScript& b)
{
iterator pc = begin();
opcodetype opcode;
vector<unsigned char> vchPushValue;
int count = 0;
do
{
while (end() - pc >= b.size() && memcmp(&pc[0], &b[0], b.size()) == 0)
{
erase(pc, pc + b.size());
count++;
}
}
while (GetOp(pc, opcode, vchPushValue));
//printf("FindAndDeleted deleted %d items\n", count); /// debug
}
void PrintHex() const
{
printf("CScript(%s)\n", HexStr(begin(), end()).c_str());
}
string ToString() const
{
string str;
opcodetype opcode;
vector<unsigned char> vch;
const_iterator it = begin();
while (GetOp(it, opcode, vch))
{
if (!str.empty())
str += " ";
if (opcode <= OP_PUSHDATA4)
str += ValueString(vch);
else
str += GetOpName(opcode);
}
return str;
}
void print() const
{
printf("%s\n", ToString().c_str());
}
};
bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType=0,
vector<vector<unsigned char> >* pvStackRet=NULL);
uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
bool IsMine(const CScript& scriptPubKey);
bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, vector<unsigned char>& vchPubKeyRet);
bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret);
bool SignSignature(const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL, CScript scriptPrereq=CScript());
bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType=0);

1158
serialize.h Normal file

File diff suppressed because it is too large Load diff

554
sha.cpp Normal file
View file

@ -0,0 +1,554 @@
// This file is public domain
// SHA routines extracted as a standalone file from:
// Crypto++: a C++ Class Library of Cryptographic Schemes
// Version 5.5.2 (9/24/2007)
// http://www.cryptopp.com
// sha.cpp - modified by Wei Dai from Steve Reid's public domain sha1.c
// Steve Reid implemented SHA-1. Wei Dai implemented SHA-2.
// Both are in the public domain.
#include <assert.h>
#include <memory.h>
#include "sha.h"
namespace CryptoPP
{
// start of Steve Reid's code
#define blk0(i) (W[i] = data[i])
#define blk1(i) (W[i&15] = rotlFixed(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1))
void SHA1::InitState(HashWordType *state)
{
state[0] = 0x67452301L;
state[1] = 0xEFCDAB89L;
state[2] = 0x98BADCFEL;
state[3] = 0x10325476L;
state[4] = 0xC3D2E1F0L;
}
#define f1(x,y,z) (z^(x&(y^z)))
#define f2(x,y,z) (x^y^z)
#define f3(x,y,z) ((x&y)|(z&(x|y)))
#define f4(x,y,z) (x^y^z)
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
#define R0(v,w,x,y,z,i) z+=f1(w,x,y)+blk0(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30);
#define R1(v,w,x,y,z,i) z+=f1(w,x,y)+blk1(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30);
#define R2(v,w,x,y,z,i) z+=f2(w,x,y)+blk1(i)+0x6ED9EBA1+rotlFixed(v,5);w=rotlFixed(w,30);
#define R3(v,w,x,y,z,i) z+=f3(w,x,y)+blk1(i)+0x8F1BBCDC+rotlFixed(v,5);w=rotlFixed(w,30);
#define R4(v,w,x,y,z,i) z+=f4(w,x,y)+blk1(i)+0xCA62C1D6+rotlFixed(v,5);w=rotlFixed(w,30);
void SHA1::Transform(word32 *state, const word32 *data)
{
word32 W[16];
/* Copy context->state[] to working vars */
word32 a = state[0];
word32 b = state[1];
word32 c = state[2];
word32 d = state[3];
word32 e = state[4];
/* 4 rounds of 20 operations each. Loop unrolled. */
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
/* Add the working vars back into context.state[] */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
}
// end of Steve Reid's code
// *************************************************************
void SHA224::InitState(HashWordType *state)
{
static const word32 s[8] = {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4};
memcpy(state, s, sizeof(s));
}
void SHA256::InitState(HashWordType *state)
{
static const word32 s[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
memcpy(state, s, sizeof(s));
}
static const word32 SHA256_K[64] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
#define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15]))
#define Ch(x,y,z) (z^(x&(y^z)))
#define Maj(x,y,z) ((x&y)|(z&(x|y)))
#define a(i) T[(0-i)&7]
#define b(i) T[(1-i)&7]
#define c(i) T[(2-i)&7]
#define d(i) T[(3-i)&7]
#define e(i) T[(4-i)&7]
#define f(i) T[(5-i)&7]
#define g(i) T[(6-i)&7]
#define h(i) T[(7-i)&7]
#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA256_K[i+j]+(j?blk2(i):blk0(i));\
d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i))
// for SHA256
#define S0(x) (rotrFixed(x,2)^rotrFixed(x,13)^rotrFixed(x,22))
#define S1(x) (rotrFixed(x,6)^rotrFixed(x,11)^rotrFixed(x,25))
#define s0(x) (rotrFixed(x,7)^rotrFixed(x,18)^(x>>3))
#define s1(x) (rotrFixed(x,17)^rotrFixed(x,19)^(x>>10))
void SHA256::Transform(word32 *state, const word32 *data)
{
word32 W[16];
word32 T[8];
/* Copy context->state[] to working vars */
memcpy(T, state, sizeof(T));
/* 64 operations, partially loop unrolled */
for (unsigned int j=0; j<64; j+=16)
{
R( 0); R( 1); R( 2); R( 3);
R( 4); R( 5); R( 6); R( 7);
R( 8); R( 9); R(10); R(11);
R(12); R(13); R(14); R(15);
}
/* Add the working vars back into context.state[] */
state[0] += a(0);
state[1] += b(0);
state[2] += c(0);
state[3] += d(0);
state[4] += e(0);
state[5] += f(0);
state[6] += g(0);
state[7] += h(0);
}
/*
// smaller but slower
void SHA256_Transform(word32 *state, const word32 *data)
{
word32 T[20];
word32 W[32];
unsigned int i = 0, j = 0;
word32 *t = T+8;
memcpy(t, state, 8*4);
word32 e = t[4], a = t[0];
do
{
word32 w = data[j];
W[j] = w;
w += K[j];
w += t[7];
w += S1(e);
w += Ch(e, t[5], t[6]);
e = t[3] + w;
t[3] = t[3+8] = e;
w += S0(t[0]);
a = w + Maj(a, t[1], t[2]);
t[-1] = t[7] = a;
--t;
++j;
if (j%8 == 0)
t += 8;
} while (j<16);
do
{
i = j&0xf;
word32 w = s1(W[i+16-2]) + s0(W[i+16-15]) + W[i] + W[i+16-7];
W[i+16] = W[i] = w;
w += K[j];
w += t[7];
w += S1(e);
w += Ch(e, t[5], t[6]);
e = t[3] + w;
t[3] = t[3+8] = e;
w += S0(t[0]);
a = w + Maj(a, t[1], t[2]);
t[-1] = t[7] = a;
w = s1(W[(i+1)+16-2]) + s0(W[(i+1)+16-15]) + W[(i+1)] + W[(i+1)+16-7];
W[(i+1)+16] = W[(i+1)] = w;
w += K[j+1];
w += (t-1)[7];
w += S1(e);
w += Ch(e, (t-1)[5], (t-1)[6]);
e = (t-1)[3] + w;
(t-1)[3] = (t-1)[3+8] = e;
w += S0((t-1)[0]);
a = w + Maj(a, (t-1)[1], (t-1)[2]);
(t-1)[-1] = (t-1)[7] = a;
t-=2;
j+=2;
if (j%8 == 0)
t += 8;
} while (j<64);
state[0] += a;
state[1] += t[1];
state[2] += t[2];
state[3] += t[3];
state[4] += e;
state[5] += t[5];
state[6] += t[6];
state[7] += t[7];
}
*/
#undef S0
#undef S1
#undef s0
#undef s1
#undef R
// *************************************************************
#ifdef WORD64_AVAILABLE
void SHA384::InitState(HashWordType *state)
{
static const word64 s[8] = {
W64LIT(0xcbbb9d5dc1059ed8), W64LIT(0x629a292a367cd507),
W64LIT(0x9159015a3070dd17), W64LIT(0x152fecd8f70e5939),
W64LIT(0x67332667ffc00b31), W64LIT(0x8eb44a8768581511),
W64LIT(0xdb0c2e0d64f98fa7), W64LIT(0x47b5481dbefa4fa4)};
memcpy(state, s, sizeof(s));
}
void SHA512::InitState(HashWordType *state)
{
static const word64 s[8] = {
W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b),
W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1),
W64LIT(0x510e527fade682d1), W64LIT(0x9b05688c2b3e6c1f),
W64LIT(0x1f83d9abfb41bd6b), W64LIT(0x5be0cd19137e2179)};
memcpy(state, s, sizeof(s));
}
CRYPTOPP_ALIGN_DATA(16) static const word64 SHA512_K[80] CRYPTOPP_SECTION_ALIGN16 = {
W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd),
W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc),
W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019),
W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118),
W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe),
W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2),
W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1),
W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694),
W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3),
W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65),
W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483),
W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5),
W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210),
W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4),
W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725),
W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70),
W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926),
W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df),
W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8),
W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b),
W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001),
W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30),
W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910),
W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8),
W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53),
W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8),
W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb),
W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3),
W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60),
W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec),
W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9),
W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b),
W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207),
W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178),
W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6),
W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b),
W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493),
W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c),
W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a),
W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817)
};
#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86
// put assembly version in separate function, otherwise MSVC 2005 SP1 doesn't generate correct code for the non-assembly version
CRYPTOPP_NAKED static void CRYPTOPP_FASTCALL SHA512_SSE2_Transform(word64 *state, const word64 *data)
{
#ifdef __GNUC__
__asm__ __volatile__
(
".intel_syntax noprefix;"
AS1( push ebx)
AS2( mov ebx, eax)
#else
AS1( push ebx)
AS1( push esi)
AS1( push edi)
AS2( lea ebx, SHA512_K)
#endif
AS2( mov eax, esp)
AS2( and esp, 0xfffffff0)
AS2( sub esp, 27*16) // 17*16 for expanded data, 20*8 for state
AS1( push eax)
AS2( xor eax, eax)
AS2( lea edi, [esp+4+8*8]) // start at middle of state buffer. will decrement pointer each round to avoid copying
AS2( lea esi, [esp+4+20*8+8]) // 16-byte alignment, then add 8
AS2( movq mm4, [ecx+0*8])
AS2( movq [edi+0*8], mm4)
AS2( movq mm0, [ecx+1*8])
AS2( movq [edi+1*8], mm0)
AS2( movq mm0, [ecx+2*8])
AS2( movq [edi+2*8], mm0)
AS2( movq mm0, [ecx+3*8])
AS2( movq [edi+3*8], mm0)
AS2( movq mm5, [ecx+4*8])
AS2( movq [edi+4*8], mm5)
AS2( movq mm0, [ecx+5*8])
AS2( movq [edi+5*8], mm0)
AS2( movq mm0, [ecx+6*8])
AS2( movq [edi+6*8], mm0)
AS2( movq mm0, [ecx+7*8])
AS2( movq [edi+7*8], mm0)
ASJ( jmp, 0, f)
#define SSE2_S0_S1(r, a, b, c) \
AS2( movq mm6, r)\
AS2( psrlq r, a)\
AS2( movq mm7, r)\
AS2( psllq mm6, 64-c)\
AS2( pxor mm7, mm6)\
AS2( psrlq r, b-a)\
AS2( pxor mm7, r)\
AS2( psllq mm6, c-b)\
AS2( pxor mm7, mm6)\
AS2( psrlq r, c-b)\
AS2( pxor r, mm7)\
AS2( psllq mm6, b-a)\
AS2( pxor r, mm6)
#define SSE2_s0(r, a, b, c) \
AS2( movdqa xmm6, r)\
AS2( psrlq r, a)\
AS2( movdqa xmm7, r)\
AS2( psllq xmm6, 64-c)\
AS2( pxor xmm7, xmm6)\
AS2( psrlq r, b-a)\
AS2( pxor xmm7, r)\
AS2( psrlq r, c-b)\
AS2( pxor r, xmm7)\
AS2( psllq xmm6, c-a)\
AS2( pxor r, xmm6)
#define SSE2_s1(r, a, b, c) \
AS2( movdqa xmm6, r)\
AS2( psrlq r, a)\
AS2( movdqa xmm7, r)\
AS2( psllq xmm6, 64-c)\
AS2( pxor xmm7, xmm6)\
AS2( psrlq r, b-a)\
AS2( pxor xmm7, r)\
AS2( psllq xmm6, c-b)\
AS2( pxor xmm7, xmm6)\
AS2( psrlq r, c-b)\
AS2( pxor r, xmm7)
ASL(SHA512_Round)
// k + w is in mm0, a is in mm4, e is in mm5
AS2( paddq mm0, [edi+7*8]) // h
AS2( movq mm2, [edi+5*8]) // f
AS2( movq mm3, [edi+6*8]) // g
AS2( pxor mm2, mm3)
AS2( pand mm2, mm5)
SSE2_S0_S1(mm5,14,18,41)
AS2( pxor mm2, mm3)
AS2( paddq mm0, mm2) // h += Ch(e,f,g)
AS2( paddq mm5, mm0) // h += S1(e)
AS2( movq mm2, [edi+1*8]) // b
AS2( movq mm1, mm2)
AS2( por mm2, mm4)
AS2( pand mm2, [edi+2*8]) // c
AS2( pand mm1, mm4)
AS2( por mm1, mm2)
AS2( paddq mm1, mm5) // temp = h + Maj(a,b,c)
AS2( paddq mm5, [edi+3*8]) // e = d + h
AS2( movq [edi+3*8], mm5)
AS2( movq [edi+11*8], mm5)
SSE2_S0_S1(mm4,28,34,39) // S0(a)
AS2( paddq mm4, mm1) // a = temp + S0(a)
AS2( movq [edi-8], mm4)
AS2( movq [edi+7*8], mm4)
AS1( ret)
// first 16 rounds
ASL(0)
AS2( movq mm0, [edx+eax*8])
AS2( movq [esi+eax*8], mm0)
AS2( movq [esi+eax*8+16*8], mm0)
AS2( paddq mm0, [ebx+eax*8])
ASC( call, SHA512_Round)
AS1( inc eax)
AS2( sub edi, 8)
AS2( test eax, 7)
ASJ( jnz, 0, b)
AS2( add edi, 8*8)
AS2( cmp eax, 16)
ASJ( jne, 0, b)
// rest of the rounds
AS2( movdqu xmm0, [esi+(16-2)*8])
ASL(1)
// data expansion, W[i-2] already in xmm0
AS2( movdqu xmm3, [esi])
AS2( paddq xmm3, [esi+(16-7)*8])
AS2( movdqa xmm2, [esi+(16-15)*8])
SSE2_s1(xmm0, 6, 19, 61)
AS2( paddq xmm0, xmm3)
SSE2_s0(xmm2, 1, 7, 8)
AS2( paddq xmm0, xmm2)
AS2( movdq2q mm0, xmm0)
AS2( movhlps xmm1, xmm0)
AS2( paddq mm0, [ebx+eax*8])
AS2( movlps [esi], xmm0)
AS2( movlps [esi+8], xmm1)
AS2( movlps [esi+8*16], xmm0)
AS2( movlps [esi+8*17], xmm1)
// 2 rounds
ASC( call, SHA512_Round)
AS2( sub edi, 8)
AS2( movdq2q mm0, xmm1)
AS2( paddq mm0, [ebx+eax*8+8])
ASC( call, SHA512_Round)
// update indices and loop
AS2( add esi, 16)
AS2( add eax, 2)
AS2( sub edi, 8)
AS2( test eax, 7)
ASJ( jnz, 1, b)
// do housekeeping every 8 rounds
AS2( mov esi, 0xf)
AS2( and esi, eax)
AS2( lea esi, [esp+4+20*8+8+esi*8])
AS2( add edi, 8*8)
AS2( cmp eax, 80)
ASJ( jne, 1, b)
#define SSE2_CombineState(i) \
AS2( movq mm0, [edi+i*8])\
AS2( paddq mm0, [ecx+i*8])\
AS2( movq [ecx+i*8], mm0)
SSE2_CombineState(0)
SSE2_CombineState(1)
SSE2_CombineState(2)
SSE2_CombineState(3)
SSE2_CombineState(4)
SSE2_CombineState(5)
SSE2_CombineState(6)
SSE2_CombineState(7)
AS1( pop esp)
AS1( emms)
#if defined(__GNUC__)
AS1( pop ebx)
".att_syntax prefix;"
:
: "a" (SHA512_K), "c" (state), "d" (data)
: "%esi", "%edi", "memory", "cc"
);
#else
AS1( pop edi)
AS1( pop esi)
AS1( pop ebx)
AS1( ret)
#endif
}
#endif // #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
void SHA512::Transform(word64 *state, const word64 *data)
{
#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86
if (HasSSE2())
{
SHA512_SSE2_Transform(state, data);
return;
}
#endif
#define S0(x) (rotrFixed(x,28)^rotrFixed(x,34)^rotrFixed(x,39))
#define S1(x) (rotrFixed(x,14)^rotrFixed(x,18)^rotrFixed(x,41))
#define s0(x) (rotrFixed(x,1)^rotrFixed(x,8)^(x>>7))
#define s1(x) (rotrFixed(x,19)^rotrFixed(x,61)^(x>>6))
#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA512_K[i+j]+(j?blk2(i):blk0(i));\
d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i))
word64 W[16];
word64 T[8];
/* Copy context->state[] to working vars */
memcpy(T, state, sizeof(T));
/* 80 operations, partially loop unrolled */
for (unsigned int j=0; j<80; j+=16)
{
R( 0); R( 1); R( 2); R( 3);
R( 4); R( 5); R( 6); R( 7);
R( 8); R( 9); R(10); R(11);
R(12); R(13); R(14); R(15);
}
/* Add the working vars back into context.state[] */
state[0] += a(0);
state[1] += b(0);
state[2] += c(0);
state[3] += d(0);
state[4] += e(0);
state[5] += f(0);
state[6] += g(0);
state[7] += h(0);
}
#endif
}

177
sha.h Normal file
View file

@ -0,0 +1,177 @@
// This file is public domain
// SHA routines extracted as a standalone file from:
// Crypto++: a C++ Class Library of Cryptographic Schemes
// Version 5.5.2 (9/24/2007)
// http://www.cryptopp.com
#ifndef CRYPTOPP_SHA_H
#define CRYPTOPP_SHA_H
#include <stdlib.h>
namespace CryptoPP
{
//
// Dependencies
//
typedef unsigned char byte;
typedef unsigned short word16;
typedef unsigned int word32;
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned __int64 word64;
#else
typedef unsigned long long word64;
#endif
template <class T> inline T rotlFixed(T x, unsigned int y)
{
assert(y < sizeof(T)*8);
return T((x<<y) | (x>>(sizeof(T)*8-y)));
}
template <class T> inline T rotrFixed(T x, unsigned int y)
{
assert(y < sizeof(T)*8);
return T((x>>y) | (x<<(sizeof(T)*8-y)));
}
// ************** endian reversal ***************
#ifdef _MSC_VER
#if _MSC_VER >= 1400
#define CRYPTOPP_FAST_ROTATE(x) 1
#elif _MSC_VER >= 1300
#define CRYPTOPP_FAST_ROTATE(x) ((x) == 32 | (x) == 64)
#else
#define CRYPTOPP_FAST_ROTATE(x) ((x) == 32)
#endif
#elif (defined(__MWERKS__) && TARGET_CPU_PPC) || \
(defined(__GNUC__) && (defined(_ARCH_PWR2) || defined(_ARCH_PWR) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || defined(_ARCH_COM)))
#define CRYPTOPP_FAST_ROTATE(x) ((x) == 32)
#elif defined(__GNUC__) && (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86) // depend on GCC's peephole optimization to generate rotate instructions
#define CRYPTOPP_FAST_ROTATE(x) 1
#else
#define CRYPTOPP_FAST_ROTATE(x) 0
#endif
inline byte ByteReverse(byte value)
{
return value;
}
inline word16 ByteReverse(word16 value)
{
#ifdef CRYPTOPP_BYTESWAP_AVAILABLE
return bswap_16(value);
#elif defined(_MSC_VER) && _MSC_VER >= 1300
return _byteswap_ushort(value);
#else
return rotlFixed(value, 8U);
#endif
}
inline word32 ByteReverse(word32 value)
{
#if defined(__GNUC__)
__asm__ ("bswap %0" : "=r" (value) : "0" (value));
return value;
#elif defined(CRYPTOPP_BYTESWAP_AVAILABLE)
return bswap_32(value);
#elif defined(__MWERKS__) && TARGET_CPU_PPC
return (word32)__lwbrx(&value,0);
#elif _MSC_VER >= 1400 || (_MSC_VER >= 1300 && !defined(_DLL))
return _byteswap_ulong(value);
#elif CRYPTOPP_FAST_ROTATE(32)
// 5 instructions with rotate instruction, 9 without
return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff);
#else
// 6 instructions with rotate instruction, 8 without
value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
return rotlFixed(value, 16U);
#endif
}
#ifdef WORD64_AVAILABLE
inline word64 ByteReverse(word64 value)
{
#if defined(__GNUC__) && defined(__x86_64__)
__asm__ ("bswap %0" : "=r" (value) : "0" (value));
return value;
#elif defined(CRYPTOPP_BYTESWAP_AVAILABLE)
return bswap_64(value);
#elif defined(_MSC_VER) && _MSC_VER >= 1300
return _byteswap_uint64(value);
#elif defined(CRYPTOPP_SLOW_WORD64)
return (word64(ByteReverse(word32(value))) << 32) | ByteReverse(word32(value>>32));
#else
value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
return rotlFixed(value, 32U);
#endif
}
#endif
//
// SHA
//
// http://www.weidai.com/scan-mirror/md.html#SHA-1
class SHA1
{
public:
typedef word32 HashWordType;
static void InitState(word32 *state);
static void Transform(word32 *digest, const word32 *data);
static const char * StaticAlgorithmName() {return "SHA-1";}
};
typedef SHA1 SHA; // for backwards compatibility
// implements the SHA-256 standard
class SHA256
{
public:
typedef word32 HashWordType;
static void InitState(word32 *state);
static void Transform(word32 *digest, const word32 *data);
static const char * StaticAlgorithmName() {return "SHA-256";}
};
// implements the SHA-224 standard
class SHA224
{
public:
typedef word32 HashWordType;
static void InitState(word32 *state);
static void Transform(word32 *digest, const word32 *data) {SHA256::Transform(digest, data);}
static const char * StaticAlgorithmName() {return "SHA-224";}
};
#ifdef WORD64_AVAILABLE
// implements the SHA-512 standard
class SHA512
{
public:
typedef word64 HashWordType;
static void InitState(word64 *state);
static void Transform(word64 *digest, const word64 *data);
static const char * StaticAlgorithmName() {return "SHA-512";}
};
// implements the SHA-384 standard
class SHA384
{
public:
typedef word64 HashWordType;
static void InitState(word64 *state);
static void Transform(word64 *digest, const word64 *data) {SHA512::Transform(digest, data);}
static const char * StaticAlgorithmName() {return "SHA-384";}
};
#endif
}
#endif

3290
ui.cpp Normal file

File diff suppressed because it is too large Load diff

420
ui.h Normal file
View file

@ -0,0 +1,420 @@
// Copyright (c) 2009 Satoshi Nakamoto
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
DECLARE_EVENT_TYPE(wxEVT_CROSSTHREADCALL, -1)
DECLARE_EVENT_TYPE(wxEVT_REPLY1, -1)
DECLARE_EVENT_TYPE(wxEVT_REPLY2, -1)
DECLARE_EVENT_TYPE(wxEVT_REPLY3, -1)
DECLARE_EVENT_TYPE(wxEVT_TABLEADDED, -1)
DECLARE_EVENT_TYPE(wxEVT_TABLEUPDATED, -1)
DECLARE_EVENT_TYPE(wxEVT_TABLEDELETED, -1)
enum
{
UICALL_ADDORDER = 1,
UICALL_UPDATEORDER,
};
extern void HandleCtrlA(wxKeyEvent& event);
extern string DateTimeStr(int64 nTime);
extern string FormatTxStatus(const CWalletTx& wtx);
extern void CrossThreadCall(int nID, void* pdata);
extern void MainFrameRepaint();
extern void Shutdown(void* parg);
class CMainFrame : public CMainFrameBase
{
protected:
// Event handlers
void OnClose(wxCloseEvent& event);
void OnMouseEvents(wxMouseEvent& event);
void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); }
void OnIdle(wxIdleEvent& event);
void OnPaint(wxPaintEvent& event);
void OnPaintListCtrl(wxPaintEvent& event);
void OnMenuFileExit(wxCommandEvent& event);
void OnMenuOptionsGenerate(wxCommandEvent& event);
void OnMenuOptionsChangeYourAddress(wxCommandEvent& event);
void OnMenuOptionsOptions(wxCommandEvent& event);
void OnMenuHelpAbout(wxCommandEvent& event);
void OnButtonSend(wxCommandEvent& event);
void OnButtonAddressBook(wxCommandEvent& event);
void OnSetFocusAddress(wxFocusEvent& event);
void OnMouseEventsAddress(wxMouseEvent& event);
void OnButtonCopy(wxCommandEvent& event);
void OnButtonChange(wxCommandEvent& event);
void OnListColBeginDrag(wxListEvent& event);
void OnListItemActivatedAllTransactions(wxListEvent& event);
void OnListItemActivatedProductsSent(wxListEvent& event);
void OnListItemActivatedOrdersSent(wxListEvent& event);
void OnListItemActivatedOrdersReceived(wxListEvent& event);
public:
/** Constructor */
CMainFrame(wxWindow* parent);
~CMainFrame();
// Custom
bool fRefreshListCtrl;
bool fRefreshListCtrlRunning;
bool fOnSetFocusAddress;
CBlockIndex* pindexBestLast;
set<uint256> setUnmaturedDisplayed;
void OnCrossThreadCall(wxCommandEvent& event);
void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5);
void InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1);
void RefreshListCtrl();
void RefreshStatus();
};
class CTxDetailsDialog : public CTxDetailsDialogBase
{
protected:
// Event handlers
void OnButtonOK(wxCommandEvent& event);
public:
/** Constructor */
CTxDetailsDialog(wxWindow* parent, CWalletTx wtx);
// State
CWalletTx wtx;
};
class COptionsDialog : public COptionsDialogBase
{
protected:
// Event handlers
void OnKillFocusTransactionFee(wxFocusEvent& event);
void OnButtonOK(wxCommandEvent& event);
void OnButtonCancel(wxCommandEvent& event);
public:
/** Constructor */
COptionsDialog(wxWindow* parent);
};
class CAboutDialog : public CAboutDialogBase
{
protected:
// Event handlers
void OnButtonOK(wxCommandEvent& event);
public:
/** Constructor */
CAboutDialog(wxWindow* parent);
};
class CSendDialog : public CSendDialogBase
{
protected:
// Event handlers
void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); }
void OnTextAddress(wxCommandEvent& event);
void OnKillFocusAmount(wxFocusEvent& event);
void OnButtonAddressBook(wxCommandEvent& event);
void OnButtonPaste(wxCommandEvent& event);
void OnButtonSend(wxCommandEvent& event);
void OnButtonCancel(wxCommandEvent& event);
public:
/** Constructor */
CSendDialog(wxWindow* parent, const wxString& strAddress="");
};
class CSendingDialog : public CSendingDialogBase
{
public:
// Event handlers
void OnClose(wxCloseEvent& event);
void OnButtonOK(wxCommandEvent& event);
void OnButtonCancel(wxCommandEvent& event);
void OnPaint(wxPaintEvent& event);
public:
/** Constructor */
CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 nPriceIn, const CWalletTx& wtxIn);
~CSendingDialog();
// State
CAddress addr;
int64 nPrice;
CWalletTx wtx;
wxDateTime start;
string strStatus;
bool fCanCancel;
bool fAbort;
bool fSuccess;
bool fUIDone;
bool fWorkDone;
void Close();
void Repaint();
bool Status();
bool Status(const string& str);
bool Error(const string& str);
void StartTransfer();
void OnReply2(CDataStream& vRecv);
void OnReply3(CDataStream& vRecv);
};
void SendingDialogStartTransfer(void* parg);
void SendingDialogOnReply2(void* parg, CDataStream& vRecv);
void SendingDialogOnReply3(void* parg, CDataStream& vRecv);
class CYourAddressDialog : public CYourAddressDialogBase
{
protected:
// Event handlers
void OnListEndLabelEdit(wxListEvent& event);
void OnListItemSelected(wxListEvent& event);
void OnListItemActivated(wxListEvent& event);
void OnButtonRename(wxCommandEvent& event);
void OnButtonNew(wxCommandEvent& event);
void OnButtonCopy(wxCommandEvent& event);
void OnButtonOK(wxCommandEvent& event);
void OnButtonCancel(wxCommandEvent& event);
void OnClose(wxCloseEvent& event);
public:
/** Constructor */
CYourAddressDialog(wxWindow* parent);
CYourAddressDialog(wxWindow* parent, const string& strInitSelected);
// Custom
wxString GetAddress();
};
class CAddressBookDialog : public CAddressBookDialogBase
{
protected:
// Event handlers
void OnListEndLabelEdit(wxListEvent& event);
void OnListItemSelected(wxListEvent& event);
void OnListItemActivated(wxListEvent& event);
void OnButtonEdit(wxCommandEvent& event);
void OnButtonDelete(wxCommandEvent& event);
void OnButtonNew(wxCommandEvent& event);
void OnButtonCopy(wxCommandEvent& event);
void OnButtonOK(wxCommandEvent& event);
void OnButtonCancel(wxCommandEvent& event);
void OnClose(wxCloseEvent& event);
public:
/** Constructor */
CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, bool fSendingIn);
// Custom
bool fSending;
wxString GetAddress();
bool CheckIfMine(const string& strAddress, const string& strTitle);
};
class CProductsDialog : public CProductsDialogBase
{
protected:
// Event handlers
void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); }
void OnCombobox(wxCommandEvent& event);
void OnButtonSearch(wxCommandEvent& event);
void OnListItemActivated(wxListEvent& event);
public:
/** Constructor */
CProductsDialog(wxWindow* parent);
// Custom
vector<CProduct> m_vProduct;
};
class CEditProductDialog : public CEditProductDialogBase
{
protected:
// Event handlers
void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); }
void OnButtonDel0(wxCommandEvent& event);
void OnButtonDel1(wxCommandEvent& event);
void OnButtonDel2(wxCommandEvent& event);
void OnButtonDel3(wxCommandEvent& event);
void OnButtonDel4(wxCommandEvent& event);
void OnButtonDel5(wxCommandEvent& event);
void OnButtonDel6(wxCommandEvent& event);
void OnButtonDel7(wxCommandEvent& event);
void OnButtonDel8(wxCommandEvent& event);
void OnButtonDel9(wxCommandEvent& event);
void OnButtonDel10(wxCommandEvent& event);
void OnButtonDel11(wxCommandEvent& event);
void OnButtonDel12(wxCommandEvent& event);
void OnButtonDel13(wxCommandEvent& event);
void OnButtonDel14(wxCommandEvent& event);
void OnButtonDel15(wxCommandEvent& event);
void OnButtonDel16(wxCommandEvent& event);
void OnButtonDel17(wxCommandEvent& event);
void OnButtonDel18(wxCommandEvent& event);
void OnButtonDel19(wxCommandEvent& event);
void OnButtonAddField(wxCommandEvent& event);
void OnButtonSend(wxCommandEvent& event);
void OnButtonPreview(wxCommandEvent& event);
void OnButtonCancel(wxCommandEvent& event);
public:
/** Constructor */
CEditProductDialog(wxWindow* parent);
// Custom
enum { FIELDS_MAX = 20 };
wxTextCtrl* m_textCtrlLabel[FIELDS_MAX];
wxTextCtrl* m_textCtrlField[FIELDS_MAX];
wxButton* m_buttonDel[FIELDS_MAX];
void LayoutAll();
void ShowLine(int i, bool fShow=true);
void OnButtonDel(wxCommandEvent& event, int n);
void SetProduct(const CProduct& productIn);
void GetProduct(CProduct& product);
};
class CViewProductDialog : public CViewProductDialogBase
{
protected:
// Event handlers
void OnButtonSubmitForm(wxCommandEvent& event);
void OnButtonCancelForm(wxCommandEvent& event);
void OnButtonBack(wxCommandEvent& event);
void OnButtonNext(wxCommandEvent& event);
void OnButtonCancel(wxCommandEvent& event);
public:
/** Constructor */
CViewProductDialog(wxWindow* parent, const CProduct& productIn);
~CViewProductDialog();
// Custom
CProduct product;
enum { FIELDS_MAX = 20 };
wxStaticText* m_staticTextLabel[FIELDS_MAX];
wxTextCtrl* m_textCtrlField[FIELDS_MAX];
wxChoice* m_choiceField[FIELDS_MAX];
void GetOrder(CWalletTx& order);
void UpdateProductDisplay(bool fDetails);
void OnReply1(wxCommandEvent& event);
};
class CViewOrderDialog : public CViewOrderDialogBase
{
protected:
// Event handlers
void OnButtonOK(wxCommandEvent& event);
public:
/** Constructor */
CViewOrderDialog(wxWindow* parent, CWalletTx order, bool fReceived);
// Custom
bool fReceived;
};
class CEditReviewDialog : public CEditReviewDialogBase
{
protected:
// Event handlers
void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); }
void OnButtonSubmit(wxCommandEvent& event);
void OnButtonCancel(wxCommandEvent& event);
public:
/** Constructor */
CEditReviewDialog(wxWindow* parent);
// Custom
void GetReview(CReview& review);
};
class CGetTextFromUserDialog : public CGetTextFromUserDialogBase
{
protected:
// Event handlers
void OnButtonOK(wxCommandEvent& event) { EndModal(true); }
void OnButtonCancel(wxCommandEvent& event) { EndModal(false); }
void OnClose(wxCloseEvent& event) { EndModal(false); }
void OnKeyDown(wxKeyEvent& event)
{
if (event.GetKeyCode() == '\r' || event.GetKeyCode() == WXK_NUMPAD_ENTER)
EndModal(true);
else
HandleCtrlA(event);
}
public:
/** Constructor */
CGetTextFromUserDialog(wxWindow* parent,
const string& strCaption,
const string& strMessage1,
const string& strValue1="",
const string& strMessage2="",
const string& strValue2="") : CGetTextFromUserDialogBase(parent, wxID_ANY, strCaption)
{
m_staticTextMessage1->SetLabel(strMessage1);
m_textCtrl1->SetValue(strValue1);
if (!strMessage2.empty())
{
m_staticTextMessage2->Show(true);
m_staticTextMessage2->SetLabel(strMessage2);
m_textCtrl2->Show(true);
m_textCtrl2->SetValue(strValue2);
SetSize(wxDefaultCoord, 180);
}
}
// Custom
string GetValue() { return (string)m_textCtrl1->GetValue(); }
string GetValue1() { return (string)m_textCtrl1->GetValue(); }
string GetValue2() { return (string)m_textCtrl2->GetValue(); }
};

14
ui.rc Normal file
View file

@ -0,0 +1,14 @@
bitcoin ICON "rc/bitcoin.ico"
#include "wx/msw/wx.rc"
check ICON "rc/check.ico"
send16 BITMAP "rc/send16.bmp"
send16mask BITMAP "rc/send16mask.bmp"
send16masknoshadow BITMAP "rc/send16masknoshadow.bmp"
send20 BITMAP "rc/send20.bmp"
send20mask BITMAP "rc/send20mask.bmp"
addressbook16 BITMAP "rc/addressbook16.bmp"
addressbook16mask BITMAP "rc/addressbook16mask.bmp"
addressbook20 BITMAP "rc/addressbook20.bmp"
addressbook20mask BITMAP "rc/addressbook20mask.bmp"

1825
uibase.cpp Normal file

File diff suppressed because it is too large Load diff

723
uibase.h Normal file
View file

@ -0,0 +1,723 @@
// Copyright (c) 2009 Satoshi Nakamoto
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Apr 16 2008)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#ifndef __uibase__
#define __uibase__
#include <wx/string.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/menu.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/toolbar.h>
#include <wx/statusbr.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>
#include <wx/button.h>
#include <wx/sizer.h>
#include <wx/panel.h>
#include <wx/choice.h>
#include <wx/listctrl.h>
#include <wx/notebook.h>
#include <wx/frame.h>
#include <wx/html/htmlwin.h>
#include <wx/dialog.h>
#include <wx/statbmp.h>
#include <wx/combobox.h>
#include <wx/scrolwin.h>
#include <wx/richtext/richtextctrl.h>
#include <wx/treectrl.h>
#include <wx/checkbox.h>
///////////////////////////////////////////////////////////////////////////
#define wxID_MAINFRAME 1000
#define wxID_OPTIONSGENERATEBITCOINS 1001
#define wxID_BUTTONSEND 1002
#define wxID_BUTTONRECEIVE 1003
#define wxID_TEXTCTRLADDRESS 1004
#define wxID_BUTTONCOPY 1005
#define wxID_BUTTONCHANGE 1006
#define wxID_TRANSACTIONFEE 1007
#define wxID_TEXTCTRLPAYTO 1008
#define wxID_BUTTONPASTE 1009
#define wxID_BUTTONADDRESSBOOK 1010
#define wxID_TEXTCTRLAMOUNT 1011
#define wxID_CHOICETRANSFERTYPE 1012
#define wxID_LISTCTRL 1013
#define wxID_BUTTONRENAME 1014
#define wxID_BUTTONNEW 1015
#define wxID_BUTTONEDIT 1016
#define wxID_BUTTONDELETE 1017
#define wxID_DEL0 1018
#define wxID_DEL1 1019
#define wxID_DEL2 1020
#define wxID_DEL3 1021
#define wxID_DEL4 1022
#define wxID_DEL5 1023
#define wxID_DEL6 1024
#define wxID_DEL7 1025
#define wxID_DEL8 1026
#define wxID_DEL9 1027
#define wxID_DEL10 1028
#define wxID_DEL11 1029
#define wxID_DEL12 1030
#define wxID_DEL13 1031
#define wxID_DEL14 1032
#define wxID_DEL15 1033
#define wxID_DEL16 1034
#define wxID_DEL17 1035
#define wxID_DEL18 1036
#define wxID_DEL19 1037
#define wxID_BUTTONPREVIEW 1038
#define wxID_BUTTONSAMPLE 1039
#define wxID_CANCEL2 1040
#define wxID_BUTTONBACK 1041
#define wxID_BUTTONNEXT 1042
#define wxID_SUBMIT 1043
#define wxID_OPENNEWTABLE 1044
#define wxID_DEALHAND 1045
#define wxID_FOLD 1046
#define wxID_CALL 1047
#define wxID_RAISE 1048
#define wxID_LEAVETABLE 1049
#define wxID_DITCHPLAYER 1050
#define wxID_TEXTCTRL 1051
///////////////////////////////////////////////////////////////////////////////
/// Class CMainFrameBase
///////////////////////////////////////////////////////////////////////////////
class CMainFrameBase : public wxFrame
{
private:
protected:
wxMenuBar* m_menubar;
wxMenu* m_menuFile;
wxMenu* m_menuHelp;
wxToolBar* m_toolBar;
wxStatusBar* m_statusBar;
wxStaticText* m_staticText32;
wxTextCtrl* m_textCtrlAddress;
wxButton* m_buttonCopy;
wxButton* m_button91;
wxPanel* m_panel14;
wxStaticText* m_staticText41;
wxStaticText* m_staticTextBalance;
wxChoice* m_choiceFilter;
wxNotebook* m_notebook;
wxPanel* m_panel7;
wxPanel* m_panel9;
wxPanel* m_panel8;
wxPanel* m_panel10;
wxPanel* m_panel11;
// Virtual event handlers, overide them in your derived class
virtual void OnClose(wxCloseEvent& event){ event.Skip(); }
virtual void OnIdle(wxIdleEvent& event){ event.Skip(); }
virtual void OnMouseEvents(wxMouseEvent& event){ event.Skip(); }
virtual void OnPaint(wxPaintEvent& event){ event.Skip(); }
virtual void OnMenuFileExit(wxCommandEvent& event){ event.Skip(); }
virtual void OnMenuOptionsGenerate(wxCommandEvent& event){ event.Skip(); }
virtual void OnMenuOptionsChangeYourAddress(wxCommandEvent& event){ event.Skip(); }
virtual void OnMenuOptionsOptions(wxCommandEvent& event){ event.Skip(); }
virtual void OnMenuHelpAbout(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonSend(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonAddressBook(wxCommandEvent& event){ event.Skip(); }
virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); }
virtual void OnMouseEventsAddress(wxMouseEvent& event){ event.Skip(); }
virtual void OnSetFocusAddress(wxFocusEvent& event){ event.Skip(); }
virtual void OnButtonCopy(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonChange(wxCommandEvent& event){ event.Skip(); }
virtual void OnListColBeginDrag(wxListEvent& event){ event.Skip(); }
virtual void OnListItemActivatedAllTransactions(wxListEvent& event){ event.Skip(); }
virtual void OnPaintListCtrl(wxPaintEvent& event){ event.Skip(); }
virtual void OnListItemActivatedOrdersSent(wxListEvent& event){ event.Skip(); }
virtual void OnListItemActivatedProductsSent(wxListEvent& event){ event.Skip(); }
virtual void OnListItemActivatedOrdersReceived(wxListEvent& event){ event.Skip(); }
public:
wxMenu* m_menuOptions;
wxListCtrl* m_listCtrl;
wxListCtrl* m_listCtrlEscrows;
wxListCtrl* m_listCtrlOrdersSent;
wxListCtrl* m_listCtrlProductsSent;
wxListCtrl* m_listCtrlOrdersReceived;
CMainFrameBase(wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = wxT("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(705,484), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL);
~CMainFrameBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class CTxDetailsDialogBase
///////////////////////////////////////////////////////////////////////////////
class CTxDetailsDialogBase : public wxDialog
{
private:
protected:
wxHtmlWindow* m_htmlWin;
wxButton* m_buttonOK;
// Virtual event handlers, overide them in your derived class
virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); }
public:
CTxDetailsDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Transaction Details"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(620,450), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER);
~CTxDetailsDialogBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class COptionsDialogBase
///////////////////////////////////////////////////////////////////////////////
class COptionsDialogBase : public wxDialog
{
private:
protected:
wxStaticText* m_staticText32;
wxStaticText* m_staticText31;
wxTextCtrl* m_textCtrlTransactionFee;
wxButton* m_buttonOK;
wxButton* m_buttonCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnKillFocusTransactionFee(wxFocusEvent& event){ event.Skip(); }
virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); }
public:
COptionsDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(500,261), long style = wxDEFAULT_DIALOG_STYLE);
~COptionsDialogBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class CAboutDialogBase
///////////////////////////////////////////////////////////////////////////////
class CAboutDialogBase : public wxDialog
{
private:
protected:
wxStaticText* m_staticText40;
wxStaticText* m_staticTextMain;
wxButton* m_buttonOK;
// Virtual event handlers, overide them in your derived class
virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); }
public:
wxStaticText* m_staticTextVersion;
CAboutDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(507,298), long style = wxDEFAULT_DIALOG_STYLE);
~CAboutDialogBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class CSendDialogBase
///////////////////////////////////////////////////////////////////////////////
class CSendDialogBase : public wxDialog
{
private:
protected:
wxStaticText* m_staticText14;
wxStaticBitmap* m_bitmapCheckMark;
wxStaticText* m_staticText36;
wxTextCtrl* m_textCtrlAddress;
wxButton* m_buttonPaste;
wxButton* m_buttonAddress;
wxStaticText* m_staticText19;
wxTextCtrl* m_textCtrlAmount;
wxStaticText* m_staticText20;
wxChoice* m_choiceTransferType;
wxStaticText* m_staticTextFrom;
wxTextCtrl* m_textCtrlFrom;
wxStaticText* m_staticTextMessage;
wxTextCtrl* m_textCtrlMessage;
wxButton* m_buttonSend;
wxButton* m_buttonCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); }
virtual void OnTextAddress(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonPaste(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonAddressBook(wxCommandEvent& event){ event.Skip(); }
virtual void OnKillFocusAmount(wxFocusEvent& event){ event.Skip(); }
virtual void OnButtonSend(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); }
public:
CSendDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Send Coins"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(675,312), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER);
~CSendDialogBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class CSendingDialogBase
///////////////////////////////////////////////////////////////////////////////
class CSendingDialogBase : public wxDialog
{
private:
protected:
wxStaticText* m_staticTextSending;
wxTextCtrl* m_textCtrlStatus;
wxButton* m_buttonOK;
wxButton* m_buttonCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnClose(wxCloseEvent& event){ event.Skip(); }
virtual void OnPaint(wxPaintEvent& event){ event.Skip(); }
virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); }
public:
CSendingDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Sending..."), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(442,151), long style = wxDEFAULT_DIALOG_STYLE);
~CSendingDialogBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class CYourAddressDialogBase
///////////////////////////////////////////////////////////////////////////////
class CYourAddressDialogBase : public wxDialog
{
private:
protected:
wxStaticText* m_staticText45;
wxListCtrl* m_listCtrl;
wxButton* m_buttonRename;
wxButton* m_buttonNew;
wxButton* m_buttonCopy;
wxButton* m_buttonOK;
wxButton* m_buttonCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnClose(wxCloseEvent& event){ event.Skip(); }
virtual void OnListEndLabelEdit(wxListEvent& event){ event.Skip(); }
virtual void OnListItemActivated(wxListEvent& event){ event.Skip(); }
virtual void OnListItemSelected(wxListEvent& event){ event.Skip(); }
virtual void OnButtonRename(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonNew(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonCopy(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); }
public:
CYourAddressDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Your Bitcoin Addresses"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(610,390), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER);
~CYourAddressDialogBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class CAddressBookDialogBase
///////////////////////////////////////////////////////////////////////////////
class CAddressBookDialogBase : public wxDialog
{
private:
protected:
wxStaticText* m_staticText55;
wxListCtrl* m_listCtrl;
wxButton* m_buttonEdit;
wxButton* m_buttonNew;
wxButton* m_buttonDelete;
wxButton* m_buttonOK;
// Virtual event handlers, overide them in your derived class
virtual void OnClose(wxCloseEvent& event){ event.Skip(); }
virtual void OnListEndLabelEdit(wxListEvent& event){ event.Skip(); }
virtual void OnListItemActivated(wxListEvent& event){ event.Skip(); }
virtual void OnListItemSelected(wxListEvent& event){ event.Skip(); }
virtual void OnButtonEdit(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonNew(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonDelete(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); }
public:
wxButton* m_buttonCancel;
CAddressBookDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Address Book"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(610,390), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER);
~CAddressBookDialogBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class CProductsDialogBase
///////////////////////////////////////////////////////////////////////////////
class CProductsDialogBase : public wxDialog
{
private:
protected:
wxComboBox* m_comboBoxCategory;
wxTextCtrl* m_textCtrlSearch;
wxButton* m_buttonSearch;
wxListCtrl* m_listCtrl;
// Virtual event handlers, overide them in your derived class
virtual void OnCombobox(wxCommandEvent& event){ event.Skip(); }
virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); }
virtual void OnButtonSearch(wxCommandEvent& event){ event.Skip(); }
virtual void OnListItemActivated(wxListEvent& event){ event.Skip(); }
public:
CProductsDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Marketplace"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(708,535), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER);
~CProductsDialogBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class CEditProductDialogBase
///////////////////////////////////////////////////////////////////////////////
class CEditProductDialogBase : public wxFrame
{
private:
protected:
wxScrolledWindow* m_scrolledWindow;
wxStaticText* m_staticText106;
wxComboBox* m_comboBoxCategory;
wxStaticText* m_staticText108;
wxTextCtrl* m_textCtrlTitle;
wxStaticText* m_staticText107;
wxTextCtrl* m_textCtrlPrice;
wxStaticText* m_staticText22;
wxTextCtrl* m_textCtrlDescription;
wxStaticText* m_staticText23;
wxTextCtrl* m_textCtrlInstructions;
wxStaticText* m_staticText24;
wxStaticText* m_staticText25;
wxTextCtrl* m_textCtrlLabel0;
wxTextCtrl* m_textCtrlField0;
wxButton* m_buttonDel0;
wxTextCtrl* m_textCtrlLabel1;
wxTextCtrl* m_textCtrlField1;
wxButton* m_buttonDel1;
wxTextCtrl* m_textCtrlLabel2;
wxTextCtrl* m_textCtrlField2;
wxButton* m_buttonDel2;
wxTextCtrl* m_textCtrlLabel3;
wxTextCtrl* m_textCtrlField3;
wxButton* m_buttonDel3;
wxTextCtrl* m_textCtrlLabel4;
wxTextCtrl* m_textCtrlField4;
wxButton* m_buttonDel4;
wxTextCtrl* m_textCtrlLabel5;
wxTextCtrl* m_textCtrlField5;
wxButton* m_buttonDel5;
wxTextCtrl* m_textCtrlLabel6;
wxTextCtrl* m_textCtrlField6;
wxButton* m_buttonDel6;
wxTextCtrl* m_textCtrlLabel7;
wxTextCtrl* m_textCtrlField7;
wxButton* m_buttonDel7;
wxTextCtrl* m_textCtrlLabel8;
wxTextCtrl* m_textCtrlField8;
wxButton* m_buttonDel8;
wxTextCtrl* m_textCtrlLabel9;
wxTextCtrl* m_textCtrlField9;
wxButton* m_buttonDel9;
wxTextCtrl* m_textCtrlLabel10;
wxTextCtrl* m_textCtrlField10;
wxButton* m_buttonDel10;
wxTextCtrl* m_textCtrlLabel11;
wxTextCtrl* m_textCtrlField11;
wxButton* m_buttonDel11;
wxTextCtrl* m_textCtrlLabel12;
wxTextCtrl* m_textCtrlField12;
wxButton* m_buttonDel12;
wxTextCtrl* m_textCtrlLabel13;
wxTextCtrl* m_textCtrlField13;
wxButton* m_buttonDel13;
wxTextCtrl* m_textCtrlLabel14;
wxTextCtrl* m_textCtrlField14;
wxButton* m_buttonDel14;
wxTextCtrl* m_textCtrlLabel15;
wxTextCtrl* m_textCtrlField15;
wxButton* m_buttonDel15;
wxTextCtrl* m_textCtrlLabel16;
wxTextCtrl* m_textCtrlField16;
wxButton* m_buttonDel16;
wxTextCtrl* m_textCtrlLabel17;
wxTextCtrl* m_textCtrlField17;
wxButton* m_buttonDel17;
wxTextCtrl* m_textCtrlLabel18;
wxTextCtrl* m_textCtrlField18;
wxButton* m_buttonDel18;
wxTextCtrl* m_textCtrlLabel19;
wxTextCtrl* m_textCtrlField19;
wxButton* m_buttonDel19;
wxButton* m_buttonAddField;
wxButton* m_buttonOK;
wxButton* m_buttonPreview;
wxButton* m_buttonCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); }
virtual void OnButtonDel0(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonDel1(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonDel2(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonDel3(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonDel4(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonDel5(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonDel6(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonDel7(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonDel8(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonDel9(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonDel10(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonDel11(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonDel12(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonDel13(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonDel14(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonDel15(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonDel16(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonDel17(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonDel18(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonDel19(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonAddField(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonSend(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonPreview(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); }
public:
wxFlexGridSizer* fgSizer5;
CEditProductDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Edit Product"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(660,640), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL);
~CEditProductDialogBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class CViewProductDialogBase
///////////////////////////////////////////////////////////////////////////////
class CViewProductDialogBase : public wxFrame
{
private:
protected:
wxHtmlWindow* m_htmlWinReviews;
wxScrolledWindow* m_scrolledWindow;
wxRichTextCtrl* m_richTextHeading;
wxStaticText* m_staticTextInstructions;
wxButton* m_buttonSubmitForm;
wxButton* m_buttonCancelForm;
wxButton* m_buttonBack;
wxButton* m_buttonNext;
wxButton* m_buttonCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnButtonSubmitForm(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonCancelForm(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonBack(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonNext(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); }
public:
CViewProductDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Order Form"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(630,520), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL);
~CViewProductDialogBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class CViewOrderDialogBase
///////////////////////////////////////////////////////////////////////////////
class CViewOrderDialogBase : public wxFrame
{
private:
protected:
wxHtmlWindow* m_htmlWin;
wxButton* m_buttonOK;
// Virtual event handlers, overide them in your derived class
virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); }
public:
CViewOrderDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("View Order"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(630,520), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL);
~CViewOrderDialogBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class CEditReviewDialogBase
///////////////////////////////////////////////////////////////////////////////
class CEditReviewDialogBase : public wxFrame
{
private:
protected:
wxStaticText* m_staticTextSeller;
wxStaticText* m_staticText110;
wxChoice* m_choiceStars;
wxStaticText* m_staticText43;
wxTextCtrl* m_textCtrlReview;
wxButton* m_buttonSubmit;
wxButton* m_buttonCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); }
virtual void OnButtonSubmit(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); }
public:
CEditReviewDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Enter Review"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(630,440), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL);
~CEditReviewDialogBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class CPokerLobbyDialogBase
///////////////////////////////////////////////////////////////////////////////
class CPokerLobbyDialogBase : public wxFrame
{
private:
protected:
wxTreeCtrl* m_treeCtrl;
wxListCtrl* m_listCtrl;
wxButton* m_buttonNewTable;
// Virtual event handlers, overide them in your derived class
virtual void OnTreeSelChanged(wxTreeEvent& event){ event.Skip(); }
virtual void OnListItemActivated(wxListEvent& event){ event.Skip(); }
virtual void OnListItemSelected(wxListEvent& event){ event.Skip(); }
virtual void OnButtonNewTable(wxCommandEvent& event){ event.Skip(); }
public:
CPokerLobbyDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Poker Lobby"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(586,457), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL);
~CPokerLobbyDialogBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class CPokerDialogBase
///////////////////////////////////////////////////////////////////////////////
class CPokerDialogBase : public wxFrame
{
private:
protected:
wxButton* m_buttonDealHand;
wxButton* m_buttonFold;
wxButton* m_buttonCall;
wxButton* m_buttonRaise;
wxButton* m_buttonLeaveTable;
wxTextCtrl* m_textDitchPlayer;
// Virtual event handlers, overide them in your derived class
virtual void OnClose(wxCloseEvent& event){ event.Skip(); }
virtual void OnMouseEvents(wxMouseEvent& event){ event.Skip(); }
virtual void OnPaint(wxPaintEvent& event){ event.Skip(); }
virtual void OnSize(wxSizeEvent& event){ event.Skip(); }
virtual void OnCheckSitOut(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonDealHand(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonFold(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonCall(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonRaise(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonLeaveTable(wxCommandEvent& event){ event.Skip(); }
virtual void OnDitchPlayer(wxCommandEvent& event){ event.Skip(); }
virtual void OnCheckPreFold(wxCommandEvent& event){ event.Skip(); }
virtual void OnCheckPreCall(wxCommandEvent& event){ event.Skip(); }
virtual void OnCheckPreCallAny(wxCommandEvent& event){ event.Skip(); }
virtual void OnCheckPreRaise(wxCommandEvent& event){ event.Skip(); }
virtual void OnCheckPreRaiseAny(wxCommandEvent& event){ event.Skip(); }
public:
wxCheckBox* m_checkSitOut;
wxCheckBox* m_checkPreFold;
wxCheckBox* m_checkPreCall;
wxCheckBox* m_checkPreCallAny;
wxCheckBox* m_checkPreRaise;
wxCheckBox* m_checkPreRaiseAny;
wxStatusBar* m_statusBar;
CPokerDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Poker"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(806,550), long style = wxDEFAULT_FRAME_STYLE|wxFRAME_NO_TASKBAR|wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL);
~CPokerDialogBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class CGetTextFromUserDialogBase
///////////////////////////////////////////////////////////////////////////////
class CGetTextFromUserDialogBase : public wxDialog
{
private:
protected:
wxStaticText* m_staticTextMessage1;
wxTextCtrl* m_textCtrl1;
wxStaticText* m_staticTextMessage2;
wxTextCtrl* m_textCtrl2;
wxButton* m_buttonOK;
wxButton* m_buttonCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnClose(wxCloseEvent& event){ event.Skip(); }
virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); }
virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); }
virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); }
public:
CGetTextFromUserDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(403,138), long style = wxDEFAULT_DIALOG_STYLE);
~CGetTextFromUserDialogBase();
};
#endif //__uibase__

750
uint256.h Normal file
View file

@ -0,0 +1,750 @@
// Copyright (c) 2009 Satoshi Nakamoto
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#include <limits.h>
#include <string>
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef __int64 int64;
typedef unsigned __int64 uint64;
#else
typedef long long int64;
typedef unsigned long long uint64;
#endif
#if defined(_MSC_VER) && _MSC_VER < 1300
#define for if (false) ; else for
#endif
inline int Testuint256AdHoc(vector<string> vArg);
// We have to keep a separate base class without constructors
// so the compiler will let us use it in a union
template<unsigned int BITS>
class base_uint
{
protected:
enum { WIDTH=BITS/32 };
unsigned int pn[WIDTH];
public:
bool operator!() const
{
for (int i = 0; i < WIDTH; i++)
if (pn[i] != 0)
return false;
return true;
}
const base_uint operator~() const
{
base_uint ret;
for (int i = 0; i < WIDTH; i++)
ret.pn[i] = ~pn[i];
return ret;
}
const base_uint operator-() const
{
base_uint ret;
for (int i = 0; i < WIDTH; i++)
ret.pn[i] = ~pn[i];
ret++;
return ret;
}
base_uint& operator=(uint64 b)
{
pn[0] = (unsigned int)b;
pn[1] = (unsigned int)(b >> 32);
for (int i = 2; i < WIDTH; i++)
pn[i] = 0;
return *this;
}
base_uint& operator^=(const base_uint& b)
{
for (int i = 0; i < WIDTH; i++)
pn[i] ^= b.pn[i];
return *this;
}
base_uint& operator&=(const base_uint& b)
{
for (int i = 0; i < WIDTH; i++)
pn[i] &= b.pn[i];
return *this;
}
base_uint& operator|=(const base_uint& b)
{
for (int i = 0; i < WIDTH; i++)
pn[i] |= b.pn[i];
return *this;
}
base_uint& operator^=(uint64 b)
{
pn[0] ^= (unsigned int)b;
pn[1] ^= (unsigned int)(b >> 32);
return *this;
}
base_uint& operator&=(uint64 b)
{
pn[0] &= (unsigned int)b;
pn[1] &= (unsigned int)(b >> 32);
return *this;
}
base_uint& operator|=(uint64 b)
{
pn[0] |= (unsigned int)b;
pn[1] |= (unsigned int)(b >> 32);
return *this;
}
base_uint& operator<<=(unsigned int shift)
{
base_uint a(*this);
for (int i = 0; i < WIDTH; i++)
pn[i] = 0;
int k = shift / 32;
shift = shift % 32;
for (int i = 0; i < WIDTH; i++)
{
if (i+k+1 < WIDTH && shift != 0)
pn[i+k+1] |= (a.pn[i] >> (32-shift));
if (i+k < WIDTH)
pn[i+k] |= (a.pn[i] << shift);
}
return *this;
}
base_uint& operator>>=(unsigned int shift)
{
base_uint a(*this);
for (int i = 0; i < WIDTH; i++)
pn[i] = 0;
int k = shift / 32;
shift = shift % 32;
for (int i = 0; i < WIDTH; i++)
{
if (i-k-1 >= 0 && shift != 0)
pn[i-k-1] |= (a.pn[i] << (32-shift));
if (i-k >= 0)
pn[i-k] |= (a.pn[i] >> shift);
}
return *this;
}
base_uint& operator+=(const base_uint& b)
{
uint64 carry = 0;
for (int i = 0; i < WIDTH; i++)
{
uint64 n = carry + pn[i] + b.pn[i];
pn[i] = n & 0xffffffff;
carry = n >> 32;
}
return *this;
}
base_uint& operator-=(const base_uint& b)
{
*this += -b;
return *this;
}
base_uint& operator+=(uint64 b64)
{
base_uint b;
b = b64;
*this += b;
return *this;
}
base_uint& operator-=(uint64 b64)
{
base_uint b;
b = b64;
*this += -b;
return *this;
}
base_uint& operator++()
{
// prefix operator
int i = 0;
while (++pn[i] == 0 && i < WIDTH-1)
i++;
return *this;
}
const base_uint operator++(int)
{
// postfix operator
const base_uint ret = *this;
++(*this);
return ret;
}
base_uint& operator--()
{
// prefix operator
int i = 0;
while (--pn[i] == -1 && i < WIDTH-1)
i++;
return *this;
}
const base_uint operator--(int)
{
// postfix operator
const base_uint ret = *this;
--(*this);
return ret;
}
friend inline bool operator<(const base_uint& a, const base_uint& b)
{
for (int i = base_uint::WIDTH-1; i >= 0; i--)
{
if (a.pn[i] < b.pn[i])
return true;
else if (a.pn[i] > b.pn[i])
return false;
}
return false;
}
friend inline bool operator<=(const base_uint& a, const base_uint& b)
{
for (int i = base_uint::WIDTH-1; i >= 0; i--)
{
if (a.pn[i] < b.pn[i])
return true;
else if (a.pn[i] > b.pn[i])
return false;
}
return true;
}
friend inline bool operator>(const base_uint& a, const base_uint& b)
{
for (int i = base_uint::WIDTH-1; i >= 0; i--)
{
if (a.pn[i] > b.pn[i])
return true;
else if (a.pn[i] < b.pn[i])
return false;
}
return false;
}
friend inline bool operator>=(const base_uint& a, const base_uint& b)
{
for (int i = base_uint::WIDTH-1; i >= 0; i--)
{
if (a.pn[i] > b.pn[i])
return true;
else if (a.pn[i] < b.pn[i])
return false;
}
return true;
}
friend inline bool operator==(const base_uint& a, const base_uint& b)
{
for (int i = 0; i < base_uint::WIDTH; i++)
if (a.pn[i] != b.pn[i])
return false;
return true;
}
friend inline bool operator==(const base_uint& a, uint64 b)
{
if (a.pn[0] != (unsigned int)b)
return false;
if (a.pn[1] != (unsigned int)(b >> 32))
return false;
for (int i = 2; i < base_uint::WIDTH; i++)
if (a.pn[i] != 0)
return false;
return true;
}
friend inline bool operator!=(const base_uint& a, const base_uint& b)
{
return (!(a == b));
}
friend inline bool operator!=(const base_uint& a, uint64 b)
{
return (!(a == b));
}
std::string GetHex() const
{
char psz[sizeof(pn)*2 + 1];
for (int i = 0; i < sizeof(pn); i++)
sprintf(psz + i*2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]);
return string(psz, psz + sizeof(pn)*2);
}
void SetHex(const std::string& str)
{
for (int i = 0; i < WIDTH; i++)
pn[i] = 0;
// skip 0x
const char* psz = str.c_str();
while (isspace(*psz))
psz++;
if (psz[0] == '0' && tolower(psz[1]) == 'x')
psz += 2;
while (isspace(*psz))
psz++;
// hex string to uint
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 };
const char* pbegin = psz;
while (phexdigit[*psz] || *psz == '0')
psz++;
psz--;
unsigned char* p1 = (unsigned char*)pn;
unsigned char* pend = p1 + WIDTH * 4;
while (psz >= pbegin && p1 < pend)
{
*p1 = phexdigit[(unsigned char)*psz--];
if (psz >= pbegin)
{
*p1 |= (phexdigit[(unsigned char)*psz--] << 4);
p1++;
}
}
}
std::string ToString() const
{
return (GetHex());
}
unsigned char* begin()
{
return (unsigned char*)&pn[0];
}
unsigned char* end()
{
return (unsigned char*)&pn[WIDTH];
}
unsigned int size()
{
return sizeof(pn);
}
unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const
{
return sizeof(pn);
}
template<typename Stream>
void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const
{
s.write((char*)pn, sizeof(pn));
}
template<typename Stream>
void Unserialize(Stream& s, int nType=0, int nVersion=VERSION)
{
s.read((char*)pn, sizeof(pn));
}
friend class uint160;
friend class uint256;
friend inline int Testuint256AdHoc(vector<string> vArg);
};
typedef base_uint<160> base_uint160;
typedef base_uint<256> base_uint256;
//
// uint160 and uint256 could be implemented as templates, but to keep
// compile errors and debugging cleaner, they're copy and pasted.
// It's safe to search and replace 160 with 256 and vice versa.
//
//////////////////////////////////////////////////////////////////////////////
//
// uint160
//
class uint160 : public base_uint160
{
public:
typedef base_uint160 basetype;
uint160()
{
}
uint160(const basetype& b)
{
for (int i = 0; i < WIDTH; i++)
pn[i] = b.pn[i];
}
uint160& operator=(const basetype& b)
{
for (int i = 0; i < WIDTH; i++)
pn[i] = b.pn[i];
return *this;
}
uint160(uint64 b)
{
pn[0] = (unsigned int)b;
pn[1] = (unsigned int)(b >> 32);
for (int i = 2; i < WIDTH; i++)
pn[i] = 0;
}
uint160& operator=(uint64 b)
{
pn[0] = (unsigned int)b;
pn[1] = (unsigned int)(b >> 32);
for (int i = 2; i < WIDTH; i++)
pn[i] = 0;
return *this;
}
explicit uint160(const std::string& str)
{
SetHex(str);
}
explicit uint160(const std::vector<unsigned char>& vch)
{
if (vch.size() == sizeof(pn))
memcpy(pn, &vch[0], sizeof(pn));
else
*this = 0;
}
};
inline bool operator==(const uint160& a, uint64 b) { return (base_uint160)a == b; }
inline bool operator!=(const uint160& a, uint64 b) { return (base_uint160)a != b; }
inline const uint160 operator<<(const base_uint160& a, unsigned int shift) { return uint160(a) <<= shift; }
inline const uint160 operator>>(const base_uint160& a, unsigned int shift) { return uint160(a) >>= shift; }
inline const uint160 operator<<(const uint160& a, unsigned int shift) { return uint160(a) <<= shift; }
inline const uint160 operator>>(const uint160& a, unsigned int shift) { return uint160(a) >>= shift; }
inline const uint160 operator^(const base_uint160& a, const base_uint160& b) { return uint160(a) ^= b; }
inline const uint160 operator&(const base_uint160& a, const base_uint160& b) { return uint160(a) &= b; }
inline const uint160 operator|(const base_uint160& a, const base_uint160& b) { return uint160(a) |= b; }
inline const uint160 operator+(const base_uint160& a, const base_uint160& b) { return uint160(a) += b; }
inline const uint160 operator-(const base_uint160& a, const base_uint160& b) { return uint160(a) -= b; }
inline bool operator<(const base_uint160& a, const uint160& b) { return (base_uint160)a < (base_uint160)b; }
inline bool operator<=(const base_uint160& a, const uint160& b) { return (base_uint160)a <= (base_uint160)b; }
inline bool operator>(const base_uint160& a, const uint160& b) { return (base_uint160)a > (base_uint160)b; }
inline bool operator>=(const base_uint160& a, const uint160& b) { return (base_uint160)a >= (base_uint160)b; }
inline bool operator==(const base_uint160& a, const uint160& b) { return (base_uint160)a == (base_uint160)b; }
inline bool operator!=(const base_uint160& a, const uint160& b) { return (base_uint160)a != (base_uint160)b; }
inline const uint160 operator^(const base_uint160& a, const uint160& b) { return (base_uint160)a ^ (base_uint160)b; }
inline const uint160 operator&(const base_uint160& a, const uint160& b) { return (base_uint160)a & (base_uint160)b; }
inline const uint160 operator|(const base_uint160& a, const uint160& b) { return (base_uint160)a | (base_uint160)b; }
inline const uint160 operator+(const base_uint160& a, const uint160& b) { return (base_uint160)a + (base_uint160)b; }
inline const uint160 operator-(const base_uint160& a, const uint160& b) { return (base_uint160)a - (base_uint160)b; }
inline bool operator<(const uint160& a, const base_uint160& b) { return (base_uint160)a < (base_uint160)b; }
inline bool operator<=(const uint160& a, const base_uint160& b) { return (base_uint160)a <= (base_uint160)b; }
inline bool operator>(const uint160& a, const base_uint160& b) { return (base_uint160)a > (base_uint160)b; }
inline bool operator>=(const uint160& a, const base_uint160& b) { return (base_uint160)a >= (base_uint160)b; }
inline bool operator==(const uint160& a, const base_uint160& b) { return (base_uint160)a == (base_uint160)b; }
inline bool operator!=(const uint160& a, const base_uint160& b) { return (base_uint160)a != (base_uint160)b; }
inline const uint160 operator^(const uint160& a, const base_uint160& b) { return (base_uint160)a ^ (base_uint160)b; }
inline const uint160 operator&(const uint160& a, const base_uint160& b) { return (base_uint160)a & (base_uint160)b; }
inline const uint160 operator|(const uint160& a, const base_uint160& b) { return (base_uint160)a | (base_uint160)b; }
inline const uint160 operator+(const uint160& a, const base_uint160& b) { return (base_uint160)a + (base_uint160)b; }
inline const uint160 operator-(const uint160& a, const base_uint160& b) { return (base_uint160)a - (base_uint160)b; }
inline bool operator<(const uint160& a, const uint160& b) { return (base_uint160)a < (base_uint160)b; }
inline bool operator<=(const uint160& a, const uint160& b) { return (base_uint160)a <= (base_uint160)b; }
inline bool operator>(const uint160& a, const uint160& b) { return (base_uint160)a > (base_uint160)b; }
inline bool operator>=(const uint160& a, const uint160& b) { return (base_uint160)a >= (base_uint160)b; }
inline bool operator==(const uint160& a, const uint160& b) { return (base_uint160)a == (base_uint160)b; }
inline bool operator!=(const uint160& a, const uint160& b) { return (base_uint160)a != (base_uint160)b; }
inline const uint160 operator^(const uint160& a, const uint160& b) { return (base_uint160)a ^ (base_uint160)b; }
inline const uint160 operator&(const uint160& a, const uint160& b) { return (base_uint160)a & (base_uint160)b; }
inline const uint160 operator|(const uint160& a, const uint160& b) { return (base_uint160)a | (base_uint160)b; }
inline const uint160 operator+(const uint160& a, const uint160& b) { return (base_uint160)a + (base_uint160)b; }
inline const uint160 operator-(const uint160& a, const uint160& b) { return (base_uint160)a - (base_uint160)b; }
//////////////////////////////////////////////////////////////////////////////
//
// uint256
//
class uint256 : public base_uint256
{
public:
typedef base_uint256 basetype;
uint256()
{
}
uint256(const basetype& b)
{
for (int i = 0; i < WIDTH; i++)
pn[i] = b.pn[i];
}
uint256& operator=(const basetype& b)
{
for (int i = 0; i < WIDTH; i++)
pn[i] = b.pn[i];
return *this;
}
uint256(uint64 b)
{
pn[0] = (unsigned int)b;
pn[1] = (unsigned int)(b >> 32);
for (int i = 2; i < WIDTH; i++)
pn[i] = 0;
}
uint256& operator=(uint64 b)
{
pn[0] = (unsigned int)b;
pn[1] = (unsigned int)(b >> 32);
for (int i = 2; i < WIDTH; i++)
pn[i] = 0;
return *this;
}
explicit uint256(const std::string& str)
{
SetHex(str);
}
explicit uint256(const std::vector<unsigned char>& vch)
{
if (vch.size() == sizeof(pn))
memcpy(pn, &vch[0], sizeof(pn));
else
*this = 0;
}
};
inline bool operator==(const uint256& a, uint64 b) { return (base_uint256)a == b; }
inline bool operator!=(const uint256& a, uint64 b) { return (base_uint256)a != b; }
inline const uint256 operator<<(const base_uint256& a, unsigned int shift) { return uint256(a) <<= shift; }
inline const uint256 operator>>(const base_uint256& a, unsigned int shift) { return uint256(a) >>= shift; }
inline const uint256 operator<<(const uint256& a, unsigned int shift) { return uint256(a) <<= shift; }
inline const uint256 operator>>(const uint256& a, unsigned int shift) { return uint256(a) >>= shift; }
inline const uint256 operator^(const base_uint256& a, const base_uint256& b) { return uint256(a) ^= b; }
inline const uint256 operator&(const base_uint256& a, const base_uint256& b) { return uint256(a) &= b; }
inline const uint256 operator|(const base_uint256& a, const base_uint256& b) { return uint256(a) |= b; }
inline const uint256 operator+(const base_uint256& a, const base_uint256& b) { return uint256(a) += b; }
inline const uint256 operator-(const base_uint256& a, const base_uint256& b) { return uint256(a) -= b; }
inline bool operator<(const base_uint256& a, const uint256& b) { return (base_uint256)a < (base_uint256)b; }
inline bool operator<=(const base_uint256& a, const uint256& b) { return (base_uint256)a <= (base_uint256)b; }
inline bool operator>(const base_uint256& a, const uint256& b) { return (base_uint256)a > (base_uint256)b; }
inline bool operator>=(const base_uint256& a, const uint256& b) { return (base_uint256)a >= (base_uint256)b; }
inline bool operator==(const base_uint256& a, const uint256& b) { return (base_uint256)a == (base_uint256)b; }
inline bool operator!=(const base_uint256& a, const uint256& b) { return (base_uint256)a != (base_uint256)b; }
inline const uint256 operator^(const base_uint256& a, const uint256& b) { return (base_uint256)a ^ (base_uint256)b; }
inline const uint256 operator&(const base_uint256& a, const uint256& b) { return (base_uint256)a & (base_uint256)b; }
inline const uint256 operator|(const base_uint256& a, const uint256& b) { return (base_uint256)a | (base_uint256)b; }
inline const uint256 operator+(const base_uint256& a, const uint256& b) { return (base_uint256)a + (base_uint256)b; }
inline const uint256 operator-(const base_uint256& a, const uint256& b) { return (base_uint256)a - (base_uint256)b; }
inline bool operator<(const uint256& a, const base_uint256& b) { return (base_uint256)a < (base_uint256)b; }
inline bool operator<=(const uint256& a, const base_uint256& b) { return (base_uint256)a <= (base_uint256)b; }
inline bool operator>(const uint256& a, const base_uint256& b) { return (base_uint256)a > (base_uint256)b; }
inline bool operator>=(const uint256& a, const base_uint256& b) { return (base_uint256)a >= (base_uint256)b; }
inline bool operator==(const uint256& a, const base_uint256& b) { return (base_uint256)a == (base_uint256)b; }
inline bool operator!=(const uint256& a, const base_uint256& b) { return (base_uint256)a != (base_uint256)b; }
inline const uint256 operator^(const uint256& a, const base_uint256& b) { return (base_uint256)a ^ (base_uint256)b; }
inline const uint256 operator&(const uint256& a, const base_uint256& b) { return (base_uint256)a & (base_uint256)b; }
inline const uint256 operator|(const uint256& a, const base_uint256& b) { return (base_uint256)a | (base_uint256)b; }
inline const uint256 operator+(const uint256& a, const base_uint256& b) { return (base_uint256)a + (base_uint256)b; }
inline const uint256 operator-(const uint256& a, const base_uint256& b) { return (base_uint256)a - (base_uint256)b; }
inline bool operator<(const uint256& a, const uint256& b) { return (base_uint256)a < (base_uint256)b; }
inline bool operator<=(const uint256& a, const uint256& b) { return (base_uint256)a <= (base_uint256)b; }
inline bool operator>(const uint256& a, const uint256& b) { return (base_uint256)a > (base_uint256)b; }
inline bool operator>=(const uint256& a, const uint256& b) { return (base_uint256)a >= (base_uint256)b; }
inline bool operator==(const uint256& a, const uint256& b) { return (base_uint256)a == (base_uint256)b; }
inline bool operator!=(const uint256& a, const uint256& b) { return (base_uint256)a != (base_uint256)b; }
inline const uint256 operator^(const uint256& a, const uint256& b) { return (base_uint256)a ^ (base_uint256)b; }
inline const uint256 operator&(const uint256& a, const uint256& b) { return (base_uint256)a & (base_uint256)b; }
inline const uint256 operator|(const uint256& a, const uint256& b) { return (base_uint256)a | (base_uint256)b; }
inline const uint256 operator+(const uint256& a, const uint256& b) { return (base_uint256)a + (base_uint256)b; }
inline const uint256 operator-(const uint256& a, const uint256& b) { return (base_uint256)a - (base_uint256)b; }
inline int Testuint256AdHoc(vector<string> vArg)
{
uint256 g(0);
printf("%s\n", g.ToString().c_str());
g--; printf("g--\n");
printf("%s\n", g.ToString().c_str());
g--; printf("g--\n");
printf("%s\n", g.ToString().c_str());
g++; printf("g++\n");
printf("%s\n", g.ToString().c_str());
g++; printf("g++\n");
printf("%s\n", g.ToString().c_str());
g++; printf("g++\n");
printf("%s\n", g.ToString().c_str());
g++; printf("g++\n");
printf("%s\n", g.ToString().c_str());
uint256 a(7);
printf("a=7\n");
printf("%s\n", a.ToString().c_str());
uint256 b;
printf("b undefined\n");
printf("%s\n", b.ToString().c_str());
int c = 3;
a = c;
a.pn[3] = 15;
printf("%s\n", a.ToString().c_str());
uint256 k(c);
a = 5;
a.pn[3] = 15;
printf("%s\n", a.ToString().c_str());
b = 1;
b <<= 52;
a |= b;
a ^= 0x500;
printf("a %s\n", a.ToString().c_str());
a = a | b | (uint256)0x1000;
printf("a %s\n", a.ToString().c_str());
printf("b %s\n", b.ToString().c_str());
a = 0xfffffffe;
a.pn[4] = 9;
printf("%s\n", a.ToString().c_str());
a++;
printf("%s\n", a.ToString().c_str());
a++;
printf("%s\n", a.ToString().c_str());
a++;
printf("%s\n", a.ToString().c_str());
a++;
printf("%s\n", a.ToString().c_str());
a--;
printf("%s\n", a.ToString().c_str());
a--;
printf("%s\n", a.ToString().c_str());
a--;
printf("%s\n", a.ToString().c_str());
uint256 d = a--;
printf("%s\n", d.ToString().c_str());
printf("%s\n", a.ToString().c_str());
a--;
printf("%s\n", a.ToString().c_str());
a--;
printf("%s\n", a.ToString().c_str());
d = a;
printf("%s\n", d.ToString().c_str());
for (int i = uint256::WIDTH-1; i >= 0; i--) printf("%08x", d.pn[i]); printf("\n");
uint256 neg = d;
neg = ~neg;
printf("%s\n", neg.ToString().c_str());
uint256 e = uint256("0xABCDEF123abcdef12345678909832180000011111111");
printf("\n");
printf("%s\n", e.ToString().c_str());
printf("\n");
uint256 x1 = uint256("0xABCDEF123abcdef12345678909832180000011111111");
uint256 x2;
printf("%s\n", x1.ToString().c_str());
for (int i = 0; i < 270; i += 4)
{
x2 = x1 << i;
printf("%s\n", x2.ToString().c_str());
}
printf("\n");
printf("%s\n", x1.ToString().c_str());
for (int i = 0; i < 270; i += 4)
{
x2 = x1;
x2 >>= i;
printf("%s\n", x2.ToString().c_str());
}
for (int i = 0; i < 100; i++)
{
uint256 k = (~uint256(0) >> i);
printf("%s\n", k.ToString().c_str());
}
for (int i = 0; i < 100; i++)
{
uint256 k = (~uint256(0) << i);
printf("%s\n", k.ToString().c_str());
}
return (0);
}

11860
uiproject.fbp Normal file

File diff suppressed because it is too large Load diff

383
util.cpp Normal file
View file

@ -0,0 +1,383 @@
// Copyright (c) 2009 Satoshi Nakamoto
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#include "headers.h"
bool fDebug = false;
// Init openssl library multithreading support
static HANDLE* lock_cs;
void win32_locking_callback(int mode, int type, const char* file, int line)
{
if (mode & CRYPTO_LOCK)
WaitForSingleObject(lock_cs[type], INFINITE);
else
ReleaseMutex(lock_cs[type]);
}
// Init
class CInit
{
public:
CInit()
{
// Init openssl library multithreading support
lock_cs = (HANDLE*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE));
for (int i = 0; i < CRYPTO_num_locks(); i++)
lock_cs[i] = CreateMutex(NULL,FALSE,NULL);
CRYPTO_set_locking_callback(win32_locking_callback);
// Seed random number generator with screen scrape and other hardware sources
RAND_screen();
// Seed random number generator with perfmon data
RandAddSeed(true);
}
~CInit()
{
// Shutdown openssl library multithreading support
CRYPTO_set_locking_callback(NULL);
for (int i =0 ; i < CRYPTO_num_locks(); i++)
CloseHandle(lock_cs[i]);
OPENSSL_free(lock_cs);
}
}
instance_of_cinit;
void RandAddSeed(bool fPerfmon)
{
// Seed with CPU performance counter
LARGE_INTEGER PerformanceCount;
QueryPerformanceCounter(&PerformanceCount);
RAND_add(&PerformanceCount, sizeof(PerformanceCount), 1.5);
memset(&PerformanceCount, 0, sizeof(PerformanceCount));
static int64 nLastPerfmon;
if (fPerfmon || GetTime() > nLastPerfmon + 5 * 60)
{
nLastPerfmon = GetTime();
// Seed with the entire set of perfmon data
unsigned char pdata[250000];
memset(pdata, 0, sizeof(pdata));
unsigned long nSize = sizeof(pdata);
long ret = RegQueryValueEx(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize);
RegCloseKey(HKEY_PERFORMANCE_DATA);
if (ret == ERROR_SUCCESS)
{
uint256 hash;
SHA256(pdata, nSize, (unsigned char*)&hash);
RAND_add(&hash, sizeof(hash), min(nSize/500.0, (double)sizeof(hash)));
hash = 0;
memset(pdata, 0, nSize);
time_t nTime;
time(&nTime);
struct tm* ptmTime = gmtime(&nTime);
char pszTime[200];
strftime(pszTime, sizeof(pszTime), "%x %H:%M:%S", ptmTime);
printf("%s RandAddSeed() got %d bytes of performance data\n", pszTime, nSize);
}
}
}
// Safer snprintf
// - prints up to limit-1 characters
// - output string is always null terminated even if limit reached
// - return value is the number of characters actually printed
int my_snprintf(char* buffer, size_t limit, const char* format, ...)
{
if (limit == 0)
return 0;
va_list arg_ptr;
va_start(arg_ptr, format);
int ret = _vsnprintf(buffer, limit, format, arg_ptr);
va_end(arg_ptr);
if (ret < 0 || ret >= limit)
{
ret = limit - 1;
buffer[limit-1] = 0;
}
return ret;
}
string strprintf(const char* format, ...)
{
char buffer[50000];
char* p = buffer;
int limit = sizeof(buffer);
int ret;
loop
{
va_list arg_ptr;
va_start(arg_ptr, format);
ret = _vsnprintf(p, limit, format, arg_ptr);
va_end(arg_ptr);
if (ret >= 0 && ret < limit)
break;
if (p != buffer)
delete p;
limit *= 2;
p = new char[limit];
if (p == NULL)
throw std::bad_alloc();
}
#ifdef _MSC_VER
// msvc optimisation
if (p == buffer)
return string(p, p+ret);
#endif
string str(p, p+ret);
if (p != buffer)
delete p;
return str;
}
bool error(const char* format, ...)
{
char buffer[50000];
int limit = sizeof(buffer);
va_list arg_ptr;
va_start(arg_ptr, format);
int ret = _vsnprintf(buffer, limit, format, arg_ptr);
va_end(arg_ptr);
if (ret < 0 || ret >= limit)
{
ret = limit - 1;
buffer[limit-1] = 0;
}
printf("ERROR: %s\n", buffer);
return false;
}
void PrintException(std::exception* pex, const char* pszThread)
{
char pszModule[260];
pszModule[0] = '\0';
GetModuleFileName(NULL, pszModule, sizeof(pszModule));
_strlwr(pszModule);
char pszMessage[1000];
if (pex)
snprintf(pszMessage, sizeof(pszMessage),
"EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread);
else
snprintf(pszMessage, sizeof(pszMessage),
"UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread);
printf("\n\n************************\n%s", pszMessage);
if (wxTheApp)
wxMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR);
throw;
//DebugBreak();
}
void ParseString(const string& str, char c, vector<string>& v)
{
unsigned int i1 = 0;
unsigned int i2;
do
{
i2 = str.find(c, i1);
v.push_back(str.substr(i1, i2-i1));
i1 = i2+1;
}
while (i2 != str.npos);
}
string FormatMoney(int64 n, bool fPlus)
{
n /= CENT;
string str = strprintf("%I64d.%02I64d", (n > 0 ? n : -n)/100, (n > 0 ? n : -n)%100);
for (int i = 6; i < str.size(); i += 4)
if (isdigit(str[str.size() - i - 1]))
str.insert(str.size() - i, 1, ',');
if (n < 0)
str.insert((unsigned int)0, 1, '-');
else if (fPlus && n > 0)
str.insert((unsigned int)0, 1, '+');
return str;
}
bool ParseMoney(const char* pszIn, int64& nRet)
{
string strWhole;
int64 nCents = 0;
const char* p = pszIn;
while (isspace(*p))
p++;
for (; *p; p++)
{
if (*p == ',' && p > pszIn && isdigit(p[-1]) && isdigit(p[1]) && isdigit(p[2]) && isdigit(p[3]) && !isdigit(p[4]))
continue;
if (*p == '.')
{
p++;
if (isdigit(*p))
{
nCents = 10 * (*p++ - '0');
if (isdigit(*p))
nCents += (*p++ - '0');
}
break;
}
if (isspace(*p))
break;
if (!isdigit(*p))
return false;
strWhole.insert(strWhole.end(), *p);
}
for (; *p; p++)
if (!isspace(*p))
return false;
if (strWhole.size() > 14)
return false;
if (nCents < 0 || nCents > 99)
return false;
int64 nWhole = atoi64(strWhole);
int64 nPreValue = nWhole * 100 + nCents;
int64 nValue = nPreValue * CENT;
if (nValue / CENT != nPreValue)
return false;
if (nValue / COIN != nWhole)
return false;
nRet = nValue;
return true;
}
bool FileExists(const char* psz)
{
#ifdef WIN32
return GetFileAttributes(psz) != -1;
#else
return access(psz, 0) != -1;
#endif
}
int GetFilesize(FILE* file)
{
int nSavePos = ftell(file);
int nFilesize = -1;
if (fseek(file, 0, SEEK_END) == 0)
nFilesize = ftell(file);
fseek(file, nSavePos, SEEK_SET);
return nFilesize;
}
uint64 GetRand(uint64 nMax)
{
if (nMax == 0)
return 0;
// The range of the random source must be a multiple of the modulus
// to give every possible output value an equal possibility
uint64 nRange = (_UI64_MAX / nMax) * nMax;
uint64 nRand = 0;
do
RAND_bytes((unsigned char*)&nRand, sizeof(nRand));
while (nRand >= nRange);
return (nRand % nMax);
}
//
// "Never go to sea with two chronometers; take one or three."
// Our three chronometers are:
// - System clock
// - Median of other server's clocks
// - NTP servers
//
// note: NTP isn't implemented yet, so until then we just use the median
// of other nodes clocks to correct ours.
//
int64 GetTime()
{
return time(NULL);
}
static int64 nTimeOffset = 0;
int64 GetAdjustedTime()
{
return GetTime() + nTimeOffset;
}
void AddTimeData(unsigned int ip, int64 nTime)
{
int64 nOffsetSample = nTime - GetTime();
// Ignore duplicates
static set<unsigned int> setKnown;
if (!setKnown.insert(ip).second)
return;
// Add data
static vector<int64> vTimeOffsets;
if (vTimeOffsets.empty())
vTimeOffsets.push_back(0);
vTimeOffsets.push_back(nOffsetSample);
printf("Added time data, samples %d, ip %08x, offset %+I64d (%+I64d minutes)\n", vTimeOffsets.size(), ip, vTimeOffsets.back(), vTimeOffsets.back()/60);
if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
{
sort(vTimeOffsets.begin(), vTimeOffsets.end());
int64 nMedian = vTimeOffsets[vTimeOffsets.size()/2];
nTimeOffset = nMedian;
if ((nMedian > 0 ? nMedian : -nMedian) > 5 * 60)
{
// Only let other nodes change our clock so far before we
// go to the NTP servers
/// todo: Get time from NTP servers, then set a flag
/// to make sure it doesn't get changed again
}
foreach(int64 n, vTimeOffsets)
printf("%+I64d ", n);
printf("| nTimeOffset = %+I64d (%+I64d minutes)\n", nTimeOffset, nTimeOffset/60);
}
}

399
util.h Normal file
View file

@ -0,0 +1,399 @@
// Copyright (c) 2009 Satoshi Nakamoto
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef __int64 int64;
typedef unsigned __int64 uint64;
#else
typedef long long int64;
typedef unsigned long long uint64;
#endif
#if defined(_MSC_VER) && _MSC_VER < 1300
#define for if (false) ; else for
#endif
#ifndef _MSC_VER
#define __forceinline inline
#endif
#define foreach BOOST_FOREACH
#define loop for (;;)
#define BEGIN(a) ((char*)&(a))
#define END(a) ((char*)&((&(a))[1]))
#define UBEGIN(a) ((unsigned char*)&(a))
#define UEND(a) ((unsigned char*)&((&(a))[1]))
#define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0]))
#ifdef _WINDOWS
#define printf OutputDebugStringF
#endif
#ifdef snprintf
#undef snprintf
#endif
#define snprintf my_snprintf
#ifndef PRId64
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MSVCRT__)
#define PRId64 "I64d"
#define PRIu64 "I64u"
#define PRIx64 "I64x"
#else
#define PRId64 "lld"
#define PRIu64 "llu"
#define PRIx64 "llx"
#endif
#endif
// This is needed because the foreach macro can't get over the comma in pair<t1, t2>
#define PAIRTYPE(t1, t2) pair<t1, t2>
// Used to bypass the rule against non-const reference to temporary
// where it makes sense with wrappers such as CFlatData or CTxDB
template<typename T>
inline T& REF(const T& val)
{
return (T&)val;
}
extern bool fDebug;
void RandAddSeed(bool fPerfmon=false);
int my_snprintf(char* buffer, size_t limit, const char* format, ...);
string strprintf(const char* format, ...);
bool error(const char* format, ...);
void PrintException(std::exception* pex, const char* pszThread);
void ParseString(const string& str, char c, vector<string>& v);
string FormatMoney(int64 n, bool fPlus=false);
bool ParseMoney(const char* pszIn, int64& nRet);
bool FileExists(const char* psz);
int GetFilesize(FILE* file);
uint64 GetRand(uint64 nMax);
int64 GetTime();
int64 GetAdjustedTime();
void AddTimeData(unsigned int ip, int64 nTime);
// Wrapper to automatically initialize critical section
// Could use wxCriticalSection for portability, but it doesn't support TryEnterCriticalSection
class CCriticalSection
{
protected:
CRITICAL_SECTION cs;
public:
char* pszFile;
int nLine;
explicit CCriticalSection() { InitializeCriticalSection(&cs); }
~CCriticalSection() { DeleteCriticalSection(&cs); }
void Enter() { EnterCriticalSection(&cs); }
void Leave() { LeaveCriticalSection(&cs); }
bool TryEnter() { return TryEnterCriticalSection(&cs); }
CRITICAL_SECTION* operator&() { return &cs; }
};
// Automatically leave critical section when leaving block, needed for exception safety
class CCriticalBlock
{
protected:
CRITICAL_SECTION* pcs;
public:
CCriticalBlock(CRITICAL_SECTION& csIn) { pcs = &csIn; EnterCriticalSection(pcs); }
CCriticalBlock(CCriticalSection& csIn) { pcs = &csIn; EnterCriticalSection(pcs); }
~CCriticalBlock() { LeaveCriticalSection(pcs); }
};
// WARNING: This will catch continue and break!
// break is caught with an assertion, but there's no way to detect continue.
// I'd rather be careful than suffer the other more error prone syntax.
// The compiler will optimise away all this loop junk.
#define CRITICAL_BLOCK(cs) \
for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false) \
for (CCriticalBlock criticalblock(cs); fcriticalblockonce && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0)
class CTryCriticalBlock
{
protected:
CRITICAL_SECTION* pcs;
public:
CTryCriticalBlock(CRITICAL_SECTION& csIn) { pcs = (TryEnterCriticalSection(&csIn) ? &csIn : NULL); }
CTryCriticalBlock(CCriticalSection& csIn) { pcs = (TryEnterCriticalSection(&csIn) ? &csIn : NULL); }
~CTryCriticalBlock() { if (pcs) LeaveCriticalSection(pcs); }
bool Entered() { return pcs != NULL; }
};
#define TRY_CRITICAL_BLOCK(cs) \
for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by TRY_CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false) \
for (CTryCriticalBlock criticalblock(cs); fcriticalblockonce && (fcriticalblockonce = criticalblock.Entered()) && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0)
inline string i64tostr(int64 n)
{
return strprintf("%"PRId64, n);
}
inline string itostr(int n)
{
return strprintf("%d", n);
}
inline int64 atoi64(const char* psz)
{
#ifdef _MSC_VER
return _atoi64(psz);
#else
return strtoll(psz, NULL, 10);
#endif
}
inline int64 atoi64(const string& str)
{
#ifdef _MSC_VER
return _atoi64(str.c_str());
#else
return strtoll(str.c_str(), NULL, 10);
#endif
}
inline int atoi(const string& str)
{
return atoi(str.c_str());
}
inline int roundint(double d)
{
return (int)(d > 0 ? d + 0.5 : d - 0.5);
}
template<typename T>
string HexStr(const T itbegin, const T itend, bool fSpaces=true)
{
const unsigned char* pbegin = (const unsigned char*)&itbegin[0];
const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);
string str;
for (const unsigned char* p = pbegin; p != pend; p++)
str += strprintf((fSpaces && p != pend-1 ? "%02x " : "%02x"), *p);
return str;
}
template<typename T>
string HexNumStr(const T itbegin, const T itend, bool f0x=true)
{
const unsigned char* pbegin = (const unsigned char*)&itbegin[0];
const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);
string str = (f0x ? "0x" : "");
for (const unsigned char* p = pend-1; p >= pbegin; p--)
str += strprintf("%02X", *p);
return str;
}
template<typename T>
void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSpaces=true)
{
printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str());
}
inline int OutputDebugStringF(const char* pszFormat, ...)
{
#ifdef __WXDEBUG__
// log file
FILE* fileout = fopen("debug.log", "a");
if (fileout)
{
va_list arg_ptr;
va_start(arg_ptr, pszFormat);
vfprintf(fileout, pszFormat, arg_ptr);
va_end(arg_ptr);
fclose(fileout);
}
// accumulate a line at a time
static CCriticalSection cs_OutputDebugStringF;
CRITICAL_BLOCK(cs_OutputDebugStringF)
{
static char pszBuffer[50000];
static char* pend;
if (pend == NULL)
pend = pszBuffer;
va_list arg_ptr;
va_start(arg_ptr, pszFormat);
int limit = END(pszBuffer) - pend - 2;
int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr);
va_end(arg_ptr);
if (ret < 0 || ret >= limit)
{
pend = END(pszBuffer) - 2;
*pend++ = '\n';
}
else
pend += ret;
*pend = '\0';
char* p1 = pszBuffer;
char* p2;
while (p2 = strchr(p1, '\n'))
{
p2++;
char c = *p2;
*p2 = '\0';
OutputDebugString(p1);
*p2 = c;
p1 = p2;
}
if (p1 != pszBuffer)
memmove(pszBuffer, p1, pend - p1 + 1);
pend -= (p1 - pszBuffer);
return ret;
}
#endif
if (!wxTheApp)
{
// print to console
va_list arg_ptr;
va_start(arg_ptr, pszFormat);
vprintf(pszFormat, arg_ptr);
va_end(arg_ptr);
}
return 0;
}
inline void heapchk()
{
if (_heapchk() != _HEAPOK)
DebugBreak();
}
// Randomize the stack to help protect against buffer overrun exploits
#define IMPLEMENT_RANDOMIZE_STACK(ThreadFn) \
{ \
static char nLoops; \
if (nLoops <= 0) \
nLoops = GetRand(50) + 1; \
if (nLoops-- > 1) \
{ \
ThreadFn; \
return; \
} \
}
#define CATCH_PRINT_EXCEPTION(pszFn) \
catch (std::exception& e) { \
PrintException(&e, (pszFn)); \
} catch (...) { \
PrintException(NULL, (pszFn)); \
}
template<typename T1>
inline uint256 Hash(const T1 pbegin, const T1 pend)
{
uint256 hash1;
SHA256((unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1);
uint256 hash2;
SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
return hash2;
}
template<typename T1, typename T2>
inline uint256 Hash(const T1 p1begin, const T1 p1end,
const T2 p2begin, const T2 p2end)
{
uint256 hash1;
SHA256_CTX ctx;
SHA256_Init(&ctx);
SHA256_Update(&ctx, (unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0]));
SHA256_Update(&ctx, (unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0]));
SHA256_Final((unsigned char*)&hash1, &ctx);
uint256 hash2;
SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
return hash2;
}
template<typename T1, typename T2, typename T3>
inline uint256 Hash(const T1 p1begin, const T1 p1end,
const T2 p2begin, const T2 p2end,
const T3 p3begin, const T3 p3end)
{
uint256 hash1;
SHA256_CTX ctx;
SHA256_Init(&ctx);
SHA256_Update(&ctx, (unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0]));
SHA256_Update(&ctx, (unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0]));
SHA256_Update(&ctx, (unsigned char*)&p3begin[0], (p3end - p3begin) * sizeof(p3begin[0]));
SHA256_Final((unsigned char*)&hash1, &ctx);
uint256 hash2;
SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
return hash2;
}
template<typename T>
uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=VERSION)
{
// Most of the time is spent allocating and deallocating CDataStream's
// buffer. If this ever needs to be optimized further, make a CStaticStream
// class with its buffer on the stack.
CDataStream ss(nType, nVersion);
ss.reserve(10000);
ss << obj;
return Hash(ss.begin(), ss.end());
}
inline uint160 Hash160(const vector<unsigned char>& vch)
{
uint256 hash1;
SHA256(&vch[0], vch.size(), (unsigned char*)&hash1);
uint160 hash2;
RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
return hash2;
}