PPCoin: Create coinstake with multiple inputs of same scriptPubKey
authorScott Nadal <scott.nadal@gmail.com>
Mon, 30 Apr 2012 14:28:42 +0000 (15:28 +0100)
committerScott Nadal <scott.nadal@gmail.com>
Mon, 30 Apr 2012 14:28:42 +0000 (15:28 +0100)
        Use this scriptPubKey for coinstake output also

src/main.cpp
src/wallet.cpp
src/wallet.h

index 6116daa..ef401cd 100644 (file)
@@ -3017,7 +3017,7 @@ CBlock* CreateNewBlock(CWallet* pwallet)
             nLastCoinStakeCheckTime++;
             txCoinStake.nTime = nLastCoinStakeCheckTime;
         }
-        if (pwallet->CreateCoinStake(txNew.vout[0].scriptPubKey, pblock->nBits, txCoinStake))
+        if (pwallet->CreateCoinStake(pblock->nBits, txCoinStake))
         {
             pblock->vtx.push_back(txCoinStake);
             pblock->vtx[0].vout[0].SetEmpty();
index f44fb22..51c4b88 100644 (file)
@@ -1062,7 +1062,7 @@ bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& w
 }
 
 // ppcoin: create coin stake transaction
-bool CWallet::CreateCoinStake(CScript scriptPubKey, unsigned int nBits, CTransaction& txNew)
+bool CWallet::CreateCoinStake(unsigned int nBits, CTransaction& txNew)
 {
     CBigNum bnTargetPerCoinDay;
     bnTargetPerCoinDay.SetCompact(nBits);
@@ -1111,13 +1111,25 @@ bool CWallet::CreateCoinStake(CScript scriptPubKey, unsigned int nBits, CTransac
             {
                 txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second));
                 nCredit += pcoin.first->vout[pcoin.second].nValue;
-                // Only spend one tx for now
                 vwtxPrev.push_back(pcoin.first);
+                // Set output scriptPubKey
+                txNew.vout.push_back(CTxOut(0, pcoin.first->vout[pcoin.second].scriptPubKey));
                 break;
             }
         }
         if (nCredit == 0 || nCredit > nBalance - nBalanceReserve)
             return false;
+        BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
+        {
+            if (pcoin.first->vout[pcoin.second].scriptPubKey == txNew.vout[1].scriptPubKey && pcoin.first->GetHash() != txNew.vin[0].prevout.hash)
+            {
+                if (nCredit + pcoin.first->vout[pcoin.second].nValue > nBalance - nBalanceReserve)
+                    break;
+                txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second));
+                nCredit += pcoin.first->vout[pcoin.second].nValue;
+                vwtxPrev.push_back(pcoin.first);
+            }
+        }
         // Calculate coin age reward
         {
             uint64 nCoinAge;
@@ -1126,9 +1138,8 @@ bool CWallet::CreateCoinStake(CScript scriptPubKey, unsigned int nBits, CTransac
                 return error("CreateCoinStake : failed to calculate coin age");
             nCredit += GetProofOfStakeReward(nCoinAge);
         }
-        // Fill vout
-        txNew.vout.push_back(CTxOut(nCredit, scriptPubKey));
-
+        // Set output amount
+        txNew.vout[1].nValue = nCredit;
 
         // Sign
         int nIn = 0;
index 07b2b7c..0e2cead 100644 (file)
@@ -89,7 +89,7 @@ public:
     int64 GetStake() const;
     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 CreateCoinStake(CScript scriptPubKey, unsigned int nBits, CTransaction& txNew);
+    bool CreateCoinStake(unsigned int nBits, CTransaction& txNew);
     bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
     bool BroadcastTransaction(CWalletTx& wtxNew);
     std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);