diff options
Diffstat (limited to 'core/include')
-rw-r--r-- | core/include/db.h | 526 | ||||
-rw-r--r-- | core/include/headers.h | 147 | ||||
-rw-r--r-- | core/include/init.h | 11 | ||||
-rw-r--r-- | core/include/irc.h | 13 | ||||
-rw-r--r-- | core/include/key.h | 18 | ||||
-rw-r--r-- | core/include/main.h | 204 | ||||
-rw-r--r-- | core/include/noui.h | 67 | ||||
-rw-r--r-- | core/include/rpc.h | 6 | ||||
-rw-r--r-- | core/include/script.h | 718 |
9 files changed, 1603 insertions, 107 deletions
diff --git a/core/include/db.h b/core/include/db.h new file mode 100644 index 0000000000..9826194ed0 --- /dev/null +++ b/core/include/db.h @@ -0,0 +1,526 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_DB_H +#define BITCOIN_DB_H + +#include "key.h" + +#include <map> +#include <string> +#include <vector> + +#include <db_cxx.h> + +class CTransaction; +class CTxIndex; +class CDiskBlockIndex; +class CDiskTxPos; +class COutPoint; +class CUser; +class CReview; +class CAddress; +class CWalletTx; +class CAccount; +class CAccountingEntry; +class CBlockLocator; + +extern std::map<std::string, std::string> mapAddressBook; +extern CCriticalSection cs_mapAddressBook; +extern std::vector<unsigned char> vchDefaultKey; +extern bool fClient; +extern int nBestHeight; + + +extern unsigned int nWalletDBUpdated; +extern DbEnv dbenv; + + +extern void DBFlush(bool fShutdown); +extern std::vector<unsigned char> GetKeyFromKeyPool(); +extern int64 GetOldestKeyPoolTime(); + + + + +class CDB +{ +protected: + Db* pdb; + std::string strFile; + std::vector<DbTxn*> vTxn; + bool fReadOnly; + + explicit CDB(const char* pszFile, const char* pszMode="r+"); + ~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; + if (fReadOnly) + assert(("Write called on database in read-only mode", 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; + if (fReadOnly) + assert(("Erase called on database in read-only mode", 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, DB_TXN_NOSYNC); + 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(std::string("version"), nVersion); + } + + bool WriteVersion(int nVersion) + { + return Write(std::string("version"), nVersion); + } +}; + + + + + + + + +class CTxDB : public CDB +{ +public: + CTxDB(const char* pszMode="r+") : CDB("blkindex.dat", pszMode) { } +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, std::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 ReadBestInvalidWork(CBigNum& bnBestInvalidWork); + bool WriteBestInvalidWork(CBigNum bnBestInvalidWork); + bool LoadBlockIndex(); +}; + + + + + +class CAddrDB : public CDB +{ +public: + CAddrDB(const char* pszMode="r+") : CDB("addr.dat", pszMode) { } +private: + CAddrDB(const CAddrDB&); + void operator=(const CAddrDB&); +public: + bool WriteAddress(const CAddress& addr); + bool EraseAddress(const CAddress& addr); + bool LoadAddresses(); +}; + +bool LoadAddresses(); + + + + + + +class CKeyPool +{ +public: + int64 nTime; + std::vector<unsigned char> vchPubKey; + + CKeyPool() + { + nTime = GetTime(); + } + + CKeyPool(const std::vector<unsigned char>& vchPubKeyIn) + { + nTime = GetTime(); + vchPubKey = vchPubKeyIn; + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(nTime); + READWRITE(vchPubKey); + ) +}; + + + + +class CWalletDB : public CDB +{ +public: + CWalletDB(const char* pszMode="r+") : CDB("wallet.dat", pszMode) + { + } +private: + CWalletDB(const CWalletDB&); + void operator=(const CWalletDB&); +public: + bool ReadName(const std::string& strAddress, std::string& strName) + { + strName = ""; + return Read(std::make_pair(std::string("name"), strAddress), strName); + } + + bool WriteName(const std::string& strAddress, const std::string& strName) + { + CRITICAL_BLOCK(cs_mapAddressBook) + mapAddressBook[strAddress] = strName; + nWalletDBUpdated++; + return Write(std::make_pair(std::string("name"), strAddress), strName); + } + + bool EraseName(const std::string& strAddress) + { + // This should only be used for sending addresses, never for receiving addresses, + // receiving addresses must always have an address book entry if they're not change return. + CRITICAL_BLOCK(cs_mapAddressBook) + mapAddressBook.erase(strAddress); + nWalletDBUpdated++; + return Erase(std::make_pair(std::string("name"), strAddress)); + } + + bool ReadTx(uint256 hash, CWalletTx& wtx) + { + return Read(std::make_pair(std::string("tx"), hash), wtx); + } + + bool WriteTx(uint256 hash, const CWalletTx& wtx) + { + nWalletDBUpdated++; + return Write(std::make_pair(std::string("tx"), hash), wtx); + } + + bool EraseTx(uint256 hash) + { + nWalletDBUpdated++; + return Erase(std::make_pair(std::string("tx"), hash)); + } + + bool ReadKey(const std::vector<unsigned char>& vchPubKey, CPrivKey& vchPrivKey) + { + vchPrivKey.clear(); + return Read(std::make_pair(std::string("key"), vchPubKey), vchPrivKey); + } + + bool WriteKey(const std::vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey) + { + nWalletDBUpdated++; + return Write(std::make_pair(std::string("key"), vchPubKey), vchPrivKey, false); + } + + bool WriteBestBlock(const CBlockLocator& locator) + { + nWalletDBUpdated++; + return Write(std::string("bestblock"), locator); + } + + bool ReadBestBlock(CBlockLocator& locator) + { + return Read(std::string("bestblock"), locator); + } + + bool ReadDefaultKey(std::vector<unsigned char>& vchPubKey) + { + vchPubKey.clear(); + return Read(std::string("defaultkey"), vchPubKey); + } + + bool WriteDefaultKey(const std::vector<unsigned char>& vchPubKey) + { + vchDefaultKey = vchPubKey; + nWalletDBUpdated++; + return Write(std::string("defaultkey"), vchPubKey); + } + + template<typename T> + bool ReadSetting(const std::string& strKey, T& value) + { + return Read(std::make_pair(std::string("setting"), strKey), value); + } + + template<typename T> + bool WriteSetting(const std::string& strKey, const T& value) + { + nWalletDBUpdated++; + return Write(std::make_pair(std::string("setting"), strKey), value); + } + + bool ReadAccount(const std::string& strAccount, CAccount& account); + bool WriteAccount(const std::string& strAccount, const CAccount& account); + bool WriteAccountingEntry(const CAccountingEntry& acentry); + int64 GetAccountCreditDebit(const std::string& strAccount); + void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& acentries); + + bool LoadWallet(); +protected: + void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool); + void KeepKey(int64 nIndex); + static void ReturnKey(int64 nIndex); + friend class CReserveKey; + friend std::vector<unsigned char> GetKeyFromKeyPool(); + friend int64 GetOldestKeyPoolTime(); +}; + +bool LoadWallet(bool& fFirstRunRet); +void BackupWallet(const std::string& strDest); + +inline bool SetAddressBookName(const std::string& strAddress, const std::string& strName) +{ + return CWalletDB().WriteName(strAddress, strName); +} + +class CReserveKey +{ +protected: + int64 nIndex; + std::vector<unsigned char> vchPubKey; +public: + CReserveKey() + { + nIndex = -1; + } + + ~CReserveKey() + { + if (!fShutdown) + ReturnKey(); + } + + std::vector<unsigned char> GetReservedKey() + { + if (nIndex == -1) + { + CKeyPool keypool; + CWalletDB().ReserveKeyFromKeyPool(nIndex, keypool); + vchPubKey = keypool.vchPubKey; + } + assert(!vchPubKey.empty()); + return vchPubKey; + } + + void KeepKey() + { + if (nIndex != -1) + CWalletDB().KeepKey(nIndex); + nIndex = -1; + vchPubKey.clear(); + } + + void ReturnKey() + { + if (nIndex != -1) + CWalletDB::ReturnKey(nIndex); + nIndex = -1; + vchPubKey.clear(); + } +}; + +#endif diff --git a/core/include/headers.h b/core/include/headers.h new file mode 100644 index 0000000000..d40c5ed0a9 --- /dev/null +++ b/core/include/headers.h @@ -0,0 +1,147 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#ifdef _MSC_VER +#pragma warning(disable:4786) +#pragma warning(disable:4804) +#pragma warning(disable:4805) +#pragma warning(disable:4717) +#endif +#ifdef _WIN32_WINNT +#undef _WIN32_WINNT +#endif +#define _WIN32_WINNT 0x0500 +#ifdef _WIN32_IE +#undef _WIN32_IE +#endif +#define _WIN32_IE 0x0400 +#define WIN32_LEAN_AND_MEAN 1 +#define __STDC_LIMIT_MACROS // to enable UINT64_MAX from stdint.h +#if (defined(__unix__) || defined(unix)) && !defined(USG) +#include <sys/param.h> // to get BSD define +#endif +#ifdef __WXMAC_OSX__ +#ifndef BSD +#define BSD 1 +#endif +#endif +#ifdef GUI +#include <wx/wx.h> +#include <wx/stdpaths.h> +#include <wx/snglinst.h> +#include <wx/utils.h> +#include <wx/clipbrd.h> +#include <wx/taskbar.h> +#endif +#include <openssl/buffer.h> +#include <openssl/ecdsa.h> +#include <openssl/evp.h> +#include <openssl/rand.h> +#include <openssl/sha.h> +#include <openssl/ripemd.h> +#include <db_cxx.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <math.h> +#include <limits.h> +#include <float.h> +#include <assert.h> +#include <memory> +#include <iostream> +#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> +#include <boost/bind.hpp> +#include <boost/function.hpp> +#include <boost/filesystem.hpp> +#include <boost/filesystem/fstream.hpp> +#include <boost/algorithm/string.hpp> +#include <boost/thread.hpp> +#include <boost/interprocess/sync/file_lock.hpp> +#include <boost/interprocess/sync/interprocess_mutex.hpp> +#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp> +#include <boost/date_time/gregorian/gregorian_types.hpp> +#include <boost/date_time/posix_time/posix_time_types.hpp> +#include <boost/config.hpp> +#include <boost/program_options/detail/config_file.hpp> +#include <boost/program_options/parsers.hpp> + +#ifdef __WXMSW__ +#include <windows.h> +#include <winsock2.h> +#include <mswsock.h> +#include <shlobj.h> +#include <shlwapi.h> +#include <io.h> +#include <process.h> +#include <malloc.h> +#else +#include <sys/time.h> +#include <sys/resource.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <unistd.h> +#include <errno.h> +#include <net/if.h> +#include <ifaddrs.h> +#include <fcntl.h> +#include <signal.h> +#endif +#ifdef BSD +#include <netinet/in.h> +#endif + + +#pragma hdrstop + +#include "strlcpy.h" +#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 "rpc.h" +#ifdef GUI +#include "uibase.h" +#include "ui.h" +#else +#include "noui.h" +#endif +#include "init.h" + +#ifdef GUI +#include "xpm/addressbook16.xpm" +#include "xpm/addressbook20.xpm" +#include "xpm/bitcoin16.xpm" +#include "xpm/bitcoin20.xpm" +#include "xpm/bitcoin32.xpm" +#include "xpm/bitcoin48.xpm" +#include "xpm/bitcoin80.xpm" +#include "xpm/check.xpm" +#include "xpm/send16.xpm" +#include "xpm/send16noshadow.xpm" +#include "xpm/send20.xpm" +#include "xpm/about.xpm" +#endif diff --git a/core/include/init.h b/core/include/init.h new file mode 100644 index 0000000000..61b2728576 --- /dev/null +++ b/core/include/init.h @@ -0,0 +1,11 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_INIT_H +#define BITCOIN_INIT_H + +void Shutdown(void* parg); +bool AppInit(int argc, char* argv[]); +bool AppInit2(int argc, char* argv[]); + +#endif diff --git a/core/include/irc.h b/core/include/irc.h new file mode 100644 index 0000000000..18e53597f6 --- /dev/null +++ b/core/include/irc.h @@ -0,0 +1,13 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_IRC_H +#define BITCOIN_IRC_H + +bool RecvLine(SOCKET hSocket, std::string& strLine); +void ThreadIRCSeed(void* parg); + +extern int nGotIRCAddresses; +extern bool fGotExternalIP; + +#endif diff --git a/core/include/key.h b/core/include/key.h index 390602e1ef..c973d6eb82 100644 --- a/core/include/key.h +++ b/core/include/key.h @@ -4,6 +4,10 @@ #ifndef BITCOIN_KEY_H #define BITCOIN_KEY_H +#include <openssl/ec.h> +#include <openssl/ecdsa.h> +#include <openssl/obj_mac.h> + // secp160k1 // const unsigned int PRIVATE_KEY_SIZE = 192; // const unsigned int PUBLIC_KEY_SIZE = 41; @@ -110,7 +114,7 @@ public: return vchPrivKey; } - bool SetPubKey(const vector<unsigned char>& vchPubKey) + bool SetPubKey(const std::vector<unsigned char>& vchPubKey) { const unsigned char* pbegin = &vchPubKey[0]; if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size())) @@ -119,19 +123,19 @@ public: return true; } - vector<unsigned char> GetPubKey() const + std::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); + std::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) + bool Sign(uint256 hash, std::vector<unsigned char>& vchSig) { vchSig.clear(); unsigned char pchSig[10000]; @@ -143,7 +147,7 @@ public: return true; } - bool Verify(uint256 hash, const vector<unsigned char>& vchSig) + bool Verify(uint256 hash, const std::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) @@ -151,7 +155,7 @@ public: return true; } - static bool Sign(const CPrivKey& vchPrivKey, uint256 hash, vector<unsigned char>& vchSig) + static bool Sign(const CPrivKey& vchPrivKey, uint256 hash, std::vector<unsigned char>& vchSig) { CKey key; if (!key.SetPrivKey(vchPrivKey)) @@ -159,7 +163,7 @@ public: return key.Sign(hash, vchSig); } - static bool Verify(const vector<unsigned char>& vchPubKey, uint256 hash, const vector<unsigned char>& vchSig) + static bool Verify(const std::vector<unsigned char>& vchPubKey, uint256 hash, const std::vector<unsigned char>& vchSig) { CKey key; if (!key.SetPubKey(vchPubKey)) diff --git a/core/include/main.h b/core/include/main.h index 7c9ace06c3..92b73fe5ad 100644 --- a/core/include/main.h +++ b/core/include/main.h @@ -7,6 +7,10 @@ #include "bignum.h" #include "net.h" #include "key.h" +#include "db.h" +#include "script.h" + +#include <list> class COutPoint; class CInPoint; @@ -79,7 +83,7 @@ bool CheckDiskSpace(uint64 nAdditionalBytes=0); FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb"); FILE* AppendBlockFile(unsigned int& nFileRet); bool AddKey(const CKey& key); -vector<unsigned char> GenerateNewKey(); +std::vector<unsigned char> GenerateNewKey(); bool AddToWallet(const CWalletTx& wtxIn); void WalletUpdateSpent(const COutPoint& prevout); int ScanForWalletTransactions(CBlockIndex* pindexStart); @@ -87,15 +91,15 @@ void ReacceptWalletTransactions(); bool LoadBlockIndex(bool fAllowNew=true); void PrintBlockTree(); bool ProcessMessages(CNode* pfrom); -bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv); +bool ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vRecv); bool SendMessages(CNode* pto, bool fSendTrickle); int64 GetBalance(); -bool CreateTransaction(const vector<pair<CScript, int64> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet); +bool CreateTransaction(const std::vector<std::pair<CScript, int64> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet); bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet); bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); bool BroadcastTransaction(CWalletTx& wtxNew); -string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); -string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); +std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); +std::string SendMoneyToBitcoinAddress(std::string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); void GenerateBitcoins(bool fGenerate); void ThreadBitcoinMiner(void* parg); CBlock* CreateNewBlock(CReserveKey& reservekey); @@ -105,7 +109,7 @@ bool CheckWork(CBlock* pblock, CReserveKey& reservekey); void BitcoinMiner(); bool CheckProofOfWork(uint256 hash, unsigned int nBits); bool IsInitialBlockDownload(); -string GetWarnings(string strFor); +std::string GetWarnings(std::string strFor); @@ -153,7 +157,7 @@ public: return !(a == b); } - string ToString() const + std::string ToString() const { if (IsNull()) return strprintf("null"); @@ -212,7 +216,7 @@ public: return !(a == b); } - string ToString() const + std::string ToString() const { return strprintf("COutPoint(%s, %d)", hash.ToString().substr(0,10).c_str(), n); } @@ -281,9 +285,9 @@ public: return !(a == b); } - string ToString() const + std::string ToString() const { - string str; + std::string str; str += strprintf("CTxIn("); str += prevout.ToString(); if (prevout.IsNull()) @@ -359,14 +363,14 @@ public: int64 GetCredit() const { if (!MoneyRange(nValue)) - throw runtime_error("CTxOut::GetCredit() : value out of range"); + throw std::runtime_error("CTxOut::GetCredit() : value out of range"); return (IsMine() ? nValue : 0); } bool IsChange() const { // On a debit transaction, a txout that's mine but isn't in the address book is change - vector<unsigned char> vchPubKey; + std::vector<unsigned char> vchPubKey; if (ExtractPubKey(scriptPubKey, true, vchPubKey)) CRITICAL_BLOCK(cs_mapAddressBook) if (!mapAddressBook.count(PubKeyToAddress(vchPubKey))) @@ -377,7 +381,7 @@ public: int64 GetChange() const { if (!MoneyRange(nValue)) - throw runtime_error("CTxOut::GetChange() : value out of range"); + throw std::runtime_error("CTxOut::GetChange() : value out of range"); return (IsChange() ? nValue : 0); } @@ -392,7 +396,7 @@ public: return !(a == b); } - string ToString() const + std::string ToString() const { if (scriptPubKey.size() < 6) return "CTxOut(error)"; @@ -416,8 +420,8 @@ class CTransaction { public: int nVersion; - vector<CTxIn> vin; - vector<CTxOut> vout; + std::vector<CTxIn> vin; + std::vector<CTxOut> vout; unsigned int nLockTime; @@ -464,7 +468,7 @@ public: nBlockTime = GetAdjustedTime(); if ((int64)nLockTime < (nLockTime < 500000000 ? (int64)nBlockHeight : nBlockTime)) return true; - foreach(const CTxIn& txin, vin) + BOOST_FOREACH(const CTxIn& txin, vin) if (!txin.IsFinal()) return false; return true; @@ -507,19 +511,19 @@ public: int GetSigOpCount() const { int n = 0; - foreach(const CTxIn& txin, vin) + BOOST_FOREACH(const CTxIn& txin, vin) n += txin.scriptSig.GetSigOpCount(); - foreach(const CTxOut& txout, vout) + BOOST_FOREACH(const CTxOut& txout, vout) n += txout.scriptPubKey.GetSigOpCount(); return n; } bool IsStandard() const { - foreach(const CTxIn& txin, vin) + BOOST_FOREACH(const CTxIn& txin, vin) if (!txin.scriptSig.IsPushOnly()) return error("nonstandard txin: %s", txin.scriptSig.ToString().c_str()); - foreach(const CTxOut& txout, vout) + BOOST_FOREACH(const CTxOut& txout, vout) if (!::IsStandard(txout.scriptPubKey)) return error("nonstandard txout: %s", txout.scriptPubKey.ToString().c_str()); return true; @@ -527,7 +531,7 @@ public: bool IsMine() const { - foreach(const CTxOut& txout, vout) + BOOST_FOREACH(const CTxOut& txout, vout) if (txout.IsMine()) return true; return false; @@ -541,11 +545,11 @@ public: int64 GetDebit() const { int64 nDebit = 0; - foreach(const CTxIn& txin, vin) + BOOST_FOREACH(const CTxIn& txin, vin) { nDebit += txin.GetDebit(); if (!MoneyRange(nDebit)) - throw runtime_error("CTransaction::GetDebit() : value out of range"); + throw std::runtime_error("CTransaction::GetDebit() : value out of range"); } return nDebit; } @@ -553,11 +557,11 @@ public: int64 GetCredit() const { int64 nCredit = 0; - foreach(const CTxOut& txout, vout) + BOOST_FOREACH(const CTxOut& txout, vout) { nCredit += txout.GetCredit(); if (!MoneyRange(nCredit)) - throw runtime_error("CTransaction::GetCredit() : value out of range"); + throw std::runtime_error("CTransaction::GetCredit() : value out of range"); } return nCredit; } @@ -567,11 +571,11 @@ public: if (IsCoinBase()) return 0; int64 nChange = 0; - foreach(const CTxOut& txout, vout) + BOOST_FOREACH(const CTxOut& txout, vout) { nChange += txout.GetChange(); if (!MoneyRange(nChange)) - throw runtime_error("CTransaction::GetChange() : value out of range"); + throw std::runtime_error("CTransaction::GetChange() : value out of range"); } return nChange; } @@ -579,11 +583,11 @@ public: int64 GetValueOut() const { int64 nValueOut = 0; - foreach(const CTxOut& txout, vout) + BOOST_FOREACH(const CTxOut& txout, vout) { nValueOut += txout.nValue; if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut)) - throw runtime_error("CTransaction::GetValueOut() : value out of range"); + throw std::runtime_error("CTransaction::GetValueOut() : value out of range"); } return nValueOut; } @@ -621,7 +625,7 @@ public: // To limit dust spam, require MIN_TX_FEE if any output is less than 0.01 if (nMinFee < MIN_TX_FEE) - foreach(const CTxOut& txout, vout) + BOOST_FOREACH(const CTxOut& txout, vout) if (txout.nValue < CENT) nMinFee = MIN_TX_FEE; @@ -674,9 +678,9 @@ public: } - string ToString() const + std::string ToString() const { - string str; + std::string str; str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n", GetHash().ToString().substr(0,10).c_str(), nVersion, @@ -700,7 +704,7 @@ public: bool ReadFromDisk(CTxDB& txdb, COutPoint prevout); bool ReadFromDisk(COutPoint prevout); bool DisconnectInputs(CTxDB& txdb); - bool ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx, + bool ConnectInputs(CTxDB& txdb, std::map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx, CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee=0); bool ClientConnectInputs(); bool CheckTransaction() const; @@ -727,7 +731,7 @@ class CMerkleTx : public CTransaction { public: uint256 hashBlock; - vector<uint256> vMerkleBranch; + std::vector<uint256> vMerkleBranch; int nIndex; // memory only @@ -782,14 +786,14 @@ public: class CWalletTx : public CMerkleTx { public: - vector<CMerkleTx> vtxPrev; - map<string, string> mapValue; - vector<pair<string, string> > vOrderForm; + std::vector<CMerkleTx> vtxPrev; + std::map<std::string, std::string> mapValue; + std::vector<std::pair<std::string, std::string> > vOrderForm; unsigned int fTimeReceivedIsTxTime; unsigned int nTimeReceived; // time received by this node char fFromMe; - string strFromAccount; - vector<char> vfSpent; + std::string strFromAccount; + std::vector<char> vfSpent; // memory only mutable char fDebitCached; @@ -856,8 +860,8 @@ public: { pthis->mapValue["fromaccount"] = pthis->strFromAccount; - string str; - foreach(char f, vfSpent) + std::string str; + BOOST_FOREACH(char f, vfSpent) { str += (f ? '1' : '0'); if (f) @@ -880,7 +884,7 @@ public: pthis->strFromAccount = pthis->mapValue["fromaccount"]; if (mapValue.count("spent")) - foreach(char c, pthis->mapValue["spent"]) + BOOST_FOREACH(char c, pthis->mapValue["spent"]) pthis->vfSpent.push_back(c != '0'); else pthis->vfSpent.assign(vout.size(), fSpent); @@ -893,7 +897,7 @@ public: // marks certain txout's as spent // returns true if any update took place - bool UpdateSpent(const vector<char>& vfNewSpent) + bool UpdateSpent(const std::vector<char>& vfNewSpent) { bool fReturn = false; for (int i=0; i < vfNewSpent.size(); i++) @@ -922,7 +926,7 @@ public: void MarkSpent(unsigned int nOut) { if (nOut >= vout.size()) - throw runtime_error("CWalletTx::MarkSpent() : nOut out of range"); + throw std::runtime_error("CWalletTx::MarkSpent() : nOut out of range"); vfSpent.resize(vout.size()); if (!vfSpent[nOut]) { @@ -934,7 +938,7 @@ public: bool IsSpent(unsigned int nOut) const { if (nOut >= vout.size()) - throw runtime_error("CWalletTx::IsSpent() : nOut out of range"); + throw std::runtime_error("CWalletTx::IsSpent() : nOut out of range"); if (nOut >= vfSpent.size()) return false; return (!!vfSpent[nOut]); @@ -982,7 +986,7 @@ public: const CTxOut &txout = vout[i]; nCredit += txout.GetCredit(); if (!MoneyRange(nCredit)) - throw runtime_error("CWalletTx::GetAvailableCredit() : value out of range"); + throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range"); } } @@ -1001,10 +1005,10 @@ public: return nChangeCached; } - void GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, list<pair<string /* address */, int64> >& listReceived, - list<pair<string /* address */, int64> >& listSent, int64& nFee, string& strSentAccount) const; + void GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, std::list<std::pair<std::string /* address */, int64> >& listReceived, + std::list<std::pair<std::string /* address */, int64> >& listSent, int64& nFee, std::string& strSentAccount) const; - void GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived, + void GetAccountAmounts(const std::string& strAccount, int64& nGenerated, int64& nReceived, int64& nSent, int64& nFee) const; bool IsFromMe() const @@ -1024,8 +1028,8 @@ public: // If no confirmations but it's from us, we can still // consider it confirmed if all dependencies are confirmed - map<uint256, const CMerkleTx*> mapPrev; - vector<const CMerkleTx*> vWorkQueue; + std::map<uint256, const CMerkleTx*> mapPrev; + std::vector<const CMerkleTx*> vWorkQueue; vWorkQueue.reserve(vtxPrev.size()+1); vWorkQueue.push_back(this); for (int i = 0; i < vWorkQueue.size(); i++) @@ -1040,10 +1044,10 @@ public: return false; if (mapPrev.empty()) - foreach(const CMerkleTx& tx, vtxPrev) + BOOST_FOREACH(const CMerkleTx& tx, vtxPrev) mapPrev[tx.GetHash()] = &tx; - foreach(const CTxIn& txin, ptx->vin) + BOOST_FOREACH(const CTxIn& txin, ptx->vin) { if (!mapPrev.count(txin.prevout.hash)) return false; @@ -1083,7 +1087,7 @@ class CTxIndex { public: CDiskTxPos pos; - vector<CDiskTxPos> vSpent; + std::vector<CDiskTxPos> vSpent; CTxIndex() { @@ -1155,10 +1159,10 @@ public: unsigned int nNonce; // network and disk - vector<CTransaction> vtx; + std::vector<CTransaction> vtx; // memory only - mutable vector<uint256> vMerkleTree; + mutable std::vector<uint256> vMerkleTree; CBlock() @@ -1213,7 +1217,7 @@ public: int GetSigOpCount() const { int n = 0; - foreach(const CTransaction& tx, vtx) + BOOST_FOREACH(const CTransaction& tx, vtx) n += tx.GetSigOpCount(); return n; } @@ -1222,14 +1226,14 @@ public: uint256 BuildMerkleTree() const { vMerkleTree.clear(); - foreach(const CTransaction& tx, vtx) + BOOST_FOREACH(const CTransaction& tx, vtx) vMerkleTree.push_back(tx.GetHash()); int j = 0; for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) { for (int i = 0; i < nSize; i += 2) { - int i2 = min(i+1, nSize-1); + int i2 = std::min(i+1, nSize-1); vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]), BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2]))); } @@ -1238,15 +1242,15 @@ public: return (vMerkleTree.empty() ? 0 : vMerkleTree.back()); } - vector<uint256> GetMerkleBranch(int nIndex) const + std::vector<uint256> GetMerkleBranch(int nIndex) const { if (vMerkleTree.empty()) BuildMerkleTree(); - vector<uint256> vMerkleBranch; + std::vector<uint256> vMerkleBranch; int j = 0; for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) { - int i = min(nIndex^1, nSize-1); + int i = std::min(nIndex^1, nSize-1); vMerkleBranch.push_back(vMerkleTree[j+i]); nIndex >>= 1; j += nSize; @@ -1254,11 +1258,11 @@ public: return vMerkleBranch; } - static uint256 CheckMerkleBranch(uint256 hash, const vector<uint256>& vMerkleBranch, int nIndex) + static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex) { if (nIndex == -1) return 0; - foreach(const uint256& otherside, vMerkleBranch) + BOOST_FOREACH(const uint256& otherside, vMerkleBranch) { if (nIndex & 1) hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash)); @@ -1489,7 +1493,7 @@ public: for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev) *(--pbegin) = pindex->GetBlockTime(); - sort(pbegin, pend); + std::sort(pbegin, pend); return pbegin[(pend - pbegin)/2]; } @@ -1507,7 +1511,7 @@ public: - string ToString() const + std::string ToString() const { return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)", pprev, pnext, nFile, nBlockPos, nHeight, @@ -1576,9 +1580,9 @@ public: } - string ToString() const + std::string ToString() const { - string str = "CDiskBlockIndex("; + std::string str = "CDiskBlockIndex("; str += CBlockIndex::ToString(); str += strprintf("\n hashBlock=%s, hashPrev=%s, hashNext=%s)", GetBlockHash().ToString().c_str(), @@ -1608,7 +1612,7 @@ public: class CBlockLocator { protected: - vector<uint256> vHave; + std::vector<uint256> vHave; public: CBlockLocator() @@ -1622,7 +1626,7 @@ public: explicit CBlockLocator(uint256 hashBlock) { - map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock); + std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock); if (mi != mapBlockIndex.end()) Set((*mi).second); } @@ -1666,9 +1670,9 @@ public: // Retrace how far back it was in the sender's branch int nDistance = 0; int nStep = 1; - foreach(const uint256& hash, vHave) + BOOST_FOREACH(const uint256& hash, vHave) { - map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash); + std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash); if (mi != mapBlockIndex.end()) { CBlockIndex* pindex = (*mi).second; @@ -1685,9 +1689,9 @@ public: CBlockIndex* GetBlockIndex() { // Find the first block the caller has in the main chain - foreach(const uint256& hash, vHave) + BOOST_FOREACH(const uint256& hash, vHave) { - map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash); + std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash); if (mi != mapBlockIndex.end()) { CBlockIndex* pindex = (*mi).second; @@ -1701,9 +1705,9 @@ public: uint256 GetBlockHash() { // Find the first block the caller has in the main chain - foreach(const uint256& hash, vHave) + BOOST_FOREACH(const uint256& hash, vHave) { - map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash); + std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash); if (mi != mapBlockIndex.end()) { CBlockIndex* pindex = (*mi).second; @@ -1737,7 +1741,7 @@ public: CPrivKey vchPrivKey; int64 nTimeCreated; int64 nTimeExpires; - string strComment; + std::string strComment; //// todo: add something to note what created it (user, getnewaddress, change) //// maybe should have a map<string, string> property map @@ -1770,7 +1774,7 @@ public: class CAccount { public: - vector<unsigned char> vchPubKey; + std::vector<unsigned char> vchPubKey; CAccount() { @@ -1799,11 +1803,11 @@ public: class CAccountingEntry { public: - string strAccount; + std::string strAccount; int64 nCreditDebit; int64 nTime; - string strOtherAccount; - string strComment; + std::string strOtherAccount; + std::string strComment; CAccountingEntry() { @@ -1854,16 +1858,16 @@ public: int64 nExpiration; int nID; int nCancel; - set<int> setCancel; + std::set<int> setCancel; int nMinVer; // lowest version inclusive int nMaxVer; // highest version inclusive - set<string> setSubVer; // empty matches all + std::set<std::string> setSubVer; // empty matches all int nPriority; // Actions - string strComment; - string strStatusBar; - string strReserved; + std::string strComment; + std::string strStatusBar; + std::string strReserved; IMPLEMENT_SERIALIZE ( @@ -1902,13 +1906,13 @@ public: strReserved.clear(); } - string ToString() const + std::string ToString() const { - string strSetCancel; - foreach(int n, setCancel) + std::string strSetCancel; + BOOST_FOREACH(int n, setCancel) strSetCancel += strprintf("%d ", n); - string strSetSubVer; - foreach(string str, setSubVer) + std::string strSetSubVer; + BOOST_FOREACH(std::string str, setSubVer) strSetSubVer += "\"" + str + "\" "; return strprintf( "CAlert(\n" @@ -1948,8 +1952,8 @@ public: class CAlert : public CUnsignedAlert { public: - vector<unsigned char> vchMsg; - vector<unsigned char> vchSig; + std::vector<unsigned char> vchMsg; + std::vector<unsigned char> vchSig; CAlert() { @@ -1991,7 +1995,7 @@ public: return (alert.nID <= nCancel || setCancel.count(alert.nID)); } - bool AppliesTo(int nVersion, string strSubVerIn) const + bool AppliesTo(int nVersion, std::string strSubVerIn) const { return (IsInEffect() && nMinVer <= nVersion && nVersion <= nMaxVer && @@ -2047,12 +2051,12 @@ public: -extern map<uint256, CTransaction> mapTransactions; -extern map<uint256, CWalletTx> mapWallet; -extern vector<uint256> vWalletUpdated; +extern std::map<uint256, CTransaction> mapTransactions; +extern std::map<uint256, CWalletTx> mapWallet; +extern std::vector<uint256> vWalletUpdated; extern CCriticalSection cs_mapWallet; -extern map<vector<unsigned char>, CPrivKey> mapKeys; -extern map<uint160, vector<unsigned char> > mapPubKeys; +extern std::map<std::vector<unsigned char>, CPrivKey> mapKeys; +extern std::map<uint160, std::vector<unsigned char> > mapPubKeys; extern CCriticalSection cs_mapKeys; extern CKey keyUser; diff --git a/core/include/noui.h b/core/include/noui.h new file mode 100644 index 0000000000..afb19526c1 --- /dev/null +++ b/core/include/noui.h @@ -0,0 +1,67 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_NOUI_H +#define BITCOIN_NOUI_H + +#include <string> + +typedef void wxWindow; +#define wxYES 0x00000002 +#define wxOK 0x00000004 +#define wxNO 0x00000008 +#define wxYES_NO (wxYES|wxNO) +#define wxCANCEL 0x00000010 +#define wxAPPLY 0x00000020 +#define wxCLOSE 0x00000040 +#define wxOK_DEFAULT 0x00000000 +#define wxYES_DEFAULT 0x00000000 +#define wxNO_DEFAULT 0x00000080 +#define wxCANCEL_DEFAULT 0x80000000 +#define wxICON_EXCLAMATION 0x00000100 +#define wxICON_HAND 0x00000200 +#define wxICON_WARNING wxICON_EXCLAMATION +#define wxICON_ERROR wxICON_HAND +#define wxICON_QUESTION 0x00000400 +#define wxICON_INFORMATION 0x00000800 +#define wxICON_STOP wxICON_HAND +#define wxICON_ASTERISK wxICON_INFORMATION +#define wxICON_MASK (0x00000100|0x00000200|0x00000400|0x00000800) +#define wxFORWARD 0x00001000 +#define wxBACKWARD 0x00002000 +#define wxRESET 0x00004000 +#define wxHELP 0x00008000 +#define wxMORE 0x00010000 +#define wxSETUP 0x00020000 + +inline int MyMessageBox(const std::string& message, const std::string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1) +{ + printf("%s: %s\n", caption.c_str(), message.c_str()); + fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str()); + return 4; +} +#define wxMessageBox MyMessageBox + +inline int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1) +{ + return MyMessageBox(message, caption, style, parent, x, y); +} + +inline bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption, wxWindow* parent) +{ + return true; +} + +inline void CalledSetStatusBar(const std::string& strText, int nField) +{ +} + +inline void UIThreadCall(boost::function0<void> fn) +{ +} + +inline void MainFrameRepaint() +{ +} + +#endif diff --git a/core/include/rpc.h b/core/include/rpc.h new file mode 100644 index 0000000000..48a7b8a8a6 --- /dev/null +++ b/core/include/rpc.h @@ -0,0 +1,6 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +void ThreadRPCServer(void* parg); +int CommandLineRPC(int argc, char *argv[]); diff --git a/core/include/script.h b/core/include/script.h new file mode 100644 index 0000000000..22a6020dce --- /dev/null +++ b/core/include/script.h @@ -0,0 +1,718 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. +#ifndef H_BITCOIN_SCRIPT +#define H_BITCOIN_SCRIPT + +#include "base58.h" + +#include <string> +#include <vector> + +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, + + // expansion + OP_NOP1, + OP_NOP2, + OP_NOP3, + OP_NOP4, + OP_NOP5, + OP_NOP6, + OP_NOP7, + OP_NOP8, + OP_NOP9, + OP_NOP10, + + + + // template matching params + OP_PUBKEYHASH = 0xfd, + OP_PUBKEY = 0xfe, + + OP_INVALIDOPCODE = 0xff, +}; + + + + + + + + +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"; + + // expanson + case OP_NOP1 : return "OP_NOP1"; + case OP_NOP2 : return "OP_NOP2"; + case OP_NOP3 : return "OP_NOP3"; + case OP_NOP4 : return "OP_NOP4"; + case OP_NOP5 : return "OP_NOP5"; + case OP_NOP6 : return "OP_NOP6"; + case OP_NOP7 : return "OP_NOP7"; + case OP_NOP8 : return "OP_NOP8"; + case OP_NOP9 : return "OP_NOP9"; + case OP_NOP10 : return "OP_NOP10"; + + + + // template matching params + case OP_PUBKEYHASH : return "OP_PUBKEYHASH"; + case OP_PUBKEY : return "OP_PUBKEY"; + + case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE"; + default: + return "OP_UNKNOWN"; + } +}; + + + + +inline std::string ValueString(const std::vector<unsigned char>& vch) +{ + if (vch.size() <= 4) + return strprintf("%d", CBigNum(vch).getint()); + else + return HexStr(vch); +} + +inline std::string StackString(const std::vector<std::vector<unsigned char> >& vStack) +{ + std::string str; + BOOST_FOREACH(const std::vector<unsigned char>& vch, vStack) + { + if (!str.empty()) + str += " "; + str += ValueString(vch); + } + return str; +} + + + + + + + + + +class CScript : public std::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 <= 16) + { + push_back(n + (OP_1 - 1)); + } + else + { + CBigNum bn(n); + *this << bn.getvch(); + } + return *this; + } + +public: + CScript() { } + CScript(const CScript& b) : std::vector<unsigned char>(b.begin(), b.end()) { } + CScript(const_iterator pbegin, const_iterator pend) : std::vector<unsigned char>(pbegin, pend) { } +#ifndef _MSC_VER + CScript(const unsigned char* pbegin, const unsigned char* pend) : std::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 std::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 < 0 || opcode > 0xff) + throw std::runtime_error("CScript::operator<<() : invalid opcode"); + insert(end(), (unsigned char)opcode); + 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 std::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 if (b.size() <= 0xffff) + { + insert(end(), OP_PUSHDATA2); + unsigned short nSize = b.size(); + insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize)); + } + else + { + insert(end(), OP_PUSHDATA4); + unsigned int 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, std::vector<unsigned char>& vchRet) + { + // Wrapper so it can be called with either iterator or const_iterator + const_iterator pc2 = pc; + bool fRet = GetOp2(pc2, opcodeRet, &vchRet); + pc = begin() + (pc2 - begin()); + return fRet; + } + + bool GetOp(iterator& pc, opcodetype& opcodeRet) + { + const_iterator pc2 = pc; + bool fRet = GetOp2(pc2, opcodeRet, NULL); + pc = begin() + (pc2 - begin()); + return fRet; + } + + bool GetOp(const_iterator& pc, opcodetype& opcodeRet, std::vector<unsigned char>& vchRet) const + { + return GetOp2(pc, opcodeRet, &vchRet); + } + + bool GetOp(const_iterator& pc, opcodetype& opcodeRet) const + { + return GetOp2(pc, opcodeRet, NULL); + } + + bool GetOp2(const_iterator& pc, opcodetype& opcodeRet, std::vector<unsigned char>* pvchRet) const + { + opcodeRet = OP_INVALIDOPCODE; + if (pvchRet) + pvchRet->clear(); + if (pc >= end()) + return false; + + // Read instruction + if (end() - pc < 1) + return false; + unsigned int opcode = *pc++; + + // Immediate operand + if (opcode <= OP_PUSHDATA4) + { + unsigned int nSize; + if (opcode < OP_PUSHDATA1) + { + nSize = opcode; + } + else if (opcode == OP_PUSHDATA1) + { + if (end() - pc < 1) + return false; + nSize = *pc++; + } + else if (opcode == OP_PUSHDATA2) + { + if (end() - pc < 2) + return false; + nSize = 0; + memcpy(&nSize, &pc[0], 2); + pc += 2; + } + else if (opcode == OP_PUSHDATA4) + { + if (end() - pc < 4) + return false; + memcpy(&nSize, &pc[0], 4); + pc += 4; + } + if (end() - pc < nSize) + return false; + if (pvchRet) + pvchRet->assign(pc, pc + nSize); + pc += nSize; + } + + opcodeRet = (opcodetype)opcode; + return true; + } + + + void FindAndDelete(const CScript& b) + { + if (b.empty()) + return; + iterator pc = begin(); + opcodetype opcode; + do + { + while (end() - pc >= b.size() && memcmp(&pc[0], &b[0], b.size()) == 0) + erase(pc, pc + b.size()); + } + while (GetOp(pc, opcode)); + } + + + int GetSigOpCount() const + { + int n = 0; + const_iterator pc = begin(); + while (pc < end()) + { + opcodetype opcode; + if (!GetOp(pc, opcode)) + break; + if (opcode == OP_CHECKSIG || opcode == OP_CHECKSIGVERIFY) + n++; + else if (opcode == OP_CHECKMULTISIG || opcode == OP_CHECKMULTISIGVERIFY) + n += 20; + } + return n; + } + + + bool IsPushOnly() const + { + if (size() > 200) + return false; + const_iterator pc = begin(); + while (pc < end()) + { + opcodetype opcode; + if (!GetOp(pc, opcode)) + return false; + if (opcode > OP_16) + return false; + } + return true; + } + + + uint160 GetBitcoinAddressHash160() const + { + opcodetype opcode; + std::vector<unsigned char> vch; + CScript::const_iterator pc = begin(); + if (!GetOp(pc, opcode, vch) || opcode != OP_DUP) return 0; + if (!GetOp(pc, opcode, vch) || opcode != OP_HASH160) return 0; + if (!GetOp(pc, opcode, vch) || vch.size() != sizeof(uint160)) return 0; + uint160 hash160 = uint160(vch); + if (!GetOp(pc, opcode, vch) || opcode != OP_EQUALVERIFY) return 0; + if (!GetOp(pc, opcode, vch) || opcode != OP_CHECKSIG) return 0; + if (pc != end()) return 0; + return hash160; + } + + std::string GetBitcoinAddress() const + { + uint160 hash160 = GetBitcoinAddressHash160(); + if (hash160 == 0) + return ""; + return Hash160ToAddress(hash160); + } + + void SetBitcoinAddress(const uint160& hash160) + { + this->clear(); + *this << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; + } + + void SetBitcoinAddress(const std::vector<unsigned char>& vchPubKey) + { + SetBitcoinAddress(Hash160(vchPubKey)); + } + + bool SetBitcoinAddress(const std::string& strAddress) + { + this->clear(); + uint160 hash160; + if (!AddressToHash160(strAddress, hash160)) + return false; + SetBitcoinAddress(hash160); + return true; + } + + + void PrintHex() const + { + printf("CScript(%s)\n", HexStr(begin(), end(), true).c_str()); + } + + std::string ToString() const + { + std::string str; + opcodetype opcode; + std::vector<unsigned char> vch; + const_iterator pc = begin(); + while (pc < end()) + { + if (!str.empty()) + str += " "; + if (!GetOp(pc, opcode, vch)) + { + str += "[error]"; + return str; + } + if (0 <= opcode && opcode <= OP_PUSHDATA4) + str += ValueString(vch); + else + str += GetOpName(opcode); + } + return str; + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + + + + + + +uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); +bool IsStandard(const CScript& scriptPubKey); +bool IsMine(const CScript& scriptPubKey); +bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, std::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); + +#endif |