PPCoin: Sign block when communicating with miners via RPC 'getwork'
[novacoin.git] / src / main.h
index d1201e6..f69c96e 100644 (file)
@@ -1,28 +1,45 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2011 The Bitcoin developers
+// Copyright (c) 2011-2012 The PPCoin developers
 // Distributed under the MIT/X11 software license, see the accompanying
 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
+#ifndef BITCOIN_MAIN_H
+#define BITCOIN_MAIN_H
+
+#include "bignum.h"
+#include "net.h"
+#include "key.h"
+#include "script.h"
+#include "db.h"
+
+#include <list>
 
-class COutPoint;
-class CInPoint;
-class CDiskTxPos;
-class CCoinBase;
-class CTxIn;
-class CTxOut;
-class CTransaction;
 class CBlock;
 class CBlockIndex;
 class CWalletTx;
+class CWallet;
 class CKeyItem;
+class CReserveKey;
+class CWalletDB;
+
+class CAddress;
+class CInv;
+class CRequestTracker;
+class CNode;
+class CBlockIndex;
 
 static const unsigned int MAX_BLOCK_SIZE = 1000000;
 static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2;
 static const int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
-static const int64 COIN = 100000000;
-static const int64 CENT = 1000000;
-static const int64 MIN_TX_FEE = 50000;
-static const int64 MAX_MONEY = 21000000 * COIN;
+static const int64 COIN = 1000000;
+static const int64 CENT = 10000;
+static const int64 MIN_TX_FEE = 10000;
+static const int64 MIN_RELAY_TX_FEE = 10000;
+static const int64 MAX_MONEY = 2000000000 * COIN;
 inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
 static const int COINBASE_MATURITY = 100;
+// Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp.
+static const int LOCKTIME_THRESHOLD = 500000000; // Tue Nov  5 00:53:20 1985 UTC
 #ifdef USE_UPNP
 static const int fHaveUPnP = true;
 #else
@@ -35,71 +52,65 @@ static const int fHaveUPnP = false;
 
 
 extern CCriticalSection cs_main;
-extern map<uint256, CBlockIndex*> mapBlockIndex;
+extern std::map<uint256, CBlockIndex*> mapBlockIndex;
+extern std::set<std::pair<COutPoint, unsigned int> > setStakeSeen;
 extern uint256 hashGenesisBlock;
-extern CBigNum bnProofOfWorkLimit;
 extern CBlockIndex* pindexGenesisBlock;
 extern int nBestHeight;
-extern CBigNum bnBestChainWork;
-extern CBigNum bnBestInvalidWork;
+extern uint64 nBestChainTrust;
+extern uint64 nBestInvalidTrust;
 extern uint256 hashBestChain;
 extern CBlockIndex* pindexBest;
 extern unsigned int nTransactionsUpdated;
-extern map<uint256, int> mapRequestCount;
-extern CCriticalSection cs_mapRequestCount;
-extern map<string, string> mapAddressBook;
-extern CCriticalSection cs_mapAddressBook;
-extern vector<unsigned char> vchDefaultKey;
 extern double dHashesPerSec;
 extern int64 nHPSTimerStart;
+extern int64 nTimeBestReceived;
+extern CCriticalSection cs_setpwalletRegistered;
+extern std::set<CWallet*> setpwalletRegistered;
+extern std::map<uint256, CBlock*> mapOrphanBlocks;
 
 // Settings
 extern int fGenerateBitcoins;
 extern int64 nTransactionFee;
-extern CAddress addrIncoming;
 extern int fLimitProcessors;
 extern int nLimitProcessors;
 extern int fMinimizeToTray;
 extern int fMinimizeOnClose;
 extern int fUseUPnP;
+extern int64 nBalanceReserve;
 
 
 
 
 
+class CReserveKey;
+class CTxDB;
+class CTxIndex;
 
-
+void RegisterWallet(CWallet* pwalletIn);
+void UnregisterWallet(CWallet* pwalletIn);
+bool ProcessBlock(CNode* pfrom, CBlock* pblock);
 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();
-bool AddToWallet(const CWalletTx& wtxIn);
-void WalletUpdateSpent(const COutPoint& prevout);
-int ScanForWalletTransactions(CBlockIndex* pindexStart);
-void ReacceptWalletTransactions();
 bool LoadBlockIndex(bool fAllowNew=true);
 void PrintBlockTree();
 bool ProcessMessages(CNode* pfrom);
-bool ProcessMessage(CNode* pfrom, 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(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);
-void GenerateBitcoins(bool fGenerate);
-void ThreadBitcoinMiner(void* parg);
-CBlock* CreateNewBlock(CReserveKey& reservekey);
-void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce, int64& nPrevTime);
+void GenerateBitcoins(bool fGenerate, CWallet* pwallet);
+CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfWorkOnly=false);
+void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
 void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1);
-bool CheckWork(CBlock* pblock, CReserveKey& reservekey);
-void BitcoinMiner();
+bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey);
 bool CheckProofOfWork(uint256 hash, unsigned int nBits);
+int64 GetProofOfStakeReward(int64 nCoinAge);
+unsigned int ComputeMinWork(unsigned int nBase, int64 nTime);
+int GetNumBlocksOfPeers();
 bool IsInitialBlockDownload();
-string GetWarnings(string strFor);
+std::string GetWarnings(std::string strFor);
+bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew);
+uint256 WantedByOrphan(const CBlock* pblockOrphan);
+const CBlockIndex* GetLastBlockIndex(const CBlockIndex* pindex, bool fProofOfStake);
 
 
 
@@ -111,6 +122,22 @@ string GetWarnings(string strFor);
 
 
 
+bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut);
+
+template<typename T>
+bool WriteSetting(const std::string& strKey, const T& value)
+{
+    bool fOk = false;
+    BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
+    {
+        std::string strWalletFile;
+        if (!GetWalletFile(pwallet, strWalletFile))
+            continue;
+        fOk |= CWalletDB(strWalletFile).WriteSetting(strKey, value);
+    }
+    return fOk;
+}
+
 
 class CDiskTxPos
 {
@@ -147,7 +174,7 @@ public:
         return !(a == b);
     }
 
-    string ToString() const
+    std::string ToString() const
     {
         if (IsNull())
             return strprintf("null");
@@ -206,7 +233,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);
     }
@@ -275,9 +302,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())
@@ -294,9 +321,6 @@ public:
     {
         printf("%s\n", ToString().c_str());
     }
-
-    bool IsMine() const;
-    int64 GetDebit() const;
 };
 
 
@@ -340,39 +364,20 @@ public:
         return (nValue == -1);
     }
 
-    uint256 GetHash() const
-    {
-        return SerializeHash(*this);
-    }
-
-    bool IsMine() const
+    bool SetEmpty()
     {
-        return ::IsMine(scriptPubKey);
-    }
-
-    int64 GetCredit() const
-    {
-        if (!MoneyRange(nValue))
-            throw runtime_error("CTxOut::GetCredit() : value out of range");
-        return (IsMine() ? nValue : 0);
+        nValue = 0;
+        scriptPubKey.clear();
     }
 
-    bool IsChange() const
+    bool IsEmpty() const
     {
-        // On a debit transaction, a txout that's mine but isn't in the address book is change
-        vector<unsigned char> vchPubKey;
-        if (ExtractPubKey(scriptPubKey, true, vchPubKey))
-            CRITICAL_BLOCK(cs_mapAddressBook)
-                if (!mapAddressBook.count(PubKeyToAddress(vchPubKey)))
-                    return true;
-        return false;
+        return (nValue == 0 && scriptPubKey.empty());
     }
 
-    int64 GetChange() const
+    uint256 GetHash() const
     {
-        if (!MoneyRange(nValue))
-            throw runtime_error("CTxOut::GetChange() : value out of range");
-        return (IsChange() ? nValue : 0);
+        return SerializeHash(*this);
     }
 
     friend bool operator==(const CTxOut& a, const CTxOut& b)
@@ -386,11 +391,12 @@ public:
         return !(a == b);
     }
 
-    string ToString() const
+    std::string ToString() const
     {
+        if (IsEmpty()) return "CTxOut(empty)";
         if (scriptPubKey.size() < 6)
             return "CTxOut(error)";
-        return strprintf("CTxOut(nValue=%"PRI64d".%08"PRI64d", scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30).c_str());
+        return strprintf("CTxOut(nValue=%s, scriptPubKey=%s)", FormatMoney(nValue).c_str(), scriptPubKey.ToString().substr(0,30).c_str());
     }
 
     void print() const
@@ -410,10 +416,14 @@ class CTransaction
 {
 public:
     int nVersion;
-    vector<CTxIn> vin;
-    vector<CTxOut> vout;
+    unsigned int nTime;
+    std::vector<CTxIn> vin;
+    std::vector<CTxOut> vout;
     unsigned int nLockTime;
 
+    // Denial-of-service detection:
+    mutable int nDoS;
+    bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
 
     CTransaction()
     {
@@ -424,6 +434,7 @@ public:
     (
         READWRITE(this->nVersion);
         nVersion = this->nVersion;
+        READWRITE(nTime);
         READWRITE(vin);
         READWRITE(vout);
         READWRITE(nLockTime);
@@ -432,9 +443,11 @@ public:
     void SetNull()
     {
         nVersion = 1;
+        nTime = GetAdjustedTime();
         vin.clear();
         vout.clear();
         nLockTime = 0;
+        nDoS = 0;  // Denial-of-service prevention
     }
 
     bool IsNull() const
@@ -456,9 +469,9 @@ public:
             nBlockHeight = nBestHeight;
         if (nBlockTime == 0)
             nBlockTime = GetAdjustedTime();
-        if ((int64)nLockTime < (nLockTime < 500000000 ? (int64)nBlockHeight : nBlockTime))
+        if ((int64)nLockTime < (nLockTime < LOCKTIME_THRESHOLD ? (int64)nBlockHeight : nBlockTime))
             return true;
-        foreach(const CTxIn& txin, vin)
+        BOOST_FOREACH(const CTxIn& txin, vin)
             if (!txin.IsFinal())
                 return false;
         return true;
@@ -495,89 +508,44 @@ public:
 
     bool IsCoinBase() const
     {
-        return (vin.size() == 1 && vin[0].prevout.IsNull());
+        return (vin.size() == 1 && vin[0].prevout.IsNull() && vout.size() == 1);
+    }
+
+    bool IsCoinStake() const
+    {
+        // ppcoin: the coin stake transaction is marked with the first output empty
+        return (vin.size() > 0 && vout.size() == 2 && vout[0].IsEmpty());
     }
 
     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;
     }
 
-    bool IsMine() const
-    {
-        foreach(const CTxOut& txout, vout)
-            if (txout.IsMine())
-                return true;
-        return false;
-    }
-
-    bool IsFromMe() const
-    {
-        return (GetDebit() > 0);
-    }
-
-    int64 GetDebit() const
-    {
-        int64 nDebit = 0;
-        foreach(const CTxIn& txin, vin)
-        {
-            nDebit += txin.GetDebit();
-            if (!MoneyRange(nDebit))
-                throw runtime_error("CTransaction::GetDebit() : value out of range");
-        }
-        return nDebit;
-    }
-
-    int64 GetCredit() const
-    {
-        int64 nCredit = 0;
-        foreach(const CTxOut& txout, vout)
-        {
-            nCredit += txout.GetCredit();
-            if (!MoneyRange(nCredit))
-                throw runtime_error("CTransaction::GetCredit() : value out of range");
-        }
-        return nCredit;
-    }
-
-    int64 GetChange() const
-    {
-        if (IsCoinBase())
-            return 0;
-        int64 nChange = 0;
-        foreach(const CTxOut& txout, vout)
-        {
-            nChange += txout.GetChange();
-            if (!MoneyRange(nChange))
-                throw runtime_error("CTransaction::GetChange() : value out of range");
-        }
-        return nChange;
-    }
-
     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;
     }
@@ -589,12 +557,14 @@ public:
         return dPriority > COIN * 144 / 250;
     }
 
-    int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true) const
+    int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=false, bool fForRelay=false) const
     {
-        // Base fee is 1 cent per kilobyte
+        // Base fee is either MIN_TX_FEE or MIN_RELAY_TX_FEE
+        int64 nBaseFee = fForRelay ? MIN_RELAY_TX_FEE : MIN_TX_FEE;
+
         unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK);
         unsigned int nNewBlockSize = nBlockSize + nBytes;
-        int64 nMinFee = (1 + (int64)nBytes / 1000) * MIN_TX_FEE;
+        int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee;
 
         if (fAllowFree)
         {
@@ -613,11 +583,11 @@ 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)
+        // To limit dust spam, require MIN_TX_FEE/MIN_RELAY_TX_FEE if any output is less than 0.01
+        if (nMinFee < nBaseFee)
+            BOOST_FOREACH(const CTxOut& txout, vout)
                 if (txout.nValue < CENT)
-                    nMinFee = MIN_TX_FEE;
+                    nMinFee = nBaseFee;
 
         // Raise the price as the block approaches full
         if (nBlockSize != 1 && nNewBlockSize >= MAX_BLOCK_SIZE_GEN/2)
@@ -657,6 +627,7 @@ public:
     friend bool operator==(const CTransaction& a, const CTransaction& b)
     {
         return (a.nVersion  == b.nVersion &&
+                a.nTime     == b.nTime &&
                 a.vin       == b.vin &&
                 a.vout      == b.vout &&
                 a.nLockTime == b.nLockTime);
@@ -668,11 +639,13 @@ public:
     }
 
 
-    string ToString() const
+    std::string ToString() const
     {
-        string str;
-        str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n",
+        std::string str;
+        str += IsCoinBase()? "Coinbase" : (IsCoinStake()? "Coinstake" : "CTransaction");
+        str += strprintf("(hash=%s, nTime=%d, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n",
             GetHash().ToString().substr(0,10).c_str(),
+            nTime,
             nVersion,
             vin.size(),
             vout.size(),
@@ -694,20 +667,18 @@ 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;
     bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
-    bool AcceptToMemoryPool(bool fCheckInputs=true, bool* pfMissingInputs=NULL)
-    {
-        CTxDB txdb("r");
-        return AcceptToMemoryPool(txdb, fCheckInputs, pfMissingInputs);
-    }
+    bool AcceptToMemoryPool(bool fCheckInputs=true, bool* pfMissingInputs=NULL);
 protected:
     bool AddToMemoryPoolUnchecked();
 public:
     bool RemoveFromMemoryPool();
+    bool GetCoinAge(CTxDB& txdb, uint64& nCoinAge) const;  // ppcoin: get transaction coin age
+    bool CheckProofOfStake(unsigned int nBits) const;
 };
 
 
@@ -721,7 +692,7 @@ class CMerkleTx : public CTransaction
 {
 public:
     uint256 hashBlock;
-    vector<uint256> vMerkleBranch;
+    std::vector<uint256> vMerkleBranch;
     int nIndex;
 
     // memory only
@@ -762,307 +733,7 @@ public:
     bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
     int GetBlocksToMaturity() const;
     bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true);
-    bool AcceptToMemoryPool() { CTxDB txdb("r"); return AcceptToMemoryPool(txdb); }
-};
-
-
-
-
-//
-// A transaction with a bunch of additional info that only the owner cares
-// about.  It includes any unrecorded transactions needed to link it back
-// to the block chain.
-//
-class CWalletTx : public CMerkleTx
-{
-public:
-    vector<CMerkleTx> vtxPrev;
-    map<string, string> mapValue;
-    vector<pair<string, string> > vOrderForm;
-    unsigned int fTimeReceivedIsTxTime;
-    unsigned int nTimeReceived;  // time received by this node
-    char fFromMe;
-    string strFromAccount;
-    vector<char> vfSpent;
-
-    // memory only
-    mutable char fDebitCached;
-    mutable char fCreditCached;
-    mutable char fAvailableCreditCached;
-    mutable char fChangeCached;
-    mutable int64 nDebitCached;
-    mutable int64 nCreditCached;
-    mutable int64 nAvailableCreditCached;
-    mutable int64 nChangeCached;
-
-    // memory only UI hints
-    mutable unsigned int nTimeDisplayed;
-    mutable int nLinesDisplayed;
-    mutable char fConfirmedDisplayed;
-
-
-    CWalletTx()
-    {
-        Init();
-    }
-
-    CWalletTx(const CMerkleTx& txIn) : CMerkleTx(txIn)
-    {
-        Init();
-    }
-
-    CWalletTx(const CTransaction& txIn) : CMerkleTx(txIn)
-    {
-        Init();
-    }
-
-    void Init()
-    {
-        vtxPrev.clear();
-        mapValue.clear();
-        vOrderForm.clear();
-        fTimeReceivedIsTxTime = false;
-        nTimeReceived = 0;
-        fFromMe = false;
-        strFromAccount.clear();
-        vfSpent.clear();
-        fDebitCached = false;
-        fCreditCached = false;
-        fAvailableCreditCached = false;
-        fChangeCached = false;
-        nDebitCached = 0;
-        nCreditCached = 0;
-        nAvailableCreditCached = 0;
-        nChangeCached = 0;
-        nTimeDisplayed = 0;
-        nLinesDisplayed = 0;
-        fConfirmedDisplayed = false;
-    }
-
-    IMPLEMENT_SERIALIZE
-    (
-        CWalletTx* pthis = const_cast<CWalletTx*>(this);
-        if (fRead)
-            pthis->Init();
-        char fSpent = false;
-
-        if (!fRead)
-        {
-            pthis->mapValue["fromaccount"] = pthis->strFromAccount;
-
-            string str;
-            foreach(char f, vfSpent)
-            {
-                str += (f ? '1' : '0');
-                if (f)
-                    fSpent = true;
-            }
-            pthis->mapValue["spent"] = str;
-        }
-
-        nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion,ser_action);
-        READWRITE(vtxPrev);
-        READWRITE(mapValue);
-        READWRITE(vOrderForm);
-        READWRITE(fTimeReceivedIsTxTime);
-        READWRITE(nTimeReceived);
-        READWRITE(fFromMe);
-        READWRITE(fSpent);
-
-        if (fRead)
-        {
-            pthis->strFromAccount = pthis->mapValue["fromaccount"];
-
-            if (mapValue.count("spent"))
-                foreach(char c, pthis->mapValue["spent"])
-                    pthis->vfSpent.push_back(c != '0');
-            else
-                pthis->vfSpent.assign(vout.size(), fSpent);
-        }
-
-        pthis->mapValue.erase("fromaccount");
-        pthis->mapValue.erase("version");
-        pthis->mapValue.erase("spent");
-    )
-
-    // marks certain txout's as spent
-    // returns true if any update took place
-    bool UpdateSpent(const vector<char>& vfNewSpent)
-    {
-        bool fReturn = false;
-        for (int i=0; i < vfNewSpent.size(); i++)
-        {
-            if (i == vfSpent.size())
-                break;
-
-            if (vfNewSpent[i] && !vfSpent[i])
-            {
-                vfSpent[i] = true;
-                fReturn = true;
-                fAvailableCreditCached = false;
-            }
-        }
-        return fReturn;
-    }
-
-    void MarkDirty()
-    {
-        fCreditCached = false;
-        fAvailableCreditCached = false;
-        fDebitCached = false;
-        fChangeCached = false;
-    }
-
-    void MarkSpent(unsigned int nOut)
-    {
-        if (nOut >= vout.size())
-            throw runtime_error("CWalletTx::MarkSpent() : nOut out of range");
-        vfSpent.resize(vout.size());
-        if (!vfSpent[nOut])
-        {
-            vfSpent[nOut] = true;
-            fAvailableCreditCached = false;
-        }
-    }
-
-    bool IsSpent(unsigned int nOut) const
-    {
-        if (nOut >= vout.size())
-            throw runtime_error("CWalletTx::IsSpent() : nOut out of range");
-        if (nOut >= vfSpent.size())
-            return false;
-        return (!!vfSpent[nOut]);
-    }
-
-    int64 GetDebit() const
-    {
-        if (vin.empty())
-            return 0;
-        if (fDebitCached)
-            return nDebitCached;
-        nDebitCached = CTransaction::GetDebit();
-        fDebitCached = true;
-        return nDebitCached;
-    }
-
-    int64 GetCredit(bool fUseCache=true) const
-    {
-        // Must wait until coinbase is safely deep enough in the chain before valuing it
-        if (IsCoinBase() && GetBlocksToMaturity() > 0)
-            return 0;
-
-        // GetBalance can assume transactions in mapWallet won't change
-        if (fUseCache && fCreditCached)
-            return nCreditCached;
-        nCreditCached = CTransaction::GetCredit();
-        fCreditCached = true;
-        return nCreditCached;
-    }
-
-    int64 GetAvailableCredit(bool fUseCache=true) const
-    {
-        // Must wait until coinbase is safely deep enough in the chain before valuing it
-        if (IsCoinBase() && GetBlocksToMaturity() > 0)
-            return 0;
-
-        if (fUseCache && fAvailableCreditCached)
-            return nAvailableCreditCached;
-
-        int64 nCredit = 0;
-        for (int i = 0; i < vout.size(); i++)
-        {
-            if (!IsSpent(i))
-            {
-                const CTxOut &txout = vout[i];
-                nCredit += txout.GetCredit();
-                if (!MoneyRange(nCredit))
-                    throw runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
-            }
-        }
-
-        nAvailableCreditCached = nCredit;
-        fAvailableCreditCached = true;
-        return nCredit;
-    }
-
-
-    int64 GetChange() const
-    {
-        if (fChangeCached)
-            return nChangeCached;
-        nChangeCached = CTransaction::GetChange();
-        fChangeCached = true;
-        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 GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived, 
-                           int64& nSent, int64& nFee) const;
-
-    bool IsFromMe() const
-    {
-        return (GetDebit() > 0);
-    }
-
-    bool IsConfirmed() const
-    {
-        // Quick answer in most cases
-        if (!IsFinal())
-            return false;
-        if (GetDepthInMainChain() >= 1)
-            return true;
-        if (!IsFromMe()) // using wtx's cached debit
-            return false;
-
-        // 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;
-        vWorkQueue.reserve(vtxPrev.size()+1);
-        vWorkQueue.push_back(this);
-        for (int i = 0; i < vWorkQueue.size(); i++)
-        {
-            const CMerkleTx* ptx = vWorkQueue[i];
-
-            if (!ptx->IsFinal())
-                return false;
-            if (ptx->GetDepthInMainChain() >= 1)
-                continue;
-            if (!ptx->IsFromMe())
-                return false;
-
-            if (mapPrev.empty())
-                foreach(const CMerkleTx& tx, vtxPrev)
-                    mapPrev[tx.GetHash()] = &tx;
-
-            foreach(const CTxIn& txin, ptx->vin)
-            {
-                if (!mapPrev.count(txin.prevout.hash))
-                    return false;
-                vWorkQueue.push_back(mapPrev[txin.prevout.hash]);
-            }
-        }
-        return true;
-    }
-
-    bool WriteToDisk()
-    {
-        return CWalletDB().WriteTx(GetHash(), *this);
-    }
-
-
-    int64 GetTxTime() const;
-    int GetRequestCount() const;
-
-    void AddSupportingTransactions(CTxDB& txdb);
-
-    bool AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs=true);
-    bool AcceptWalletTransaction() { CTxDB txdb("r"); return AcceptWalletTransaction(txdb); }
-
-    void RelayWalletTransaction(CTxDB& txdb);
-    void RelayWalletTransaction() { CTxDB txdb("r"); RelayWalletTransaction(txdb); }
+    bool AcceptToMemoryPool();
 };
 
 
@@ -1077,7 +748,7 @@ class CTxIndex
 {
 public:
     CDiskTxPos pos;
-    vector<CDiskTxPos> vSpent;
+    std::vector<CDiskTxPos> vSpent;
 
     CTxIndex()
     {
@@ -1149,11 +820,17 @@ public:
     unsigned int nNonce;
 
     // network and disk
-    vector<CTransaction> vtx;
+    std::vector<CTransaction> vtx;
+
+    // ppcoin: block signature - signed by coin base txout[0]'s owner
+    std::vector<unsigned char> vchBlockSig;
 
     // memory only
-    mutable vector<uint256> vMerkleTree;
+    mutable std::vector<uint256> vMerkleTree;
 
+    // Denial-of-service detection:
+    mutable int nDoS;
+    bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
 
     CBlock()
     {
@@ -1170,11 +847,17 @@ public:
         READWRITE(nBits);
         READWRITE(nNonce);
 
-        // ConnectBlock depends on vtx being last so it can calculate offset
+        // ConnectBlock depends on vtx following header to generate CDiskTxPos
         if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY)))
+        {
             READWRITE(vtx);
+            READWRITE(vchBlockSig);
+        }
         else if (fRead)
+        {
             const_cast<CBlock*>(this)->vtx.clear();
+            const_cast<CBlock*>(this)->vchBlockSig.clear();
+        }
     )
 
     void SetNull()
@@ -1186,7 +869,9 @@ public:
         nBits = 0;
         nNonce = 0;
         vtx.clear();
+        vchBlockSig.clear();
         vMerkleTree.clear();
+        nDoS = 0;
     }
 
     bool IsNull() const
@@ -1204,10 +889,35 @@ public:
         return (int64)nTime;
     }
 
+    // ppcoin: two types of block: proof-of-work or proof-of-stake
+    bool IsProofOfStake() const
+    {
+        return (vtx.size() > 1 && vtx[1].IsCoinStake());
+    }
+
+    bool IsProofOfWork() const
+    {
+        return !IsProofOfStake();
+    }
+
+    std::pair<COutPoint, unsigned int> GetProofOfStake() const
+    {
+        return IsProofOfStake()? std::make_pair(vtx[1].vin[0].prevout, vtx[1].nTime) : std::make_pair(COutPoint(), (unsigned int)0);
+    }
+
+    // ppcoin: get max transaction timestamp
+    int64 GetMaxTransactionTime() const
+    {
+        int64 maxTransactionTime = 0;
+        BOOST_FOREACH(const CTransaction& tx, vtx)
+            maxTransactionTime = std::max(maxTransactionTime, (int64)tx.nTime);
+        return maxTransactionTime;
+    }
+
     int GetSigOpCount() const
     {
         int n = 0;
-        foreach(const CTransaction& tx, vtx)
+        BOOST_FOREACH(const CTransaction& tx, vtx)
             n += tx.GetSigOpCount();
         return n;
     }
@@ -1216,14 +926,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])));
             }
@@ -1232,15 +942,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;
@@ -1248,11 +958,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));
@@ -1285,7 +995,7 @@ public:
         fflush(fileout);
         if (!IsInitialBlockDownload() || (nBestHeight+1) % 500 == 0)
         {
-#ifdef __WXMSW__
+#ifdef WIN32
             _commit(_fileno(fileout));
 #else
             fsync(fileno(fileout));
@@ -1310,7 +1020,7 @@ public:
         filein >> *this;
 
         // Check the header
-        if (!CheckProofOfWork(GetHash(), nBits))
+        if (fReadTransactions && IsProofOfWork() && !CheckProofOfWork(GetHash(), nBits))
             return error("CBlock::ReadFromDisk() : errors in block header");
 
         return true;
@@ -1320,13 +1030,14 @@ public:
 
     void print() const
     {
-        printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n",
+        printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d, vchBlockSig=%s)\n",
             GetHash().ToString().substr(0,20).c_str(),
             nVersion,
             hashPrevBlock.ToString().substr(0,20).c_str(),
             hashMerkleRoot.ToString().substr(0,10).c_str(),
             nTime, nBits, nNonce,
-            vtx.size());
+            vtx.size(),
+            HexStr(vchBlockSig.begin(), vchBlockSig.end()).c_str());
         for (int i = 0; i < vtx.size(); i++)
         {
             printf("  ");
@@ -1339,6 +1050,56 @@ public:
     }
 
 
+    bool SignBlock(const CKeyStore& keystore)
+    {
+        std::vector<std::pair<opcodetype, valtype> > vSolution;
+        const CTxOut& txout = IsProofOfStake()? vtx[1].vout[1] : vtx[0].vout[0];
+
+        if (!Solver(txout.scriptPubKey, vSolution))
+            return false;
+        BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
+        {
+            if (item.first == OP_PUBKEY)
+            {
+                // Sign
+                const valtype& vchPubKey = item.second;
+                CKey key;
+                if (!keystore.GetKey(Hash160(vchPubKey), key))
+                    return false;
+                if (key.GetPubKey() != vchPubKey)
+                    return false;
+                return key.Sign(GetHash(), vchBlockSig);
+            }
+        }
+        return false;
+    }
+
+    bool CheckBlockSignature() const
+    {
+        if (GetHash() == hashGenesisBlock)
+            return vchBlockSig.empty();
+
+        std::vector<std::pair<opcodetype, valtype> > vSolution;
+        const CTxOut& txout = IsProofOfStake()? vtx[1].vout[1] : vtx[0].vout[0];
+
+        if (!Solver(txout.scriptPubKey, vSolution))
+            return false;
+        BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
+        {
+            if (item.first == OP_PUBKEY)
+            {
+                const valtype& vchPubKey = item.second;
+                CKey key;
+                if (!key.SetPubKey(vchPubKey))
+                    return false;
+                if (vchBlockSig.empty())
+                    return false;
+                return key.Verify(GetHash(), vchBlockSig);
+            }
+        }
+        return false;
+    }
+
     bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex);
     bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex);
     bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true);
@@ -1346,6 +1107,7 @@ public:
     bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos);
     bool CheckBlock() const;
     bool AcceptBlock();
+    bool GetCoinAge(uint64& nCoinAge) const; // ppcoin: calculate total coin age spent in block
 };
 
 
@@ -1369,8 +1131,11 @@ public:
     CBlockIndex* pnext;
     unsigned int nFile;
     unsigned int nBlockPos;
+    uint64 nChainTrust;// ppcoin: trust score of chain, in the unit of coin-days
     int nHeight;
-    CBigNum bnChainWork;
+    bool fProofOfStake; // ppcoin: is the block of proof-of-stake type
+    COutPoint prevoutStake;
+    unsigned int nStakeTime;
 
     // block header
     int nVersion;
@@ -1388,7 +1153,10 @@ public:
         nFile = 0;
         nBlockPos = 0;
         nHeight = 0;
-        bnChainWork = 0;
+        nChainTrust = 0;
+        fProofOfStake = true;
+        prevoutStake.SetNull();
+        nStakeTime = 0;
 
         nVersion       = 0;
         hashMerkleRoot = 0;
@@ -1405,7 +1173,18 @@ public:
         nFile = nFileIn;
         nBlockPos = nBlockPosIn;
         nHeight = 0;
-        bnChainWork = 0;
+        nChainTrust = 0;
+        fProofOfStake = block.IsProofOfStake();
+        if (fProofOfStake)
+        {
+            prevoutStake = block.vtx[1].vin[0].prevout;
+            nStakeTime = block.vtx[1].nTime;
+        }
+        else
+        {
+            prevoutStake.SetNull();
+            nStakeTime = 0;
+        }
 
         nVersion       = block.nVersion;
         hashMerkleRoot = block.hashMerkleRoot;
@@ -1437,13 +1216,9 @@ public:
         return (int64)nTime;
     }
 
-    CBigNum GetBlockWork() const
+    int64 GetBlockTrust() const
     {
-        CBigNum bnTarget;
-        bnTarget.SetCompact(nBits);
-        if (bnTarget <= 0)
-            return 0;
-        return (CBigNum(1)<<256) / (bnTarget+1);
+        return (nChainTrust - (pprev? pprev->nChainTrust : 0));
     }
 
     bool IsInMainChain() const
@@ -1453,7 +1228,7 @@ public:
 
     bool CheckIndex() const
     {
-        return CheckProofOfWork(GetBlockHash(), nBits);
+        return IsProofOfWork() ? CheckProofOfWork(GetBlockHash(), nBits) : true;
     }
 
     bool EraseBlockFromDisk()
@@ -1483,7 +1258,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];
     }
 
@@ -1499,12 +1274,21 @@ public:
         return pindex->GetMedianTimePast();
     }
 
+    bool IsProofOfWork() const
+    {
+        return !fProofOfStake;
+    }
 
+    bool IsProofOfStake() const
+    {
+        return fProofOfStake;
+    }
 
-    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,
+        return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nChainTrust=%"PRI64d" nHeight=%d, fProofOfStake=%d prevoutStake=(%s), nStakeTime=%d merkle=%s, hashBlock=%s)",
+            pprev, pnext, nFile, nBlockPos, nChainTrust, nHeight,
+            fProofOfStake, prevoutStake.ToString().c_str(), nStakeTime,
             hashMerkleRoot.ToString().substr(0,10).c_str(),
             GetBlockHash().ToString().substr(0,20).c_str());
     }
@@ -1546,7 +1330,19 @@ public:
         READWRITE(hashNext);
         READWRITE(nFile);
         READWRITE(nBlockPos);
+        READWRITE(nChainTrust);
         READWRITE(nHeight);
+        READWRITE(fProofOfStake);
+        if (fProofOfStake)
+        {
+            READWRITE(prevoutStake);
+            READWRITE(nStakeTime);
+        }
+        else if (fRead)
+        {
+            const_cast<CDiskBlockIndex*>(this)->prevoutStake.SetNull();
+            const_cast<CDiskBlockIndex*>(this)->nStakeTime = 0;
+        }
 
         // block header
         READWRITE(this->nVersion);
@@ -1570,9 +1366,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(),
@@ -1602,7 +1398,7 @@ public:
 class CBlockLocator
 {
 protected:
-    vector<uint256> vHave;
+    std::vector<uint256> vHave;
 public:
 
     CBlockLocator()
@@ -1616,7 +1412,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);
     }
@@ -1660,9 +1456,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;
@@ -1679,9 +1475,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;
@@ -1695,9 +1491,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;
@@ -1722,114 +1518,6 @@ public:
 
 
 
-//
-// Private key that includes an expiration date in case it never gets used.
-//
-class CWalletKey
-{
-public:
-    CPrivKey vchPrivKey;
-    int64 nTimeCreated;
-    int64 nTimeExpires;
-    string strComment;
-    //// todo: add something to note what created it (user, getnewaddress, change)
-    ////   maybe should have a map<string, string> property map
-
-    CWalletKey(int64 nExpires=0)
-    {
-        nTimeCreated = (nExpires ? GetTime() : 0);
-        nTimeExpires = nExpires;
-    }
-
-    IMPLEMENT_SERIALIZE
-    (
-        if (!(nType & SER_GETHASH))
-            READWRITE(nVersion);
-        READWRITE(vchPrivKey);
-        READWRITE(nTimeCreated);
-        READWRITE(nTimeExpires);
-        READWRITE(strComment);
-    )
-};
-
-
-
-
-
-
-//
-// Account information.
-// Stored in wallet with key "acc"+string account name
-//
-class CAccount
-{
-public:
-    vector<unsigned char> vchPubKey;
-
-    CAccount()
-    {
-        SetNull();
-    }
-
-    void SetNull()
-    {
-        vchPubKey.clear();
-    }
-
-    IMPLEMENT_SERIALIZE
-    (
-        if (!(nType & SER_GETHASH))
-            READWRITE(nVersion);
-        READWRITE(vchPubKey);
-    )
-};
-
-
-
-//
-// Internal transfers.
-// Database key is acentry<account><counter>
-//
-class CAccountingEntry
-{
-public:
-    string strAccount;
-    int64 nCreditDebit;
-    int64 nTime;
-    string strOtherAccount;
-    string strComment;
-
-    CAccountingEntry()
-    {
-        SetNull();
-    }
-
-    void SetNull()
-    {
-        nCreditDebit = 0;
-        nTime = 0;
-        strAccount.clear();
-        strOtherAccount.clear();
-        strComment.clear();
-    }
-
-    IMPLEMENT_SERIALIZE
-    (
-        if (!(nType & SER_GETHASH))
-            READWRITE(nVersion);
-        // Note: strAccount is serialized as part of the key, not here.
-        READWRITE(nCreditDebit);
-        READWRITE(nTime);
-        READWRITE(strOtherAccount);
-        READWRITE(strComment);
-    )
-};
-
-
-
-
-
-
 
 
 
@@ -1848,16 +1536,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
     (
@@ -1896,13 +1584,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"
@@ -1942,8 +1630,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()
     {
@@ -1985,7 +1673,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 &&
@@ -2018,7 +1706,7 @@ public:
     bool CheckSignature()
     {
         CKey key;
-        if (!key.SetPubKey(ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284")))
+        if (!key.SetPubKey(ParseHex("0487ca85b6ae9d311f996c7616d20d0c88a5b4f07d25e78f419019f35cce6522acf978b2d99f0e7a58db1f120439e5c1889266927854aa57c93956c2569188a539")))
             return error("CAlert::CheckSignature() : SetPubKey failed");
         if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig))
             return error("CAlert::CheckSignature() : verify signature failed");
@@ -2032,20 +1720,4 @@ public:
     bool ProcessAlert();
 };
 
-
-
-
-
-
-
-
-
-
-extern map<uint256, CTransaction> mapTransactions;
-extern map<uint256, CWalletTx> mapWallet;
-extern vector<uint256> vWalletUpdated;
-extern CCriticalSection cs_mapWallet;
-extern map<vector<unsigned char>, CPrivKey> mapKeys;
-extern map<uint160, vector<unsigned char> > mapPubKeys;
-extern CCriticalSection cs_mapKeys;
-extern CKey keyUser;
+#endif