Bitcoin Core  27.99.0
P2P Digital Currency
transactionrecord.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2022 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 <qt/transactionrecord.h>
6 
7 #include <chain.h>
8 #include <interfaces/wallet.h>
9 #include <key_io.h>
10 #include <wallet/types.h>
11 
12 #include <stdint.h>
13 
14 #include <QDateTime>
15 
16 using wallet::ISMINE_NO;
19 using wallet::isminetype;
20 
21 /* Return positive answer if transaction should be shown in list.
22  */
24 {
25  // There are currently no cases where we hide transactions, but
26  // we may want to use this in the future for things like RBF.
27  return true;
28 }
29 
30 /*
31  * Decompose CWallet transaction to model transaction records.
32  */
34 {
35  QList<TransactionRecord> parts;
36  int64_t nTime = wtx.time;
37  CAmount nCredit = wtx.credit;
38  CAmount nDebit = wtx.debit;
39  CAmount nNet = nCredit - nDebit;
40  uint256 hash = wtx.tx->GetHash();
41  std::map<std::string, std::string> mapValue = wtx.value_map;
42 
43  bool involvesWatchAddress = false;
44  isminetype fAllFromMe = ISMINE_SPENDABLE;
45  bool any_from_me = false;
46  if (wtx.is_coinbase) {
47  fAllFromMe = ISMINE_NO;
48  } else {
49  for (const isminetype mine : wtx.txin_is_mine)
50  {
51  if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true;
52  if(fAllFromMe > mine) fAllFromMe = mine;
53  if (mine) any_from_me = true;
54  }
55  }
56 
57  if (fAllFromMe || !any_from_me) {
58  for (const isminetype mine : wtx.txout_is_mine)
59  {
60  if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true;
61  }
62 
63  CAmount nTxFee = nDebit - wtx.tx->GetValueOut();
64 
65  for(unsigned int i = 0; i < wtx.tx->vout.size(); i++)
66  {
67  const CTxOut& txout = wtx.tx->vout[i];
68 
69  if (fAllFromMe) {
70  // Change is only really possible if we're the sender
71  // Otherwise, someone just sent bitcoins to a change address, which should be shown
72  if (wtx.txout_is_change[i]) {
73  continue;
74  }
75 
76  //
77  // Debit
78  //
79 
80  TransactionRecord sub(hash, nTime);
81  sub.idx = i;
83 
84  if (!std::get_if<CNoDestination>(&wtx.txout_address[i]))
85  {
86  // Sent to Bitcoin Address
89  }
90  else
91  {
92  // Sent to IP, or other non-address transaction like OP_EVAL
94  sub.address = mapValue["to"];
95  }
96 
97  CAmount nValue = txout.nValue;
98  /* Add fee to first output */
99  if (nTxFee > 0)
100  {
101  nValue += nTxFee;
102  nTxFee = 0;
103  }
104  sub.debit = -nValue;
105 
106  parts.append(sub);
107  }
108 
109  isminetype mine = wtx.txout_is_mine[i];
110  if(mine)
111  {
112  //
113  // Credit
114  //
115 
116  TransactionRecord sub(hash, nTime);
117  sub.idx = i; // vout index
118  sub.credit = txout.nValue;
120  if (wtx.txout_address_is_mine[i])
121  {
122  // Received by Bitcoin Address
125  }
126  else
127  {
128  // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction
130  sub.address = mapValue["from"];
131  }
132  if (wtx.is_coinbase)
133  {
134  // Generated
136  }
137 
138  parts.append(sub);
139  }
140  }
141  } else {
142  //
143  // Mixed debit transaction, can't break down payees
144  //
145  parts.append(TransactionRecord(hash, nTime, TransactionRecord::Other, "", nNet, 0));
146  parts.last().involvesWatchAddress = involvesWatchAddress;
147  }
148 
149  return parts;
150 }
151 
152 void TransactionRecord::updateStatus(const interfaces::WalletTxStatus& wtx, const uint256& block_hash, int numBlocks, int64_t block_time)
153 {
154  // Determine transaction status
155 
156  // Sort order, unrecorded transactions sort to the top
157  int typesort;
158  switch (type) {
159  case SendToAddress: case SendToOther:
160  typesort = 2; break;
161  case RecvWithAddress: case RecvFromOther:
162  typesort = 3; break;
163  default:
164  typesort = 9;
165  }
166  status.sortKey = strprintf("%010d-%01d-%010u-%03d-%d",
167  wtx.block_height,
168  wtx.is_coinbase ? 1 : 0,
169  wtx.time_received,
170  idx,
171  typesort);
174  status.m_cur_block_hash = block_hash;
175 
176  // For generated transactions, determine maturity
178  if (wtx.blocks_to_maturity > 0)
179  {
181 
182  if (wtx.is_in_main_chain)
183  {
185  }
186  else
187  {
189  }
190  }
191  else
192  {
194  }
195  }
196  else
197  {
198  if (status.depth < 0)
199  {
201  }
202  else if (status.depth == 0)
203  {
205  if (wtx.is_abandoned)
207  }
209  {
211  }
212  else
213  {
215  }
216  }
217  status.needsUpdate = false;
218 }
219 
220 bool TransactionRecord::statusUpdateNeeded(const uint256& block_hash) const
221 {
222  assert(!block_hash.IsNull());
223  return status.m_cur_block_hash != block_hash || status.needsUpdate;
224 }
225 
227 {
228  return QString::fromStdString(hash.ToString());
229 }
230 
232 {
233  return idx;
234 }
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
An output of a transaction.
Definition: transaction.h:150
CAmount nValue
Definition: transaction.h:152
UI model for a transaction.
int idx
Subtransaction index, for sort key.
static QList< TransactionRecord > decomposeTransaction(const interfaces::WalletTx &wtx)
static const int RecommendedNumConfirmations
Number of confirmation recommended for accepting a transaction.
static bool showTransaction()
Decompose CWallet transaction to model transaction records.
TransactionStatus status
Status: can change with block chain update.
int getOutputIndex() const
Return the output index of the subtransaction
QString getTxHash() const
Return the unique identifier for this transaction (part)
bool statusUpdateNeeded(const uint256 &block_hash) const
Return whether a status update is needed.
void updateStatus(const interfaces::WalletTxStatus &wtx, const uint256 &block_hash, int numBlocks, int64_t block_time)
Update status from core wallet tx.
bool involvesWatchAddress
Whether the transaction was sent/received with a watch-only address.
constexpr bool IsNull() const
Definition: uint256.h:42
std::string ToString() const
Definition: uint256.cpp:55
256-bit opaque blob.
Definition: uint256.h:106
std::string EncodeDestination(const CTxDestination &dest)
Definition: key_io.cpp:287
isminetype
IsMine() return codes, which depend on ScriptPubKeyMan implementation.
Definition: types.h:40
@ ISMINE_NO
Definition: types.h:41
@ ISMINE_SPENDABLE
Definition: types.h:43
@ ISMINE_WATCH_ONLY
Definition: types.h:42
bool countsForBalance
Transaction counts towards available balance.
uint256 m_cur_block_hash
Current block hash (to know whether cached status is still valid)
@ Confirmed
Have 6 or more confirmations (normal tx) or fully mature (mined tx)
@ Unconfirmed
Normal (sent/received) transactions.
@ Immature
Generated (mined) transactions.
@ Confirming
Confirmed, but waiting for the recommended number of confirmations.
@ NotAccepted
Mined but not accepted.
@ Conflicted
Conflicts with other transaction or mempool.
@ Abandoned
Abandoned from the wallet.
std::string sortKey
Sorting key based on status.
std::vector< wallet::isminetype > txin_is_mine
Definition: wallet.h:394
std::vector< CTxDestination > txout_address
Definition: wallet.h:397
std::vector< wallet::isminetype > txout_address_is_mine
Definition: wallet.h:398
CTransactionRef tx
Definition: wallet.h:393
std::vector< bool > txout_is_change
Definition: wallet.h:396
std::map< std::string, std::string > value_map
Definition: wallet.h:403
std::vector< wallet::isminetype > txout_is_mine
Definition: wallet.h:395
Updated transaction status.
Definition: wallet.h:411
unsigned int time_received
Definition: wallet.h:415
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1162
assert(!tx.IsCoinBase())