Fabcoin Core  0.16.2
P2P Digital Currency
transactiondesc.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2017 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <transactiondesc.h>
6 
7 #include <fabcoinunits.h>
8 #include <guiutil.h>
9 #include <paymentserver.h>
10 #include <transactionrecord.h>
11 
12 #include <base58.h>
13 #include <consensus/consensus.h>
14 #include <validation.h>
15 #include <script/script.h>
16 #include <timedata.h>
17 #include <util.h>
18 #include <wallet/db.h>
19 #include <wallet/wallet.h>
20 
21 #include <stdint.h>
22 #include <string>
23 
25 {
27  if (!CheckFinalTx(wtx))
28  {
29  if (wtx.tx->nLockTime < LOCKTIME_THRESHOLD)
30  return tr("Open for %n more block(s)", "", wtx.tx->nLockTime - chainActive.Height());
31  else
32  return tr("Open until %1").arg(GUIUtil::dateTimeStr(wtx.tx->nLockTime));
33  }
34  else
35  {
36  int nDepth = wtx.GetDepthInMainChain();
37  if (nDepth < 0)
38  return tr("conflicted with a transaction with %1 confirmations").arg(-nDepth);
39  else if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0)
40  return tr("%1/offline").arg(nDepth);
41  else if (nDepth == 0)
42  return tr("0/unconfirmed, %1").arg((wtx.InMempool() ? tr("in memory pool") : tr("not in memory pool"))) + (wtx.isAbandoned() ? ", "+tr("abandoned") : "");
43  else if (nDepth < 6)
44  return tr("%1/unconfirmed").arg(nDepth);
45  else
46  return tr("%1 confirmations").arg(nDepth);
47  }
48 }
49 
50 QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionRecord *rec, int unit)
51 {
52  QString strHTML;
53 
54  LOCK2(cs_main, wallet->cs_wallet);
55  strHTML.reserve(4000);
56  strHTML += "<html><font face='verdana, arial, helvetica, sans-serif'>";
57 
58  int64_t nTime = wtx.GetTxTime();
59  CAmount nCredit = wtx.GetCredit(ISMINE_ALL);
60  CAmount nDebit = wtx.GetDebit(ISMINE_ALL);
61  CAmount nNet = nCredit - nDebit;
62 
63  strHTML += "<b>" + tr("Status") + ":</b> " + FormatTxStatus(wtx);
64  int nRequests = wtx.GetRequestCount();
65  if (nRequests != -1)
66  {
67  if (nRequests == 0)
68  strHTML += tr(", has not been successfully broadcast yet");
69  else if (nRequests > 0)
70  strHTML += tr(", broadcast through %n node(s)", "", nRequests);
71  }
72  strHTML += "<br>";
73 
74  strHTML += "<b>" + tr("Date") + ":</b> " + (nTime ? GUIUtil::dateTimeStr(nTime) : "") + "<br>";
75 
76  //
77  // From
78  //
79  if (wtx.IsCoinBase())
80  {
81  strHTML += "<b>" + tr("Source") + ":</b> " + tr("Generated") + "<br>";
82  }
83  else if (wtx.mapValue.count("from") && !wtx.mapValue["from"].empty())
84  {
85  // Online transaction
86  strHTML += "<b>" + tr("From") + ":</b> " + GUIUtil::HtmlEscape(wtx.mapValue["from"]) + "<br>";
87  }
88  else
89  {
90  // Offline transaction
91  if (nNet > 0)
92  {
93  // Credit
94  if (CFabcoinAddress(rec->address).IsValid())
95  {
97  if (wallet->mapAddressBook.count(address))
98  {
99  strHTML += "<b>" + tr("From") + ":</b> " + tr("unknown") + "<br>";
100  strHTML += "<b>" + tr("To") + ":</b> ";
101  strHTML += GUIUtil::HtmlEscape(rec->address);
102  QString addressOwned = (::IsMine(*wallet, address) == ISMINE_SPENDABLE) ? tr("own address") : tr("watch-only");
103  if (!wallet->mapAddressBook[address].name.empty())
104  strHTML += " (" + addressOwned + ", " + tr("label") + ": " + GUIUtil::HtmlEscape(wallet->mapAddressBook[address].name) + ")";
105  else
106  strHTML += " (" + addressOwned + ")";
107  strHTML += "<br>";
108  }
109  }
110  }
111  }
112 
113  //
114  // To
115  //
116  if (wtx.mapValue.count("to") && !wtx.mapValue["to"].empty())
117  {
118  // Online transaction
119  std::string strAddress = wtx.mapValue["to"];
120  strHTML += "<b>" + tr("To") + ":</b> ";
121  CTxDestination dest = CFabcoinAddress(strAddress).Get();
122  if (wallet->mapAddressBook.count(dest) && !wallet->mapAddressBook[dest].name.empty())
123  strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[dest].name) + " ";
124  strHTML += GUIUtil::HtmlEscape(strAddress) + "<br>";
125  }
126 
127  //
128  // Amount
129  //
130  if (wtx.IsCoinBase() && nCredit == 0)
131  {
132  //
133  // Coinbase
134  //
135  CAmount nUnmatured = 0;
136  for (const CTxOut& txout : wtx.tx->vout)
137  nUnmatured += wallet->GetCredit(txout, ISMINE_ALL);
138  strHTML += "<b>" + tr("Credit") + ":</b> ";
139  if (wtx.IsInMainChain())
140  strHTML += FabcoinUnits::formatHtmlWithUnit(unit, nUnmatured)+ " (" + tr("matures in %n more block(s)", "", wtx.GetBlocksToMaturity()) + ")";
141  else
142  strHTML += "(" + tr("not accepted") + ")";
143  strHTML += "<br>";
144  }
145  else if (nNet > 0)
146  {
147  //
148  // Credit
149  //
150  strHTML += "<b>" + tr("Credit") + ":</b> " + FabcoinUnits::formatHtmlWithUnit(unit, nNet) + "<br>";
151  }
152  else
153  {
154  isminetype fAllFromMe = ISMINE_SPENDABLE;
155  for (const CTxIn& txin : wtx.tx->vin)
156  {
157  isminetype mine = wallet->IsMine(txin);
158  if(fAllFromMe > mine) fAllFromMe = mine;
159  }
160 
161  isminetype fAllToMe = ISMINE_SPENDABLE;
162  for (const CTxOut& txout : wtx.tx->vout)
163  {
164  isminetype mine = wallet->IsMine(txout);
165  if(fAllToMe > mine) fAllToMe = mine;
166  }
167 
168  if (fAllFromMe)
169  {
170  if(fAllFromMe & ISMINE_WATCH_ONLY)
171  strHTML += "<b>" + tr("From") + ":</b> " + tr("watch-only") + "<br>";
172 
173  //
174  // Debit
175  //
176  for (const CTxOut& txout : wtx.tx->vout)
177  {
178  // Ignore change
179  isminetype toSelf = wallet->IsMine(txout);
180  if ((toSelf == ISMINE_SPENDABLE) && (fAllFromMe == ISMINE_SPENDABLE))
181  continue;
182 
183  if (!wtx.mapValue.count("to") || wtx.mapValue["to"].empty())
184  {
185  // Offline transaction
187  if (ExtractDestination(txout.scriptPubKey, address))
188  {
189  strHTML += "<b>" + tr("To") + ":</b> ";
190  if (wallet->mapAddressBook.count(address) && !wallet->mapAddressBook[address].name.empty())
191  strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[address].name) + " ";
192  strHTML += GUIUtil::HtmlEscape(CFabcoinAddress(address).ToString());
193  if(toSelf == ISMINE_SPENDABLE)
194  strHTML += " (own address)";
195  else if(toSelf & ISMINE_WATCH_ONLY)
196  strHTML += " (watch-only)";
197  strHTML += "<br>";
198  }
199  }
200 
201  strHTML += "<b>" + tr("Debit") + ":</b> " + FabcoinUnits::formatHtmlWithUnit(unit, -txout.nValue) + "<br>";
202  if(toSelf)
203  strHTML += "<b>" + tr("Credit") + ":</b> " + FabcoinUnits::formatHtmlWithUnit(unit, txout.nValue) + "<br>";
204  }
205 
206  if (fAllToMe)
207  {
208  // Payment to self
209  CAmount nChange = wtx.GetChange();
210  CAmount nValue = nCredit - nChange;
211  strHTML += "<b>" + tr("Total debit") + ":</b> " + FabcoinUnits::formatHtmlWithUnit(unit, -nValue) + "<br>";
212  strHTML += "<b>" + tr("Total credit") + ":</b> " + FabcoinUnits::formatHtmlWithUnit(unit, nValue) + "<br>";
213  }
214 
215  CAmount nTxFee = nDebit - wtx.tx->GetValueOut();
216  if (nTxFee > 0)
217  strHTML += "<b>" + tr("Transaction fee") + ":</b> " + FabcoinUnits::formatHtmlWithUnit(unit, -nTxFee) + "<br>";
218  }
219  else
220  {
221  //
222  // Mixed debit transaction
223  //
224  for (const CTxIn& txin : wtx.tx->vin)
225  if (wallet->IsMine(txin))
226  strHTML += "<b>" + tr("Debit") + ":</b> " + FabcoinUnits::formatHtmlWithUnit(unit, -wallet->GetDebit(txin, ISMINE_ALL)) + "<br>";
227  for (const CTxOut& txout : wtx.tx->vout)
228  if (wallet->IsMine(txout))
229  strHTML += "<b>" + tr("Credit") + ":</b> " + FabcoinUnits::formatHtmlWithUnit(unit, wallet->GetCredit(txout, ISMINE_ALL)) + "<br>";
230  }
231  }
232 
233  strHTML += "<b>" + tr("Net amount") + ":</b> " + FabcoinUnits::formatHtmlWithUnit(unit, nNet, true) + "<br>";
234 
235  //
236  // Message
237  //
238  if (wtx.mapValue.count("message") && !wtx.mapValue["message"].empty())
239  strHTML += "<br><b>" + tr("Message") + ":</b><br>" + GUIUtil::HtmlEscape(wtx.mapValue["message"], true) + "<br>";
240  if (wtx.mapValue.count("comment") && !wtx.mapValue["comment"].empty())
241  strHTML += "<br><b>" + tr("Comment") + ":</b><br>" + GUIUtil::HtmlEscape(wtx.mapValue["comment"], true) + "<br>";
242 
243  strHTML += "<b>" + tr("Transaction ID") + ":</b> " + rec->getTxID() + "<br>";
244  strHTML += "<b>" + tr("Transaction total size") + ":</b> " + QString::number(wtx.tx->GetTotalSize()) + " bytes<br>";
245  strHTML += "<b>" + tr("Output index") + ":</b> " + QString::number(rec->getOutputIndex()) + "<br>";
246 
247  // Message from normal fabcoin:URI (fabcoin:123...?message=example)
248  for (const std::pair<std::string, std::string>& r : wtx.vOrderForm)
249  if (r.first == "Message")
250  strHTML += "<br><b>" + tr("Message") + ":</b><br>" + GUIUtil::HtmlEscape(r.second, true) + "<br>";
251 
252  //
253  // PaymentRequest info:
254  //
255  for (const std::pair<std::string, std::string>& r : wtx.vOrderForm)
256  {
257  if (r.first == "PaymentRequest")
258  {
259  PaymentRequestPlus req;
260  req.parse(QByteArray::fromRawData(r.second.data(), r.second.size()));
261  QString merchant;
262  if (req.getMerchant(PaymentServer::getCertStore(), merchant))
263  strHTML += "<b>" + tr("Merchant") + ":</b> " + GUIUtil::HtmlEscape(merchant) + "<br>";
264  }
265  }
266 
267  if (wtx.IsCoinBase())
268  {
269  quint32 numBlocksToMaturity = COINBASE_MATURITY + 1;
270  strHTML += "<br>" + tr("Generated coins must mature %1 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.").arg(QString::number(numBlocksToMaturity)) + "<br>";
271  }
272 
273  //
274  // Debug view
275  //
276  if (logCategories != BCLog::NONE)
277  {
278  strHTML += "<hr><br>" + tr("Debug information") + "<br><br>";
279  for (const CTxIn& txin : wtx.tx->vin)
280  if(wallet->IsMine(txin))
281  strHTML += "<b>" + tr("Debit") + ":</b> " + FabcoinUnits::formatHtmlWithUnit(unit, -wallet->GetDebit(txin, ISMINE_ALL)) + "<br>";
282  for (const CTxOut& txout : wtx.tx->vout)
283  if(wallet->IsMine(txout))
284  strHTML += "<b>" + tr("Credit") + ":</b> " + FabcoinUnits::formatHtmlWithUnit(unit, wallet->GetCredit(txout, ISMINE_ALL)) + "<br>";
285 
286  strHTML += "<br><b>" + tr("Transaction") + ":</b><br>";
287  strHTML += GUIUtil::HtmlEscape(wtx.tx->ToString(), true);
288 
289  strHTML += "<br><b>" + tr("Inputs") + ":</b>";
290  strHTML += "<ul>";
291 
292  for (const CTxIn& txin : wtx.tx->vin)
293  {
294  COutPoint prevout = txin.prevout;
295 
296  Coin prev;
297  if(pcoinsTip->GetCoin(prevout, prev))
298  {
299  {
300  strHTML += "<li>";
301  const CTxOut &vout = prev.out;
303  if (ExtractDestination(vout.scriptPubKey, address))
304  {
305  if (wallet->mapAddressBook.count(address) && !wallet->mapAddressBook[address].name.empty())
306  strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[address].name) + " ";
307  strHTML += QString::fromStdString(CFabcoinAddress(address).ToString());
308  }
309  strHTML = strHTML + " " + tr("Amount") + "=" + FabcoinUnits::formatHtmlWithUnit(unit, vout.nValue);
310  strHTML = strHTML + " IsMine=" + (wallet->IsMine(vout) & ISMINE_SPENDABLE ? tr("true") : tr("false")) + "</li>";
311  strHTML = strHTML + " IsWatchOnly=" + (wallet->IsMine(vout) & ISMINE_WATCH_ONLY ? tr("true") : tr("false")) + "</li>";
312  }
313  }
314  }
315 
316  strHTML += "</ul>";
317  }
318 
319  strHTML += "</font></html>";
320  return strHTML;
321 }
CAmount nValue
Definition: transaction.h:134
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:79
int GetDepthInMainChain(const CBlockIndex *&pindexRet) const
Return depth of transaction in blockchain: <0 : conflicts with a transaction this deep in the blockch...
Definition: wallet.cpp:4504
CAmount GetCredit(const CTxOut &txout, const isminefilter &filter) const
Definition: wallet.cpp:1340
CScript scriptPubKey
Definition: transaction.h:135
A UTXO entry.
Definition: coins.h:29
QString getTxID() const
Return the unique identifier for this transaction (part)
std::map< CTxDestination, CAddressBookData > mapAddressBook
Definition: wallet.h:826
CCriticalSection cs_wallet
Definition: wallet.h:748
int getOutputIndex() const
Return the output index of the subtransaction.
bool getMerchant(X509_STORE *certStore, QString &merchant) const
CCriticalSection cs_main
Definition: validation.cpp:77
base58-encoded Fabcoin addresses.
Definition: base58.h:104
CTxOut out
unspent transaction output
Definition: coins.h:33
QString dateTimeStr(const QDateTime &date)
Definition: guiutil.cpp:80
isminetype IsMine(const CKeyStore &keystore, const CScript &scriptPubKey, SigVersion sigversion)
Definition: ismine.cpp:29
bool IsValid() const
Definition: base58.cpp:247
QString HtmlEscape(const QString &str, bool fMultiLine)
Definition: guiutil.cpp:258
int64_t GetTxTime() const
Definition: wallet.cpp:1505
std::atomic< uint32_t > logCategories
CAmount GetCredit(const isminefilter &filter) const
Definition: wallet.cpp:1785
CAmount GetDebit(const isminefilter &filter) const
filter decides which addresses will count towards the debit
Definition: wallet.cpp:1754
mapValue_t mapValue
Key/value map with information about the transaction.
Definition: wallet.h:318
int64_t CAmount
Amount in lius (Can be negative)
Definition: amount.h:15
#define AssertLockHeld(cs)
Definition: sync.h:85
int GetBlocksToMaturity() const
Definition: wallet.cpp:4523
CCoinsViewCache * pcoinsTip
Global variable that points to the active CCoinsView (protected by cs_main)
Definition: validation.cpp:252
#define LOCK2(cs1, cs2)
Definition: sync.h:176
int Height() const
Return the maximal height in the chain.
Definition: chain.h:543
bool IsInMainChain() const
Definition: wallet.h:270
UI model for a transaction.
bool CheckFinalTx(const CTransaction &tx, int flags)
Check if transaction will be final in the next block to be created.
Definition: validation.cpp:271
bool InMempool() const
Definition: wallet.cpp:1914
CTransactionRef tx
Definition: wallet.h:211
isminetype
IsMine() return codes.
Definition: ismine.h:17
An input of a transaction.
Definition: transaction.h:61
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet, txnouttype *typeRet)
Definition: standard.cpp:268
CAmount GetDebit(const CTxIn &txin, const isminefilter &filter) const
Returns amount of debit if the input matches the filter, otherwise returns 0.
Definition: wallet.cpp:1319
An output of a transaction.
Definition: transaction.h:131
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).
Definition: validation.cpp:80
static X509_STORE * getCertStore()
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:18
CTxDestination Get() const
Definition: base58.cpp:260
bool parse(const QByteArray &data)
A transaction with a bunch of additional info that only the owner cares about.
Definition: wallet.h:287
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:60
int GetRequestCount() const
Definition: wallet.cpp:1511
int64_t GetAdjustedTime()
Definition: timedata.cpp:35
bool isAbandoned() const
Definition: wallet.h:275
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances...
Definition: wallet.h:672
static QString formatHtmlWithUnit(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as HTML string (with unit)
isminetype IsMine(const CTxIn &txin) const
Definition: wallet.cpp:1302
static QString FormatTxStatus(const CWalletTx &wtx)
struct evm_uint160be address(struct evm_env *env)
Definition: capi.c:13
unsigned int nTimeReceived
time received by this node
Definition: wallet.h:321
COutPoint prevout
Definition: transaction.h:64
static QString toHTML(CWallet *wallet, CWalletTx &wtx, TransactionRecord *rec, int unit)
void mine(Client &c, int numBlocks)
Definition: TestHelper.cpp:39
CAmount GetChange() const
Definition: wallet.cpp:1905
bool IsCoinBase() const
Definition: wallet.h:279
std::vector< std::pair< std::string, std::string > > vOrderForm
Definition: wallet.h:319