Experimental: use Solver to find out all solutions for txout.scriptPublicKey
[novacoin.git] / src / qt / transactionrecord.cpp
index 4c30719..ec4ba10 100644 (file)
@@ -3,6 +3,8 @@
 #include "wallet.h"
 #include "base58.h"
 
+extern CWallet* pwalletMain;
+
 /* Return positive answer if transaction should be shown in list.
  */
 bool TransactionRecord::showTransaction(const CWalletTx &wtx)
@@ -24,14 +26,14 @@ bool TransactionRecord::showTransaction(const CWalletTx &wtx)
 QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *wallet, const CWalletTx &wtx)
 {
     QList<TransactionRecord> parts;
-    int64 nTime = wtx.GetTxTime();
-    int64 nCredit = wtx.GetCredit(true);
-    int64 nDebit = wtx.GetDebit();
-    int64 nNet = nCredit - nDebit;
-    uint256 hash = wtx.GetHash();
+    int64_t nTime = wtx.GetTxTime();
+    int64_t nCredit = wtx.GetCredit(MINE_ALL);
+    int64_t nDebit = wtx.GetDebit(MINE_ALL);
+    int64_t nNet = nCredit - nDebit;
+    uint256 hash = wtx.GetHash(), hashPrev = 0;
     std::map<std::string, std::string> mapValue = wtx.mapValue;
 
-    if (nNet > 0 || wtx.IsCoinBase())
+    if (nNet > 0 || wtx.IsCoinBase() || wtx.IsCoinStake())
     {
         //
         // Credit
@@ -41,25 +43,85 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
             if(wallet->IsMine(txout))
             {
                 TransactionRecord sub(hash, nTime);
-                CTxDestination address;
                 sub.idx = parts.size(); // sequence number
                 sub.credit = txout.nValue;
-                if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address))
+
+                if (!fTestNet)
                 {
-                    // Received by Bitcoin Address
-                    sub.type = TransactionRecord::RecvWithAddress;
-                    sub.address = CBitcoinAddress(address).ToString();
+                    CTxDestination address;
+                    if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address))
+                    {
+                        // Received by Bitcoin Address
+                        sub.type = TransactionRecord::RecvWithAddress;
+                        sub.address = CBitcoinAddress(address).ToString();
+                    }
+                    else
+                    {
+                        // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction
+                        sub.type = TransactionRecord::RecvFromOther;
+                        sub.address = mapValue["from"];
+                    }
+                    }
+                    else
+                    {
+                    txnouttype whichType;
+                    std::vector<valtype> vSolutions;
+                    if (Solver(txout.scriptPubKey, whichType, vSolutions))
+                    {
+                        CTxDestination address;
+                        if (whichType == TX_PUBKEY)
+                        {
+                            // Pay-to-Pubkey
+                            address = CPubKey(vSolutions[0]).GetID();
+                            sub.type = TransactionRecord::RecvWithAddress;
+                            sub.address = CBitcoinAddress(address).ToString();
+                        }
+                        else if (whichType == TX_PUBKEYHASH)
+                        {
+                            // Pay-to-PubkeyHash
+                            address = CKeyID(uint160(vSolutions[0]));
+                            sub.type = TransactionRecord::RecvWithAddress;
+                            sub.address = CBitcoinAddress(address).ToString();
+                        }
+                        else if (whichType == TX_SCRIPTHASH)
+                        {
+                            // Pay-to-ScriptHash
+                            address = CScriptID(uint160(vSolutions[0]));
+                            sub.type = TransactionRecord::RecvWithAddress;
+                            sub.address = CBitcoinAddress(address).ToString();
+                        }
+                        else if (whichType == TX_PUBKEY_DROP)
+                        {
+                            // Pay-to-Pubkey-R
+                            sub.type = TransactionRecord::RecvWithAddress;
+
+                            CMalleableKeyView view;
+                            pwalletMain->CheckOwnership(CPubKey(vSolutions[0]), CPubKey(vSolutions[1]), view);
+                            sub.address = view.GetMalleablePubKey().ToString();
+                        }
+                        else
+                        {
+                            // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction
+                            sub.type = TransactionRecord::RecvFromOther;
+                            sub.address = mapValue["from"];
+                        }
+                    }
                 }
-                else
+                if (wtx.IsCoinBase())
                 {
-                    // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction
-                    sub.type = TransactionRecord::RecvFromOther;
-                    sub.address = mapValue["from"];
+                    // Generated (proof-of-work)
+                    sub.type = TransactionRecord::Generated;
                 }
-                if (wtx.IsCoinBase())
+                if (wtx.IsCoinStake())
                 {
-                    // Generated
+                    // Generated (proof-of-stake)
+
+                    if (hashPrev == hash)
+                        continue; // last coinstake output
+
                     sub.type = TransactionRecord::Generated;
+                    sub.credit = nNet > 0 ? nNet : wtx.GetValueOut() - nDebit;
+                    hashPrev = hash;
                 }
 
                 parts.append(sub);
@@ -79,7 +141,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
         if (fAllFromMe && fAllToMe)
         {
             // Payment to self
-            int64 nChange = wtx.GetChange();
+            int64_t nChange = wtx.GetChange();
 
             parts.append(TransactionRecord(hash, nTime, TransactionRecord::SendToSelf, "",
                             -(nDebit - nChange), nCredit - nChange));
@@ -89,7 +151,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
             //
             // Debit
             //
-            int64 nTxFee = nDebit - wtx.GetValueOut();
+            int64_t nTxFee = nDebit - wtx.GetValueOut();
 
             for (unsigned int nOut = 0; nOut < wtx.vout.size(); nOut++)
             {
@@ -118,7 +180,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
                     sub.address = mapValue["to"];
                 }
 
-                int64 nValue = txout.nValue;
+                int64_t nValue = txout.nValue;
                 /* Add fee to first output */
                 if (nTxFee > 0)
                 {
@@ -158,7 +220,7 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx)
         (wtx.IsCoinBase() ? 1 : 0),
         wtx.nTimeReceived,
         idx);
-    status.confirmed = wtx.IsConfirmed();
+    status.confirmed = wtx.IsTrusted();
     status.depth = wtx.GetDepthInMainChain();
     status.cur_num_blocks = nBestHeight;
 
@@ -194,8 +256,7 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx)
     // For generated transactions, determine maturity
     if(type == TransactionRecord::Generated)
     {
-        int64 nCredit = wtx.GetCredit(true);
-        if (nCredit == 0)
+        if (wtx.GetBlocksToMaturity() > 0)
         {
             status.maturity = TransactionStatus::Immature;