]> Git Repo - VerusCoin.git/blob - src/qt/transactiondesc.cpp
Merge pull request #3103 from gavinandresen/appbundle
[VerusCoin.git] / src / qt / transactiondesc.cpp
1 #include "transactiondesc.h"
2
3 #include "guiutil.h"
4 #include "bitcoinunits.h"
5 #include "main.h"
6 #include "wallet.h"
7 #include "db.h"
8 #include "ui_interface.h"
9 #include "base58.h"
10 #include "paymentserver.h"
11 #include "transactionrecord.h"
12
13 #include <string>
14
15 QString TransactionDesc::FormatTxStatus(const CWalletTx& wtx)
16 {
17     if (!IsFinalTx(wtx))
18     {
19         if (wtx.nLockTime < LOCKTIME_THRESHOLD)
20             return tr("Open for %n more block(s)", "", wtx.nLockTime - chainActive.Height() + 1);
21         else
22             return tr("Open until %1").arg(GUIUtil::dateTimeStr(wtx.nLockTime));
23     }
24     else
25     {
26         int nDepth = wtx.GetDepthInMainChain();
27         if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0)
28             return tr("%1/offline").arg(nDepth);
29         else if (nDepth < 6)
30             return tr("%1/unconfirmed").arg(nDepth);
31         else
32             return tr("%1 confirmations").arg(nDepth);
33     }
34 }
35
36 QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, int vout, int unit)
37 {
38     QString strHTML;
39
40     {
41         LOCK(wallet->cs_wallet);
42         strHTML.reserve(4000);
43         strHTML += "<html><font face='verdana, arial, helvetica, sans-serif'>";
44
45         int64 nTime = wtx.GetTxTime();
46         int64 nCredit = wtx.GetCredit();
47         int64 nDebit = wtx.GetDebit();
48         int64 nNet = nCredit - nDebit;
49
50         strHTML += "<b>" + tr("Status") + ":</b> " + FormatTxStatus(wtx);
51         int nRequests = wtx.GetRequestCount();
52         if (nRequests != -1)
53         {
54             if (nRequests == 0)
55                 strHTML += tr(", has not been successfully broadcast yet");
56             else if (nRequests > 0)
57                 strHTML += tr(", broadcast through %n node(s)", "", nRequests);
58         }
59         strHTML += "<br>";
60
61         strHTML += "<b>" + tr("Date") + ":</b> " + (nTime ? GUIUtil::dateTimeStr(nTime) : "") + "<br>";
62
63         //
64         // From
65         //
66         if (wtx.IsCoinBase())
67         {
68             strHTML += "<b>" + tr("Source") + ":</b> " + tr("Generated") + "<br>";
69         }
70         else if (wtx.mapValue.count("from") && !wtx.mapValue["from"].empty())
71         {
72             // Online transaction
73             strHTML += "<b>" + tr("From") + ":</b> " + GUIUtil::HtmlEscape(wtx.mapValue["from"]) + "<br>";
74         }
75         else
76         {
77             // Offline transaction
78             if (nNet > 0)
79             {
80                 // Credit
81                 BOOST_FOREACH(const CTxOut& txout, wtx.vout)
82                 {
83                     if (wallet->IsMine(txout))
84                     {
85                         CTxDestination address;
86                         if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address))
87                         {
88                             if (wallet->mapAddressBook.count(address))
89                             {
90                                 strHTML += "<b>" + tr("From") + ":</b> " + tr("unknown") + "<br>";
91                                 strHTML += "<b>" + tr("To") + ":</b> ";
92                                 strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString());
93                                 if (!wallet->mapAddressBook[address].name.empty())
94                                     strHTML += " (" + tr("own address") + ", " + tr("label") + ": " + GUIUtil::HtmlEscape(wallet->mapAddressBook[address].name) + ")";
95                                 else
96                                     strHTML += " (" + tr("own address") + ")";
97                                 strHTML += "<br>";
98                             }
99                         }
100                         break;
101                     }
102                 }
103             }
104         }
105
106         //
107         // To
108         //
109         if (wtx.mapValue.count("to") && !wtx.mapValue["to"].empty())
110         {
111             // Online transaction
112             std::string strAddress = wtx.mapValue["to"];
113             strHTML += "<b>" + tr("To") + ":</b> ";
114             CTxDestination dest = CBitcoinAddress(strAddress).Get();
115             if (wallet->mapAddressBook.count(dest) && !wallet->mapAddressBook[dest].name.empty())
116                 strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[dest].name) + " ";
117             strHTML += GUIUtil::HtmlEscape(strAddress) + "<br>";
118         }
119
120         //
121         // Amount
122         //
123         if (wtx.IsCoinBase() && nCredit == 0)
124         {
125             //
126             // Coinbase
127             //
128             int64 nUnmatured = 0;
129             BOOST_FOREACH(const CTxOut& txout, wtx.vout)
130                 nUnmatured += wallet->GetCredit(txout);
131             strHTML += "<b>" + tr("Credit") + ":</b> ";
132             if (wtx.IsInMainChain())
133                 strHTML += BitcoinUnits::formatWithUnit(unit, nUnmatured)+ " (" + tr("matures in %n more block(s)", "", wtx.GetBlocksToMaturity()) + ")";
134             else
135                 strHTML += "(" + tr("not accepted") + ")";
136             strHTML += "<br>";
137         }
138         else if (nNet > 0)
139         {
140             //
141             // Credit
142             //
143             strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, nNet) + "<br>";
144         }
145         else
146         {
147             bool fAllFromMe = true;
148             BOOST_FOREACH(const CTxIn& txin, wtx.vin)
149                 fAllFromMe = fAllFromMe && wallet->IsMine(txin);
150
151             bool fAllToMe = true;
152             BOOST_FOREACH(const CTxOut& txout, wtx.vout)
153                 fAllToMe = fAllToMe && wallet->IsMine(txout);
154
155             if (fAllFromMe)
156             {
157                 //
158                 // Debit
159                 //
160                 BOOST_FOREACH(const CTxOut& txout, wtx.vout)
161                 {
162                     if (wallet->IsMine(txout))
163                         continue;
164
165                     if (!wtx.mapValue.count("to") || wtx.mapValue["to"].empty())
166                     {
167                         // Offline transaction
168                         CTxDestination address;
169                         if (ExtractDestination(txout.scriptPubKey, address))
170                         {
171                             strHTML += "<b>" + tr("To") + ":</b> ";
172                             if (wallet->mapAddressBook.count(address) && !wallet->mapAddressBook[address].name.empty())
173                                 strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[address].name) + " ";
174                             strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString());
175                             strHTML += "<br>";
176                         }
177                     }
178
179                     strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, -txout.nValue) + "<br>";
180                 }
181
182                 if (fAllToMe)
183                 {
184                     // Payment to self
185                     int64 nChange = wtx.GetChange();
186                     int64 nValue = nCredit - nChange;
187                     strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, -nValue) + "<br>";
188                     strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, nValue) + "<br>";
189                 }
190
191                 int64 nTxFee = nDebit - GetValueOut(wtx);
192                 if (nTxFee > 0)
193                     strHTML += "<b>" + tr("Transaction fee") + ":</b> " + BitcoinUnits::formatWithUnit(unit, -nTxFee) + "<br>";
194             }
195             else
196             {
197                 //
198                 // Mixed debit transaction
199                 //
200                 BOOST_FOREACH(const CTxIn& txin, wtx.vin)
201                     if (wallet->IsMine(txin))
202                         strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, -wallet->GetDebit(txin)) + "<br>";
203                 BOOST_FOREACH(const CTxOut& txout, wtx.vout)
204                     if (wallet->IsMine(txout))
205                         strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, wallet->GetCredit(txout)) + "<br>";
206             }
207         }
208
209         strHTML += "<b>" + tr("Net amount") + ":</b> " + BitcoinUnits::formatWithUnit(unit, nNet, true) + "<br>";
210
211         //
212         // Message
213         //
214         if (wtx.mapValue.count("message") && !wtx.mapValue["message"].empty())
215             strHTML += "<br><b>" + tr("Message") + ":</b><br>" + GUIUtil::HtmlEscape(wtx.mapValue["message"], true) + "<br>";
216         if (wtx.mapValue.count("comment") && !wtx.mapValue["comment"].empty())
217             strHTML += "<br><b>" + tr("Comment") + ":</b><br>" + GUIUtil::HtmlEscape(wtx.mapValue["comment"], true) + "<br>";
218
219         strHTML += "<b>" + tr("Transaction ID") + ":</b> " + TransactionRecord::formatSubTxId(wtx.GetHash(), vout) + "<br>";
220
221         //
222         // PaymentRequest info:
223         //
224         foreach (const PAIRTYPE(string, string)& r, wtx.vOrderForm)
225         {
226             if (r.first == "PaymentRequest")
227             {
228                 PaymentRequestPlus req;
229                 req.parse(QByteArray::fromRawData(r.second.data(), r.second.size()));
230                 QString merchant;
231                 if (req.getMerchant(PaymentServer::getCertStore(), merchant))
232                     strHTML += "<b>" + tr("Merchant") + ":</b> " + GUIUtil::HtmlEscape(merchant) + "<br>";
233             }
234         }
235
236         if (wtx.IsCoinBase())
237             strHTML += "<br>" + tr("Generated coins must mature 120 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to \"not accepted\" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.") + "<br>";
238
239         //
240         // Debug view
241         //
242         if (fDebug)
243         {
244             strHTML += "<hr><br>" + tr("Debug information") + "<br><br>";
245             BOOST_FOREACH(const CTxIn& txin, wtx.vin)
246                 if(wallet->IsMine(txin))
247                     strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, -wallet->GetDebit(txin)) + "<br>";
248             BOOST_FOREACH(const CTxOut& txout, wtx.vout)
249                 if(wallet->IsMine(txout))
250                     strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatWithUnit(unit, wallet->GetCredit(txout)) + "<br>";
251
252             strHTML += "<br><b>" + tr("Transaction") + ":</b><br>";
253             strHTML += GUIUtil::HtmlEscape(wtx.ToString(), true);
254
255             strHTML += "<br><b>" + tr("Inputs") + ":</b>";
256             strHTML += "<ul>";
257
258             {
259                 LOCK(wallet->cs_wallet);
260                 BOOST_FOREACH(const CTxIn& txin, wtx.vin)
261                 {
262                     COutPoint prevout = txin.prevout;
263
264                     CCoins prev;
265                     if(pcoinsTip->GetCoins(prevout.hash, prev))
266                     {
267                         if (prevout.n < prev.vout.size())
268                         {
269                             strHTML += "<li>";
270                             const CTxOut &vout = prev.vout[prevout.n];
271                             CTxDestination address;
272                             if (ExtractDestination(vout.scriptPubKey, address))
273                             {
274                                 if (wallet->mapAddressBook.count(address) && !wallet->mapAddressBook[address].name.empty())
275                                     strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[address].name) + " ";
276                                 strHTML += QString::fromStdString(CBitcoinAddress(address).ToString());
277                             }
278                             strHTML = strHTML + " " + tr("Amount") + "=" + BitcoinUnits::formatWithUnit(unit, vout.nValue);
279                             strHTML = strHTML + " IsMine=" + (wallet->IsMine(vout) ? tr("true") : tr("false")) + "</li>";
280                         }
281                     }
282                 }
283             }
284
285             strHTML += "</ul>";
286         }
287
288         strHTML += "</font></html>";
289     }
290     return strHTML;
291 }
This page took 0.039734 seconds and 4 git commands to generate.