Bitcoin Core  22.99.0
P2P Digital Currency
coins.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2021 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 <core_io.h>
6 #include <key_io.h>
7 #include <rpc/util.h>
8 #include <util/moneystr.h>
9 #include <wallet/coincontrol.h>
10 #include <wallet/receive.h>
11 #include <wallet/rpc/util.h>
12 #include <wallet/spend.h>
13 #include <wallet/wallet.h>
14 
15 #include <univalue.h>
16 
17 
18 namespace wallet {
19 static CAmount GetReceived(const CWallet& wallet, const UniValue& params, bool by_label) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
20 {
21  std::set<CTxDestination> address_set;
22 
23  if (by_label) {
24  // Get the set of addresses assigned to label
25  std::string label = LabelFromValue(params[0]);
26  address_set = wallet.GetLabelAddresses(label);
27  } else {
28  // Get the address
29  CTxDestination dest = DecodeDestination(params[0].get_str());
30  if (!IsValidDestination(dest)) {
31  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
32  }
33  CScript script_pub_key = GetScriptForDestination(dest);
34  if (!wallet.IsMine(script_pub_key)) {
35  throw JSONRPCError(RPC_WALLET_ERROR, "Address not found in wallet");
36  }
37  address_set.insert(dest);
38  }
39 
40  // Minimum confirmations
41  int min_depth = 1;
42  if (!params[1].isNull())
43  min_depth = params[1].get_int();
44 
45  const bool include_immature_coinbase{params[2].isNull() ? false : params[2].get_bool()};
46 
47  // Excluding coinbase outputs is deprecated
48  // It can be enabled by setting deprecatedrpc=exclude_coinbase
49  const bool include_coinbase{!wallet.chain().rpcEnableDeprecated("exclude_coinbase")};
50 
51  if (include_immature_coinbase && !include_coinbase) {
52  throw JSONRPCError(RPC_INVALID_PARAMETER, "include_immature_coinbase is incompatible with deprecated exclude_coinbase");
53  }
54 
55  // Tally
56  CAmount amount = 0;
57  for (const std::pair<const uint256, CWalletTx>& wtx_pair : wallet.mapWallet) {
58  const CWalletTx& wtx = wtx_pair.second;
59  int depth{wallet.GetTxDepthInMainChain(wtx)};
60  if (depth < min_depth
61  // Coinbase with less than 1 confirmation is no longer in the main chain
62  || (wtx.IsCoinBase() && (depth < 1 || !include_coinbase))
63  || (wallet.IsTxImmatureCoinBase(wtx) && !include_immature_coinbase)
64  || !wallet.chain().checkFinalTx(*wtx.tx)) {
65  continue;
66  }
67 
68  for (const CTxOut& txout : wtx.tx->vout) {
69  CTxDestination address;
70  if (ExtractDestination(txout.scriptPubKey, address) && wallet.IsMine(address) && address_set.count(address)) {
71  amount += txout.nValue;
72  }
73  }
74  }
75 
76  return amount;
77 }
78 
79 
81 {
82  return RPCHelpMan{"getreceivedbyaddress",
83  "\nReturns the total amount received by the given address in transactions with at least minconf confirmations.\n",
84  {
85  {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address for transactions."},
86  {"minconf", RPCArg::Type::NUM, RPCArg::Default{1}, "Only include transactions confirmed at least this many times."},
87  {"include_immature_coinbase", RPCArg::Type::BOOL, RPCArg::Default{false}, "Include immature coinbase transactions."},
88  },
89  RPCResult{
90  RPCResult::Type::STR_AMOUNT, "amount", "The total amount in " + CURRENCY_UNIT + " received at this address."
91  },
93  "\nThe amount from transactions with at least 1 confirmation\n"
94  + HelpExampleCli("getreceivedbyaddress", "\"" + EXAMPLE_ADDRESS[0] + "\"") +
95  "\nThe amount including unconfirmed transactions, zero confirmations\n"
96  + HelpExampleCli("getreceivedbyaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 0") +
97  "\nThe amount with at least 6 confirmations\n"
98  + HelpExampleCli("getreceivedbyaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 6") +
99  "\nThe amount with at least 6 confirmations including immature coinbase outputs\n"
100  + HelpExampleCli("getreceivedbyaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 6 true") +
101  "\nAs a JSON-RPC call\n"
102  + HelpExampleRpc("getreceivedbyaddress", "\"" + EXAMPLE_ADDRESS[0] + "\", 6")
103  },
104  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
105 {
106  const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
107  if (!pwallet) return NullUniValue;
108 
109  // Make sure the results are valid at least up to the most recent block
110  // the user could have gotten from another RPC command prior to now
111  pwallet->BlockUntilSyncedToCurrentChain();
112 
113  LOCK(pwallet->cs_wallet);
114 
115  return ValueFromAmount(GetReceived(*pwallet, request.params, /* by_label */ false));
116 },
117  };
118 }
119 
120 
122 {
123  return RPCHelpMan{"getreceivedbylabel",
124  "\nReturns the total amount received by addresses with <label> in transactions with at least [minconf] confirmations.\n",
125  {
126  {"label", RPCArg::Type::STR, RPCArg::Optional::NO, "The selected label, may be the default label using \"\"."},
127  {"minconf", RPCArg::Type::NUM, RPCArg::Default{1}, "Only include transactions confirmed at least this many times."},
128  {"include_immature_coinbase", RPCArg::Type::BOOL, RPCArg::Default{false}, "Include immature coinbase transactions."},
129  },
130  RPCResult{
131  RPCResult::Type::STR_AMOUNT, "amount", "The total amount in " + CURRENCY_UNIT + " received for this label."
132  },
133  RPCExamples{
134  "\nAmount received by the default label with at least 1 confirmation\n"
135  + HelpExampleCli("getreceivedbylabel", "\"\"") +
136  "\nAmount received at the tabby label including unconfirmed amounts with zero confirmations\n"
137  + HelpExampleCli("getreceivedbylabel", "\"tabby\" 0") +
138  "\nThe amount with at least 6 confirmations\n"
139  + HelpExampleCli("getreceivedbylabel", "\"tabby\" 6") +
140  "\nThe amount with at least 6 confirmations including immature coinbase outputs\n"
141  + HelpExampleCli("getreceivedbylabel", "\"tabby\" 6 true") +
142  "\nAs a JSON-RPC call\n"
143  + HelpExampleRpc("getreceivedbylabel", "\"tabby\", 6, true")
144  },
145  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
146 {
147  const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
148  if (!pwallet) return NullUniValue;
149 
150  // Make sure the results are valid at least up to the most recent block
151  // the user could have gotten from another RPC command prior to now
152  pwallet->BlockUntilSyncedToCurrentChain();
153 
154  LOCK(pwallet->cs_wallet);
155 
156  return ValueFromAmount(GetReceived(*pwallet, request.params, /* by_label */ true));
157 },
158  };
159 }
160 
161 
163 {
164  return RPCHelpMan{"getbalance",
165  "\nReturns the total available balance.\n"
166  "The available balance is what the wallet considers currently spendable, and is\n"
167  "thus affected by options which limit spendability such as -spendzeroconfchange.\n",
168  {
169  {"dummy", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "Remains for backward compatibility. Must be excluded or set to \"*\"."},
170  {"minconf", RPCArg::Type::NUM, RPCArg::Default{0}, "Only include transactions confirmed at least this many times."},
171  {"include_watchonly", RPCArg::Type::BOOL, RPCArg::DefaultHint{"true for watch-only wallets, otherwise false"}, "Also include balance in watch-only addresses (see 'importaddress')"},
172  {"avoid_reuse", RPCArg::Type::BOOL, RPCArg::Default{true}, "(only available if avoid_reuse wallet flag is set) Do not include balance in dirty outputs; addresses are considered dirty if they have previously been used in a transaction."},
173  },
174  RPCResult{
175  RPCResult::Type::STR_AMOUNT, "amount", "The total amount in " + CURRENCY_UNIT + " received for this wallet."
176  },
177  RPCExamples{
178  "\nThe total amount in the wallet with 0 or more confirmations\n"
179  + HelpExampleCli("getbalance", "") +
180  "\nThe total amount in the wallet with at least 6 confirmations\n"
181  + HelpExampleCli("getbalance", "\"*\" 6") +
182  "\nAs a JSON-RPC call\n"
183  + HelpExampleRpc("getbalance", "\"*\", 6")
184  },
185  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
186 {
187  const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
188  if (!pwallet) return NullUniValue;
189 
190  // Make sure the results are valid at least up to the most recent block
191  // the user could have gotten from another RPC command prior to now
192  pwallet->BlockUntilSyncedToCurrentChain();
193 
194  LOCK(pwallet->cs_wallet);
195 
196  const UniValue& dummy_value = request.params[0];
197  if (!dummy_value.isNull() && dummy_value.get_str() != "*") {
198  throw JSONRPCError(RPC_METHOD_DEPRECATED, "dummy first argument must be excluded or set to \"*\".");
199  }
200 
201  int min_depth = 0;
202  if (!request.params[1].isNull()) {
203  min_depth = request.params[1].get_int();
204  }
205 
206  bool include_watchonly = ParseIncludeWatchonly(request.params[2], *pwallet);
207 
208  bool avoid_reuse = GetAvoidReuseFlag(*pwallet, request.params[3]);
209 
210  const auto bal = GetBalance(*pwallet, min_depth, avoid_reuse);
211 
212  return ValueFromAmount(bal.m_mine_trusted + (include_watchonly ? bal.m_watchonly_trusted : 0));
213 },
214  };
215 }
216 
218 {
219  return RPCHelpMan{"getunconfirmedbalance",
220  "DEPRECATED\nIdentical to getbalances().mine.untrusted_pending\n",
221  {},
222  RPCResult{RPCResult::Type::NUM, "", "The balance"},
223  RPCExamples{""},
224  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
225 {
226  const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
227  if (!pwallet) return NullUniValue;
228 
229  // Make sure the results are valid at least up to the most recent block
230  // the user could have gotten from another RPC command prior to now
231  pwallet->BlockUntilSyncedToCurrentChain();
232 
233  LOCK(pwallet->cs_wallet);
234 
236 },
237  };
238 }
239 
241 {
242  return RPCHelpMan{"lockunspent",
243  "\nUpdates list of temporarily unspendable outputs.\n"
244  "Temporarily lock (unlock=false) or unlock (unlock=true) specified transaction outputs.\n"
245  "If no transaction outputs are specified when unlocking then all current locked transaction outputs are unlocked.\n"
246  "A locked transaction output will not be chosen by automatic coin selection, when spending bitcoins.\n"
247  "Manually selected coins are automatically unlocked.\n"
248  "Locks are stored in memory only, unless persistent=true, in which case they will be written to the\n"
249  "wallet database and loaded on node start. Unwritten (persistent=false) locks are always cleared\n"
250  "(by virtue of process exit) when a node stops or fails. Unlocking will clear both persistent and not.\n"
251  "Also see the listunspent call\n",
252  {
253  {"unlock", RPCArg::Type::BOOL, RPCArg::Optional::NO, "Whether to unlock (true) or lock (false) the specified transactions"},
254  {"transactions", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "The transaction outputs and within each, the txid (string) vout (numeric).",
255  {
257  {
258  {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
259  {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"},
260  },
261  },
262  },
263  },
264  {"persistent", RPCArg::Type::BOOL, RPCArg::Default{false}, "Whether to write/erase this lock in the wallet database, or keep the change in memory only. Ignored for unlocking."},
265  },
266  RPCResult{
267  RPCResult::Type::BOOL, "", "Whether the command was successful or not"
268  },
269  RPCExamples{
270  "\nList the unspent transactions\n"
271  + HelpExampleCli("listunspent", "") +
272  "\nLock an unspent transaction\n"
273  + HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
274  "\nList the locked transactions\n"
275  + HelpExampleCli("listlockunspent", "") +
276  "\nUnlock the transaction again\n"
277  + HelpExampleCli("lockunspent", "true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
278  "\nLock the transaction persistently in the wallet database\n"
279  + HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\" true") +
280  "\nAs a JSON-RPC call\n"
281  + HelpExampleRpc("lockunspent", "false, \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"")
282  },
283  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
284 {
285  std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
286  if (!pwallet) return NullUniValue;
287 
288  // Make sure the results are valid at least up to the most recent block
289  // the user could have gotten from another RPC command prior to now
290  pwallet->BlockUntilSyncedToCurrentChain();
291 
292  LOCK(pwallet->cs_wallet);
293 
294  RPCTypeCheckArgument(request.params[0], UniValue::VBOOL);
295 
296  bool fUnlock = request.params[0].get_bool();
297 
298  const bool persistent{request.params[2].isNull() ? false : request.params[2].get_bool()};
299 
300  if (request.params[1].isNull()) {
301  if (fUnlock) {
302  if (!pwallet->UnlockAllCoins())
303  throw JSONRPCError(RPC_WALLET_ERROR, "Unlocking coins failed");
304  }
305  return true;
306  }
307 
308  RPCTypeCheckArgument(request.params[1], UniValue::VARR);
309 
310  const UniValue& output_params = request.params[1];
311 
312  // Create and validate the COutPoints first.
313 
314  std::vector<COutPoint> outputs;
315  outputs.reserve(output_params.size());
316 
317  for (unsigned int idx = 0; idx < output_params.size(); idx++) {
318  const UniValue& o = output_params[idx].get_obj();
319 
320  RPCTypeCheckObj(o,
321  {
322  {"txid", UniValueType(UniValue::VSTR)},
323  {"vout", UniValueType(UniValue::VNUM)},
324  });
325 
326  const uint256 txid(ParseHashO(o, "txid"));
327  const int nOutput = find_value(o, "vout").get_int();
328  if (nOutput < 0) {
329  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout cannot be negative");
330  }
331 
332  const COutPoint outpt(txid, nOutput);
333 
334  const auto it = pwallet->mapWallet.find(outpt.hash);
335  if (it == pwallet->mapWallet.end()) {
336  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, unknown transaction");
337  }
338 
339  const CWalletTx& trans = it->second;
340 
341  if (outpt.n >= trans.tx->vout.size()) {
342  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout index out of bounds");
343  }
344 
345  if (pwallet->IsSpent(outpt.hash, outpt.n)) {
346  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected unspent output");
347  }
348 
349  const bool is_locked = pwallet->IsLockedCoin(outpt.hash, outpt.n);
350 
351  if (fUnlock && !is_locked) {
352  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected locked output");
353  }
354 
355  if (!fUnlock && is_locked && !persistent) {
356  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, output already locked");
357  }
358 
359  outputs.push_back(outpt);
360  }
361 
362  std::unique_ptr<WalletBatch> batch = nullptr;
363  // Unlock is always persistent
364  if (fUnlock || persistent) batch = std::make_unique<WalletBatch>(pwallet->GetDatabase());
365 
366  // Atomically set (un)locked status for the outputs.
367  for (const COutPoint& outpt : outputs) {
368  if (fUnlock) {
369  if (!pwallet->UnlockCoin(outpt, batch.get())) throw JSONRPCError(RPC_WALLET_ERROR, "Unlocking coin failed");
370  } else {
371  if (!pwallet->LockCoin(outpt, batch.get())) throw JSONRPCError(RPC_WALLET_ERROR, "Locking coin failed");
372  }
373  }
374 
375  return true;
376 },
377  };
378 }
379 
381 {
382  return RPCHelpMan{"listlockunspent",
383  "\nReturns list of temporarily unspendable outputs.\n"
384  "See the lockunspent call to lock and unlock transactions for spending.\n",
385  {},
386  RPCResult{
387  RPCResult::Type::ARR, "", "",
388  {
389  {RPCResult::Type::OBJ, "", "",
390  {
391  {RPCResult::Type::STR_HEX, "txid", "The transaction id locked"},
392  {RPCResult::Type::NUM, "vout", "The vout value"},
393  }},
394  }
395  },
396  RPCExamples{
397  "\nList the unspent transactions\n"
398  + HelpExampleCli("listunspent", "") +
399  "\nLock an unspent transaction\n"
400  + HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
401  "\nList the locked transactions\n"
402  + HelpExampleCli("listlockunspent", "") +
403  "\nUnlock the transaction again\n"
404  + HelpExampleCli("lockunspent", "true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
405  "\nAs a JSON-RPC call\n"
406  + HelpExampleRpc("listlockunspent", "")
407  },
408  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
409 {
410  const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
411  if (!pwallet) return NullUniValue;
412 
413  LOCK(pwallet->cs_wallet);
414 
415  std::vector<COutPoint> vOutpts;
416  pwallet->ListLockedCoins(vOutpts);
417 
419 
420  for (const COutPoint& outpt : vOutpts) {
422 
423  o.pushKV("txid", outpt.hash.GetHex());
424  o.pushKV("vout", (int)outpt.n);
425  ret.push_back(o);
426  }
427 
428  return ret;
429 },
430  };
431 }
432 
434 {
435  return RPCHelpMan{
436  "getbalances",
437  "Returns an object with all balances in " + CURRENCY_UNIT + ".\n",
438  {},
439  RPCResult{
440  RPCResult::Type::OBJ, "", "",
441  {
442  {RPCResult::Type::OBJ, "mine", "balances from outputs that the wallet can sign",
443  {
444  {RPCResult::Type::STR_AMOUNT, "trusted", "trusted balance (outputs created by the wallet or confirmed outputs)"},
445  {RPCResult::Type::STR_AMOUNT, "untrusted_pending", "untrusted pending balance (outputs created by others that are in the mempool)"},
446  {RPCResult::Type::STR_AMOUNT, "immature", "balance from immature coinbase outputs"},
447  {RPCResult::Type::STR_AMOUNT, "used", /*optional=*/true, "(only present if avoid_reuse is set) balance from coins sent to addresses that were previously spent from (potentially privacy violating)"},
448  }},
449  {RPCResult::Type::OBJ, "watchonly", /*optional=*/true, "watchonly balances (not present if wallet does not watch anything)",
450  {
451  {RPCResult::Type::STR_AMOUNT, "trusted", "trusted balance (outputs created by the wallet or confirmed outputs)"},
452  {RPCResult::Type::STR_AMOUNT, "untrusted_pending", "untrusted pending balance (outputs created by others that are in the mempool)"},
453  {RPCResult::Type::STR_AMOUNT, "immature", "balance from immature coinbase outputs"},
454  }},
455  }
456  },
457  RPCExamples{
458  HelpExampleCli("getbalances", "") +
459  HelpExampleRpc("getbalances", "")},
460  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
461 {
462  const std::shared_ptr<const CWallet> rpc_wallet = GetWalletForJSONRPCRequest(request);
463  if (!rpc_wallet) return NullUniValue;
464  const CWallet& wallet = *rpc_wallet;
465 
466  // Make sure the results are valid at least up to the most recent block
467  // the user could have gotten from another RPC command prior to now
468  wallet.BlockUntilSyncedToCurrentChain();
469 
470  LOCK(wallet.cs_wallet);
471 
472  const auto bal = GetBalance(wallet);
473  UniValue balances{UniValue::VOBJ};
474  {
475  UniValue balances_mine{UniValue::VOBJ};
476  balances_mine.pushKV("trusted", ValueFromAmount(bal.m_mine_trusted));
477  balances_mine.pushKV("untrusted_pending", ValueFromAmount(bal.m_mine_untrusted_pending));
478  balances_mine.pushKV("immature", ValueFromAmount(bal.m_mine_immature));
479  if (wallet.IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE)) {
480  // If the AVOID_REUSE flag is set, bal has been set to just the un-reused address balance. Get
481  // the total balance, and then subtract bal to get the reused address balance.
482  const auto full_bal = GetBalance(wallet, 0, false);
483  balances_mine.pushKV("used", ValueFromAmount(full_bal.m_mine_trusted + full_bal.m_mine_untrusted_pending - bal.m_mine_trusted - bal.m_mine_untrusted_pending));
484  }
485  balances.pushKV("mine", balances_mine);
486  }
487  auto spk_man = wallet.GetLegacyScriptPubKeyMan();
488  if (spk_man && spk_man->HaveWatchOnly()) {
489  UniValue balances_watchonly{UniValue::VOBJ};
490  balances_watchonly.pushKV("trusted", ValueFromAmount(bal.m_watchonly_trusted));
491  balances_watchonly.pushKV("untrusted_pending", ValueFromAmount(bal.m_watchonly_untrusted_pending));
492  balances_watchonly.pushKV("immature", ValueFromAmount(bal.m_watchonly_immature));
493  balances.pushKV("watchonly", balances_watchonly);
494  }
495  return balances;
496 },
497  };
498 }
499 
501 {
502  return RPCHelpMan{
503  "listunspent",
504  "\nReturns array of unspent transaction outputs\n"
505  "with between minconf and maxconf (inclusive) confirmations.\n"
506  "Optionally filter to only include txouts paid to specified addresses.\n",
507  {
508  {"minconf", RPCArg::Type::NUM, RPCArg::Default{1}, "The minimum confirmations to filter"},
509  {"maxconf", RPCArg::Type::NUM, RPCArg::Default{9999999}, "The maximum confirmations to filter"},
510  {"addresses", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "The bitcoin addresses to filter",
511  {
512  {"address", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "bitcoin address"},
513  },
514  },
515  {"include_unsafe", RPCArg::Type::BOOL, RPCArg::Default{true}, "Include outputs that are not safe to spend\n"
516  "See description of \"safe\" attribute below."},
517  {"query_options", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED_NAMED_ARG, "JSON with query options",
518  {
519  {"minimumAmount", RPCArg::Type::AMOUNT, RPCArg::Default{FormatMoney(0)}, "Minimum value of each UTXO in " + CURRENCY_UNIT + ""},
520  {"maximumAmount", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"unlimited"}, "Maximum value of each UTXO in " + CURRENCY_UNIT + ""},
521  {"maximumCount", RPCArg::Type::NUM, RPCArg::DefaultHint{"unlimited"}, "Maximum number of UTXOs"},
522  {"minimumSumAmount", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"unlimited"}, "Minimum sum value of all UTXOs in " + CURRENCY_UNIT + ""},
523  },
524  "query_options"},
525  },
526  RPCResult{
527  RPCResult::Type::ARR, "", "",
528  {
529  {RPCResult::Type::OBJ, "", "",
530  {
531  {RPCResult::Type::STR_HEX, "txid", "the transaction id"},
532  {RPCResult::Type::NUM, "vout", "the vout value"},
533  {RPCResult::Type::STR, "address", /*optional=*/true, "the bitcoin address"},
534  {RPCResult::Type::STR, "label", /*optional=*/true, "The associated label, or \"\" for the default label"},
535  {RPCResult::Type::STR, "scriptPubKey", "the script key"},
536  {RPCResult::Type::STR_AMOUNT, "amount", "the transaction output amount in " + CURRENCY_UNIT},
537  {RPCResult::Type::NUM, "confirmations", "The number of confirmations"},
538  {RPCResult::Type::NUM, "ancestorcount", /*optional=*/true, "The number of in-mempool ancestor transactions, including this one (if transaction is in the mempool)"},
539  {RPCResult::Type::NUM, "ancestorsize", /*optional=*/true, "The virtual transaction size of in-mempool ancestors, including this one (if transaction is in the mempool)"},
540  {RPCResult::Type::STR_AMOUNT, "ancestorfees", /*optional=*/true, "The total fees of in-mempool ancestors (including this one) with fee deltas used for mining priority in " + CURRENCY_ATOM + " (if transaction is in the mempool)"},
541  {RPCResult::Type::STR_HEX, "redeemScript", /*optional=*/true, "The redeemScript if scriptPubKey is P2SH"},
542  {RPCResult::Type::STR, "witnessScript", /*optional=*/true, "witnessScript if the scriptPubKey is P2WSH or P2SH-P2WSH"},
543  {RPCResult::Type::BOOL, "spendable", "Whether we have the private keys to spend this output"},
544  {RPCResult::Type::BOOL, "solvable", "Whether we know how to spend this output, ignoring the lack of keys"},
545  {RPCResult::Type::BOOL, "reused", /*optional=*/true, "(only present if avoid_reuse is set) Whether this output is reused/dirty (sent to an address that was previously spent from)"},
546  {RPCResult::Type::STR, "desc", /*optional=*/true, "(only when solvable) A descriptor for spending this output"},
547  {RPCResult::Type::BOOL, "safe", "Whether this output is considered safe to spend. Unconfirmed transactions\n"
548  "from outside keys and unconfirmed replacement transactions are considered unsafe\n"
549  "and are not eligible for spending by fundrawtransaction and sendtoaddress."},
550  }},
551  }
552  },
553  RPCExamples{
554  HelpExampleCli("listunspent", "")
555  + HelpExampleCli("listunspent", "6 9999999 \"[\\\"" + EXAMPLE_ADDRESS[0] + "\\\",\\\"" + EXAMPLE_ADDRESS[1] + "\\\"]\"")
556  + HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"" + EXAMPLE_ADDRESS[0] + "\\\",\\\"" + EXAMPLE_ADDRESS[1] + "\\\"]\"")
557  + HelpExampleCli("listunspent", "6 9999999 '[]' true '{ \"minimumAmount\": 0.005 }'")
558  + HelpExampleRpc("listunspent", "6, 9999999, [] , true, { \"minimumAmount\": 0.005 } ")
559  },
560  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
561 {
562  const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
563  if (!pwallet) return NullUniValue;
564 
565  int nMinDepth = 1;
566  if (!request.params[0].isNull()) {
567  RPCTypeCheckArgument(request.params[0], UniValue::VNUM);
568  nMinDepth = request.params[0].get_int();
569  }
570 
571  int nMaxDepth = 9999999;
572  if (!request.params[1].isNull()) {
573  RPCTypeCheckArgument(request.params[1], UniValue::VNUM);
574  nMaxDepth = request.params[1].get_int();
575  }
576 
577  std::set<CTxDestination> destinations;
578  if (!request.params[2].isNull()) {
579  RPCTypeCheckArgument(request.params[2], UniValue::VARR);
580  UniValue inputs = request.params[2].get_array();
581  for (unsigned int idx = 0; idx < inputs.size(); idx++) {
582  const UniValue& input = inputs[idx];
583  CTxDestination dest = DecodeDestination(input.get_str());
584  if (!IsValidDestination(dest)) {
585  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Bitcoin address: ") + input.get_str());
586  }
587  if (!destinations.insert(dest).second) {
588  throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + input.get_str());
589  }
590  }
591  }
592 
593  bool include_unsafe = true;
594  if (!request.params[3].isNull()) {
595  RPCTypeCheckArgument(request.params[3], UniValue::VBOOL);
596  include_unsafe = request.params[3].get_bool();
597  }
598 
599  CAmount nMinimumAmount = 0;
600  CAmount nMaximumAmount = MAX_MONEY;
601  CAmount nMinimumSumAmount = MAX_MONEY;
602  uint64_t nMaximumCount = 0;
603 
604  if (!request.params[4].isNull()) {
605  const UniValue& options = request.params[4].get_obj();
606 
607  RPCTypeCheckObj(options,
608  {
609  {"minimumAmount", UniValueType()},
610  {"maximumAmount", UniValueType()},
611  {"minimumSumAmount", UniValueType()},
612  {"maximumCount", UniValueType(UniValue::VNUM)},
613  },
614  true, true);
615 
616  if (options.exists("minimumAmount"))
617  nMinimumAmount = AmountFromValue(options["minimumAmount"]);
618 
619  if (options.exists("maximumAmount"))
620  nMaximumAmount = AmountFromValue(options["maximumAmount"]);
621 
622  if (options.exists("minimumSumAmount"))
623  nMinimumSumAmount = AmountFromValue(options["minimumSumAmount"]);
624 
625  if (options.exists("maximumCount"))
626  nMaximumCount = options["maximumCount"].get_int64();
627  }
628 
629  // Make sure the results are valid at least up to the most recent block
630  // the user could have gotten from another RPC command prior to now
631  pwallet->BlockUntilSyncedToCurrentChain();
632 
633  UniValue results(UniValue::VARR);
634  std::vector<COutput> vecOutputs;
635  {
636  CCoinControl cctl;
637  cctl.m_avoid_address_reuse = false;
638  cctl.m_min_depth = nMinDepth;
639  cctl.m_max_depth = nMaxDepth;
640  cctl.m_include_unsafe_inputs = include_unsafe;
641  LOCK(pwallet->cs_wallet);
642  AvailableCoins(*pwallet, vecOutputs, &cctl, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount);
643  }
644 
645  LOCK(pwallet->cs_wallet);
646 
647  const bool avoid_reuse = pwallet->IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE);
648 
649  for (const COutput& out : vecOutputs) {
650  CTxDestination address;
651  const CScript& scriptPubKey = out.tx->tx->vout[out.i].scriptPubKey;
652  bool fValidAddress = ExtractDestination(scriptPubKey, address);
653  bool reused = avoid_reuse && pwallet->IsSpentKey(out.tx->GetHash(), out.i);
654 
655  if (destinations.size() && (!fValidAddress || !destinations.count(address)))
656  continue;
657 
658  UniValue entry(UniValue::VOBJ);
659  entry.pushKV("txid", out.tx->GetHash().GetHex());
660  entry.pushKV("vout", out.i);
661 
662  if (fValidAddress) {
663  entry.pushKV("address", EncodeDestination(address));
664 
665  const auto* address_book_entry = pwallet->FindAddressBookEntry(address);
666  if (address_book_entry) {
667  entry.pushKV("label", address_book_entry->GetLabel());
668  }
669 
670  std::unique_ptr<SigningProvider> provider = pwallet->GetSolvingProvider(scriptPubKey);
671  if (provider) {
672  if (scriptPubKey.IsPayToScriptHash()) {
673  const CScriptID& hash = CScriptID(std::get<ScriptHash>(address));
674  CScript redeemScript;
675  if (provider->GetCScript(hash, redeemScript)) {
676  entry.pushKV("redeemScript", HexStr(redeemScript));
677  // Now check if the redeemScript is actually a P2WSH script
678  CTxDestination witness_destination;
679  if (redeemScript.IsPayToWitnessScriptHash()) {
680  bool extracted = ExtractDestination(redeemScript, witness_destination);
681  CHECK_NONFATAL(extracted);
682  // Also return the witness script
683  const WitnessV0ScriptHash& whash = std::get<WitnessV0ScriptHash>(witness_destination);
684  CScriptID id;
685  CRIPEMD160().Write(whash.begin(), whash.size()).Finalize(id.begin());
686  CScript witnessScript;
687  if (provider->GetCScript(id, witnessScript)) {
688  entry.pushKV("witnessScript", HexStr(witnessScript));
689  }
690  }
691  }
692  } else if (scriptPubKey.IsPayToWitnessScriptHash()) {
693  const WitnessV0ScriptHash& whash = std::get<WitnessV0ScriptHash>(address);
694  CScriptID id;
695  CRIPEMD160().Write(whash.begin(), whash.size()).Finalize(id.begin());
696  CScript witnessScript;
697  if (provider->GetCScript(id, witnessScript)) {
698  entry.pushKV("witnessScript", HexStr(witnessScript));
699  }
700  }
701  }
702  }
703 
704  entry.pushKV("scriptPubKey", HexStr(scriptPubKey));
705  entry.pushKV("amount", ValueFromAmount(out.tx->tx->vout[out.i].nValue));
706  entry.pushKV("confirmations", out.nDepth);
707  if (!out.nDepth) {
708  size_t ancestor_count, descendant_count, ancestor_size;
709  CAmount ancestor_fees;
710  pwallet->chain().getTransactionAncestry(out.tx->GetHash(), ancestor_count, descendant_count, &ancestor_size, &ancestor_fees);
711  if (ancestor_count) {
712  entry.pushKV("ancestorcount", uint64_t(ancestor_count));
713  entry.pushKV("ancestorsize", uint64_t(ancestor_size));
714  entry.pushKV("ancestorfees", uint64_t(ancestor_fees));
715  }
716  }
717  entry.pushKV("spendable", out.fSpendable);
718  entry.pushKV("solvable", out.fSolvable);
719  if (out.fSolvable) {
720  std::unique_ptr<SigningProvider> provider = pwallet->GetSolvingProvider(scriptPubKey);
721  if (provider) {
722  auto descriptor = InferDescriptor(scriptPubKey, *provider);
723  entry.pushKV("desc", descriptor->ToString());
724  }
725  }
726  if (avoid_reuse) entry.pushKV("reused", reused);
727  entry.pushKV("safe", out.fSafe);
728  results.push_back(entry);
729  }
730 
731  return results;
732 },
733  };
734 }
735 } // namespace wallet
HelpExampleCli
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: util.cpp:156
wallet::CCoinControl::m_max_depth
int m_max_depth
Maximum chain depth value for coin availability.
Definition: coincontrol.h:61
UniValue::VOBJ
@ VOBJ
Definition: univalue.h:19
CRIPEMD160
A hasher class for RIPEMD-160.
Definition: ripemd160.h:12
wallet.h
CHECK_NONFATAL
#define CHECK_NONFATAL(condition)
Throw a NonFatalCheckError when the condition evaluates to false.
Definition: check.h:32
wallet::getbalance
RPCHelpMan getbalance()
Definition: coins.cpp:162
key_io.h
moneystr.h
RPCHelpMan
Definition: util.h:345
CRIPEMD160::Finalize
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition: ripemd160.cpp:273
CScript::IsPayToWitnessScriptHash
bool IsPayToWitnessScriptHash() const
Definition: script.cpp:210
COutPoint::hash
uint256 hash
Definition: transaction.h:29
NullUniValue
const UniValue NullUniValue
Definition: univalue.cpp:13
GetScriptForDestination
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
Definition: standard.cpp:310
RPC_INVALID_PARAMETER
@ RPC_INVALID_PARAMETER
Invalid, missing or duplicate parameter.
Definition: protocol.h:43
RPCArg::Optional::NO
@ NO
Required arg.
wallet::getreceivedbyaddress
RPCHelpMan getreceivedbyaddress()
Definition: coins.cpp:80
RPCArg::Type::STR
@ STR
RPCArg::Type::ARR
@ ARR
BaseHash::begin
unsigned char * begin()
Definition: hash_type.h:18
wallet::GetWalletForJSONRPCRequest
std::shared_ptr< CWallet > GetWalletForJSONRPCRequest(const JSONRPCRequest &request)
Figures out what wallet, if any, to use for a JSONRPCRequest.
Definition: util.cpp:55
RPCResult::Type::NUM
@ NUM
wallet
Definition: node.h:38
UniValue::isNull
bool isNull() const
Definition: univalue.h:75
wallet::listunspent
RPCHelpMan listunspent()
Definition: coins.cpp:500
CScript::IsPayToScriptHash
bool IsPayToScriptHash() const
Definition: script.cpp:201
RPCTypeCheckObj
void RPCTypeCheckObj(const UniValue &o, const std::map< std::string, UniValueType > &typesExpected, bool fAllowNull, bool fStrict)
Definition: util.cpp:48
wallet::CWalletTx
A transaction with a bunch of additional info that only the owner cares about.
Definition: transaction.h:137
RPCTypeCheckArgument
void RPCTypeCheckArgument(const UniValue &value, const UniValueType &typeExpected)
Type-check one argument; throws JSONRPCError if wrong type given.
Definition: util.cpp:41
core_io.h
UniValue::pushKV
bool pushKV(const std::string &key, const UniValue &val)
Definition: univalue.cpp:133
ValueFromAmount
UniValue ValueFromAmount(const CAmount amount)
Definition: core_write.cpp:21
UniValue
Definition: univalue.h:17
wallet::AvailableCoins
void AvailableCoins(const CWallet &wallet, std::vector< COutput > &vCoins, const CCoinControl *coinControl, const CAmount &nMinimumAmount, const CAmount &nMaximumAmount, const CAmount &nMinimumSumAmount, const uint64_t nMaximumCount)
populate vCoins with vector of available COutputs.
Definition: spend.cpp:89
RPCArg::Type::NUM
@ NUM
RPC_METHOD_DEPRECATED
@ RPC_METHOD_DEPRECATED
RPC method is deprecated.
Definition: protocol.h:50
CTxOut::nValue
CAmount nValue
Definition: transaction.h:131
UniValue::get_str
const std::string & get_str() const
Definition: univalue_get.cpp:98
UniValueType
Wrapper for UniValue::VType, which includes typeAny: Used to denote don't care type.
Definition: util.h:44
CURRENCY_UNIT
const std::string CURRENCY_UNIT
Definition: feerate.h:14
RPCArg::Type::OBJ
@ OBJ
UniValue::get_obj
const UniValue & get_obj() const
Definition: univalue_get.cpp:135
util.h
CTxDestination
std::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:157
RPCArg::DefaultHint
std::string DefaultHint
Definition: util.h:155
IsValidDestination
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
Definition: standard.cpp:332
RPCArg::Optional::OMITTED_NAMED_ARG
@ OMITTED_NAMED_ARG
Optional arg that is a named argument and has a default value of null.
CTxOut
An output of a transaction.
Definition: transaction.h:128
RPCArg::Type::STR_HEX
@ STR_HEX
Special type that is a STR with only hex chars.
RPCResult::Type::OBJ
@ OBJ
wallet::CWallet
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
Definition: wallet.h:232
CTxOut::scriptPubKey
CScript scriptPubKey
Definition: transaction.h:132
wallet::CCoinControl::m_avoid_address_reuse
bool m_avoid_address_reuse
Forbids inclusion of dirty (previously used) addresses.
Definition: coincontrol.h:55
UniValue::exists
bool exists(const std::string &key) const
Definition: univalue.h:73
UniValue::VBOOL
@ VBOOL
Definition: univalue.h:19
univalue.h
wallet::GetReceived
static CAmount GetReceived(const CWallet &wallet, const UniValue &params, bool by_label) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
Definition: coins.cpp:19
CURRENCY_ATOM
const std::string CURRENCY_ATOM
Definition: feerate.h:15
CRIPEMD160::Write
CRIPEMD160 & Write(const unsigned char *data, size_t len)
Definition: ripemd160.cpp:247
RPCResult::Type::STR_HEX
@ STR_HEX
Special string with only hex chars.
wallet::CCoinControl::m_min_depth
int m_min_depth
Minimum chain depth value for coin availability.
Definition: coincontrol.h:59
CAmount
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
RPCExamples
Definition: util.h:335
id
static NodeId id
Definition: denialofservice_tests.cpp:37
wallet::WALLET_FLAG_AVOID_REUSE
@ WALLET_FLAG_AVOID_REUSE
Definition: walletutil.h:42
RPC_WALLET_ERROR
@ RPC_WALLET_ERROR
Wallet errors.
Definition: protocol.h:71
wallet::getbalances
RPCHelpMan getbalances()
Definition: coins.cpp:433
RPCResult::Type::STR
@ STR
UniValue::VNUM
@ VNUM
Definition: univalue.h:19
uint256
256-bit opaque blob.
Definition: uint256.h:124
RPCResult::Type::ARR
@ ARR
CScript
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:405
HelpExampleRpc
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: util.cpp:174
ExtractDestination
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
Definition: standard.cpp:213
wallet::listlockunspent
RPCHelpMan listlockunspent()
Definition: coins.cpp:380
wallet::CCoinControl::m_include_unsafe_inputs
bool m_include_unsafe_inputs
If false, only safe inputs will be used.
Definition: coincontrol.h:39
wallet::getreceivedbylabel
RPCHelpMan getreceivedbylabel()
Definition: coins.cpp:121
RPC_INVALID_ADDRESS_OR_KEY
@ RPC_INVALID_ADDRESS_OR_KEY
Invalid address or key.
Definition: protocol.h:41
ParseHashO
uint256 ParseHashO(const UniValue &o, std::string strKey)
Definition: util.cpp:99
RPCResult::Type::BOOL
@ BOOL
UniValue::get_int
int get_int() const
Definition: univalue_get.cpp:105
BaseHash::size
size_t size() const
Definition: hash_type.h:63
EXCLUSIVE_LOCKS_REQUIRED
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:49
COutPoint::n
uint32_t n
Definition: transaction.h:30
JSONRPCError
UniValue JSONRPCError(int code, const std::string &message)
Definition: request.cpp:51
LOCK
#define LOCK(cs)
Definition: sync.h:226
wallet::COutput
Definition: spend.h:17
RPCArg::Type::BOOL
@ BOOL
RPCArg::Optional::OMITTED
@ OMITTED
Optional argument with default value omitted because they are implicitly clear.
DecodeDestination
CTxDestination DecodeDestination(const std::string &str, std::string &error_msg, std::vector< int > *error_locations)
Definition: key_io.cpp:281
UniValue::push_back
bool push_back(const UniValue &val)
Definition: univalue.cpp:108
EXAMPLE_ADDRESS
const std::string EXAMPLE_ADDRESS[2]
Example bech32 addresses for the RPCExamples help documentation.
Definition: util.cpp:22
wallet::GetBalance
Balance GetBalance(const CWallet &wallet, const int min_depth, bool avoid_reuse)
Definition: receive.cpp:318
receive.h
UniValue::size
size_t size() const
Definition: univalue.h:66
wallet::Balance::m_mine_untrusted_pending
CAmount m_mine_untrusted_pending
Untrusted, but in mempool (pending)
Definition: receive.h:54
RPCArg::Type::AMOUNT
@ AMOUNT
Special type representing a floating point amount (can be either NUM or STR)
JSONRPCRequest
Definition: request.h:28
MAX_MONEY
static constexpr CAmount MAX_MONEY
No amount larger than this (in satoshi) is valid.
Definition: amount.h:26
RPCResult
Definition: util.h:231
wallet::lockunspent
RPCHelpMan lockunspent()
Definition: coins.cpp:240
COutPoint
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:26
find_value
const UniValue & find_value(const UniValue &obj, const std::string &name)
Definition: univalue.cpp:236
wallet::getunconfirmedbalance
RPCHelpMan getunconfirmedbalance()
Definition: coins.cpp:217
RPCResult::Type::STR_AMOUNT
@ STR_AMOUNT
Special string to represent a floating point amount.
UniValue::get_array
const UniValue & get_array() const
Definition: univalue_get.cpp:142
UniValue::VARR
@ VARR
Definition: univalue.h:19
coincontrol.h
WitnessV0ScriptHash
Definition: standard.h:102
AmountFromValue
static CAmount AmountFromValue(const UniValue &value)
Definition: bitcoin-tx.cpp:550
InferDescriptor
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible.
Definition: descriptor.cpp:1413
CScriptID
A reference to a CScript: the Hash160 of its serialization (see script.h)
Definition: standard.h:25
HexStr
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
Definition: strencodings.cpp:510
UniValue::VSTR
@ VSTR
Definition: univalue.h:19
wallet::CCoinControl
Coin Control Features.
Definition: coincontrol.h:29
spend.h
EncodeDestination
std::string EncodeDestination(const CTxDestination &dest)
Definition: key_io.cpp:276
wallet::ParseIncludeWatchonly
bool ParseIncludeWatchonly(const UniValue &include_watchonly, const CWallet &wallet)
Used by RPC commands that have an include_watchonly parameter.
Definition: util.cpp:34
wallet::CWalletTx::IsCoinBase
bool IsCoinBase() const
Definition: transaction.h:299
wallet::GetAvoidReuseFlag
bool GetAvoidReuseFlag(const CWallet &wallet, const UniValue &param)
Definition: util.cpp:19
wallet::CWalletTx::tx
CTransactionRef tx
Definition: transaction.h:219
FormatMoney
std::string FormatMoney(const CAmount n)
Money parsing/formatting utilities.
Definition: moneystr.cpp:15
wallet::LabelFromValue
std::string LabelFromValue(const UniValue &value)
Definition: util.cpp:118