Changeset View
Changeset View
Standalone View
Standalone View
src/qt/transactiondesc.cpp
// Copyright (c) 2011-2016 The Bitcoin Core developers | // Copyright (c) 2011-2016 The Bitcoin Core developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include "transactiondesc.h" | #include "transactiondesc.h" | ||||
#include "bitcoinunits.h" | #include "bitcoinunits.h" | ||||
#include "guiutil.h" | #include "guiutil.h" | ||||
#include "paymentserver.h" | #include "paymentserver.h" | ||||
#include "transactionrecord.h" | #include "transactionrecord.h" | ||||
#include "chain.h" | #include "chain.h" | ||||
#include "consensus/consensus.h" | #include "consensus/consensus.h" | ||||
#include "dstencode.h" | #include "dstencode.h" | ||||
#include "interface/node.h" | |||||
#include "script/script.h" | #include "script/script.h" | ||||
#include "timedata.h" | #include "timedata.h" | ||||
#include "util.h" | #include "util.h" | ||||
#include "validation.h" | #include "validation.h" | ||||
#include "wallet/db.h" | #include "wallet/db.h" | ||||
#include "wallet/finaltx.h" | #include "wallet/finaltx.h" | ||||
#include "wallet/wallet.h" | #include "wallet/wallet.h" | ||||
#include <cstdint> | #include <cstdint> | ||||
#include <string> | #include <string> | ||||
QString TransactionDesc::FormatTxStatus(const CWalletTx &wtx) { | QString TransactionDesc::FormatTxStatus(const interface::WalletTx &wtx, | ||||
AssertLockHeld(cs_main); | const interface::WalletTxStatus &status, | ||||
if (!CheckFinalTx(*wtx.tx)) { | bool inMempool, int numBlocks, | ||||
int64_t adjustedTime) { | |||||
if (!status.is_final) { | |||||
if (wtx.tx->nLockTime < LOCKTIME_THRESHOLD) { | if (wtx.tx->nLockTime < LOCKTIME_THRESHOLD) { | ||||
return tr("Open for %n more block(s)", "", | return tr("Open for %n more block(s)", "", | ||||
wtx.tx->nLockTime - chainActive.Height()); | wtx.tx->nLockTime - numBlocks); | ||||
} else { | } else { | ||||
return tr("Open until %1") | return tr("Open until %1") | ||||
.arg(GUIUtil::dateTimeStr(wtx.tx->nLockTime)); | .arg(GUIUtil::dateTimeStr(wtx.tx->nLockTime)); | ||||
} | } | ||||
} else { | } else { | ||||
int nDepth = wtx.GetDepthInMainChain(); | int nDepth = status.depth_in_main_chain; | ||||
if (nDepth < 0) { | if (nDepth < 0) { | ||||
return tr("conflicted with a transaction with %1 confirmations") | return tr("conflicted with a transaction with %1 confirmations") | ||||
.arg(-nDepth); | .arg(-nDepth); | ||||
} else if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && | } else if (adjustedTime - status.time_received > 2 * 60 && | ||||
wtx.GetRequestCount() == 0) { | status.request_count == 0) { | ||||
return tr("%1/offline").arg(nDepth); | return tr("%1/offline").arg(nDepth); | ||||
} else if (nDepth == 0) { | } else if (nDepth == 0) { | ||||
return tr("0/unconfirmed, %1") | return tr("0/unconfirmed, %1") | ||||
.arg((wtx.InMempool() ? tr("in memory pool") | .arg((inMempool ? tr("in memory pool") | ||||
: tr("not in memory pool"))) + | : tr("not in memory pool"))) + | ||||
(wtx.isAbandoned() ? ", " + tr("abandoned") : ""); | (status.is_abandoned ? ", " + tr("abandoned") : ""); | ||||
} else if (nDepth < 6) { | } else if (nDepth < 6) { | ||||
return tr("%1/unconfirmed").arg(nDepth); | return tr("%1/unconfirmed").arg(nDepth); | ||||
} else { | } else { | ||||
return tr("%1 confirmations").arg(nDepth); | return tr("%1 confirmations").arg(nDepth); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, | QString TransactionDesc::toHTML(interface::Node &node, | ||||
interface::Wallet &wallet, | |||||
TransactionRecord *rec, int unit) { | TransactionRecord *rec, int unit) { | ||||
int numBlocks; | |||||
int64_t adjustedTime; | |||||
interface::WalletTxStatus status; | |||||
interface::WalletOrderForm orderForm; | |||||
bool inMempool; | |||||
interface::WalletTx wtx = wallet.getWalletTxDetails( | |||||
rec->txid, status, orderForm, inMempool, numBlocks, adjustedTime); | |||||
QString strHTML; | QString strHTML; | ||||
LOCK2(cs_main, wallet->cs_wallet); | |||||
strHTML.reserve(4000); | strHTML.reserve(4000); | ||||
strHTML += "<html><font face='verdana, arial, helvetica, sans-serif'>"; | strHTML += "<html><font face='verdana, arial, helvetica, sans-serif'>"; | ||||
int64_t nTime = wtx.GetTxTime(); | int64_t nTime = wtx.time; | ||||
Amount nCredit = wtx.GetCredit(ISMINE_ALL); | Amount nCredit = wtx.credit; | ||||
Amount nDebit = wtx.GetDebit(ISMINE_ALL); | Amount nDebit = wtx.debit; | ||||
Amount nNet = nCredit - nDebit; | Amount nNet = nCredit - nDebit; | ||||
strHTML += "<b>" + tr("Status") + ":</b> " + FormatTxStatus(wtx); | strHTML += "<b>" + tr("Status") + ":</b> " + | ||||
int nRequests = wtx.GetRequestCount(); | FormatTxStatus(wtx, status, inMempool, numBlocks, adjustedTime); | ||||
int nRequests = status.request_count; | |||||
if (nRequests != -1) { | if (nRequests != -1) { | ||||
if (nRequests == 0) { | if (nRequests == 0) { | ||||
strHTML += tr(", has not been successfully broadcast yet"); | strHTML += tr(", has not been successfully broadcast yet"); | ||||
} else if (nRequests > 0) { | } else if (nRequests > 0) { | ||||
strHTML += tr(", broadcast through %n node(s)", "", nRequests); | strHTML += tr(", broadcast through %n node(s)", "", nRequests); | ||||
} | } | ||||
} | } | ||||
strHTML += "<br>"; | strHTML += "<br>"; | ||||
strHTML += "<b>" + tr("Date") + ":</b> " + | strHTML += "<b>" + tr("Date") + ":</b> " + | ||||
(nTime ? GUIUtil::dateTimeStr(nTime) : "") + "<br>"; | (nTime ? GUIUtil::dateTimeStr(nTime) : "") + "<br>"; | ||||
// | // | ||||
// From | // From | ||||
// | // | ||||
if (wtx.IsCoinBase()) { | if (wtx.is_coinbase) { | ||||
strHTML += "<b>" + tr("Source") + ":</b> " + tr("Generated") + "<br>"; | strHTML += "<b>" + tr("Source") + ":</b> " + tr("Generated") + "<br>"; | ||||
} else if (wtx.mapValue.count("from") && !wtx.mapValue["from"].empty()) { | } else if (wtx.value_map.count("from") && !wtx.value_map["from"].empty()) { | ||||
// Online transaction | // Online transaction | ||||
strHTML += "<b>" + tr("From") + ":</b> " + | strHTML += "<b>" + tr("From") + ":</b> " + | ||||
GUIUtil::HtmlEscape(wtx.mapValue["from"]) + "<br>"; | GUIUtil::HtmlEscape(wtx.value_map["from"]) + "<br>"; | ||||
} else { | } else { | ||||
// Offline transaction | // Offline transaction | ||||
if (nNet > Amount::zero()) { | if (nNet > Amount::zero()) { | ||||
// Credit | // Credit | ||||
CTxDestination address = | CTxDestination address = | ||||
DecodeDestination(rec->address, wallet->chainParams); | DecodeDestination(rec->address, wallet.getChainParams()); | ||||
if (IsValidDestination(address)) { | if (IsValidDestination(address)) { | ||||
if (wallet->mapAddressBook.count(address)) { | std::string name; | ||||
isminetype ismine; | |||||
if (wallet.getAddress(address, &name, &ismine)) { | |||||
strHTML += | strHTML += | ||||
"<b>" + tr("From") + ":</b> " + tr("unknown") + "<br>"; | "<b>" + tr("From") + ":</b> " + tr("unknown") + "<br>"; | ||||
strHTML += "<b>" + tr("To") + ":</b> "; | strHTML += "<b>" + tr("To") + ":</b> "; | ||||
strHTML += GUIUtil::HtmlEscape(rec->address); | strHTML += GUIUtil::HtmlEscape(rec->address); | ||||
QString addressOwned = | QString addressOwned = ismine == ISMINE_SPENDABLE | ||||
(::IsMine(*wallet, address) == ISMINE_SPENDABLE) | |||||
? tr("own address") | ? tr("own address") | ||||
: tr("watch-only"); | : tr("watch-only"); | ||||
if (!wallet->mapAddressBook[address].name.empty()) { | if (!name.empty()) { | ||||
strHTML += " (" + addressOwned + ", " + tr("label") + | strHTML += " (" + addressOwned + ", " + tr("label") + | ||||
": " + | ": " + GUIUtil::HtmlEscape(name) + ")"; | ||||
GUIUtil::HtmlEscape( | |||||
wallet->mapAddressBook[address].name) + | |||||
")"; | |||||
} else { | } else { | ||||
strHTML += " (" + addressOwned + ")"; | strHTML += " (" + addressOwned + ")"; | ||||
} | } | ||||
strHTML += "<br>"; | strHTML += "<br>"; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
// | // | ||||
// To | // To | ||||
// | // | ||||
if (wtx.mapValue.count("to") && !wtx.mapValue["to"].empty()) { | if (wtx.value_map.count("to") && !wtx.value_map["to"].empty()) { | ||||
// Online transaction | // Online transaction | ||||
std::string strAddress = wtx.mapValue["to"]; | std::string strAddress = wtx.value_map["to"]; | ||||
strHTML += "<b>" + tr("To") + ":</b> "; | strHTML += "<b>" + tr("To") + ":</b> "; | ||||
CTxDestination dest = | CTxDestination dest = | ||||
DecodeDestination(strAddress, wallet->chainParams); | DecodeDestination(strAddress, wallet.getChainParams()); | ||||
if (wallet->mapAddressBook.count(dest) && | std::string name; | ||||
!wallet->mapAddressBook[dest].name.empty()) { | if (wallet.getAddress(dest, &name) && !name.empty()) { | ||||
strHTML += | strHTML += GUIUtil::HtmlEscape(name) + " "; | ||||
GUIUtil::HtmlEscape(wallet->mapAddressBook[dest].name) + " "; | |||||
} | } | ||||
strHTML += GUIUtil::HtmlEscape(strAddress) + "<br>"; | strHTML += GUIUtil::HtmlEscape(strAddress) + "<br>"; | ||||
} | } | ||||
// | // | ||||
// Amount | // Amount | ||||
// | // | ||||
if (wtx.IsCoinBase() && nCredit == Amount::zero()) { | if (wtx.is_coinbase && nCredit == Amount::zero()) { | ||||
// | // | ||||
// Coinbase | // Coinbase | ||||
// | // | ||||
Amount nUnmatured = Amount::zero(); | Amount nUnmatured = Amount::zero(); | ||||
for (const CTxOut &txout : wtx.tx->vout) { | for (const CTxOut &txout : wtx.tx->vout) { | ||||
nUnmatured += wallet->GetCredit(txout, ISMINE_ALL); | nUnmatured += wallet.getCredit(txout, ISMINE_ALL); | ||||
} | } | ||||
strHTML += "<b>" + tr("Credit") + ":</b> "; | strHTML += "<b>" + tr("Credit") + ":</b> "; | ||||
if (wtx.IsInMainChain()) { | if (status.is_in_main_chain) { | ||||
strHTML += BitcoinUnits::formatHtmlWithUnit(unit, nUnmatured) + | strHTML += BitcoinUnits::formatHtmlWithUnit(unit, nUnmatured) + | ||||
" (" + | " (" + | ||||
tr("matures in %n more block(s)", "", | tr("matures in %n more block(s)", "", | ||||
wtx.GetBlocksToMaturity()) + | status.blocks_to_maturity) + | ||||
")"; | ")"; | ||||
} else { | } else { | ||||
strHTML += "(" + tr("not accepted") + ")"; | strHTML += "(" + tr("not accepted") + ")"; | ||||
} | } | ||||
strHTML += "<br>"; | strHTML += "<br>"; | ||||
} else if (nNet > Amount::zero()) { | } else if (nNet > Amount::zero()) { | ||||
// | // | ||||
// Credit | // Credit | ||||
// | // | ||||
strHTML += "<b>" + tr("Credit") + ":</b> " + | strHTML += "<b>" + tr("Credit") + ":</b> " + | ||||
BitcoinUnits::formatHtmlWithUnit(unit, nNet) + "<br>"; | BitcoinUnits::formatHtmlWithUnit(unit, nNet) + "<br>"; | ||||
} else { | } else { | ||||
isminetype fAllFromMe = ISMINE_SPENDABLE; | isminetype fAllFromMe = ISMINE_SPENDABLE; | ||||
for (const CTxIn &txin : wtx.tx->vin) { | for (isminetype mine : wtx.txin_is_mine) { | ||||
isminetype mine = wallet->IsMine(txin); | |||||
if (fAllFromMe > mine) { | if (fAllFromMe > mine) { | ||||
fAllFromMe = mine; | fAllFromMe = mine; | ||||
} | } | ||||
} | } | ||||
isminetype fAllToMe = ISMINE_SPENDABLE; | isminetype fAllToMe = ISMINE_SPENDABLE; | ||||
for (const CTxOut &txout : wtx.tx->vout) { | for (isminetype mine : wtx.txout_is_mine) { | ||||
isminetype mine = wallet->IsMine(txout); | |||||
if (fAllToMe > mine) { | if (fAllToMe > mine) { | ||||
fAllToMe = mine; | fAllToMe = mine; | ||||
} | } | ||||
} | } | ||||
if (fAllFromMe) { | if (fAllFromMe) { | ||||
if (fAllFromMe & ISMINE_WATCH_ONLY) { | if (fAllFromMe & ISMINE_WATCH_ONLY) { | ||||
strHTML += | strHTML += | ||||
"<b>" + tr("From") + ":</b> " + tr("watch-only") + "<br>"; | "<b>" + tr("From") + ":</b> " + tr("watch-only") + "<br>"; | ||||
} | } | ||||
// | // | ||||
// Debit | // Debit | ||||
// | // | ||||
auto mine = wtx.txout_is_mine.begin(); | |||||
for (const CTxOut &txout : wtx.tx->vout) { | for (const CTxOut &txout : wtx.tx->vout) { | ||||
// Ignore change | // Ignore change | ||||
isminetype toSelf = wallet->IsMine(txout); | isminetype toSelf = *(mine++); | ||||
if ((toSelf == ISMINE_SPENDABLE) && | if ((toSelf == ISMINE_SPENDABLE) && | ||||
(fAllFromMe == ISMINE_SPENDABLE)) { | (fAllFromMe == ISMINE_SPENDABLE)) { | ||||
continue; | continue; | ||||
} | } | ||||
if (!wtx.mapValue.count("to") || wtx.mapValue["to"].empty()) { | if (!wtx.value_map.count("to") || wtx.value_map["to"].empty()) { | ||||
// Offline transaction | // Offline transaction | ||||
CTxDestination address; | CTxDestination address; | ||||
if (ExtractDestination(txout.scriptPubKey, address)) { | if (ExtractDestination(txout.scriptPubKey, address)) { | ||||
strHTML += "<b>" + tr("To") + ":</b> "; | strHTML += "<b>" + tr("To") + ":</b> "; | ||||
if (wallet->mapAddressBook.count(address) && | std::string name; | ||||
!wallet->mapAddressBook[address].name.empty()) { | if (wallet.getAddress(address, &name) && | ||||
strHTML += | !name.empty()) { | ||||
GUIUtil::HtmlEscape( | strHTML += GUIUtil::HtmlEscape(name) + " "; | ||||
wallet->mapAddressBook[address].name) + | |||||
" "; | |||||
} | } | ||||
strHTML += | strHTML += | ||||
GUIUtil::HtmlEscape(EncodeDestination(address)); | GUIUtil::HtmlEscape(EncodeDestination(address)); | ||||
if (toSelf == ISMINE_SPENDABLE) { | if (toSelf == ISMINE_SPENDABLE) { | ||||
strHTML += " (own address)"; | strHTML += " (own address)"; | ||||
} else if (toSelf & ISMINE_WATCH_ONLY) { | } else if (toSelf & ISMINE_WATCH_ONLY) { | ||||
strHTML += " (watch-only)"; | strHTML += " (watch-only)"; | ||||
} | } | ||||
Show All 10 Lines | if (wtx.is_coinbase && nCredit == Amount::zero()) { | ||||
"<b>" + tr("Credit") + ":</b> " + | "<b>" + tr("Credit") + ":</b> " + | ||||
BitcoinUnits::formatHtmlWithUnit(unit, txout.nValue) + | BitcoinUnits::formatHtmlWithUnit(unit, txout.nValue) + | ||||
"<br>"; | "<br>"; | ||||
} | } | ||||
} | } | ||||
if (fAllToMe) { | if (fAllToMe) { | ||||
// Payment to self | // Payment to self | ||||
Amount nChange = wtx.GetChange(); | Amount nChange = wtx.change; | ||||
Amount nValue = nCredit - nChange; | Amount nValue = nCredit - nChange; | ||||
strHTML += "<b>" + tr("Total debit") + ":</b> " + | strHTML += "<b>" + tr("Total debit") + ":</b> " + | ||||
BitcoinUnits::formatHtmlWithUnit(unit, -1 * nValue) + | BitcoinUnits::formatHtmlWithUnit(unit, -1 * nValue) + | ||||
"<br>"; | "<br>"; | ||||
strHTML += "<b>" + tr("Total credit") + ":</b> " + | strHTML += "<b>" + tr("Total credit") + ":</b> " + | ||||
BitcoinUnits::formatHtmlWithUnit(unit, nValue) + | BitcoinUnits::formatHtmlWithUnit(unit, nValue) + | ||||
"<br>"; | "<br>"; | ||||
} | } | ||||
Amount nTxFee = nDebit - wtx.tx->GetValueOut(); | Amount nTxFee = nDebit - wtx.tx->GetValueOut(); | ||||
if (nTxFee > Amount::zero()) | if (nTxFee > Amount::zero()) | ||||
strHTML += "<b>" + tr("Transaction fee") + ":</b> " + | strHTML += "<b>" + tr("Transaction fee") + ":</b> " + | ||||
BitcoinUnits::formatHtmlWithUnit(unit, -1 * nTxFee) + | BitcoinUnits::formatHtmlWithUnit(unit, -1 * nTxFee) + | ||||
"<br>"; | "<br>"; | ||||
} else { | } else { | ||||
// | // | ||||
// Mixed debit transaction | // Mixed debit transaction | ||||
// | // | ||||
auto mine = wtx.txin_is_mine.begin(); | |||||
for (const CTxIn &txin : wtx.tx->vin) { | for (const CTxIn &txin : wtx.tx->vin) { | ||||
if (wallet->IsMine(txin)) { | if (*(mine++)) { | ||||
strHTML += | strHTML += "<b>" + tr("Debit") + ":</b> " + | ||||
"<b>" + tr("Debit") + ":</b> " + | |||||
BitcoinUnits::formatHtmlWithUnit( | BitcoinUnits::formatHtmlWithUnit( | ||||
unit, -1 * wallet->GetDebit(txin, ISMINE_ALL)) + | unit, -wallet.getDebit(txin, ISMINE_ALL)) + | ||||
"<br>"; | "<br>"; | ||||
} | } | ||||
} | } | ||||
mine = wtx.txout_is_mine.begin(); | |||||
for (const CTxOut &txout : wtx.tx->vout) { | for (const CTxOut &txout : wtx.tx->vout) { | ||||
if (wallet->IsMine(txout)) { | if (*(mine++)) { | ||||
strHTML += "<b>" + tr("Credit") + ":</b> " + | strHTML += "<b>" + tr("Credit") + ":</b> " + | ||||
BitcoinUnits::formatHtmlWithUnit( | BitcoinUnits::formatHtmlWithUnit( | ||||
unit, wallet->GetCredit(txout, ISMINE_ALL)) + | unit, wallet.getCredit(txout, ISMINE_ALL)) + | ||||
"<br>"; | "<br>"; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
strHTML += "<b>" + tr("Net amount") + ":</b> " + | strHTML += "<b>" + tr("Net amount") + ":</b> " + | ||||
BitcoinUnits::formatHtmlWithUnit(unit, nNet, true) + "<br>"; | BitcoinUnits::formatHtmlWithUnit(unit, nNet, true) + "<br>"; | ||||
// | // | ||||
// Message | // Message | ||||
// | // | ||||
if (wtx.mapValue.count("message") && !wtx.mapValue["message"].empty()) { | if (wtx.value_map.count("message") && !wtx.value_map["message"].empty()) { | ||||
strHTML += "<br><b>" + tr("Message") + ":</b><br>" + | strHTML += "<br><b>" + tr("Message") + ":</b><br>" + | ||||
GUIUtil::HtmlEscape(wtx.mapValue["message"], true) + "<br>"; | GUIUtil::HtmlEscape(wtx.value_map["message"], true) + "<br>"; | ||||
} | } | ||||
if (wtx.mapValue.count("comment") && !wtx.mapValue["comment"].empty()) { | if (wtx.value_map.count("comment") && !wtx.value_map["comment"].empty()) { | ||||
strHTML += "<br><b>" + tr("Comment") + ":</b><br>" + | strHTML += "<br><b>" + tr("Comment") + ":</b><br>" + | ||||
GUIUtil::HtmlEscape(wtx.mapValue["comment"], true) + "<br>"; | GUIUtil::HtmlEscape(wtx.value_map["comment"], true) + "<br>"; | ||||
} | } | ||||
strHTML += | strHTML += | ||||
"<b>" + tr("Transaction ID") + ":</b> " + rec->getTxID() + "<br>"; | "<b>" + tr("Transaction ID") + ":</b> " + rec->getTxID() + "<br>"; | ||||
strHTML += "<b>" + tr("Transaction total size") + ":</b> " + | strHTML += "<b>" + tr("Transaction total size") + ":</b> " + | ||||
QString::number(wtx.tx->GetTotalSize()) + " bytes<br>"; | QString::number(wtx.tx->GetTotalSize()) + " bytes<br>"; | ||||
strHTML += "<b>" + tr("Output index") + ":</b> " + | strHTML += "<b>" + tr("Output index") + ":</b> " + | ||||
QString::number(rec->getOutputIndex()) + "<br>"; | QString::number(rec->getOutputIndex()) + "<br>"; | ||||
// Message from normal bitcoincash:URI (bitcoincash:123...?message=example) | // Message from normal bitcoincash:URI (bitcoincash:123...?message=example) | ||||
for (const std::pair<std::string, std::string> &r : wtx.vOrderForm) { | for (const std::pair<std::string, std::string> &r : orderForm) { | ||||
if (r.first == "Message") { | if (r.first == "Message") { | ||||
strHTML += "<br><b>" + tr("Message") + ":</b><br>" + | strHTML += "<br><b>" + tr("Message") + ":</b><br>" + | ||||
GUIUtil::HtmlEscape(r.second, true) + "<br>"; | GUIUtil::HtmlEscape(r.second, true) + "<br>"; | ||||
} | } | ||||
} | } | ||||
// | // | ||||
// PaymentRequest info: | // PaymentRequest info: | ||||
// | // | ||||
for (const std::pair<std::string, std::string> &r : wtx.vOrderForm) { | for (const std::pair<std::string, std::string> &r : orderForm) { | ||||
if (r.first == "PaymentRequest") { | if (r.first == "PaymentRequest") { | ||||
PaymentRequestPlus req; | PaymentRequestPlus req; | ||||
req.parse( | req.parse( | ||||
QByteArray::fromRawData(r.second.data(), r.second.size())); | QByteArray::fromRawData(r.second.data(), r.second.size())); | ||||
QString merchant; | QString merchant; | ||||
if (req.getMerchant(PaymentServer::getCertStore(), merchant)) { | if (req.getMerchant(PaymentServer::getCertStore(), merchant)) { | ||||
strHTML += "<b>" + tr("Merchant") + ":</b> " + | strHTML += "<b>" + tr("Merchant") + ":</b> " + | ||||
GUIUtil::HtmlEscape(merchant) + "<br>"; | GUIUtil::HtmlEscape(merchant) + "<br>"; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if (wtx.IsCoinBase()) { | if (wtx.is_coinbase) { | ||||
quint32 numBlocksToMaturity = COINBASE_MATURITY + 1; | quint32 numBlocksToMaturity = COINBASE_MATURITY + 1; | ||||
strHTML += | strHTML += | ||||
"<br>" + | "<br>" + | ||||
tr("Generated coins must mature %1 blocks before they can be " | tr("Generated coins must mature %1 blocks before they can be " | ||||
"spent. When you generated this block, it was broadcast to the " | "spent. When you generated this block, it was broadcast to the " | ||||
"network to be added to the block chain. If it fails to get " | "network to be added to the block chain. If it fails to get " | ||||
"into the chain, its state will change to \"not accepted\" and " | "into the chain, its state will change to \"not accepted\" and " | ||||
"it won't be spendable. This may occasionally happen if another " | "it won't be spendable. This may occasionally happen if another " | ||||
"node generates a block within a few seconds of yours.") | "node generates a block within a few seconds of yours.") | ||||
.arg(QString::number(numBlocksToMaturity)) + | .arg(QString::number(numBlocksToMaturity)) + | ||||
"<br>"; | "<br>"; | ||||
} | } | ||||
// | // | ||||
// Debug view | // Debug view | ||||
// | // | ||||
if (gArgs.GetBoolArg("-debug", false)) { | if (gArgs.GetBoolArg("-debug", false)) { | ||||
strHTML += "<hr><br>" + tr("Debug information") + "<br><br>"; | strHTML += "<hr><br>" + tr("Debug information") + "<br><br>"; | ||||
for (const CTxIn &txin : wtx.tx->vin) { | for (const CTxIn &txin : wtx.tx->vin) { | ||||
if (wallet->IsMine(txin)) { | if (wallet.txinIsMine(txin)) { | ||||
strHTML += "<b>" + tr("Debit") + ":</b> " + | strHTML += "<b>" + tr("Debit") + ":</b> " + | ||||
BitcoinUnits::formatHtmlWithUnit( | BitcoinUnits::formatHtmlWithUnit( | ||||
unit, -1 * wallet->GetDebit(txin, ISMINE_ALL)) + | unit, -wallet.getDebit(txin, ISMINE_ALL)) + | ||||
"<br>"; | "<br>"; | ||||
} | } | ||||
} | } | ||||
for (const CTxOut &txout : wtx.tx->vout) { | for (const CTxOut &txout : wtx.tx->vout) { | ||||
if (wallet->IsMine(txout)) { | if (wallet.txoutIsMine(txout)) { | ||||
strHTML += "<b>" + tr("Credit") + ":</b> " + | strHTML += "<b>" + tr("Credit") + ":</b> " + | ||||
BitcoinUnits::formatHtmlWithUnit( | BitcoinUnits::formatHtmlWithUnit( | ||||
unit, wallet->GetCredit(txout, ISMINE_ALL)) + | unit, wallet.getCredit(txout, ISMINE_ALL)) + | ||||
"<br>"; | "<br>"; | ||||
} | } | ||||
} | } | ||||
strHTML += "<br><b>" + tr("Transaction") + ":</b><br>"; | strHTML += "<br><b>" + tr("Transaction") + ":</b><br>"; | ||||
strHTML += GUIUtil::HtmlEscape(wtx.tx->ToString(), true); | strHTML += GUIUtil::HtmlEscape(wtx.tx->ToString(), true); | ||||
strHTML += "<br><b>" + tr("Inputs") + ":</b>"; | strHTML += "<br><b>" + tr("Inputs") + ":</b>"; | ||||
strHTML += "<ul>"; | strHTML += "<ul>"; | ||||
for (const CTxIn &txin : wtx.tx->vin) { | for (const CTxIn &txin : wtx.tx->vin) { | ||||
COutPoint prevout = txin.prevout; | COutPoint prevout = txin.prevout; | ||||
Coin prev; | Coin prev; | ||||
if (pcoinsTip->GetCoin(prevout, prev)) { | if (node.getUnspentOutput(prevout, prev)) { | ||||
strHTML += "<li>"; | strHTML += "<li>"; | ||||
const CTxOut &vout = prev.GetTxOut(); | const CTxOut &vout = prev.GetTxOut(); | ||||
CTxDestination address; | CTxDestination address; | ||||
if (ExtractDestination(vout.scriptPubKey, address)) { | if (ExtractDestination(vout.scriptPubKey, address)) { | ||||
if (wallet->mapAddressBook.count(address) && | std::string name; | ||||
!wallet->mapAddressBook[address].name.empty()) { | if (wallet.getAddress(address, &name) && !name.empty()) { | ||||
strHTML += GUIUtil::HtmlEscape( | strHTML += GUIUtil::HtmlEscape(name) + " "; | ||||
wallet->mapAddressBook[address].name) + | |||||
" "; | |||||
} | } | ||||
strHTML += | strHTML += | ||||
QString::fromStdString(EncodeDestination(address)); | QString::fromStdString(EncodeDestination(address)); | ||||
} | } | ||||
strHTML = strHTML + " " + tr("Amount") + "=" + | strHTML = strHTML + " " + tr("Amount") + "=" + | ||||
BitcoinUnits::formatHtmlWithUnit(unit, vout.nValue); | BitcoinUnits::formatHtmlWithUnit(unit, vout.nValue); | ||||
strHTML = | strHTML = strHTML + " IsMine=" + | ||||
strHTML + " IsMine=" + | (wallet.txoutIsMine(vout) & ISMINE_SPENDABLE | ||||
(wallet->IsMine(vout) & ISMINE_SPENDABLE ? tr("true") | ? tr("true") | ||||
: tr("false")) + | : tr("false")) + | ||||
"</li>"; | "</li>"; | ||||
strHTML = | strHTML = strHTML + " IsWatchOnly=" + | ||||
strHTML + " IsWatchOnly=" + | (wallet.txoutIsMine(vout) & ISMINE_WATCH_ONLY | ||||
(wallet->IsMine(vout) & ISMINE_WATCH_ONLY ? tr("true") | ? tr("true") | ||||
: tr("false")) + | : tr("false")) + | ||||
"</li>"; | "</li>"; | ||||
} | } | ||||
} | } | ||||
strHTML += "</ul>"; | strHTML += "</ul>"; | ||||
} | } | ||||
strHTML += "</font></html>"; | strHTML += "</font></html>"; | ||||
return strHTML; | return strHTML; | ||||
} | } |