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