Raven Core  3.0.0
P2P Digital Currency
rpcwallet.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 The Bitcoin Core developers
3 // Copyright (c) 2017-2019 The Raven Core developers
4 // Distributed under the MIT software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 
7 #include "amount.h"
8 #include "base58.h"
9 #include "chain.h"
10 #include "consensus/validation.h"
11 #include "core_io.h"
12 #include "httpserver.h"
13 #include "validation.h"
14 #include "net.h"
15 #include "policy/feerate.h"
16 #include "policy/fees.h"
17 #include "policy/policy.h"
18 #include "policy/rbf.h"
19 #include "rpc/mining.h"
20 #include "rpc/safemode.h"
21 #include "rpc/server.h"
22 #include "script/sign.h"
23 #include "timedata.h"
24 #include "util.h"
25 #include "utiltime.h"
26 #include "utilmoneystr.h"
27 #include "wallet/coincontrol.h"
28 #include "wallet/feebumper.h"
29 #include "wallet/wallet.h"
30 #include "wallet/walletdb.h"
31 
32 #include <init.h> // For StartShutdown
33 
34 #include <stdint.h>
35 
36 #include <univalue.h>
37 
38 static const std::string WALLET_ENDPOINT_BASE = "/wallet/";
39 
41 {
42  if (request.URI.substr(0, WALLET_ENDPOINT_BASE.size()) == WALLET_ENDPOINT_BASE) {
43  // wallet endpoint was used
44  std::string requestedWallet = urlDecode(request.URI.substr(WALLET_ENDPOINT_BASE.size()));
45  for (CWalletRef pwallet : ::vpwallets) {
46  if (pwallet->GetName() == requestedWallet) {
47  return pwallet;
48  }
49  }
50  throw JSONRPCError(RPC_WALLET_NOT_FOUND, "Requested wallet does not exist or is not loaded");
51  }
52  return ::vpwallets.size() == 1 || (request.fHelp && ::vpwallets.size() > 0) ? ::vpwallets[0] : nullptr;
53 }
54 
55 
56 std::string HelpRequiringPassphrase(CWallet * const pwallet)
57 {
58  return pwallet && pwallet->IsCrypted()
59  ? "\nRequires wallet passphrase to be set with walletpassphrase call."
60  : "";
61 }
62 
63 bool EnsureWalletIsAvailable(CWallet * const pwallet, bool avoidException)
64 {
65  if (pwallet) return true;
66  if (avoidException) return false;
67  if (::vpwallets.empty()) {
68  // Note: It isn't currently possible to trigger this error because
69  // wallet RPC methods aren't registered unless a wallet is loaded. But
70  // this error is being kept as a precaution, because it's possible in
71  // the future that wallet RPC methods might get or remain registered
72  // when no wallets are loaded.
73  throw JSONRPCError(
74  RPC_METHOD_NOT_FOUND, "Method not found (wallet method is disabled because no wallet is loaded)");
75  }
77  "Wallet file not specified (must request wallet RPC through /wallet/<filename> uri-path).");
78 }
79 
80 void EnsureWalletIsUnlocked(CWallet * const pwallet)
81 {
82  if (pwallet->IsLocked()) {
83  throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first.");
84  }
85 }
86 
87 void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry)
88 {
89  int confirms = wtx.GetDepthInMainChain();
90  entry.push_back(Pair("confirmations", confirms));
91  if (wtx.IsCoinBase())
92  entry.push_back(Pair("generated", true));
93  if (confirms > 0)
94  {
95  entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex()));
96  entry.push_back(Pair("blockindex", wtx.nIndex));
97  entry.push_back(Pair("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime()));
98  } else {
99  entry.push_back(Pair("trusted", wtx.IsTrusted()));
100  }
101  uint256 hash = wtx.GetHash();
102  entry.push_back(Pair("txid", hash.GetHex()));
103  UniValue conflicts(UniValue::VARR);
104  for (const uint256& conflict : wtx.GetConflicts())
105  conflicts.push_back(conflict.GetHex());
106  entry.push_back(Pair("walletconflicts", conflicts));
107  entry.push_back(Pair("time", wtx.GetTxTime()));
108  entry.push_back(Pair("timereceived", (int64_t)wtx.nTimeReceived));
109 
110  // Add opt-in RBF status
111  std::string rbfStatus = "no";
112 // if (confirms <= 0) {
113 // LOCK(mempool.cs);
114 // RBFTransactionState rbfState = IsRBFOptIn(wtx, mempool);
115 // if (rbfState == RBF_TRANSACTIONSTATE_UNKNOWN)
116 // rbfStatus = "unknown";
117 // else if (rbfState == RBF_TRANSACTIONSTATE_REPLACEABLE_BIP125)
118 // rbfStatus = "yes";
119 // }
120  entry.push_back(Pair("bip125-replaceable", rbfStatus));
121 
122  for (const std::pair<std::string, std::string>& item : wtx.mapValue)
123  entry.push_back(Pair(item.first, item.second));
124 }
125 
126 std::string AccountFromValue(const UniValue& value)
127 {
128  std::string strAccount = value.get_str();
129  if (strAccount == "*")
130  throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Invalid account name");
131  return strAccount;
132 }
133 
135 {
136  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
137  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
138  return NullUniValue;
139  }
140 
141  if (request.fHelp || request.params.size() > 1)
142  throw std::runtime_error(
143  "getnewaddress ( \"account\" )\n"
144  "\nReturns a new Raven address for receiving payments.\n"
145  "If 'account' is specified (DEPRECATED), it is added to the address book \n"
146  "so payments received with the address will be credited to 'account'.\n"
147  "\nArguments:\n"
148  "1. \"account\" (string, optional) DEPRECATED. The account name for the address to be linked to. If not provided, the default account \"\" is used. It can also be set to the empty string \"\" to represent the default account. The account does not need to exist, it will be created if there is no account by the given name.\n"
149  "\nResult:\n"
150  "\"address\" (string) The new raven address\n"
151  "\nExamples:\n"
152  + HelpExampleCli("getnewaddress", "")
153  + HelpExampleRpc("getnewaddress", "")
154  );
155 
156  LOCK2(cs_main, pwallet->cs_wallet);
157 
158  // Parse the account first so we don't generate a key if there's an error
159  std::string strAccount;
160  if (!request.params[0].isNull())
161  strAccount = AccountFromValue(request.params[0]);
162 
163  if (!pwallet->IsLocked()) {
164  pwallet->TopUpKeyPool();
165  }
166 
167  // Generate a new key that is added to wallet
168  CPubKey newKey;
169  if (!pwallet->GetKeyFromPool(newKey)) {
170  throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
171  }
172  CKeyID keyID = newKey.GetID();
173 
174  pwallet->SetAddressBook(keyID, strAccount, "receive");
175 
176  return EncodeDestination(keyID);
177 }
178 
179 
180 CTxDestination GetAccountAddress(CWallet* const pwallet, std::string strAccount, bool bForceNew=false)
181 {
182  CPubKey pubKey;
183  if (!pwallet->GetAccountPubkey(pubKey, strAccount, bForceNew)) {
184  throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
185  }
186 
187  return pubKey.GetID();
188 }
189 
191 {
192  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
193  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
194  return NullUniValue;
195  }
196 
197  if (request.fHelp || request.params.size() != 1)
198  throw std::runtime_error(
199  "getaccountaddress \"account\"\n"
200  "\nDEPRECATED. Returns the current Raven address for receiving payments to this account.\n"
201  "\nArguments:\n"
202  "1. \"account\" (string, required) The account name for the address. It can also be set to the empty string \"\" to represent the default account. The account does not need to exist, it will be created and a new address created if there is no account by the given name.\n"
203  "\nResult:\n"
204  "\"address\" (string) The account raven address\n"
205  "\nExamples:\n"
206  + HelpExampleCli("getaccountaddress", "")
207  + HelpExampleCli("getaccountaddress", "\"\"")
208  + HelpExampleCli("getaccountaddress", "\"myaccount\"")
209  + HelpExampleRpc("getaccountaddress", "\"myaccount\"")
210  );
211 
212  LOCK2(cs_main, pwallet->cs_wallet);
213 
214  // Parse the account first so we don't generate a key if there's an error
215  std::string strAccount = AccountFromValue(request.params[0]);
216 
218 
219  ret = EncodeDestination(GetAccountAddress(pwallet, strAccount));
220  return ret;
221 }
222 
223 
225 {
226  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
227  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
228  return NullUniValue;
229  }
230 
231  if (request.fHelp || request.params.size() > 0)
232  throw std::runtime_error(
233  "getrawchangeaddress\n"
234  "\nReturns a new Raven address, for receiving change.\n"
235  "This is for use with raw transactions, NOT normal use.\n"
236  "\nResult:\n"
237  "\"address\" (string) The address\n"
238  "\nExamples:\n"
239  + HelpExampleCli("getrawchangeaddress", "")
240  + HelpExampleRpc("getrawchangeaddress", "")
241  );
242 
243  LOCK2(cs_main, pwallet->cs_wallet);
244 
245  if (!pwallet->IsLocked()) {
246  pwallet->TopUpKeyPool();
247  }
248 
249  CReserveKey reservekey(pwallet);
250  CPubKey vchPubKey;
251  if (!reservekey.GetReservedKey(vchPubKey, true))
252  throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
253 
254  reservekey.KeepKey();
255 
256  CKeyID keyID = vchPubKey.GetID();
257 
258  return EncodeDestination(keyID);
259 }
260 
261 
263 {
264  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
265  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
266  return NullUniValue;
267  }
268 
269  if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
270  throw std::runtime_error(
271  "setaccount \"address\" \"account\"\n"
272  "\nDEPRECATED. Sets the account associated with the given address.\n"
273  "\nArguments:\n"
274  "1. \"address\" (string, required) The raven address to be associated with an account.\n"
275  "2. \"account\" (string, required) The account to assign the address to.\n"
276  "\nExamples:\n"
277  + HelpExampleCli("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"tabby\"")
278  + HelpExampleRpc("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"tabby\"")
279  );
280 
281  LOCK2(cs_main, pwallet->cs_wallet);
282 
283  CTxDestination dest = DecodeDestination(request.params[0].get_str());
284  if (!IsValidDestination(dest)) {
285  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Raven address");
286  }
287 
288  std::string strAccount;
289  if (!request.params[1].isNull())
290  strAccount = AccountFromValue(request.params[1]);
291 
292  // Only add the account if the address is yours.
293  if (IsMine(*pwallet, dest)) {
294  // Detect when changing the account of an address that is the 'unused current key' of another account:
295  if (pwallet->mapAddressBook.count(dest)) {
296  std::string strOldAccount = pwallet->mapAddressBook[dest].name;
297  if (dest == GetAccountAddress(pwallet, strOldAccount)) {
298  GetAccountAddress(pwallet, strOldAccount, true);
299  }
300  }
301  pwallet->SetAddressBook(dest, strAccount, "receive");
302  }
303  else
304  throw JSONRPCError(RPC_MISC_ERROR, "setaccount can only be used with own address");
305 
306  return NullUniValue;
307 }
308 
309 
311 {
312  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
313  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
314  return NullUniValue;
315  }
316 
317  if (request.fHelp || request.params.size() != 1)
318  throw std::runtime_error(
319  "getaccount \"address\"\n"
320  "\nDEPRECATED. Returns the account associated with the given address.\n"
321  "\nArguments:\n"
322  "1. \"address\" (string, required) The raven address for account lookup.\n"
323  "\nResult:\n"
324  "\"accountname\" (string) the account address\n"
325  "\nExamples:\n"
326  + HelpExampleCli("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"")
327  + HelpExampleRpc("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"")
328  );
329 
330  LOCK2(cs_main, pwallet->cs_wallet);
331 
332  CTxDestination dest = DecodeDestination(request.params[0].get_str());
333  if (!IsValidDestination(dest)) {
334  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Raven address");
335  }
336 
337  std::string strAccount;
338  std::map<CTxDestination, CAddressBookData>::iterator mi = pwallet->mapAddressBook.find(dest);
339  if (mi != pwallet->mapAddressBook.end() && !(*mi).second.name.empty()) {
340  strAccount = (*mi).second.name;
341  }
342  return strAccount;
343 }
344 
345 
347 {
348  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
349  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
350  return NullUniValue;
351  }
352 
353  if (request.fHelp || request.params.size() != 1)
354  throw std::runtime_error(
355  "getaddressesbyaccount \"account\"\n"
356  "\nDEPRECATED. Returns the list of addresses for the given account.\n"
357  "\nArguments:\n"
358  "1. \"account\" (string, required) The account name.\n"
359  "\nResult:\n"
360  "[ (json array of string)\n"
361  " \"address\" (string) a raven address associated with the given account\n"
362  " ,...\n"
363  "]\n"
364  "\nExamples:\n"
365  + HelpExampleCli("getaddressesbyaccount", "\"tabby\"")
366  + HelpExampleRpc("getaddressesbyaccount", "\"tabby\"")
367  );
368 
369  LOCK2(cs_main, pwallet->cs_wallet);
370 
371  std::string strAccount = AccountFromValue(request.params[0]);
372 
373  // Find all addresses that have the given account
375  for (const std::pair<CTxDestination, CAddressBookData>& item : pwallet->mapAddressBook) {
376  const CTxDestination& dest = item.first;
377  const std::string& strName = item.second.name;
378  if (strName == strAccount) {
379  ret.push_back(EncodeDestination(dest));
380  }
381  }
382  return ret;
383 }
384 
385 static void SendMoney(CWallet * const pwallet, const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew, const CCoinControl& coin_control)
386 {
387  CAmount curBalance = pwallet->GetBalance();
388 
389  // Check amount
390  if (nValue <= 0)
391  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount (2)");
392 
393  if (nValue > curBalance)
394  throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds");
395 
396  if (pwallet->GetBroadcastTransactions() && !g_connman) {
397  throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
398  }
399 
400  // Parse Raven address
401  CScript scriptPubKey = GetScriptForDestination(address);
402 
403  // Create and send the transaction
404  CReserveKey reservekey(pwallet);
405  CAmount nFeeRequired;
406  std::string strError;
407  std::vector<CRecipient> vecSend;
408  int nChangePosRet = -1;
409  CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount};
410  vecSend.push_back(recipient);
411  if (!pwallet->CreateTransaction(vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError, coin_control)) {
412  if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance)
413  strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired));
414  throw JSONRPCError(RPC_WALLET_ERROR, strError);
415  }
416  CValidationState state;
417  if (!pwallet->CommitTransaction(wtxNew, reservekey, g_connman.get(), state)) {
418  strError = strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason());
419  throw JSONRPCError(RPC_WALLET_ERROR, strError);
420  }
421 }
422 
424 {
425  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
426  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
427  return NullUniValue;
428  }
429 
430  if (request.fHelp || request.params.size() < 2 || request.params.size() > 7)
431  throw std::runtime_error(
432  "sendtoaddress \"address\" amount ( \"comment\" \"comment_to\" subtractfeefromamount replaceable conf_target \"estimate_mode\")\n"
433  "\nSend an amount to a given address.\n"
434  + HelpRequiringPassphrase(pwallet) +
435  "\nArguments:\n"
436  "1. \"address\" (string, required) The raven address to send to.\n"
437  "2. \"amount\" (numeric or string, required) The amount in " + CURRENCY_UNIT + " to send. eg 0.1\n"
438  "3. \"comment\" (string, optional) A comment used to store what the transaction is for. \n"
439  " This is not part of the transaction, just kept in your wallet.\n"
440  "4. \"comment_to\" (string, optional) A comment to store the name of the person or organization \n"
441  " to which you're sending the transaction. This is not part of the \n"
442  " transaction, just kept in your wallet.\n"
443  "5. subtractfeefromamount (boolean, optional, default=false) The fee will be deducted from the amount being sent.\n"
444  " The recipient will receive less ravens than you enter in the amount field.\n"
445 // "6. replaceable (boolean, optional) Allow this transaction to be replaced by a transaction with higher fees via BIP 125\n"
446  "6. conf_target (numeric, optional) Confirmation target (in blocks)\n"
447  "7. \"estimate_mode\" (string, optional, default=UNSET) The fee estimate mode, must be one of:\n"
448  " \"UNSET\"\n"
449  " \"ECONOMICAL\"\n"
450  " \"CONSERVATIVE\"\n"
451  "\nResult:\n"
452  "\"txid\" (string) The transaction id.\n"
453  "\nExamples:\n"
454  + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1")
455  + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"donation\" \"seans outpost\"")
456  + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"\" \"\" true")
457  + HelpExampleRpc("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.1, \"donation\", \"seans outpost\"")
458  );
459 
460  ObserveSafeMode();
461  LOCK2(cs_main, pwallet->cs_wallet);
462 
463  CTxDestination dest = DecodeDestination(request.params[0].get_str());
464  if (!IsValidDestination(dest)) {
465  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
466  }
467 
468  // Amount
469  CAmount nAmount = AmountFromValue(request.params[1]);
470  if (nAmount <= 0)
471  throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
472 
473  // Wallet comments
474  CWalletTx wtx;
475  if (!request.params[2].isNull() && !request.params[2].get_str().empty())
476  wtx.mapValue["comment"] = request.params[2].get_str();
477  if (!request.params[3].isNull() && !request.params[3].get_str().empty())
478  wtx.mapValue["to"] = request.params[3].get_str();
479 
480  bool fSubtractFeeFromAmount = false;
481  if (!request.params[4].isNull()) {
482  fSubtractFeeFromAmount = request.params[4].get_bool();
483  }
484 
485  CCoinControl coin_control;
486 // if (!request.params[5].isNull()) {
487 // coin_control.signalRbf = request.params[5].get_bool();
488 // }
489 
490  if (!request.params[5].isNull()) {
491  coin_control.m_confirm_target = ParseConfirmTarget(request.params[6]);
492  }
493 
494  if (!request.params[6].isNull()) {
495  if (!FeeModeFromString(request.params[7].get_str(), coin_control.m_fee_mode)) {
496  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid estimate_mode parameter");
497  }
498  }
499 
500 
501  EnsureWalletIsUnlocked(pwallet);
502 
503  SendMoney(pwallet, dest, nAmount, fSubtractFeeFromAmount, wtx, coin_control);
504 
505  return wtx.GetHash().GetHex();
506 }
507 
509 {
510  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
511  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
512  return NullUniValue;
513  }
514 
515  if (request.fHelp || request.params.size() != 0)
516  throw std::runtime_error(
517  "listaddressgroupings\n"
518  "\nLists groups of addresses which have had their common ownership\n"
519  "made public by common use as inputs or as the resulting change\n"
520  "in past transactions\n"
521  "\nResult:\n"
522  "[\n"
523  " [\n"
524  " [\n"
525  " \"address\", (string) The raven address\n"
526  " amount, (numeric) The amount in " + CURRENCY_UNIT + "\n"
527  " \"account\" (string, optional) DEPRECATED. The account\n"
528  " ]\n"
529  " ,...\n"
530  " ]\n"
531  " ,...\n"
532  "]\n"
533  "\nExamples:\n"
534  + HelpExampleCli("listaddressgroupings", "")
535  + HelpExampleRpc("listaddressgroupings", "")
536  );
537 
538  ObserveSafeMode();
539  LOCK2(cs_main, pwallet->cs_wallet);
540 
541  UniValue jsonGroupings(UniValue::VARR);
542  std::map<CTxDestination, CAmount> balances = pwallet->GetAddressBalances();
543  for (const std::set<CTxDestination>& grouping : pwallet->GetAddressGroupings()) {
544  UniValue jsonGrouping(UniValue::VARR);
545  for (const CTxDestination& address : grouping)
546  {
547  UniValue addressInfo(UniValue::VARR);
548  addressInfo.push_back(EncodeDestination(address));
549  addressInfo.push_back(ValueFromAmount(balances[address]));
550  {
551  if (pwallet->mapAddressBook.find(address) != pwallet->mapAddressBook.end()) {
552  addressInfo.push_back(pwallet->mapAddressBook.find(address)->second.name);
553  }
554  }
555  jsonGrouping.push_back(addressInfo);
556  }
557  jsonGroupings.push_back(jsonGrouping);
558  }
559  return jsonGroupings;
560 }
561 
563 {
564  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
565  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
566  return NullUniValue;
567  }
568 
569  if (request.fHelp || request.params.size() != 2)
570  throw std::runtime_error(
571  "signmessage \"address\" \"message\"\n"
572  "\nSign a message with the private key of an address"
573  + HelpRequiringPassphrase(pwallet) + "\n"
574  "\nArguments:\n"
575  "1. \"address\" (string, required) The raven address to use for the private key.\n"
576  "2. \"message\" (string, required) The message to create a signature of.\n"
577  "\nResult:\n"
578  "\"signature\" (string) The signature of the message encoded in base 64\n"
579  "\nExamples:\n"
580  "\nUnlock the wallet for 30 seconds\n"
581  + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
582  "\nCreate the signature\n"
583  + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") +
584  "\nVerify the signature\n"
585  + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") +
586  "\nAs json rpc\n"
587  + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"my message\"")
588  );
589 
590  LOCK2(cs_main, pwallet->cs_wallet);
591 
592  EnsureWalletIsUnlocked(pwallet);
593 
594  std::string strAddress = request.params[0].get_str();
595  std::string strMessage = request.params[1].get_str();
596 
597  CTxDestination dest = DecodeDestination(strAddress);
598  if (!IsValidDestination(dest)) {
599  throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
600  }
601 
602  const CKeyID *keyID = boost::get<CKeyID>(&dest);
603  if (!keyID) {
604  throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
605  }
606 
607  CKey key;
608  if (!pwallet->GetKey(*keyID, key)) {
609  throw JSONRPCError(RPC_WALLET_ERROR, "Private key not available");
610  }
611 
612  CHashWriter ss(SER_GETHASH, 0);
613  ss << strMessageMagic;
614  ss << strMessage;
615 
616  std::vector<unsigned char> vchSig;
617  if (!key.SignCompact(ss.GetHash(), vchSig))
618  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed");
619 
620  return EncodeBase64(vchSig.data(), vchSig.size());
621 }
622 
624 {
625  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
626  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
627  return NullUniValue;
628  }
629 
630  if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
631  throw std::runtime_error(
632  "getreceivedbyaddress \"address\" ( minconf )\n"
633  "\nReturns the total amount received by the given address in transactions with at least minconf confirmations.\n"
634  "\nArguments:\n"
635  "1. \"address\" (string, required) The raven address for transactions.\n"
636  "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
637  "\nResult:\n"
638  "amount (numeric) The total amount in " + CURRENCY_UNIT + " received at this address.\n"
639  "\nExamples:\n"
640  "\nThe amount from transactions with at least 1 confirmation\n"
641  + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"") +
642  "\nThe amount including unconfirmed transactions, zero confirmations\n"
643  + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" 0") +
644  "\nThe amount with at least 6 confirmations\n"
645  + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" 6") +
646  "\nAs a json rpc call\n"
647  + HelpExampleRpc("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", 6")
648  );
649 
650  ObserveSafeMode();
651  LOCK2(cs_main, pwallet->cs_wallet);
652 
653  // Raven address
654  CTxDestination dest = DecodeDestination(request.params[0].get_str());
655  if (!IsValidDestination(dest)) {
656  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Raven address");
657  }
658  CScript scriptPubKey = GetScriptForDestination(dest);
659  if (!IsMine(*pwallet, scriptPubKey)) {
660  return ValueFromAmount(0);
661  }
662 
663  // Minimum confirmations
664  int nMinDepth = 1;
665  if (!request.params[1].isNull())
666  nMinDepth = request.params[1].get_int();
667 
668  // Tally
669  CAmount nAmount = 0;
670  for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
671  const CWalletTx& wtx = pairWtx.second;
672  if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx))
673  continue;
674 
675  for (const CTxOut& txout : wtx.tx->vout)
676  if (txout.scriptPubKey == scriptPubKey)
677  if (wtx.GetDepthInMainChain() >= nMinDepth)
678  nAmount += txout.nValue;
679  }
680 
681  return ValueFromAmount(nAmount);
682 }
683 
684 
686 {
687  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
688  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
689  return NullUniValue;
690  }
691 
692  if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
693  throw std::runtime_error(
694  "getreceivedbyaccount \"account\" ( minconf )\n"
695  "\nDEPRECATED. Returns the total amount received by addresses with <account> in transactions with at least [minconf] confirmations.\n"
696  "\nArguments:\n"
697  "1. \"account\" (string, required) The selected account, may be the default account using \"\".\n"
698  "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
699  "\nResult:\n"
700  "amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n"
701  "\nExamples:\n"
702  "\nAmount received by the default account with at least 1 confirmation\n"
703  + HelpExampleCli("getreceivedbyaccount", "\"\"") +
704  "\nAmount received at the tabby account including unconfirmed amounts with zero confirmations\n"
705  + HelpExampleCli("getreceivedbyaccount", "\"tabby\" 0") +
706  "\nThe amount with at least 6 confirmations\n"
707  + HelpExampleCli("getreceivedbyaccount", "\"tabby\" 6") +
708  "\nAs a json rpc call\n"
709  + HelpExampleRpc("getreceivedbyaccount", "\"tabby\", 6")
710  );
711 
712  ObserveSafeMode();
713  LOCK2(cs_main, pwallet->cs_wallet);
714 
715  // Minimum confirmations
716  int nMinDepth = 1;
717  if (!request.params[1].isNull())
718  nMinDepth = request.params[1].get_int();
719 
720  // Get the set of pub keys assigned to account
721  std::string strAccount = AccountFromValue(request.params[0]);
722  std::set<CTxDestination> setAddress = pwallet->GetAccountAddresses(strAccount);
723 
724  // Tally
725  CAmount nAmount = 0;
726  for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
727  const CWalletTx& wtx = pairWtx.second;
728  if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx))
729  continue;
730 
731  for (const CTxOut& txout : wtx.tx->vout)
732  {
733  CTxDestination address;
734  if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*pwallet, address) && setAddress.count(address)) {
735  if (wtx.GetDepthInMainChain() >= nMinDepth)
736  nAmount += txout.nValue;
737  }
738  }
739  }
740 
741  return ValueFromAmount(nAmount);
742 }
743 
744 
746 {
747  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
748  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
749  return NullUniValue;
750  }
751 
752  if (request.fHelp || request.params.size() > 3)
753  throw std::runtime_error(
754  "getbalance ( \"account\" minconf include_watchonly )\n"
755  "\nIf account is not specified, returns the server's total available balance.\n"
756  "If account is specified (DEPRECATED), returns the balance in the account.\n"
757  "Note that the account \"\" is not the same as leaving the parameter out.\n"
758  "The server total may be different to the balance in the default \"\" account.\n"
759  "\nArguments:\n"
760  "1. \"account\" (string, optional) DEPRECATED. The account string may be given as a\n"
761  " specific account name to find the balance associated with wallet keys in\n"
762  " a named account, or as the empty string (\"\") to find the balance\n"
763  " associated with wallet keys not in any named account, or as \"*\" to find\n"
764  " the balance associated with all wallet keys regardless of account.\n"
765  " When this option is specified, it calculates the balance in a different\n"
766  " way than when it is not specified, and which can count spends twice when\n"
767  " there are conflicting pending transactions (such as those created by\n"
768  " the bumpfee command), temporarily resulting in low or even negative\n"
769  " balances. In general, account balance calculation is not considered\n"
770  " reliable and has resulted in confusing outcomes, so it is recommended to\n"
771  " avoid passing this argument.\n"
772  "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
773  "3. include_watchonly (bool, optional, default=false) Also include balance in watch-only addresses (see 'importaddress')\n"
774  "\nResult:\n"
775  "amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n"
776  "\nExamples:\n"
777  "\nThe total amount in the wallet with 1 or more confirmations\n"
778  + HelpExampleCli("getbalance", "") +
779  "\nThe total amount in the wallet at least 6 blocks confirmed\n"
780  + HelpExampleCli("getbalance", "\"*\" 6") +
781  "\nAs a json rpc call\n"
782  + HelpExampleRpc("getbalance", "\"*\", 6")
783  );
784 
785  ObserveSafeMode();
786  LOCK2(cs_main, pwallet->cs_wallet);
787 
788  const UniValue& account_value = request.params[0];
789  const UniValue& minconf = request.params[1];
790  const UniValue& include_watchonly = request.params[2];
791 
792  if (account_value.isNull()) {
793  if (!minconf.isNull()) {
795  "getbalance minconf option is only currently supported if an account is specified");
796  }
797  if (!include_watchonly.isNull()) {
799  "getbalance include_watchonly option is only currently supported if an account is specified");
800  }
801  return ValueFromAmount(pwallet->GetBalance());
802  }
803 
804  const std::string& account_param = account_value.get_str();
805  const std::string* account = account_param != "*" ? &account_param : nullptr;
806 
807  int nMinDepth = 1;
808  if (!minconf.isNull())
809  nMinDepth = minconf.get_int();
811  if(!include_watchonly.isNull())
812  if(include_watchonly.get_bool())
813  filter = filter | ISMINE_WATCH_ONLY;
814 
815  return ValueFromAmount(pwallet->GetLegacyBalance(filter, nMinDepth, account));
816 }
817 
819 {
820  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
821  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
822  return NullUniValue;
823  }
824 
825  if (request.fHelp || request.params.size() > 0)
826  throw std::runtime_error(
827  "getunconfirmedbalance\n"
828  "Returns the server's total unconfirmed balance\n");
829 
830  ObserveSafeMode();
831  LOCK2(cs_main, pwallet->cs_wallet);
832 
833  return ValueFromAmount(pwallet->GetUnconfirmedBalance());
834 }
835 
836 
838 {
839  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
840  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
841  return NullUniValue;
842  }
843 
844  if (request.fHelp || request.params.size() < 3 || request.params.size() > 5)
845  throw std::runtime_error(
846  "move \"fromaccount\" \"toaccount\" amount ( minconf \"comment\" )\n"
847  "\nDEPRECATED. Move a specified amount from one account in your wallet to another.\n"
848  "\nArguments:\n"
849  "1. \"fromaccount\" (string, required) The name of the account to move funds from. May be the default account using \"\".\n"
850  "2. \"toaccount\" (string, required) The name of the account to move funds to. May be the default account using \"\".\n"
851  "3. amount (numeric) Quantity of " + CURRENCY_UNIT + " to move between accounts.\n"
852  "4. (dummy) (numeric, optional) Ignored. Remains for backward compatibility.\n"
853  "5. \"comment\" (string, optional) An optional comment, stored in the wallet only.\n"
854  "\nResult:\n"
855  "true|false (boolean) true if successful.\n"
856  "\nExamples:\n"
857  "\nMove 0.01 " + CURRENCY_UNIT + " from the default account to the account named tabby\n"
858  + HelpExampleCli("move", "\"\" \"tabby\" 0.01") +
859  "\nMove 0.01 " + CURRENCY_UNIT + " timotei to akiko with a comment and funds have 6 confirmations\n"
860  + HelpExampleCli("move", "\"timotei\" \"akiko\" 0.01 6 \"happy birthday!\"") +
861  "\nAs a json rpc call\n"
862  + HelpExampleRpc("move", "\"timotei\", \"akiko\", 0.01, 6, \"happy birthday!\"")
863  );
864 
865  ObserveSafeMode();
866  LOCK2(cs_main, pwallet->cs_wallet);
867 
868  std::string strFrom = AccountFromValue(request.params[0]);
869  std::string strTo = AccountFromValue(request.params[1]);
870  CAmount nAmount = AmountFromValue(request.params[2]);
871  if (nAmount <= 0)
872  throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
873  if (!request.params[3].isNull())
874  // unused parameter, used to be nMinDepth, keep type-checking it though
875  (void)request.params[3].get_int();
876  std::string strComment;
877  if (!request.params[4].isNull())
878  strComment = request.params[4].get_str();
879 
880  if (!pwallet->AccountMove(strFrom, strTo, nAmount, strComment)) {
881  throw JSONRPCError(RPC_DATABASE_ERROR, "database error");
882  }
883 
884  return true;
885 }
886 
887 
889 {
890  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
891  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
892  return NullUniValue;
893  }
894 
895  if (request.fHelp || request.params.size() < 3 || request.params.size() > 6)
896  throw std::runtime_error(
897  "sendfrom \"fromaccount\" \"toaddress\" amount ( minconf \"comment\" \"comment_to\" )\n"
898  "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a raven address."
899  + HelpRequiringPassphrase(pwallet) + "\n"
900  "\nArguments:\n"
901  "1. \"fromaccount\" (string, required) The name of the account to send funds from. May be the default account using \"\".\n"
902  " Specifying an account does not influence coin selection, but it does associate the newly created\n"
903  " transaction with the account, so the account's balance computation and transaction history can reflect\n"
904  " the spend.\n"
905  "2. \"toaddress\" (string, required) The raven address to send funds to.\n"
906  "3. amount (numeric or string, required) The amount in " + CURRENCY_UNIT + " (transaction fee is added on top).\n"
907  "4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n"
908  "5. \"comment\" (string, optional) A comment used to store what the transaction is for. \n"
909  " This is not part of the transaction, just kept in your wallet.\n"
910  "6. \"comment_to\" (string, optional) An optional comment to store the name of the person or organization \n"
911  " to which you're sending the transaction. This is not part of the transaction, \n"
912  " it is just kept in your wallet.\n"
913  "\nResult:\n"
914  "\"txid\" (string) The transaction id.\n"
915  "\nExamples:\n"
916  "\nSend 0.01 " + CURRENCY_UNIT + " from the default account to the address, must have at least 1 confirmation\n"
917  + HelpExampleCli("sendfrom", "\"\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01") +
918  "\nSend 0.01 from the tabby account to the given address, funds must have at least 6 confirmations\n"
919  + HelpExampleCli("sendfrom", "\"tabby\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01 6 \"donation\" \"seans outpost\"") +
920  "\nAs a json rpc call\n"
921  + HelpExampleRpc("sendfrom", "\"tabby\", \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.01, 6, \"donation\", \"seans outpost\"")
922  );
923 
924  ObserveSafeMode();
925  LOCK2(cs_main, pwallet->cs_wallet);
926 
927  std::string strAccount = AccountFromValue(request.params[0]);
928  CTxDestination dest = DecodeDestination(request.params[1].get_str());
929  if (!IsValidDestination(dest)) {
930  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Raven address");
931  }
932  CAmount nAmount = AmountFromValue(request.params[2]);
933  if (nAmount <= 0)
934  throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
935  int nMinDepth = 1;
936  if (!request.params[3].isNull())
937  nMinDepth = request.params[3].get_int();
938 
939  CWalletTx wtx;
940  wtx.strFromAccount = strAccount;
941  if (!request.params[4].isNull() && !request.params[4].get_str().empty())
942  wtx.mapValue["comment"] = request.params[4].get_str();
943  if (!request.params[5].isNull() && !request.params[5].get_str().empty())
944  wtx.mapValue["to"] = request.params[5].get_str();
945 
946  EnsureWalletIsUnlocked(pwallet);
947 
948  // Check funds
949  CAmount nBalance = pwallet->GetLegacyBalance(ISMINE_SPENDABLE, nMinDepth, &strAccount);
950  if (nAmount > nBalance)
951  throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
952 
953  CCoinControl no_coin_control; // This is a deprecated API
954  SendMoney(pwallet, dest, nAmount, false, wtx, no_coin_control);
955 
956  return wtx.GetHash().GetHex();
957 }
958 
959 
961 {
962  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
963  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
964  return NullUniValue;
965  }
966 
967  if (request.fHelp || request.params.size() < 2 || request.params.size() > 8)
968  throw std::runtime_error(
969  "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" [\"address\",...] replaceable conf_target \"estimate_mode\")\n"
970  "\nSend multiple times. Amounts are double-precision floating point numbers."
971  + HelpRequiringPassphrase(pwallet) + "\n"
972  "\nArguments:\n"
973  "1. \"fromaccount\" (string, required) DEPRECATED. The account to send the funds from. Should be \"\" for the default account\n"
974  "2. \"amounts\" (string, required) A json object with addresses and amounts\n"
975  " {\n"
976  " \"address\":amount (numeric or string) The raven address is the key, the numeric amount (can be string) in " + CURRENCY_UNIT + " is the value\n"
977  " ,...\n"
978  " }\n"
979  "3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n"
980  "4. \"comment\" (string, optional) A comment\n"
981  "5. subtractfeefrom (array, optional) A json array with addresses.\n"
982  " The fee will be equally deducted from the amount of each selected address.\n"
983  " Those recipients will receive less ravens than you enter in their corresponding amount field.\n"
984  " If no addresses are specified here, the sender pays the fee.\n"
985  " [\n"
986  " \"address\" (string) Subtract fee from this address\n"
987  " ,...\n"
988  " ]\n"
989 // "6. replaceable (boolean, optional) Allow this transaction to be replaced by a transaction with higher fees via BIP 125\n"
990  "6. conf_target (numeric, optional) Confirmation target (in blocks)\n"
991  "7. \"estimate_mode\" (string, optional, default=UNSET) The fee estimate mode, must be one of:\n"
992  " \"UNSET\"\n"
993  " \"ECONOMICAL\"\n"
994  " \"CONSERVATIVE\"\n"
995  "\nResult:\n"
996  "\"txid\" (string) The transaction id for the send. Only 1 transaction is created regardless of \n"
997  " the number of addresses.\n"
998  "\nExamples:\n"
999  "\nSend two amounts to two different addresses:\n"
1000  + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") +
1001  "\nSend two amounts to two different addresses setting the confirmation and comment:\n"
1002  + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 6 \"testing\"") +
1003  "\nSend two amounts to two different addresses, subtract fee from amount:\n"
1004  + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 1 \"\" \"[\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\",\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\"]\"") +
1005  "\nAs a json rpc call\n"
1006  + HelpExampleRpc("sendmany", "\"\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"")
1007  );
1008 
1009  ObserveSafeMode();
1010  LOCK2(cs_main, pwallet->cs_wallet);
1011 
1012  if (pwallet->GetBroadcastTransactions() && !g_connman) {
1013  throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
1014  }
1015 
1016  std::string strAccount = AccountFromValue(request.params[0]);
1017  UniValue sendTo = request.params[1].get_obj();
1018  int nMinDepth = 1;
1019  if (!request.params[2].isNull())
1020  nMinDepth = request.params[2].get_int();
1021 
1022  CWalletTx wtx;
1023  wtx.strFromAccount = strAccount;
1024  if (!request.params[3].isNull() && !request.params[3].get_str().empty())
1025  wtx.mapValue["comment"] = request.params[3].get_str();
1026 
1027  UniValue subtractFeeFromAmount(UniValue::VARR);
1028  if (!request.params[4].isNull())
1029  subtractFeeFromAmount = request.params[4].get_array();
1030 
1031  CCoinControl coin_control;
1032 // if (!request.params[5].isNull()) {
1033 // coin_control.signalRbf = request.params[5].get_bool();
1034 // }
1035 
1036  if (!request.params[5].isNull()) {
1037  coin_control.m_confirm_target = ParseConfirmTarget(request.params[6]);
1038  }
1039 
1040  if (!request.params[6].isNull()) {
1041  if (!FeeModeFromString(request.params[7].get_str(), coin_control.m_fee_mode)) {
1042  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid estimate_mode parameter");
1043  }
1044  }
1045 
1046  std::set<CTxDestination> destinations;
1047  std::vector<CRecipient> vecSend;
1048 
1049  CAmount totalAmount = 0;
1050  std::vector<std::string> keys = sendTo.getKeys();
1051  for (const std::string& name_ : keys) {
1052  CTxDestination dest = DecodeDestination(name_);
1053  if (!IsValidDestination(dest)) {
1054  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Raven address: ") + name_);
1055  }
1056 
1057  if (destinations.count(dest)) {
1058  throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + name_);
1059  }
1060  destinations.insert(dest);
1061 
1062  CScript scriptPubKey = GetScriptForDestination(dest);
1063  CAmount nAmount = AmountFromValue(sendTo[name_]);
1064  if (nAmount <= 0)
1065  throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
1066  totalAmount += nAmount;
1067 
1068  bool fSubtractFeeFromAmount = false;
1069  for (unsigned int idx = 0; idx < subtractFeeFromAmount.size(); idx++) {
1070  const UniValue& addr = subtractFeeFromAmount[idx];
1071  if (addr.get_str() == name_)
1072  fSubtractFeeFromAmount = true;
1073  }
1074 
1075  CRecipient recipient = {scriptPubKey, nAmount, fSubtractFeeFromAmount};
1076  vecSend.push_back(recipient);
1077  }
1078 
1079  EnsureWalletIsUnlocked(pwallet);
1080 
1081  // Check funds
1082  CAmount nBalance = pwallet->GetLegacyBalance(ISMINE_SPENDABLE, nMinDepth, &strAccount);
1083  if (totalAmount > nBalance)
1084  throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
1085 
1086  // Send
1087  CReserveKey keyChange(pwallet);
1088  CAmount nFeeRequired = 0;
1089  int nChangePosRet = -1;
1090  std::string strFailReason;
1091  bool fCreated = pwallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, nChangePosRet, strFailReason, coin_control);
1092  if (!fCreated)
1093  throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
1094  CValidationState state;
1095  if (!pwallet->CommitTransaction(wtx, keyChange, g_connman.get(), state)) {
1096  strFailReason = strprintf("Transaction commit failed:: %s", state.GetRejectReason());
1097  throw JSONRPCError(RPC_WALLET_ERROR, strFailReason);
1098  }
1099 
1100  return wtx.GetHash().GetHex();
1101 }
1102 
1103 // Defined in rpc/misc.cpp
1104 extern CScript _createmultisig_redeemScript(CWallet * const pwallet, const UniValue& params);
1105 
1107 {
1108  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1109  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1110  return NullUniValue;
1111  }
1112 
1113  if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
1114  {
1115  std::string msg = "addmultisigaddress nrequired [\"key\",...] ( \"account\" )\n"
1116  "\nAdd a nrequired-to-sign multisignature address to the wallet.\n"
1117  "Each key is a Raven address or hex-encoded public key.\n"
1118  "If 'account' is specified (DEPRECATED), assign address to that account.\n"
1119 
1120  "\nArguments:\n"
1121  "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
1122  "2. \"keys\" (string, required) A json array of raven addresses or hex-encoded public keys\n"
1123  " [\n"
1124  " \"address\" (string) raven address or hex-encoded public key\n"
1125  " ...,\n"
1126  " ]\n"
1127  "3. \"account\" (string, optional) DEPRECATED. An account to assign the addresses to.\n"
1128 
1129  "\nResult:\n"
1130  "\"address\" (string) A raven address associated with the keys.\n"
1131 
1132  "\nExamples:\n"
1133  "\nAdd a multisig address from 2 addresses\n"
1134  + HelpExampleCli("addmultisigaddress", "2 \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") +
1135  "\nAs json rpc call\n"
1136  + HelpExampleRpc("addmultisigaddress", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"")
1137  ;
1138  throw std::runtime_error(msg);
1139  }
1140 
1141  LOCK2(cs_main, pwallet->cs_wallet);
1142 
1143  std::string strAccount;
1144  if (!request.params[2].isNull())
1145  strAccount = AccountFromValue(request.params[2]);
1146 
1147  // Construct using pay-to-script-hash:
1148  CScript inner = _createmultisig_redeemScript(pwallet, request.params);
1149  CScriptID innerID(inner);
1150  pwallet->AddCScript(inner);
1151 
1152  pwallet->SetAddressBook(innerID, strAccount, "send");
1153  return EncodeDestination(innerID);
1154 }
1155 
1156 class Witnessifier : public boost::static_visitor<bool>
1157 {
1158 public:
1159  CWallet * const pwallet;
1161 
1162  explicit Witnessifier(CWallet *_pwallet) : pwallet(_pwallet) {}
1163 
1164  bool operator()(const CNoDestination &dest) const { return false; }
1165 
1166  bool operator()(const CKeyID &keyID) {
1167  if (pwallet) {
1168  CScript basescript = GetScriptForDestination(keyID);
1169  CScript witscript = GetScriptForWitness(basescript);
1170  SignatureData sigs;
1171  // This check is to make sure that the script we created can actually be solved for and signed by us
1172  // if we were to have the private keys. This is just to make sure that the script is valid and that,
1173  // if found in a transaction, we would still accept and relay that transaction.
1174  if (!ProduceSignature(DummySignatureCreator(pwallet), witscript, sigs) ||
1175  !VerifyScript(sigs.scriptSig, witscript, &sigs.scriptWitness, MANDATORY_SCRIPT_VERIFY_FLAGS | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, DummySignatureCreator(pwallet).Checker())) {
1176  return false;
1177  }
1178  pwallet->AddCScript(witscript);
1179  result = CScriptID(witscript);
1180  return true;
1181  }
1182  return false;
1183  }
1184 
1185  bool operator()(const CScriptID &scriptID) {
1186  CScript subscript;
1187  if (pwallet && pwallet->GetCScript(scriptID, subscript)) {
1188  int witnessversion;
1189  std::vector<unsigned char> witprog;
1190  if (subscript.IsWitnessProgram(witnessversion, witprog)) {
1191  result = scriptID;
1192  return true;
1193  }
1194  CScript witscript = GetScriptForWitness(subscript);
1195  SignatureData sigs;
1196  // This check is to make sure that the script we created can actually be solved for and signed by us
1197  // if we were to have the private keys. This is just to make sure that the script is valid and that,
1198  // if found in a transaction, we would still accept and relay that transaction.
1199  if (!ProduceSignature(DummySignatureCreator(pwallet), witscript, sigs) ||
1200  !VerifyScript(sigs.scriptSig, witscript, &sigs.scriptWitness, MANDATORY_SCRIPT_VERIFY_FLAGS | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, DummySignatureCreator(pwallet).Checker())) {
1201  return false;
1202  }
1203  pwallet->AddCScript(witscript);
1204  result = CScriptID(witscript);
1205  return true;
1206  }
1207  return false;
1208  }
1209 };
1210 
1212 {
1213  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1214  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1215  return NullUniValue;
1216  }
1217 
1218  if (request.fHelp || request.params.size() < 1 || request.params.size() > 1)
1219  {
1220  std::string msg = "addwitnessaddress \"address\"\n"
1221  "\nAdd a witness address for a script (with pubkey or redeemscript known).\n"
1222  "It returns the witness script.\n"
1223 
1224  "\nArguments:\n"
1225  "1. \"address\" (string, required) An address known to the wallet\n"
1226 
1227  "\nResult:\n"
1228  "\"witnessaddress\", (string) The value of the new address (P2SH of witness script).\n"
1229  "}\n"
1230  ;
1231  throw std::runtime_error(msg);
1232  }
1233 
1234  {
1235  LOCK(cs_main);
1236  if (!IsWitnessEnabled(chainActive.Tip(), Params().GetConsensus()) && !gArgs.GetBoolArg("-walletprematurewitness", false)) {
1237  throw JSONRPCError(RPC_WALLET_ERROR, "Segregated witness not enabled on network");
1238  }
1239  }
1240 
1241  CTxDestination dest = DecodeDestination(request.params[0].get_str());
1242  if (!IsValidDestination(dest)) {
1243  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Raven address");
1244  }
1245 
1246  Witnessifier w(pwallet);
1247  bool ret = boost::apply_visitor(w, dest);
1248  if (!ret) {
1249  throw JSONRPCError(RPC_WALLET_ERROR, "Public key or redeemscript not known to wallet, or the key is uncompressed");
1250  }
1251 
1252  pwallet->SetAddressBook(w.result, "", "receive");
1253 
1254  return EncodeDestination(w.result);
1255 }
1256 
1258 {
1260  int nConf;
1261  std::vector<uint256> txids;
1264  {
1265  nAmount = 0;
1266  nConf = std::numeric_limits<int>::max();
1267  fIsWatchonly = false;
1268  }
1269 };
1270 
1271 UniValue ListReceived(CWallet * const pwallet, const UniValue& params, bool fByAccounts)
1272 {
1273  // Minimum confirmations
1274  int nMinDepth = 1;
1275  if (!params[0].isNull())
1276  nMinDepth = params[0].get_int();
1277 
1278  // Whether to include empty accounts
1279  bool fIncludeEmpty = false;
1280  if (!params[1].isNull())
1281  fIncludeEmpty = params[1].get_bool();
1282 
1283  isminefilter filter = ISMINE_SPENDABLE;
1284  if(!params[2].isNull())
1285  if(params[2].get_bool())
1286  filter = filter | ISMINE_WATCH_ONLY;
1287 
1288  // Tally
1289  std::map<CTxDestination, tallyitem> mapTally;
1290  for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
1291  const CWalletTx& wtx = pairWtx.second;
1292 
1293  if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx))
1294  continue;
1295 
1296  int nDepth = wtx.GetDepthInMainChain();
1297  if (nDepth < nMinDepth)
1298  continue;
1299 
1300  for (const CTxOut& txout : wtx.tx->vout)
1301  {
1302  CTxDestination address;
1303  if (!ExtractDestination(txout.scriptPubKey, address))
1304  continue;
1305 
1306  isminefilter mine = IsMine(*pwallet, address);
1307  if(!(mine & filter))
1308  continue;
1309 
1310  tallyitem& item = mapTally[address];
1311  item.nAmount += txout.nValue;
1312  item.nConf = std::min(item.nConf, nDepth);
1313  item.txids.push_back(wtx.GetHash());
1314  if (mine & ISMINE_WATCH_ONLY)
1315  item.fIsWatchonly = true;
1316  }
1317  }
1318 
1319  // Reply
1320  UniValue ret(UniValue::VARR);
1321  std::map<std::string, tallyitem> mapAccountTally;
1322  for (const std::pair<CTxDestination, CAddressBookData>& item : pwallet->mapAddressBook) {
1323  const CTxDestination& dest = item.first;
1324  const std::string& strAccount = item.second.name;
1325  std::map<CTxDestination, tallyitem>::iterator it = mapTally.find(dest);
1326  if (it == mapTally.end() && !fIncludeEmpty)
1327  continue;
1328 
1329  CAmount nAmount = 0;
1330  int nConf = std::numeric_limits<int>::max();
1331  bool fIsWatchonly = false;
1332  if (it != mapTally.end())
1333  {
1334  nAmount = (*it).second.nAmount;
1335  nConf = (*it).second.nConf;
1336  fIsWatchonly = (*it).second.fIsWatchonly;
1337  }
1338 
1339  if (fByAccounts)
1340  {
1341  tallyitem& _item = mapAccountTally[strAccount];
1342  _item.nAmount += nAmount;
1343  _item.nConf = std::min(_item.nConf, nConf);
1344  _item.fIsWatchonly = fIsWatchonly;
1345  }
1346  else
1347  {
1348  UniValue obj(UniValue::VOBJ);
1349  if(fIsWatchonly)
1350  obj.push_back(Pair("involvesWatchonly", true));
1351  obj.push_back(Pair("address", EncodeDestination(dest)));
1352  obj.push_back(Pair("account", strAccount));
1353  obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
1354  obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
1355  if (!fByAccounts)
1356  obj.push_back(Pair("label", strAccount));
1357  UniValue transactions(UniValue::VARR);
1358  if (it != mapTally.end())
1359  {
1360  for (const uint256& _item : (*it).second.txids)
1361  {
1362  transactions.push_back(_item.GetHex());
1363  }
1364  }
1365  obj.push_back(Pair("txids", transactions));
1366  ret.push_back(obj);
1367  }
1368  }
1369 
1370  if (fByAccounts)
1371  {
1372  for (std::map<std::string, tallyitem>::iterator it = mapAccountTally.begin(); it != mapAccountTally.end(); ++it)
1373  {
1374  CAmount nAmount = (*it).second.nAmount;
1375  int nConf = (*it).second.nConf;
1376  UniValue obj(UniValue::VOBJ);
1377  if((*it).second.fIsWatchonly)
1378  obj.push_back(Pair("involvesWatchonly", true));
1379  obj.push_back(Pair("account", (*it).first));
1380  obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
1381  obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
1382  ret.push_back(obj);
1383  }
1384  }
1385 
1386  return ret;
1387 }
1388 
1390 {
1391  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1392  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1393  return NullUniValue;
1394  }
1395 
1396  if (request.fHelp || request.params.size() > 3)
1397  throw std::runtime_error(
1398  "listreceivedbyaddress ( minconf include_empty include_watchonly)\n"
1399  "\nList balances by receiving address.\n"
1400  "\nArguments:\n"
1401  "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
1402  "2. include_empty (bool, optional, default=false) Whether to include addresses that haven't received any payments.\n"
1403  "3. include_watchonly (bool, optional, default=false) Whether to include watch-only addresses (see 'importaddress').\n"
1404 
1405  "\nResult:\n"
1406  "[\n"
1407  " {\n"
1408  " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n"
1409  " \"address\" : \"receivingaddress\", (string) The receiving address\n"
1410  " \"account\" : \"accountname\", (string) DEPRECATED. The account of the receiving address. The default account is \"\".\n"
1411  " \"amount\" : x.xxx, (numeric) The total amount in " + CURRENCY_UNIT + " received by the address\n"
1412  " \"confirmations\" : n, (numeric) The number of confirmations of the most recent transaction included\n"
1413  " \"label\" : \"label\", (string) A comment for the address/transaction, if any\n"
1414  " \"txids\": [\n"
1415  " n, (numeric) The ids of transactions received with the address \n"
1416  " ...\n"
1417  " ]\n"
1418  " }\n"
1419  " ,...\n"
1420  "]\n"
1421 
1422  "\nExamples:\n"
1423  + HelpExampleCli("listreceivedbyaddress", "")
1424  + HelpExampleCli("listreceivedbyaddress", "6 true")
1425  + HelpExampleRpc("listreceivedbyaddress", "6, true, true")
1426  );
1427 
1428  ObserveSafeMode();
1429  LOCK2(cs_main, pwallet->cs_wallet);
1430 
1431  return ListReceived(pwallet, request.params, false);
1432 }
1433 
1435 {
1436  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1437  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1438  return NullUniValue;
1439  }
1440 
1441  if (request.fHelp || request.params.size() > 3)
1442  throw std::runtime_error(
1443  "listreceivedbyaccount ( minconf include_empty include_watchonly)\n"
1444  "\nDEPRECATED. List balances by account.\n"
1445  "\nArguments:\n"
1446  "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
1447  "2. include_empty (bool, optional, default=false) Whether to include accounts that haven't received any payments.\n"
1448  "3. include_watchonly (bool, optional, default=false) Whether to include watch-only addresses (see 'importaddress').\n"
1449 
1450  "\nResult:\n"
1451  "[\n"
1452  " {\n"
1453  " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n"
1454  " \"account\" : \"accountname\", (string) The account name of the receiving account\n"
1455  " \"amount\" : x.xxx, (numeric) The total amount received by addresses with this account\n"
1456  " \"confirmations\" : n, (numeric) The number of confirmations of the most recent transaction included\n"
1457  " \"label\" : \"label\" (string) A comment for the address/transaction, if any\n"
1458  " }\n"
1459  " ,...\n"
1460  "]\n"
1461 
1462  "\nExamples:\n"
1463  + HelpExampleCli("listreceivedbyaccount", "")
1464  + HelpExampleCli("listreceivedbyaccount", "6 true")
1465  + HelpExampleRpc("listreceivedbyaccount", "6, true, true")
1466  );
1467 
1468  ObserveSafeMode();
1469  LOCK2(cs_main, pwallet->cs_wallet);
1470 
1471  return ListReceived(pwallet, request.params, true);
1472 }
1473 
1474 static void MaybePushAddress(UniValue & entry, const CTxDestination &dest)
1475 {
1476  if (IsValidDestination(dest)) {
1477  entry.push_back(Pair("address", EncodeDestination(dest)));
1478  }
1479 }
1480 
1492 void ListTransactions(CWallet* const pwallet, const CWalletTx& wtx, const std::string& strAccount, int nMinDepth, bool fLong, UniValue& ret, UniValue& retAssets, const isminefilter& filter)
1493 {
1494  CAmount nFee;
1495  std::string strSentAccount;
1496  std::list<COutputEntry> listReceived;
1497  std::list<COutputEntry> listSent;
1498 
1499  std::list<CAssetOutputEntry> listAssetsReceived;
1500  std::list<CAssetOutputEntry> listAssetsSent;
1501 
1502  wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount, filter, listAssetsReceived, listAssetsSent);
1503 
1504  bool fAllAccounts = (strAccount == std::string("*"));
1505  bool involvesWatchonly = wtx.IsFromMe(ISMINE_WATCH_ONLY);
1506 
1507  // Sent
1508  if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount))
1509  {
1510  for (const COutputEntry& s : listSent)
1511  {
1512  UniValue entry(UniValue::VOBJ);
1513  if (involvesWatchonly || (::IsMine(*pwallet, s.destination) & ISMINE_WATCH_ONLY)) {
1514  entry.push_back(Pair("involvesWatchonly", true));
1515  }
1516  entry.push_back(Pair("account", strSentAccount));
1517  MaybePushAddress(entry, s.destination);
1518  entry.push_back(Pair("category", "send"));
1519  entry.push_back(Pair("amount", ValueFromAmount(-s.amount)));
1520  if (pwallet->mapAddressBook.count(s.destination)) {
1521  entry.push_back(Pair("label", pwallet->mapAddressBook[s.destination].name));
1522  }
1523  entry.push_back(Pair("vout", s.vout));
1524  entry.push_back(Pair("fee", ValueFromAmount(-nFee)));
1525  if (fLong)
1526  WalletTxToJSON(wtx, entry);
1527  entry.push_back(Pair("abandoned", wtx.isAbandoned()));
1528  ret.push_back(entry);
1529  }
1530  }
1531 
1532  // Received
1533  if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth)
1534  {
1535  for (const COutputEntry& r : listReceived)
1536  {
1537  std::string account;
1538  if (pwallet->mapAddressBook.count(r.destination)) {
1539  account = pwallet->mapAddressBook[r.destination].name;
1540  }
1541  if (fAllAccounts || (account == strAccount))
1542  {
1543  UniValue entry(UniValue::VOBJ);
1544  if (involvesWatchonly || (::IsMine(*pwallet, r.destination) & ISMINE_WATCH_ONLY)) {
1545  entry.push_back(Pair("involvesWatchonly", true));
1546  }
1547  entry.push_back(Pair("account", account));
1548  MaybePushAddress(entry, r.destination);
1549  if (wtx.IsCoinBase())
1550  {
1551  if (wtx.GetDepthInMainChain() < 1)
1552  entry.push_back(Pair("category", "orphan"));
1553  else if (wtx.GetBlocksToMaturity() > 0)
1554  entry.push_back(Pair("category", "immature"));
1555  else
1556  entry.push_back(Pair("category", "generate"));
1557  }
1558  else
1559  {
1560  entry.push_back(Pair("category", "receive"));
1561  }
1562  entry.push_back(Pair("amount", ValueFromAmount(r.amount)));
1563  if (pwallet->mapAddressBook.count(r.destination)) {
1564  entry.push_back(Pair("label", account));
1565  }
1566  entry.push_back(Pair("vout", r.vout));
1567  if (fLong)
1568  WalletTxToJSON(wtx, entry);
1569  ret.push_back(entry);
1570  }
1571  }
1572  }
1573 
1575  if (AreAssetsDeployed()) {
1576  if (listAssetsReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth) {
1577  for (const CAssetOutputEntry &data : listAssetsReceived) {
1578  UniValue entry(UniValue::VOBJ);
1579 
1580  entry.push_back(Pair("asset_type", GetTxnOutputType(data.type)));
1581  entry.push_back(Pair("asset_name", data.assetName));
1582  entry.push_back(Pair("amount", ValueFromAmount(data.nAmount)));
1583  entry.push_back(Pair("message", EncodeAssetData(data.message)));
1584  if (!data.message.empty() && data.expireTime > 0)
1585  entry.push_back(Pair("message_expires", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", data.expireTime)));
1586  entry.push_back(Pair("destination", EncodeDestination(data.destination)));
1587  entry.push_back(Pair("vout", data.vout));
1588  entry.push_back(Pair("category", "receive"));
1589  retAssets.push_back(entry);
1590  }
1591  }
1592 
1593  if ((!listAssetsSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount)) {
1594  for (const CAssetOutputEntry &data : listAssetsSent) {
1595  UniValue entry(UniValue::VOBJ);
1596 
1597  entry.push_back(Pair("asset_type", GetTxnOutputType(data.type)));
1598  entry.push_back(Pair("asset_name", data.assetName));
1599  entry.push_back(Pair("amount", ValueFromAmount(data.nAmount)));
1600  entry.push_back(Pair("message", EncodeAssetData(data.message)));
1601  if (!data.message.empty() && data.expireTime > 0)
1602  entry.push_back(Pair("message_expires", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", data.expireTime)));
1603  entry.push_back(Pair("destination", EncodeDestination(data.destination)));
1604  entry.push_back(Pair("vout", data.vout));
1605  entry.push_back(Pair("category", "send"));
1606  retAssets.push_back(entry);
1607  }
1608  }
1609  }
1611 }
1612 
1613 void ListTransactions(CWallet* const pwallet, const CWalletTx& wtx, const std::string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter)
1614 {
1615  UniValue assetDetails(UniValue::VARR);
1616 
1617  ListTransactions(pwallet, wtx, strAccount, nMinDepth, fLong, ret, assetDetails, filter);
1618 }
1619 
1620 void AcentryToJSON(const CAccountingEntry& acentry, const std::string& strAccount, UniValue& ret)
1621 {
1622  bool fAllAccounts = (strAccount == std::string("*"));
1623 
1624  if (fAllAccounts || acentry.strAccount == strAccount)
1625  {
1626  UniValue entry(UniValue::VOBJ);
1627  entry.push_back(Pair("account", acentry.strAccount));
1628  entry.push_back(Pair("category", "move"));
1629  entry.push_back(Pair("time", acentry.nTime));
1630  entry.push_back(Pair("amount", ValueFromAmount(acentry.nCreditDebit)));
1631  entry.push_back(Pair("otheraccount", acentry.strOtherAccount));
1632  entry.push_back(Pair("comment", acentry.strComment));
1633  ret.push_back(entry);
1634  }
1635 }
1636 
1638 {
1639  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1640  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1641  return NullUniValue;
1642  }
1643 
1644  if (request.fHelp || request.params.size() > 4)
1645  throw std::runtime_error(
1646  "listtransactions ( \"account\" count skip include_watchonly)\n"
1647  "\nReturns up to 'count' most recent transactions skipping the first 'from' transactions for account 'account'.\n"
1648  "\nArguments:\n"
1649  "1. \"account\" (string, optional) DEPRECATED. The account name. Should be \"*\".\n"
1650  "2. count (numeric, optional, default=10) The number of transactions to return\n"
1651  "3. skip (numeric, optional, default=0) The number of transactions to skip\n"
1652  "4. include_watchonly (bool, optional, default=false) Include transactions to watch-only addresses (see 'importaddress')\n"
1653  "\nResult:\n"
1654  "[\n"
1655  " {\n"
1656  " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. \n"
1657  " It will be \"\" for the default account.\n"
1658  " \"address\":\"address\", (string) The raven address of the transaction. Not present for \n"
1659  " move transactions (category = move).\n"
1660  " \"category\":\"send|receive|move\", (string) The transaction category. 'move' is a local (off blockchain)\n"
1661  " transaction between accounts, and not associated with an address,\n"
1662  " transaction id or block. 'send' and 'receive' transactions are \n"
1663  " associated with an address, transaction id and block details\n"
1664  " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the\n"
1665  " 'move' category for moves outbound. It is positive for the 'receive' category,\n"
1666  " and for the 'move' category for inbound funds.\n"
1667  " \"label\": \"label\", (string) A comment for the address/transaction, if any\n"
1668  " \"vout\": n, (numeric) the vout value\n"
1669  " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n"
1670  " 'send' category of transactions.\n"
1671  " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and \n"
1672  " 'receive' category of transactions. Negative confirmations indicate the\n"
1673  " transaction conflicts with the block chain\n"
1674  " \"trusted\": xxx, (bool) Whether we consider the outputs of this unconfirmed transaction safe to spend.\n"
1675  " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive'\n"
1676  " category of transactions.\n"
1677  " \"blockindex\": n, (numeric) The index of the transaction in the block that includes it. Available for 'send' and 'receive'\n"
1678  " category of transactions.\n"
1679  " \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n"
1680  " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
1681  " \"time\": xxx, (numeric) The transaction time in seconds since epoch (midnight Jan 1 1970 GMT).\n"
1682  " \"timereceived\": xxx, (numeric) The time received in seconds since epoch (midnight Jan 1 1970 GMT). Available \n"
1683  " for 'send' and 'receive' category of transactions.\n"
1684  " \"comment\": \"...\", (string) If a comment is associated with the transaction.\n"
1685  " \"otheraccount\": \"accountname\", (string) DEPRECATED. For the 'move' category of transactions, the account the funds came \n"
1686  " from (for receiving funds, positive amounts), or went to (for sending funds,\n"
1687  " negative amounts).\n"
1688  " \"bip125-replaceable\": \"yes|no|unknown\", (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n"
1689  " may be unknown for unconfirmed transactions not in the mempool\n"
1690  " \"abandoned\": xxx (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n"
1691  " 'send' category of transactions.\n"
1692  " }\n"
1693  "]\n"
1694 
1695  "\nExamples:\n"
1696  "\nList the most recent 10 transactions in the systems\n"
1697  + HelpExampleCli("listtransactions", "") +
1698  "\nList transactions 100 to 120\n"
1699  + HelpExampleCli("listtransactions", "\"*\" 20 100") +
1700  "\nAs a json rpc call\n"
1701  + HelpExampleRpc("listtransactions", "\"*\", 20, 100")
1702  );
1703 
1704  ObserveSafeMode();
1705  LOCK2(cs_main, pwallet->cs_wallet);
1706 
1707  std::string strAccount = "*";
1708  if (!request.params[0].isNull())
1709  strAccount = request.params[0].get_str();
1710  int nCount = 10;
1711  if (!request.params[1].isNull())
1712  nCount = request.params[1].get_int();
1713  int nFrom = 0;
1714  if (!request.params[2].isNull())
1715  nFrom = request.params[2].get_int();
1716  isminefilter filter = ISMINE_SPENDABLE;
1717  if(!request.params[3].isNull())
1718  if(request.params[3].get_bool())
1719  filter = filter | ISMINE_WATCH_ONLY;
1720 
1721  if (nCount < 0)
1722  throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count");
1723  if (nFrom < 0)
1724  throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from");
1725 
1726  UniValue ret(UniValue::VARR);
1727 
1728  const CWallet::TxItems & txOrdered = pwallet->wtxOrdered;
1729 
1730  // iterate backwards until we have nCount items to return:
1731  for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
1732  {
1733  CWalletTx *const pwtx = (*it).second.first;
1734  if (pwtx != nullptr)
1735  ListTransactions(pwallet, *pwtx, strAccount, 0, true, ret, filter);
1736  CAccountingEntry *const pacentry = (*it).second.second;
1737  if (pacentry != nullptr)
1738  AcentryToJSON(*pacentry, strAccount, ret);
1739 
1740  if ((int)ret.size() >= (nCount+nFrom)) break;
1741  }
1742  // ret is newest to oldest
1743 
1744  if (nFrom > (int)ret.size())
1745  nFrom = ret.size();
1746  if ((nFrom + nCount) > (int)ret.size())
1747  nCount = ret.size() - nFrom;
1748 
1749  std::vector<UniValue> arrTmp = ret.getValues();
1750 
1751  std::vector<UniValue>::iterator first = arrTmp.begin();
1752  std::advance(first, nFrom);
1753  std::vector<UniValue>::iterator last = arrTmp.begin();
1754  std::advance(last, nFrom+nCount);
1755 
1756  if (last != arrTmp.end()) arrTmp.erase(last, arrTmp.end());
1757  if (first != arrTmp.begin()) arrTmp.erase(arrTmp.begin(), first);
1758 
1759  std::reverse(arrTmp.begin(), arrTmp.end()); // Return oldest to newest
1760 
1761  ret.clear();
1762  ret.setArray();
1763  ret.push_backV(arrTmp);
1764 
1765  return ret;
1766 }
1767 
1769 {
1770  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1771  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1772  return NullUniValue;
1773  }
1774 
1775  if (request.fHelp || request.params.size() > 2)
1776  throw std::runtime_error(
1777  "listaccounts ( minconf include_watchonly)\n"
1778  "\nDEPRECATED. Returns Object that has account names as keys, account balances as values.\n"
1779  "\nArguments:\n"
1780  "1. minconf (numeric, optional, default=1) Only include transactions with at least this many confirmations\n"
1781  "2. include_watchonly (bool, optional, default=false) Include balances in watch-only addresses (see 'importaddress')\n"
1782  "\nResult:\n"
1783  "{ (json object where keys are account names, and values are numeric balances\n"
1784  " \"account\": x.xxx, (numeric) The property name is the account name, and the value is the total balance for the account.\n"
1785  " ...\n"
1786  "}\n"
1787  "\nExamples:\n"
1788  "\nList account balances where there at least 1 confirmation\n"
1789  + HelpExampleCli("listaccounts", "") +
1790  "\nList account balances including zero confirmation transactions\n"
1791  + HelpExampleCli("listaccounts", "0") +
1792  "\nList account balances for 6 or more confirmations\n"
1793  + HelpExampleCli("listaccounts", "6") +
1794  "\nAs json rpc call\n"
1795  + HelpExampleRpc("listaccounts", "6")
1796  );
1797 
1798  ObserveSafeMode();
1799  LOCK2(cs_main, pwallet->cs_wallet);
1800 
1801  int nMinDepth = 1;
1802  if (!request.params[0].isNull())
1803  nMinDepth = request.params[0].get_int();
1804  isminefilter includeWatchonly = ISMINE_SPENDABLE;
1805  if(!request.params[1].isNull())
1806  if(request.params[1].get_bool())
1807  includeWatchonly = includeWatchonly | ISMINE_WATCH_ONLY;
1808 
1809  std::map<std::string, CAmount> mapAccountBalances;
1810  for (const std::pair<CTxDestination, CAddressBookData>& entry : pwallet->mapAddressBook) {
1811  if (IsMine(*pwallet, entry.first) & includeWatchonly) { // This address belongs to me
1812  mapAccountBalances[entry.second.name] = 0;
1813  }
1814  }
1815 
1816  for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
1817  const CWalletTx& wtx = pairWtx.second;
1818  CAmount nFee;
1819  std::string strSentAccount;
1820  std::list<COutputEntry> listReceived;
1821  std::list<COutputEntry> listSent;
1822  int nDepth = wtx.GetDepthInMainChain();
1823  if (wtx.GetBlocksToMaturity() > 0 || nDepth < 0)
1824  continue;
1825  wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount, includeWatchonly);
1826  mapAccountBalances[strSentAccount] -= nFee;
1827  for (const COutputEntry& s : listSent)
1828  mapAccountBalances[strSentAccount] -= s.amount;
1829  if (nDepth >= nMinDepth)
1830  {
1831  for (const COutputEntry& r : listReceived)
1832  if (pwallet->mapAddressBook.count(r.destination)) {
1833  mapAccountBalances[pwallet->mapAddressBook[r.destination].name] += r.amount;
1834  }
1835  else
1836  mapAccountBalances[""] += r.amount;
1837  }
1838  }
1839 
1840  const std::list<CAccountingEntry>& acentries = pwallet->laccentries;
1841  for (const CAccountingEntry& entry : acentries)
1842  mapAccountBalances[entry.strAccount] += entry.nCreditDebit;
1843 
1844  UniValue ret(UniValue::VOBJ);
1845  for (const std::pair<std::string, CAmount>& accountBalance : mapAccountBalances) {
1846  ret.push_back(Pair(accountBalance.first, ValueFromAmount(accountBalance.second)));
1847  }
1848  return ret;
1849 }
1850 
1852 {
1853  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1854  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1855  return NullUniValue;
1856  }
1857 
1858  if (request.fHelp || request.params.size() > 4)
1859  throw std::runtime_error(
1860  "listsinceblock ( \"blockhash\" target_confirmations include_watchonly include_removed )\n"
1861  "\nGet all transactions in blocks since block [blockhash], or all transactions if omitted.\n"
1862  "If \"blockhash\" is no longer a part of the main chain, transactions from the fork point onward are included.\n"
1863  "Additionally, if include_removed is set, transactions affecting the wallet which were removed are returned in the \"removed\" array.\n"
1864  "\nArguments:\n"
1865  "1. \"blockhash\" (string, optional) The block hash to list transactions since\n"
1866  "2. target_confirmations: (numeric, optional, default=1) Return the nth block hash from the main chain. e.g. 1 would mean the best block hash. Note: this is not used as a filter, but only affects [lastblock] in the return value\n"
1867  "3. include_watchonly: (bool, optional, default=false) Include transactions to watch-only addresses (see 'importaddress')\n"
1868  "4. include_removed: (bool, optional, default=true) Show transactions that were removed due to a reorg in the \"removed\" array\n"
1869  " (not guaranteed to work on pruned nodes)\n"
1870  "\nResult:\n"
1871  "{\n"
1872  " \"transactions\": [\n"
1873  " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. Will be \"\" for the default account.\n"
1874  " \"address\":\"address\", (string) The raven address of the transaction. Not present for move transactions (category = move).\n"
1875  " \"category\":\"send|receive\", (string) The transaction category. 'send' has negative amounts, 'receive' has positive amounts.\n"
1876  " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the 'move' category for moves \n"
1877  " outbound. It is positive for the 'receive' category, and for the 'move' category for inbound funds.\n"
1878  " \"vout\" : n, (numeric) the vout value\n"
1879  " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the 'send' category of transactions.\n"
1880  " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and 'receive' category of transactions.\n"
1881  " When it's < 0, it means the transaction conflicted that many blocks ago.\n"
1882  " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive' category of transactions.\n"
1883  " \"blockindex\": n, (numeric) The index of the transaction in the block that includes it. Available for 'send' and 'receive' category of transactions.\n"
1884  " \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n"
1885  " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
1886  " \"time\": xxx, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT).\n"
1887  " \"timereceived\": xxx, (numeric) The time received in seconds since epoch (Jan 1 1970 GMT). Available for 'send' and 'receive' category of transactions.\n"
1888  " \"bip125-replaceable\": \"yes|no|unknown\", (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n"
1889  " may be unknown for unconfirmed transactions not in the mempool\n"
1890  " \"abandoned\": xxx, (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the 'send' category of transactions.\n"
1891  " \"comment\": \"...\", (string) If a comment is associated with the transaction.\n"
1892  " \"label\" : \"label\" (string) A comment for the address/transaction, if any\n"
1893  " \"to\": \"...\", (string) If a comment to is associated with the transaction.\n"
1894  " ],\n"
1895  " \"removed\": [\n"
1896  " <structure is the same as \"transactions\" above, only present if include_removed=true>\n"
1897  " Note: transactions that were readded in the active chain will appear as-is in this array, and may thus have a positive confirmation count.\n"
1898  " ],\n"
1899  " \"lastblock\": \"lastblockhash\" (string) The hash of the block (target_confirmations-1) from the best block on the main chain. This is typically used to feed back into listsinceblock the next time you call it. So you would generally use a target_confirmations of say 6, so you will be continually re-notified of transactions until they've reached 6 confirmations plus any new ones\n"
1900  "}\n"
1901  "\nExamples:\n"
1902  + HelpExampleCli("listsinceblock", "")
1903  + HelpExampleCli("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\" 6")
1904  + HelpExampleRpc("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\", 6")
1905  );
1906 
1907  ObserveSafeMode();
1908  LOCK2(cs_main, pwallet->cs_wallet);
1909 
1910  const CBlockIndex* pindex = nullptr; // Block index of the specified block or the common ancestor, if the block provided was in a deactivated chain.
1911  const CBlockIndex* paltindex = nullptr; // Block index of the specified block, even if it's in a deactivated chain.
1912  int target_confirms = 1;
1913  isminefilter filter = ISMINE_SPENDABLE;
1914 
1915  if (!request.params[0].isNull()) {
1916  uint256 blockId;
1917 
1918  blockId.SetHex(request.params[0].get_str());
1919  BlockMap::iterator it = mapBlockIndex.find(blockId);
1920  if (it != mapBlockIndex.end()) {
1921  paltindex = pindex = it->second;
1922  if (chainActive[pindex->nHeight] != pindex) {
1923  // the block being asked for is a part of a deactivated chain;
1924  // we don't want to depend on its perceived height in the block
1925  // chain, we want to instead use the last common ancestor
1926  pindex = chainActive.FindFork(pindex);
1927  }
1928  }
1929  }
1930 
1931  if (!request.params[1].isNull()) {
1932  target_confirms = request.params[1].get_int();
1933 
1934  if (target_confirms < 1) {
1935  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter");
1936  }
1937  }
1938 
1939  if (!request.params[2].isNull() && request.params[2].get_bool()) {
1940  filter = filter | ISMINE_WATCH_ONLY;
1941  }
1942 
1943  bool include_removed = (request.params[3].isNull() || request.params[3].get_bool());
1944 
1945  int depth = pindex ? (1 + chainActive.Height() - pindex->nHeight) : -1;
1946 
1947  UniValue transactions(UniValue::VARR);
1948 
1949  for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
1950  CWalletTx tx = pairWtx.second;
1951 
1952  if (depth == -1 || tx.GetDepthInMainChain() < depth) {
1953  ListTransactions(pwallet, tx, "*", 0, true, transactions, filter);
1954  }
1955  }
1956 
1957  // when a reorg'd block is requested, we also list any relevant transactions
1958  // in the blocks of the chain that was detached
1959  UniValue removed(UniValue::VARR);
1960  while (include_removed && paltindex && paltindex != pindex) {
1961  CBlock block;
1962  if (!ReadBlockFromDisk(block, paltindex, Params().GetConsensus())) {
1963  throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
1964  }
1965  for (const CTransactionRef& tx : block.vtx) {
1966  auto it = pwallet->mapWallet.find(tx->GetHash());
1967  if (it != pwallet->mapWallet.end()) {
1968  // We want all transactions regardless of confirmation count to appear here,
1969  // even negative confirmation ones, hence the big negative.
1970  ListTransactions(pwallet, it->second, "*", -100000000, true, removed, filter);
1971  }
1972  }
1973  paltindex = paltindex->pprev;
1974  }
1975 
1976  CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms];
1977  uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : uint256();
1978 
1979  UniValue ret(UniValue::VOBJ);
1980  ret.push_back(Pair("transactions", transactions));
1981  if (include_removed) ret.push_back(Pair("removed", removed));
1982  ret.push_back(Pair("lastblock", lastblock.GetHex()));
1983 
1984  return ret;
1985 }
1986 
1988 {
1989  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1990  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1991  return NullUniValue;
1992  }
1993 
1994  if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
1995  throw std::runtime_error(
1996  "gettransaction \"txid\" ( include_watchonly )\n"
1997  "\nGet detailed information about in-wallet transaction <txid>\n"
1998  "\nArguments:\n"
1999  "1. \"txid\" (string, required) The transaction id\n"
2000  "2. \"include_watchonly\" (bool, optional, default=false) Whether to include watch-only addresses in balance calculation and details[]\n"
2001  "\nResult:\n"
2002  "{\n"
2003  " \"amount\" : x.xxx, (numeric) The transaction amount in " + CURRENCY_UNIT + "\n"
2004  " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n"
2005  " 'send' category of transactions.\n"
2006  " \"confirmations\" : n, (numeric) The number of confirmations\n"
2007  " \"blockhash\" : \"hash\", (string) The block hash\n"
2008  " \"blockindex\" : xx, (numeric) The index of the transaction in the block that includes it\n"
2009  " \"blocktime\" : ttt, (numeric) The time in seconds since epoch (1 Jan 1970 GMT)\n"
2010  " \"txid\" : \"transactionid\", (string) The transaction id.\n"
2011  " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (1 Jan 1970 GMT)\n"
2012  " \"timereceived\" : ttt, (numeric) The time received in seconds since epoch (1 Jan 1970 GMT)\n"
2013  " \"bip125-replaceable\": \"yes|no|unknown\", (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n"
2014  " may be unknown for unconfirmed transactions not in the mempool\n"
2015  " \"details\" : [\n"
2016  " {\n"
2017  " \"account\" : \"accountname\", (string) DEPRECATED. The account name involved in the transaction, can be \"\" for the default account.\n"
2018  " \"address\" : \"address\", (string) The raven address involved in the transaction\n"
2019  " \"category\" : \"send|receive\", (string) The category, either 'send' or 'receive'\n"
2020  " \"amount\" : x.xxx, (numeric) The amount in " + CURRENCY_UNIT + "\n"
2021  " \"label\" : \"label\", (string) A comment for the address/transaction, if any\n"
2022  " \"vout\" : n, (numeric) the vout value\n"
2023  " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n"
2024  " 'send' category of transactions.\n"
2025  " \"abandoned\": xxx (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n"
2026  " 'send' category of transactions.\n"
2027  " }\n"
2028  " ,...\n"
2029  " ],\n"
2030  " \"asset_details\" : [\n"
2031  " {\n"
2032  " \"asset_type\" : \"new_asset|transfer_asset|reissue_asset\", (string) The type of asset transaction\n"
2033  " \"asset_name\" : \"asset_name\", (string) The name of the asset\n"
2034  " \"amount\" : x.xxx, (numeric) The amount in " + CURRENCY_UNIT + "\n"
2035  " \"address\" : \"address\", (string) The raven address involved in the transaction\n"
2036  " \"vout\" : n, (numeric) the vout value\n"
2037  " \"category\" : \"send|receive\", (string) The category, either 'send' or 'receive'\n"
2038  " }\n"
2039  " ,...\n"
2040  " ],\n"
2041 
2042  " \"hex\" : \"data\" (string) Raw data for transaction\n"
2043  "}\n"
2044 
2045  "\nExamples:\n"
2046  + HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
2047  + HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\" true")
2048  + HelpExampleRpc("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
2049  );
2050 
2051  ObserveSafeMode();
2052  LOCK2(cs_main, pwallet->cs_wallet);
2053 
2054  uint256 hash;
2055  hash.SetHex(request.params[0].get_str());
2056 
2057  isminefilter filter = ISMINE_SPENDABLE;
2058  if(!request.params[1].isNull())
2059  if(request.params[1].get_bool())
2060  filter = filter | ISMINE_WATCH_ONLY;
2061 
2062  UniValue entry(UniValue::VOBJ);
2063  auto it = pwallet->mapWallet.find(hash);
2064  if (it == pwallet->mapWallet.end()) {
2065  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
2066  }
2067  const CWalletTx& wtx = it->second;
2068 
2069  CAmount nCredit = wtx.GetCredit(filter);
2070  CAmount nDebit = wtx.GetDebit(filter);
2071  CAmount nNet = nCredit - nDebit;
2072  CAmount nFee = (wtx.IsFromMe(filter) ? wtx.tx->GetValueOut() - nDebit : 0);
2073 
2074  entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
2075  if (wtx.IsFromMe(filter))
2076  entry.push_back(Pair("fee", ValueFromAmount(nFee)));
2077 
2078  WalletTxToJSON(wtx, entry);
2079 
2080  UniValue details(UniValue::VARR);
2081  UniValue assetDetails(UniValue::VARR);
2082  ListTransactions(pwallet, wtx, "*", 0, false, details, assetDetails, filter);
2083  entry.push_back(Pair("details", details));
2084  entry.push_back(Pair("asset_details", assetDetails));
2085 
2086  std::string strHex = EncodeHexTx(static_cast<CTransaction>(wtx), RPCSerializationFlags());
2087  entry.push_back(Pair("hex", strHex));
2088 
2089  return entry;
2090 }
2091 
2093 {
2094  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2095  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2096  return NullUniValue;
2097  }
2098 
2099  if (request.fHelp || request.params.size() != 1)
2100  throw std::runtime_error(
2101  "abandontransaction \"txid\"\n"
2102  "\nMark in-wallet transaction <txid> as abandoned\n"
2103  "This will mark this transaction and all its in-wallet descendants as abandoned which will allow\n"
2104  "for their inputs to be respent. It can be used to replace \"stuck\" or evicted transactions.\n"
2105  "It only works on transactions which are not included in a block and are not currently in the mempool.\n"
2106  "It has no effect on transactions which are already conflicted or abandoned.\n"
2107  "\nArguments:\n"
2108  "1. \"txid\" (string, required) The transaction id\n"
2109  "\nResult:\n"
2110  "\nExamples:\n"
2111  + HelpExampleCli("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
2112  + HelpExampleRpc("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
2113  );
2114 
2115  ObserveSafeMode();
2116  LOCK2(cs_main, pwallet->cs_wallet);
2117 
2118  uint256 hash;
2119  hash.SetHex(request.params[0].get_str());
2120 
2121  if (!pwallet->mapWallet.count(hash)) {
2122  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
2123  }
2124  if (!pwallet->AbandonTransaction(hash)) {
2125  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not eligible for abandonment");
2126  }
2127 
2128  return NullUniValue;
2129 }
2130 
2131 
2133 {
2134  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2135  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2136  return NullUniValue;
2137  }
2138 
2139  if (request.fHelp || request.params.size() != 1)
2140  throw std::runtime_error(
2141  "backupwallet \"destination\"\n"
2142  "\nSafely copies current wallet file to destination, which can be a directory or a path with filename.\n"
2143  "\nArguments:\n"
2144  "1. \"destination\" (string) The destination directory or file\n"
2145  "\nExamples:\n"
2146  + HelpExampleCli("backupwallet", "\"backup.dat\"")
2147  + HelpExampleRpc("backupwallet", "\"backup.dat\"")
2148  );
2149 
2150  LOCK2(cs_main, pwallet->cs_wallet);
2151 
2152  std::string strDest = request.params[0].get_str();
2153  if (!pwallet->BackupWallet(strDest)) {
2154  throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!");
2155  }
2156 
2157  return NullUniValue;
2158 }
2159 
2160 
2162 {
2163  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2164  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2165  return NullUniValue;
2166  }
2167 
2168  if (request.fHelp || request.params.size() > 1)
2169  throw std::runtime_error(
2170  "keypoolrefill ( newsize )\n"
2171  "\nFills the keypool."
2172  + HelpRequiringPassphrase(pwallet) + "\n"
2173  "\nArguments\n"
2174  "1. newsize (numeric, optional, default=100) The new keypool size\n"
2175  "\nExamples:\n"
2176  + HelpExampleCli("keypoolrefill", "")
2177  + HelpExampleRpc("keypoolrefill", "")
2178  );
2179 
2180  LOCK2(cs_main, pwallet->cs_wallet);
2181 
2182  // 0 is interpreted by TopUpKeyPool() as the default keypool size given by -keypool
2183  unsigned int kpSize = 0;
2184  if (!request.params[0].isNull()) {
2185  if (request.params[0].get_int() < 0)
2186  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected valid size.");
2187  kpSize = (unsigned int)request.params[0].get_int();
2188  }
2189 
2190  EnsureWalletIsUnlocked(pwallet);
2191  pwallet->TopUpKeyPool(kpSize);
2192 
2193  if (pwallet->GetKeyPoolSize() < kpSize) {
2194  throw JSONRPCError(RPC_WALLET_ERROR, "Error refreshing keypool.");
2195  }
2196 
2197  return NullUniValue;
2198 }
2199 
2200 
2201 static void LockWallet(CWallet* pWallet)
2202 {
2203  LOCK(pWallet->cs_wallet);
2204  pWallet->nRelockTime = 0;
2205  pWallet->Lock();
2206 }
2207 
2209 {
2210  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2211  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2212  return NullUniValue;
2213  }
2214 
2215  if (pwallet->IsCrypted() && (request.fHelp || request.params.size() != 2)) {
2216  throw std::runtime_error(
2217  "walletpassphrase \"passphrase\" timeout\n"
2218  "\nStores the wallet decryption key in memory for 'timeout' seconds.\n"
2219  "This is needed prior to performing transactions related to private keys such as sending ravens\n"
2220  "\nArguments:\n"
2221  "1. \"passphrase\" (string, required) The wallet passphrase\n"
2222  "2. timeout (numeric, required) The time to keep the decryption key in seconds.\n"
2223  "\nNote:\n"
2224  "Issuing the walletpassphrase command while the wallet is already unlocked will set a new unlock\n"
2225  "time that overrides the old one.\n"
2226  "\nExamples:\n"
2227  "\nUnlock the wallet for 60 seconds\n"
2228  + HelpExampleCli("walletpassphrase", "\"my pass phrase\" 60") +
2229  "\nLock the wallet again (before 60 seconds)\n"
2230  + HelpExampleCli("walletlock", "") +
2231  "\nAs json rpc call\n"
2232  + HelpExampleRpc("walletpassphrase", "\"my pass phrase\", 60")
2233  );
2234  }
2235 
2236  LOCK2(cs_main, pwallet->cs_wallet);
2237 
2238  if (request.fHelp)
2239  return true;
2240  if (!pwallet->IsCrypted()) {
2241  throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrase was called.");
2242  }
2243 
2244  // Note that the walletpassphrase is stored in request.params[0] which is not mlock()ed
2245  SecureString strWalletPass;
2246  strWalletPass.reserve(100);
2247  // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
2248  // Alternately, find a way to make request.params[0] mlock()'d to begin with.
2249  strWalletPass = request.params[0].get_str().c_str();
2250 
2251  if (strWalletPass.length() > 0)
2252  {
2253  if (!pwallet->Unlock(strWalletPass)) {
2254  throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect.");
2255  }
2256  }
2257  else
2258  throw std::runtime_error(
2259  "walletpassphrase <passphrase> <timeout>\n"
2260  "Stores the wallet decryption key in memory for <timeout> seconds.");
2261 
2262  pwallet->TopUpKeyPool();
2263 
2264  int64_t nSleepTime = request.params[1].get_int64();
2265  pwallet->nRelockTime = GetTime() + nSleepTime;
2266  RPCRunLater(strprintf("lockwallet(%s)", pwallet->GetName()), boost::bind(LockWallet, pwallet), nSleepTime);
2267 
2268  return NullUniValue;
2269 }
2270 
2271 
2273 {
2274  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2275  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2276  return NullUniValue;
2277  }
2278 
2279  if (pwallet->IsCrypted() && (request.fHelp || request.params.size() != 2)) {
2280  throw std::runtime_error(
2281  "walletpassphrasechange \"oldpassphrase\" \"newpassphrase\"\n"
2282  "\nChanges the wallet passphrase from 'oldpassphrase' to 'newpassphrase'.\n"
2283  "\nArguments:\n"
2284  "1. \"oldpassphrase\" (string) The current passphrase\n"
2285  "2. \"newpassphrase\" (string) The new passphrase\n"
2286  "\nExamples:\n"
2287  + HelpExampleCli("walletpassphrasechange", "\"old one\" \"new one\"")
2288  + HelpExampleRpc("walletpassphrasechange", "\"old one\", \"new one\"")
2289  );
2290  }
2291 
2292  LOCK2(cs_main, pwallet->cs_wallet);
2293 
2294  if (request.fHelp)
2295  return true;
2296  if (!pwallet->IsCrypted()) {
2297  throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrasechange was called.");
2298  }
2299 
2300  // TODO: get rid of these .c_str() calls by implementing SecureString::operator=(std::string)
2301  // Alternately, find a way to make request.params[0] mlock()'d to begin with.
2302  SecureString strOldWalletPass;
2303  strOldWalletPass.reserve(100);
2304  strOldWalletPass = request.params[0].get_str().c_str();
2305 
2306  SecureString strNewWalletPass;
2307  strNewWalletPass.reserve(100);
2308  strNewWalletPass = request.params[1].get_str().c_str();
2309 
2310  if (strOldWalletPass.length() < 1 || strNewWalletPass.length() < 1)
2311  throw std::runtime_error(
2312  "walletpassphrasechange <oldpassphrase> <newpassphrase>\n"
2313  "Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>.");
2314 
2315  if (!pwallet->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass)) {
2316  throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect.");
2317  }
2318 
2319  return NullUniValue;
2320 }
2321 
2322 
2324 {
2325  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2326  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2327  return NullUniValue;
2328  }
2329 
2330  if (pwallet->IsCrypted() && (request.fHelp || request.params.size() != 0)) {
2331  throw std::runtime_error(
2332  "walletlock\n"
2333  "\nRemoves the wallet encryption key from memory, locking the wallet.\n"
2334  "After calling this method, you will need to call walletpassphrase again\n"
2335  "before being able to call any methods which require the wallet to be unlocked.\n"
2336  "\nExamples:\n"
2337  "\nSet the passphrase for 2 minutes to perform a transaction\n"
2338  + HelpExampleCli("walletpassphrase", "\"my pass phrase\" 120") +
2339  "\nPerform a send (requires passphrase set)\n"
2340  + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 1.0") +
2341  "\nClear the passphrase since we are done before 2 minutes is up\n"
2342  + HelpExampleCli("walletlock", "") +
2343  "\nAs json rpc call\n"
2344  + HelpExampleRpc("walletlock", "")
2345  );
2346  }
2347 
2348  LOCK2(cs_main, pwallet->cs_wallet);
2349 
2350  if (request.fHelp)
2351  return true;
2352  if (!pwallet->IsCrypted()) {
2353  throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletlock was called.");
2354  }
2355 
2356  pwallet->Lock();
2357  pwallet->nRelockTime = 0;
2358 
2359  return NullUniValue;
2360 }
2361 
2362 
2364 {
2365  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2366  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2367  return NullUniValue;
2368  }
2369 
2370  if (!pwallet->IsCrypted() && (request.fHelp || request.params.size() != 1)) {
2371  throw std::runtime_error(
2372  "encryptwallet \"passphrase\"\n"
2373  "\nEncrypts the wallet with 'passphrase'. This is for first time encryption.\n"
2374  "After this, any calls that interact with private keys such as sending or signing \n"
2375  "will require the passphrase to be set prior the making these calls.\n"
2376  "Use the walletpassphrase call for this, and then walletlock call.\n"
2377  "If the wallet is already encrypted, use the walletpassphrasechange call.\n"
2378  "Note that this will shutdown the server.\n"
2379  "\nArguments:\n"
2380  "1. \"passphrase\" (string) The pass phrase to encrypt the wallet with. It must be at least 1 character, but should be long.\n"
2381  "\nExamples:\n"
2382  "\nEncrypt your wallet\n"
2383  + HelpExampleCli("encryptwallet", "\"my pass phrase\"") +
2384  "\nNow set the passphrase to use the wallet, such as for signing or sending raven\n"
2385  + HelpExampleCli("walletpassphrase", "\"my pass phrase\"") +
2386  "\nNow we can do something like sign\n"
2387  + HelpExampleCli("signmessage", "\"address\" \"test message\"") +
2388  "\nNow lock the wallet again by removing the passphrase\n"
2389  + HelpExampleCli("walletlock", "") +
2390  "\nAs a json rpc call\n"
2391  + HelpExampleRpc("encryptwallet", "\"my pass phrase\"")
2392  );
2393  }
2394 
2395  LOCK2(cs_main, pwallet->cs_wallet);
2396 
2397  if (request.fHelp)
2398  return true;
2399  if (pwallet->IsCrypted()) {
2400  throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an encrypted wallet, but encryptwallet was called.");
2401  }
2402 
2403  // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
2404  // Alternately, find a way to make request.params[0] mlock()'d to begin with.
2405  SecureString strWalletPass;
2406  strWalletPass.reserve(100);
2407  strWalletPass = request.params[0].get_str().c_str();
2408 
2409  if (strWalletPass.length() < 1)
2410  throw std::runtime_error(
2411  "encryptwallet <passphrase>\n"
2412  "Encrypts the wallet with <passphrase>.");
2413 
2414  if (!pwallet->EncryptWallet(strWalletPass)) {
2415  throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Error: Failed to encrypt the wallet.");
2416  }
2417 
2418  // BDB seems to have a bad habit of writing old data into
2419  // slack space in .dat files; that is bad if the old data is
2420  // unencrypted private keys. So:
2421  StartShutdown();
2422  return "wallet encrypted; Raven server stopping, restart to run with encrypted wallet. The keypool has been flushed and a new HD seed was generated (if you are using HD). You need to make a new backup.";
2423 }
2424 
2426 {
2427  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2428  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2429  return NullUniValue;
2430  }
2431 
2432  if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
2433  throw std::runtime_error(
2434  "lockunspent unlock ([{\"txid\":\"txid\",\"vout\":n},...])\n"
2435  "\nUpdates list of temporarily unspendable outputs.\n"
2436  "Temporarily lock (unlock=false) or unlock (unlock=true) specified transaction outputs.\n"
2437  "If no transaction outputs are specified when unlocking then all current locked transaction outputs are unlocked.\n"
2438  "A locked transaction output will not be chosen by automatic coin selection, when spending ravens.\n"
2439  "Locks are stored in memory only. Nodes start with zero locked outputs, and the locked output list\n"
2440  "is always cleared (by virtue of process exit) when a node stops or fails.\n"
2441  "Also see the listunspent call\n"
2442  "\nArguments:\n"
2443  "1. unlock (boolean, required) Whether to unlock (true) or lock (false) the specified transactions\n"
2444  "2. \"transactions\" (string, optional) A json array of objects. Each object the txid (string) vout (numeric)\n"
2445  " [ (json array of json objects)\n"
2446  " {\n"
2447  " \"txid\":\"id\", (string) The transaction id\n"
2448  " \"vout\": n (numeric) The output number\n"
2449  " }\n"
2450  " ,...\n"
2451  " ]\n"
2452 
2453  "\nResult:\n"
2454  "true|false (boolean) Whether the command was successful or not\n"
2455 
2456  "\nExamples:\n"
2457  "\nList the unspent transactions\n"
2458  + HelpExampleCli("listunspent", "") +
2459  "\nLock an unspent transaction\n"
2460  + HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2461  "\nList the locked transactions\n"
2462  + HelpExampleCli("listlockunspent", "") +
2463  "\nUnlock the transaction again\n"
2464  + HelpExampleCli("lockunspent", "true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2465  "\nAs a json rpc call\n"
2466  + HelpExampleRpc("lockunspent", "false, \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"")
2467  );
2468 
2469  LOCK2(cs_main, pwallet->cs_wallet);
2470 
2472 
2473  bool fUnlock = request.params[0].get_bool();
2474 
2475  if (request.params[1].isNull()) {
2476  if (fUnlock)
2477  pwallet->UnlockAllCoins();
2478  return true;
2479  }
2480 
2482 
2483  UniValue outputs = request.params[1].get_array();
2484  for (unsigned int idx = 0; idx < outputs.size(); idx++) {
2485  const UniValue& output = outputs[idx];
2486  if (!output.isObject())
2487  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected object");
2488  const UniValue& o = output.get_obj();
2489 
2490  RPCTypeCheckObj(o,
2491  {
2492  {"txid", UniValueType(UniValue::VSTR)},
2493  {"vout", UniValueType(UniValue::VNUM)},
2494  });
2495 
2496  std::string txid = find_value(o, "txid").get_str();
2497  if (!IsHex(txid))
2498  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected hex txid");
2499 
2500  int nOutput = find_value(o, "vout").get_int();
2501  if (nOutput < 0)
2502  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
2503 
2504  COutPoint outpt(uint256S(txid), nOutput);
2505 
2506  if (fUnlock)
2507  pwallet->UnlockCoin(outpt);
2508  else
2509  pwallet->LockCoin(outpt);
2510  }
2511 
2512  return true;
2513 }
2514 
2516 {
2517  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2518  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2519  return NullUniValue;
2520  }
2521 
2522  if (request.fHelp || request.params.size() > 0)
2523  throw std::runtime_error(
2524  "listlockunspent\n"
2525  "\nReturns list of temporarily unspendable outputs.\n"
2526  "See the lockunspent call to lock and unlock transactions for spending.\n"
2527  "\nResult:\n"
2528  "[\n"
2529  " {\n"
2530  " \"txid\" : \"transactionid\", (string) The transaction id locked\n"
2531  " \"vout\" : n (numeric) The vout value\n"
2532  " }\n"
2533  " ,...\n"
2534  "]\n"
2535  "\nExamples:\n"
2536  "\nList the unspent transactions\n"
2537  + HelpExampleCli("listunspent", "") +
2538  "\nLock an unspent transaction\n"
2539  + HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2540  "\nList the locked transactions\n"
2541  + HelpExampleCli("listlockunspent", "") +
2542  "\nUnlock the transaction again\n"
2543  + HelpExampleCli("lockunspent", "true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2544  "\nAs a json rpc call\n"
2545  + HelpExampleRpc("listlockunspent", "")
2546  );
2547 
2548  ObserveSafeMode();
2549  LOCK2(cs_main, pwallet->cs_wallet);
2550 
2551  std::vector<COutPoint> vOutpts;
2552  pwallet->ListLockedCoins(vOutpts);
2553 
2554  UniValue ret(UniValue::VARR);
2555 
2556  for (COutPoint &outpt : vOutpts) {
2558 
2559  o.push_back(Pair("txid", outpt.hash.GetHex()));
2560  o.push_back(Pair("vout", (int)outpt.n));
2561  ret.push_back(o);
2562  }
2563 
2564  return ret;
2565 }
2566 
2568 {
2569  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2570  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2571  return NullUniValue;
2572  }
2573 
2574  if (request.fHelp || request.params.size() < 1 || request.params.size() > 1)
2575  throw std::runtime_error(
2576  "settxfee amount\n"
2577  "\nSet the transaction fee per kB. Overwrites the paytxfee parameter.\n"
2578  "\nArguments:\n"
2579  "1. amount (numeric or string, required) The transaction fee in " + CURRENCY_UNIT + "/kB\n"
2580  "\nResult\n"
2581  "true|false (boolean) Returns true if successful\n"
2582  "\nExamples:\n"
2583  + HelpExampleCli("settxfee", "0.00001")
2584  + HelpExampleRpc("settxfee", "0.00001")
2585  );
2586 
2587  LOCK2(cs_main, pwallet->cs_wallet);
2588 
2589  // Amount
2590  CAmount nAmount = AmountFromValue(request.params[0]);
2591 
2592  payTxFee = CFeeRate(nAmount, 1000);
2593  return true;
2594 }
2595 
2597 {
2598  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2599  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2600  return NullUniValue;
2601  }
2602 
2603  if (request.fHelp || request.params.size() != 0)
2604  throw std::runtime_error(
2605  "getwalletinfo\n"
2606  "Returns an object containing various wallet state info.\n"
2607  "\nResult:\n"
2608  "{\n"
2609  " \"walletname\": xxxxx, (string) the wallet name\n"
2610  " \"walletversion\": xxxxx, (numeric) the wallet version\n"
2611  " \"balance\": xxxxxxx, (numeric) the total confirmed balance of the wallet in " + CURRENCY_UNIT + "\n"
2612  " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed balance of the wallet in " + CURRENCY_UNIT + "\n"
2613  " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet in " + CURRENCY_UNIT + "\n"
2614  " \"txcount\": xxxxxxx, (numeric) the total number of transactions in the wallet\n"
2615  " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since Unix epoch) of the oldest pre-generated key in the key pool\n"
2616  " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated (only counts external keys)\n"
2617  " \"keypoolsize_hd_internal\": xxxx, (numeric) how many new keys are pre-generated for internal use (used for change outputs, only appears if the wallet is using this feature, otherwise external keys are used)\n"
2618  " \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n"
2619  " \"paytxfee\": x.xxxx, (numeric) the transaction fee configuration, set in " + CURRENCY_UNIT + "/kB\n"
2620  " \"hdseedid\": \"<hash160>\" (string, optional) the Hash160 of the HD seed (only present when HD is enabled)\n"
2621  " \"hdmasterkeyid\": \"<hash160>\" (string, optional) alias for hdseedid retained for backwards-compatibility. Will be removed in V0.18.\n"
2622  "}\n"
2623  "\nExamples:\n"
2624  + HelpExampleCli("getwalletinfo", "")
2625  + HelpExampleRpc("getwalletinfo", "")
2626  );
2627 
2628  ObserveSafeMode();
2629  LOCK2(cs_main, pwallet->cs_wallet);
2630 
2631  UniValue obj(UniValue::VOBJ);
2632 
2633  size_t kpExternalSize = pwallet->KeypoolCountExternalKeys();
2634  obj.push_back(Pair("walletname", pwallet->GetName()));
2635  obj.push_back(Pair("walletversion", pwallet->GetVersion()));
2636  obj.push_back(Pair("balance", ValueFromAmount(pwallet->GetBalance())));
2637  obj.push_back(Pair("unconfirmed_balance", ValueFromAmount(pwallet->GetUnconfirmedBalance())));
2638  obj.push_back(Pair("immature_balance", ValueFromAmount(pwallet->GetImmatureBalance())));
2639  obj.push_back(Pair("txcount", (int)pwallet->mapWallet.size()));
2640  obj.push_back(Pair("keypoololdest", pwallet->GetOldestKeyPoolTime()));
2641  obj.push_back(Pair("keypoolsize", (int64_t)kpExternalSize));
2642  CKeyID seed_id = pwallet->GetHDChain().seed_id;
2643  if (!seed_id.IsNull() && pwallet->CanSupportFeature(FEATURE_HD_SPLIT)) {
2644  obj.push_back(Pair("keypoolsize_hd_internal", (int64_t)(pwallet->GetKeyPoolSize() - kpExternalSize)));
2645  }
2646  if (pwallet->IsCrypted()) {
2647  obj.push_back(Pair("unlocked_until", pwallet->nRelockTime));
2648  }
2649  obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())));
2650  if (!seed_id.IsNull()) {
2651  obj.push_back(Pair("hdseedid", seed_id.GetHex()));
2652  obj.push_back(Pair("hdmasterkeyid", seed_id.GetHex()));
2653  }
2654  return obj;
2655 }
2656 
2658 {
2659  if (request.fHelp || request.params.size() != 0)
2660  throw std::runtime_error(
2661  "listwallets\n"
2662  "Returns a list of currently loaded wallets.\n"
2663  "For full information on the wallet, use \"getwalletinfo\"\n"
2664  "\nResult:\n"
2665  "[ (json array of strings)\n"
2666  " \"walletname\" (string) the wallet name\n"
2667  " ...\n"
2668  "]\n"
2669  "\nExamples:\n"
2670  + HelpExampleCli("listwallets", "")
2671  + HelpExampleRpc("listwallets", "")
2672  );
2673 
2674  UniValue obj(UniValue::VARR);
2675 
2676  for (CWalletRef pwallet : vpwallets) {
2677 
2678  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2679  return NullUniValue;
2680  }
2681 
2682  LOCK(pwallet->cs_wallet);
2683 
2684  obj.push_back(pwallet->GetName());
2685  }
2686 
2687  return obj;
2688 }
2689 
2691 {
2692  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2693  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2694  return NullUniValue;
2695  }
2696 
2697  if (request.fHelp || request.params.size() != 0)
2698  throw std::runtime_error(
2699  "resendwallettransactions\n"
2700  "Immediately re-broadcast unconfirmed wallet transactions to all peers.\n"
2701  "Intended only for testing; the wallet code periodically re-broadcasts\n"
2702  "automatically.\n"
2703  "Returns an RPC error if -walletbroadcast is set to false.\n"
2704  "Returns array of transaction ids that were re-broadcast.\n"
2705  );
2706 
2707  if (!g_connman)
2708  throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
2709 
2710  LOCK2(cs_main, pwallet->cs_wallet);
2711 
2712  if (!pwallet->GetBroadcastTransactions()) {
2713  throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet transaction broadcasting is disabled with -walletbroadcast");
2714  }
2715 
2716  std::vector<uint256> txids = pwallet->ResendWalletTransactionsBefore(GetTime(), g_connman.get());
2718  for (const uint256& txid : txids)
2719  {
2720  result.push_back(txid.ToString());
2721  }
2722  return result;
2723 }
2724 
2726 {
2727  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2728  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2729  return NullUniValue;
2730  }
2731 
2732  if (request.fHelp || request.params.size() > 5)
2733  throw std::runtime_error(
2734  "listunspent ( minconf maxconf [\"addresses\",...] [include_unsafe] [query_options])\n"
2735  "\nReturns array of unspent transaction outputs\n"
2736  "with between minconf and maxconf (inclusive) confirmations.\n"
2737  "Optionally filter to only include txouts paid to specified addresses.\n"
2738  "\nArguments:\n"
2739  "1. minconf (numeric, optional, default=1) The minimum confirmations to filter\n"
2740  "2. maxconf (numeric, optional, default=9999999) The maximum confirmations to filter\n"
2741  "3. \"addresses\" (string) A json array of raven addresses to filter\n"
2742  " [\n"
2743  " \"address\" (string) raven address\n"
2744  " ,...\n"
2745  " ]\n"
2746  "4. include_unsafe (bool, optional, default=true) Include outputs that are not safe to spend\n"
2747  " See description of \"safe\" attribute below.\n"
2748  "5. query_options (json, optional) JSON with query options\n"
2749  " {\n"
2750  " \"minimumAmount\" (numeric or string, default=0) Minimum value of each UTXO in " + CURRENCY_UNIT + "\n"
2751  " \"maximumAmount\" (numeric or string, default=unlimited) Maximum value of each UTXO in " + CURRENCY_UNIT + "\n"
2752  " \"maximumCount\" (numeric or string, default=unlimited) Maximum number of UTXOs\n"
2753  " \"minimumSumAmount\" (numeric or string, default=unlimited) Minimum sum value of all UTXOs in " + CURRENCY_UNIT + "\n"
2754  " }\n"
2755  "\nResult\n"
2756  "[ (array of json object)\n"
2757  " {\n"
2758  " \"txid\" : \"txid\", (string) the transaction id \n"
2759  " \"vout\" : n, (numeric) the vout value\n"
2760  " \"address\" : \"address\", (string) the raven address\n"
2761  " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n"
2762  " \"scriptPubKey\" : \"key\", (string) the script key\n"
2763  " \"amount\" : x.xxx, (numeric) the transaction output amount in " + CURRENCY_UNIT + "\n"
2764  " \"confirmations\" : n, (numeric) The number of confirmations\n"
2765  " \"redeemScript\" : n (string) The redeemScript if scriptPubKey is P2SH\n"
2766  " \"spendable\" : xxx, (bool) Whether we have the private keys to spend this output\n"
2767  " \"solvable\" : xxx, (bool) Whether we know how to spend this output, ignoring the lack of keys\n"
2768  " \"safe\" : xxx (bool) Whether this output is considered safe to spend. Unconfirmed transactions\n"
2769  " from outside keys and unconfirmed replacement transactions are considered unsafe\n"
2770  " and are not eligible for spending by fundrawtransaction and sendtoaddress.\n"
2771  " }\n"
2772  " ,...\n"
2773  "]\n"
2774 
2775  "\nExamples\n"
2776  + HelpExampleCli("listunspent", "")
2777  + HelpExampleCli("listunspent", "6 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"")
2778  + HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"")
2779  + HelpExampleCli("listunspent", "6 9999999 '[]' true '{ \"minimumAmount\": 0.005 }'")
2780  + HelpExampleRpc("listunspent", "6, 9999999, [] , true, { \"minimumAmount\": 0.005 } ")
2781  );
2782 
2783  ObserveSafeMode();
2784 
2785  int nMinDepth = 1;
2786  if (!request.params[0].isNull()) {
2788  nMinDepth = request.params[0].get_int();
2789  }
2790 
2791  int nMaxDepth = 9999999;
2792  if (!request.params[1].isNull()) {
2794  nMaxDepth = request.params[1].get_int();
2795  }
2796 
2797  std::set<CTxDestination> destinations;
2798  if (!request.params[2].isNull()) {
2800  UniValue inputs = request.params[2].get_array();
2801  for (unsigned int idx = 0; idx < inputs.size(); idx++) {
2802  const UniValue& input = inputs[idx];
2803  CTxDestination dest = DecodeDestination(input.get_str());
2804  if (!IsValidDestination(dest)) {
2805  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Raven address: ") + input.get_str());
2806  }
2807  if (!destinations.insert(dest).second) {
2808  throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + input.get_str());
2809  }
2810  }
2811  }
2812 
2813  bool include_unsafe = true;
2814  if (!request.params[3].isNull()) {
2816  include_unsafe = request.params[3].get_bool();
2817  }
2818 
2819  CAmount nMinimumAmount = 0;
2820  CAmount nMaximumAmount = MAX_MONEY;
2821  CAmount nMinimumSumAmount = MAX_MONEY;
2822  uint64_t nMaximumCount = 0;
2823 
2824  if (!request.params[4].isNull()) {
2825  const UniValue& options = request.params[4].get_obj();
2826 
2827  if (options.exists("minimumAmount"))
2828  nMinimumAmount = AmountFromValue(options["minimumAmount"]);
2829 
2830  if (options.exists("maximumAmount"))
2831  nMaximumAmount = AmountFromValue(options["maximumAmount"]);
2832 
2833  if (options.exists("minimumSumAmount"))
2834  nMinimumSumAmount = AmountFromValue(options["minimumSumAmount"]);
2835 
2836  if (options.exists("maximumCount"))
2837  nMaximumCount = options["maximumCount"].get_int64();
2838  }
2839 
2840  UniValue results(UniValue::VARR);
2841  std::vector<COutput> vecOutputs;
2842  assert(pwallet != nullptr);
2843  LOCK2(cs_main, pwallet->cs_wallet);
2844 
2845  pwallet->AvailableCoins(vecOutputs, !include_unsafe, nullptr, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount, nMinDepth, nMaxDepth);
2846  for (const COutput& out : vecOutputs) {
2847  CTxDestination address;
2848  const CScript& scriptPubKey = out.tx->tx->vout[out.i].scriptPubKey;
2849  bool fValidAddress = ExtractDestination(scriptPubKey, address);
2850 
2851  if (destinations.size() && (!fValidAddress || !destinations.count(address)))
2852  continue;
2853 
2854  UniValue entry(UniValue::VOBJ);
2855  entry.push_back(Pair("txid", out.tx->GetHash().GetHex()));
2856  entry.push_back(Pair("vout", out.i));
2857 
2858  if (fValidAddress) {
2859  entry.push_back(Pair("address", EncodeDestination(address)));
2860 
2861  if (pwallet->mapAddressBook.count(address)) {
2862  entry.push_back(Pair("account", pwallet->mapAddressBook[address].name));
2863  }
2864 
2865  if (scriptPubKey.IsPayToScriptHash()) {
2866  const CScriptID& hash = boost::get<CScriptID>(address);
2867  CScript redeemScript;
2868  if (pwallet->GetCScript(hash, redeemScript)) {
2869  entry.push_back(Pair("redeemScript", HexStr(redeemScript.begin(), redeemScript.end())));
2870  }
2871  }
2872  }
2873 
2874  entry.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
2875  entry.push_back(Pair("amount", ValueFromAmount(out.tx->tx->vout[out.i].nValue)));
2876  entry.push_back(Pair("confirmations", out.nDepth));
2877  entry.push_back(Pair("spendable", out.fSpendable));
2878  entry.push_back(Pair("solvable", out.fSolvable));
2879  entry.push_back(Pair("safe", out.fSafe));
2880  results.push_back(entry);
2881  }
2882 
2883  return results;
2884 }
2885 
2887 {
2888  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2889  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2890  return NullUniValue;
2891  }
2892 
2893  if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
2894  throw std::runtime_error(
2895  "fundrawtransaction \"hexstring\" ( options )\n"
2896  "\nAdd inputs to a transaction until it has enough in value to meet its out value.\n"
2897  "This will not modify existing inputs, and will add at most one change output to the outputs.\n"
2898  "No existing outputs will be modified unless \"subtractFeeFromOutputs\" is specified.\n"
2899  "Note that inputs which were signed may need to be resigned after completion since in/outputs have been added.\n"
2900  "The inputs added will not be signed, use signrawtransaction for that.\n"
2901  "Note that all existing inputs must have their previous output transaction be in the wallet.\n"
2902  "Note that all inputs selected must be of standard form and P2SH scripts must be\n"
2903  "in the wallet using importaddress or addmultisigaddress (to calculate fees).\n"
2904  "You can see whether this is the case by checking the \"solvable\" field in the listunspent output.\n"
2905  "Only pay-to-pubkey, multisig, and P2SH versions thereof are currently supported for watch-only\n"
2906  "\nArguments:\n"
2907  "1. \"hexstring\" (string, required) The hex string of the raw transaction\n"
2908  "2. options (object, optional)\n"
2909  " {\n"
2910  " \"changeAddress\" (string, optional, default pool address) The raven address to receive the change\n"
2911  " \"changePosition\" (numeric, optional, default random) The index of the change output\n"
2912  " \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n"
2913  " \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\n"
2914  " \"feeRate\" (numeric, optional, default not set: makes wallet determine the fee) Set a specific fee rate in " + CURRENCY_UNIT + "/kB\n"
2915  " \"subtractFeeFromOutputs\" (array, optional) A json array of integers.\n"
2916  " The fee will be equally deducted from the amount of each specified output.\n"
2917  " The outputs are specified by their zero-based index, before any change output is added.\n"
2918  " Those recipients will receive less ravens than you enter in their corresponding amount field.\n"
2919  " If no outputs are specified here, the sender pays the fee.\n"
2920  " [vout_index,...]\n"
2921 // " \"replaceable\" (boolean, optional) Marks this transaction as BIP125 replaceable.\n"
2922  " Allows this transaction to be replaced by a transaction with higher fees\n"
2923  " \"conf_target\" (numeric, optional) Confirmation target (in blocks)\n"
2924  " \"estimate_mode\" (string, optional, default=UNSET) The fee estimate mode, must be one of:\n"
2925  " \"UNSET\"\n"
2926  " \"ECONOMICAL\"\n"
2927  " \"CONSERVATIVE\"\n"
2928  " }\n"
2929  " for backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}\n"
2930  "\nResult:\n"
2931  "{\n"
2932  " \"hex\": \"value\", (string) The resulting raw transaction (hex-encoded string)\n"
2933  " \"fee\": n, (numeric) Fee in " + CURRENCY_UNIT + " the resulting transaction pays\n"
2934  " \"changepos\": n (numeric) The position of the added change output, or -1\n"
2935  "}\n"
2936  "\nExamples:\n"
2937  "\nCreate a transaction with no inputs\n"
2938  + HelpExampleCli("createrawtransaction", "\"[]\" \"{\\\"myaddress\\\":0.01}\"") +
2939  "\nAdd sufficient unsigned inputs to meet the output value\n"
2940  + HelpExampleCli("fundrawtransaction", "\"rawtransactionhex\"") +
2941  "\nSign the transaction\n"
2942  + HelpExampleCli("signrawtransaction", "\"fundedtransactionhex\"") +
2943  "\nSend the transaction\n"
2944  + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"")
2945  );
2946 
2947  ObserveSafeMode();
2948  RPCTypeCheck(request.params, {UniValue::VSTR});
2949 
2950  CCoinControl coinControl;
2951  int changePosition = -1;
2952  bool lockUnspents = false;
2953  UniValue subtractFeeFromOutputs;
2954  std::set<int> setSubtractFeeFromOutputs;
2955 
2956  if (!request.params[1].isNull()) {
2957  if (request.params[1].type() == UniValue::VBOOL) {
2958  // backward compatibility bool only fallback
2959  coinControl.fAllowWatchOnly = request.params[1].get_bool();
2960  }
2961  else {
2962  RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VOBJ});
2963 
2964  UniValue options = request.params[1];
2965 
2966  RPCTypeCheckObj(options,
2967  {
2968  {"changeAddress", UniValueType(UniValue::VSTR)},
2969  {"changePosition", UniValueType(UniValue::VNUM)},
2970  {"includeWatching", UniValueType(UniValue::VBOOL)},
2971  {"lockUnspents", UniValueType(UniValue::VBOOL)},
2972  {"reserveChangeKey", UniValueType(UniValue::VBOOL)}, // DEPRECATED (and ignored), should be removed in 0.16 or so.
2973  {"feeRate", UniValueType()}, // will be checked below
2974  {"subtractFeeFromOutputs", UniValueType(UniValue::VARR)},
2975 // {"replaceable", UniValueType(UniValue::VBOOL)},
2976  {"conf_target", UniValueType(UniValue::VNUM)},
2977  {"estimate_mode", UniValueType(UniValue::VSTR)},
2978  },
2979  true, true);
2980 
2981  if (options.exists("changeAddress")) {
2982  CTxDestination dest = DecodeDestination(options["changeAddress"].get_str());
2983 
2984  if (!IsValidDestination(dest)) {
2985  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "changeAddress must be a valid raven address");
2986  }
2987 
2988  coinControl.destChange = dest;
2989  }
2990 
2991  if (options.exists("changePosition"))
2992  changePosition = options["changePosition"].get_int();
2993 
2994  if (options.exists("includeWatching"))
2995  coinControl.fAllowWatchOnly = options["includeWatching"].get_bool();
2996 
2997  if (options.exists("lockUnspents"))
2998  lockUnspents = options["lockUnspents"].get_bool();
2999 
3000  if (options.exists("feeRate"))
3001  {
3002  coinControl.m_feerate = CFeeRate(AmountFromValue(options["feeRate"]));
3003  coinControl.fOverrideFeeRate = true;
3004  }
3005 
3006  if (options.exists("subtractFeeFromOutputs"))
3007  subtractFeeFromOutputs = options["subtractFeeFromOutputs"].get_array();
3008 
3009 // if (options.exists("replaceable")) {
3010 // coinControl.signalRbf = options["replaceable"].get_bool();
3011 // }
3012  if (options.exists("conf_target")) {
3013  if (options.exists("feeRate")) {
3014  throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both conf_target and feeRate");
3015  }
3016  coinControl.m_confirm_target = ParseConfirmTarget(options["conf_target"]);
3017  }
3018  if (options.exists("estimate_mode")) {
3019  if (options.exists("feeRate")) {
3020  throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both estimate_mode and feeRate");
3021  }
3022  if (!FeeModeFromString(options["estimate_mode"].get_str(), coinControl.m_fee_mode)) {
3023  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid estimate_mode parameter");
3024  }
3025  }
3026  }
3027  }
3028 
3029  // parse hex string from parameter
3031  if (!DecodeHexTx(tx, request.params[0].get_str(), true))
3032  throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
3033 
3034  if (tx.vout.size() == 0)
3035  throw JSONRPCError(RPC_INVALID_PARAMETER, "TX must have at least one output");
3036 
3037  if (changePosition != -1 && (changePosition < 0 || (unsigned int)changePosition > tx.vout.size()))
3038  throw JSONRPCError(RPC_INVALID_PARAMETER, "changePosition out of bounds");
3039 
3040  for (unsigned int idx = 0; idx < subtractFeeFromOutputs.size(); idx++) {
3041  int pos = subtractFeeFromOutputs[idx].get_int();
3042  if (setSubtractFeeFromOutputs.count(pos))
3043  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, duplicated position: %d", pos));
3044  if (pos < 0)
3045  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, negative position: %d", pos));
3046  if (pos >= int(tx.vout.size()))
3047  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, position too large: %d", pos));
3048  setSubtractFeeFromOutputs.insert(pos);
3049  }
3050 
3051  CAmount nFeeOut;
3052  std::string strFailReason;
3053 
3054  if (!pwallet->FundTransaction(tx, nFeeOut, changePosition, strFailReason, lockUnspents, setSubtractFeeFromOutputs, coinControl)) {
3055  throw JSONRPCError(RPC_WALLET_ERROR, strFailReason);
3056  }
3057 
3059  result.push_back(Pair("hex", EncodeHexTx(tx)));
3060  result.push_back(Pair("changepos", changePosition));
3061  result.push_back(Pair("fee", ValueFromAmount(nFeeOut)));
3062 
3063  return result;
3064 }
3065 
3067 {
3068  throw std::runtime_error("bumpfee has been deprecated on the RVN Wallet.");
3069 
3070 // CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
3071 //
3072 // if (!EnsureWalletIsAvailable(pwallet, request.fHelp))
3073 // return NullUniValue;
3074 //
3075 // if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
3076 // throw std::runtime_error(
3077 // "bumpfee \"txid\" ( options ) \n"
3078 // "\nBumps the fee of an opt-in-RBF transaction T, replacing it with a new transaction B.\n"
3079 // "An opt-in RBF transaction with the given txid must be in the wallet.\n"
3080 // "The command will pay the additional fee by decreasing (or perhaps removing) its change output.\n"
3081 // "If the change output is not big enough to cover the increased fee, the command will currently fail\n"
3082 // "instead of adding new inputs to compensate. (A future implementation could improve this.)\n"
3083 // "The command will fail if the wallet or mempool contains a transaction that spends one of T's outputs.\n"
3084 // "By default, the new fee will be calculated automatically using estimatefee.\n"
3085 // "The user can specify a confirmation target for estimatefee.\n"
3086 // "Alternatively, the user can specify totalFee, or use RPC settxfee to set a higher fee rate.\n"
3087 // "At a minimum, the new fee rate must be high enough to pay an additional new relay fee (incrementalfee\n"
3088 // "returned by getnetworkinfo) to enter the node's mempool.\n"
3089 // "\nArguments:\n"
3090 // "1. txid (string, required) The txid to be bumped\n"
3091 // "2. options (object, optional)\n"
3092 // " {\n"
3093 // " \"confTarget\" (numeric, optional) Confirmation target (in blocks)\n"
3094 // " \"totalFee\" (numeric, optional) Total fee (NOT feerate) to pay, in satoshis.\n"
3095 // " In rare cases, the actual fee paid might be slightly higher than the specified\n"
3096 // " totalFee if the tx change output has to be removed because it is too close to\n"
3097 // " the dust threshold.\n"
3098 // " \"replaceable\" (boolean, optional, default true) Whether the new transaction should still be\n"
3099 // " marked bip-125 replaceable. If true, the sequence numbers in the transaction will\n"
3100 // " be left unchanged from the original. If false, any input sequence numbers in the\n"
3101 // " original transaction that were less than 0xfffffffe will be increased to 0xfffffffe\n"
3102 // " so the new transaction will not be explicitly bip-125 replaceable (though it may\n"
3103 // " still be replaceable in practice, for example if it has unconfirmed ancestors which\n"
3104 // " are replaceable).\n"
3105 // " \"estimate_mode\" (string, optional, default=UNSET) The fee estimate mode, must be one of:\n"
3106 // " \"UNSET\"\n"
3107 // " \"ECONOMICAL\"\n"
3108 // " \"CONSERVATIVE\"\n"
3109 // " }\n"
3110 // "\nResult:\n"
3111 // "{\n"
3112 // " \"txid\": \"value\", (string) The id of the new transaction\n"
3113 // " \"origfee\": n, (numeric) Fee of the replaced transaction\n"
3114 // " \"fee\": n, (numeric) Fee of the new transaction\n"
3115 // " \"errors\": [ str... ] (json array of strings) Errors encountered during processing (may be empty)\n"
3116 // "}\n"
3117 // "\nExamples:\n"
3118 // "\nBump the fee, get the new transaction\'s txid\n" +
3119 // HelpExampleCli("bumpfee", "<txid>"));
3120 // }
3121 //
3122 // RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VOBJ});
3123 // uint256 hash;
3124 // hash.SetHex(request.params[0].get_str());
3125 //
3126 // // optional parameters
3127 // CAmount totalFee = 0;
3128 // CCoinControl coin_control;
3129 // coin_control.signalRbf = true;
3130 // if (!request.params[1].isNull()) {
3131 // UniValue options = request.params[1];
3132 // RPCTypeCheckObj(options,
3133 // {
3134 // {"confTarget", UniValueType(UniValue::VNUM)},
3135 // {"totalFee", UniValueType(UniValue::VNUM)},
3136 // {"replaceable", UniValueType(UniValue::VBOOL)},
3137 // {"estimate_mode", UniValueType(UniValue::VSTR)},
3138 // },
3139 // true, true);
3140 //
3141 // if (options.exists("confTarget") && options.exists("totalFee")) {
3142 // throw JSONRPCError(RPC_INVALID_PARAMETER, "confTarget and totalFee options should not both be set. Please provide either a confirmation target for fee estimation or an explicit total fee for the transaction.");
3143 // } else if (options.exists("confTarget")) { // TODO: alias this to conf_target
3144 // coin_control.m_confirm_target = ParseConfirmTarget(options["confTarget"]);
3145 // } else if (options.exists("totalFee")) {
3146 // totalFee = options["totalFee"].get_int64();
3147 // if (totalFee <= 0) {
3148 // throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid totalFee %s (must be greater than 0)", FormatMoney(totalFee)));
3149 // }
3150 // }
3151 //
3152 // if (options.exists("replaceable")) {
3153 // coin_control.signalRbf = options["replaceable"].get_bool();
3154 // }
3155 // if (options.exists("estimate_mode")) {
3156 // if (!FeeModeFromString(options["estimate_mode"].get_str(), coin_control.m_fee_mode)) {
3157 // throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid estimate_mode parameter");
3158 // }
3159 // }
3160 // }
3161 //
3162 // LOCK2(cs_main, pwallet->cs_wallet);
3163 // EnsureWalletIsUnlocked(pwallet);
3164 //
3165 // CFeeBumper feeBump(pwallet, hash, coin_control, totalFee);
3166 // BumpFeeResult res = feeBump.getResult();
3167 // if (res != BumpFeeResult::OK)
3168 // {
3169 // switch(res) {
3170 // case BumpFeeResult::INVALID_ADDRESS_OR_KEY:
3171 // throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, feeBump.getErrors()[0]);
3172 // break;
3173 // case BumpFeeResult::INVALID_REQUEST:
3174 // throw JSONRPCError(RPC_INVALID_REQUEST, feeBump.getErrors()[0]);
3175 // break;
3176 // case BumpFeeResult::INVALID_PARAMETER:
3177 // throw JSONRPCError(RPC_INVALID_PARAMETER, feeBump.getErrors()[0]);
3178 // break;
3179 // case BumpFeeResult::WALLET_ERROR:
3180 // throw JSONRPCError(RPC_WALLET_ERROR, feeBump.getErrors()[0]);
3181 // break;
3182 // default:
3183 // throw JSONRPCError(RPC_MISC_ERROR, feeBump.getErrors()[0]);
3184 // break;
3185 // }
3186 // }
3187 //
3188 // // sign bumped transaction
3189 // if (!feeBump.signTransaction(pwallet)) {
3190 // throw JSONRPCError(RPC_WALLET_ERROR, "Can't sign transaction.");
3191 // }
3192 // // commit the bumped transaction
3193 // if(!feeBump.commit(pwallet)) {
3194 // throw JSONRPCError(RPC_WALLET_ERROR, feeBump.getErrors()[0]);
3195 // }
3196 // UniValue result(UniValue::VOBJ);
3197 // result.push_back(Pair("txid", feeBump.getBumpedTxId().GetHex()));
3198 // result.push_back(Pair("origfee", ValueFromAmount(feeBump.getOldFee())));
3199 // result.push_back(Pair("fee", ValueFromAmount(feeBump.getNewFee())));
3200 // UniValue errors(UniValue::VARR);
3201 // for (const std::string& err: feeBump.getErrors())
3202 // errors.push_back(err);
3203 // result.push_back(Pair("errors", errors));
3204 //
3205 // return result;
3206 }
3207 
3209 {
3210  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
3211 
3212  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
3213  return NullUniValue;
3214  }
3215 
3216  if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
3217  throw std::runtime_error(
3218  "generate nblocks ( maxtries )\n"
3219  "\nMine up to nblocks blocks immediately (before the RPC call returns) to an address in the wallet.\n"
3220  "\nArguments:\n"
3221  "1. nblocks (numeric, required) How many blocks are generated immediately.\n"
3222  "2. maxtries (numeric, optional) How many iterations to try (default = 1000000).\n"
3223  "\nResult:\n"
3224  "[ blockhashes ] (array) hashes of blocks generated\n"
3225  "\nExamples:\n"
3226  "\nGenerate 11 blocks\n"
3227  + HelpExampleCli("generate", "11")
3228  );
3229  }
3230 
3231  int num_generate = request.params[0].get_int();
3232  uint64_t max_tries = 1000000;
3233  if (!request.params[1].isNull()) {
3234  max_tries = request.params[1].get_int();
3235  }
3236 
3237  std::shared_ptr<CReserveScript> coinbase_script;
3238  pwallet->GetScriptForMining(coinbase_script);
3239 
3240  // If the keypool is exhausted, no script is returned at all. Catch this.
3241  if (!coinbase_script) {
3242  throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
3243  }
3244 
3245  //throw an error if no script was provided
3246  if (coinbase_script->reserveScript.empty()) {
3247  throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available");
3248  }
3249 
3250  return generateBlocks(coinbase_script, num_generate, max_tries, true);
3251 }
3252 
3254 {
3255  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
3256  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
3257  return NullUniValue;
3258  }
3259 
3260  if (request.fHelp || request.params.size() > 2) {
3261  throw std::runtime_error(
3262  "rescanblockchain (\"start_height\") (\"stop_height\")\n"
3263  "\nRescan the local blockchain for wallet related transactions.\n"
3264  "\nArguments:\n"
3265  "1. \"start_height\" (numeric, optional) block height where the rescan should start\n"
3266  "2. \"stop_height\" (numeric, optional) the last block height that should be scanned\n"
3267  "\nResult:\n"
3268  "{\n"
3269  " \"start_height\" (numeric) The block height where the rescan has started. If omitted, rescan started from the genesis block.\n"
3270  " \"stop_height\" (numeric) The height of the last rescanned block. If omitted, rescan stopped at the chain tip.\n"
3271  "}\n"
3272  "\nExamples:\n"
3273  + HelpExampleCli("rescanblockchain", "100000 120000")
3274  + HelpExampleRpc("rescanblockchain", "100000, 120000")
3275  );
3276  }
3277 
3278  LOCK2(cs_main, pwallet->cs_wallet);
3279 
3280  CBlockIndex *pindexStart = chainActive.Genesis();
3281  CBlockIndex *pindexStop = nullptr;
3282  if (!request.params[0].isNull()) {
3283  pindexStart = chainActive[request.params[0].get_int()];
3284  if (!pindexStart) {
3285  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid start_height");
3286  }
3287  }
3288 
3289  if (!request.params[1].isNull()) {
3290  pindexStop = chainActive[request.params[1].get_int()];
3291  if (!pindexStop) {
3292  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid stop_height");
3293  }
3294  else if (pindexStop->nHeight < pindexStart->nHeight) {
3295  throw JSONRPCError(RPC_INVALID_PARAMETER, "stop_height must be greater then start_height");
3296  }
3297  }
3298 
3299  // We can't rescan beyond non-pruned blocks, stop and throw an error
3300  if (fPruneMode) {
3301  CBlockIndex *block = pindexStop ? pindexStop : chainActive.Tip();
3302  while (block && block->nHeight >= pindexStart->nHeight) {
3303  if (!(block->nStatus & BLOCK_HAVE_DATA)) {
3304  throw JSONRPCError(RPC_MISC_ERROR, "Can't rescan beyond pruned data. Use RPC call getblockchaininfo to determine your pruned height.");
3305  }
3306  block = block->pprev;
3307  }
3308  }
3309 
3310  CBlockIndex *stopBlock = pwallet->ScanForWalletTransactions(pindexStart, pindexStop, true);
3311  if (!stopBlock) {
3312  if (pwallet->IsAbortingRescan()) {
3313  throw JSONRPCError(RPC_MISC_ERROR, "Rescan aborted.");
3314  }
3315  // if we got a nullptr returned, ScanForWalletTransactions did rescan up to the requested stopindex
3316  stopBlock = pindexStop ? pindexStop : chainActive.Tip();
3317  }
3318  else {
3319  throw JSONRPCError(RPC_MISC_ERROR, "Rescan failed. Potentially corrupted data files.");
3320  }
3321 
3322  UniValue response(UniValue::VOBJ);
3323  response.pushKV("start_height", pindexStart->nHeight);
3324  response.pushKV("stop_height", stopBlock->nHeight);
3325  return response;
3326 }
3327 
3328 extern UniValue abortrescan(const JSONRPCRequest& request); // in rpcdump.cpp
3329 extern UniValue dumpprivkey(const JSONRPCRequest& request); // in rpcdump.cpp
3330 extern UniValue importprivkey(const JSONRPCRequest& request);
3331 extern UniValue importaddress(const JSONRPCRequest& request);
3332 extern UniValue importpubkey(const JSONRPCRequest& request);
3333 extern UniValue dumpwallet(const JSONRPCRequest& request);
3334 extern UniValue importwallet(const JSONRPCRequest& request);
3335 extern UniValue importprunedfunds(const JSONRPCRequest& request);
3336 extern UniValue removeprunedfunds(const JSONRPCRequest& request);
3337 extern UniValue importmulti(const JSONRPCRequest& request);
3338 extern UniValue rescanblockchain(const JSONRPCRequest& request);
3339 
3340 static const CRPCCommand commands[] =
3341 { // category name actor (function) argNames
3342  // --------------------- ------------------------ ----------------------- ----------
3343  { "rawtransactions", "fundrawtransaction", &fundrawtransaction, {"hexstring","options"} },
3344  { "hidden", "resendwallettransactions", &resendwallettransactions, {} },
3345  { "wallet", "abandontransaction", &abandontransaction, {"txid"} },
3346  { "wallet", "abortrescan", &abortrescan, {} },
3347  { "wallet", "addmultisigaddress", &addmultisigaddress, {"nrequired","keys","account"} },
3348  { "wallet", "addwitnessaddress", &addwitnessaddress, {"address"} },
3349  { "wallet", "backupwallet", &backupwallet, {"destination"} },
3350  { "wallet", "bumpfee", &bumpfee, {"txid", "options"} },
3351  { "wallet", "dumpprivkey", &dumpprivkey, {"address"} },
3352  { "wallet", "dumpwallet", &dumpwallet, {"filename"} },
3353  { "wallet", "encryptwallet", &encryptwallet, {"passphrase"} },
3354  { "wallet", "getaccountaddress", &getaccountaddress, {"account"} },
3355  { "wallet", "getaccount", &getaccount, {"address"} },
3356  { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, {"account"} },
3357  { "wallet", "getbalance", &getbalance, {"account","minconf","include_watchonly"} },
3358  { "wallet", "getnewaddress", &getnewaddress, {"account"} },
3359  { "wallet", "getrawchangeaddress", &getrawchangeaddress, {} },
3360  { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, {"account","minconf"} },
3361  { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, {"address","minconf"} },
3362  { "wallet", "gettransaction", &gettransaction, {"txid","include_watchonly"} },
3363  { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, {} },
3364  { "wallet", "getwalletinfo", &getwalletinfo, {} },
3365  { "wallet", "importmulti", &importmulti, {"requests","options"} },
3366  { "wallet", "importprivkey", &importprivkey, {"privkey","label","rescan"} },
3367  { "wallet", "importwallet", &importwallet, {"filename"} },
3368  { "wallet", "importaddress", &importaddress, {"address","label","rescan","p2sh"} },
3369  { "wallet", "importprunedfunds", &importprunedfunds, {"rawtransaction","txoutproof"} },
3370  { "wallet", "importpubkey", &importpubkey, {"pubkey","label","rescan"} },
3371  { "wallet", "keypoolrefill", &keypoolrefill, {"newsize"} },
3372  { "wallet", "listaccounts", &listaccounts, {"minconf","include_watchonly"} },
3373  { "wallet", "listaddressgroupings", &listaddressgroupings, {} },
3374  { "wallet", "listlockunspent", &listlockunspent, {} },
3375  { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, {"minconf","include_empty","include_watchonly"} },
3376  { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, {"minconf","include_empty","include_watchonly"} },
3377  { "wallet", "listsinceblock", &listsinceblock, {"blockhash","target_confirmations","include_watchonly","include_removed"} },
3378  { "wallet", "listtransactions", &listtransactions, {"account","count","skip","include_watchonly"} },
3379  { "wallet", "listunspent", &listunspent, {"minconf","maxconf","addresses","include_unsafe","query_options"} },
3380  { "wallet", "listwallets", &listwallets, {} },
3381  { "wallet", "lockunspent", &lockunspent, {"unlock","transactions"} },
3382  { "wallet", "move", &movecmd, {"fromaccount","toaccount","amount","minconf","comment"} },
3383  { "wallet", "sendfrom", &sendfrom, {"fromaccount","toaddress","amount","minconf","comment","comment_to"} },
3384  { "wallet", "sendmany", &sendmany, {"fromaccount","amounts","minconf","comment","subtractfeefrom", "conf_target","estimate_mode"} },
3385  { "wallet", "sendtoaddress", &sendtoaddress, {"address","amount","comment","comment_to","subtractfeefromamount", "conf_target","estimate_mode"} },
3386  { "wallet", "setaccount", &setaccount, {"address","account"} },
3387  { "wallet", "settxfee", &settxfee, {"amount"} },
3388  { "wallet", "signmessage", &signmessage, {"address","message"} },
3389  { "wallet", "walletlock", &walletlock, {} },
3390  { "wallet", "walletpassphrasechange", &walletpassphrasechange, {"oldpassphrase","newpassphrase"} },
3391  { "wallet", "walletpassphrase", &walletpassphrase, {"passphrase","timeout"} },
3392  { "wallet", "removeprunedfunds", &removeprunedfunds, {"txid"} },
3393  { "wallet", "rescanblockchain", &rescanblockchain, {"start_height", "stop_height"} },
3394 
3395  { "generating", "generate", &generate, {"nblocks","maxtries"} },
3396 };
3397 
3399 {
3400  for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
3401  t.appendCommand(commands[vcidx].name, &commands[vcidx]);
3402 }
UniValue getunconfirmedbalance(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:818
No wallet specified (error when there are multiple wallets loaded)
Definition: protocol.h:88
CAmount nValue
Definition: transaction.h:140
void RPCTypeCheckObj(const UniValue &o, const std::map< std::string, UniValueType > &typesExpected, bool fAllowNull, bool fStrict)
Definition: server.cpp:83
std::set< std::set< CTxDestination > > GetAddressGroupings()
Definition: wallet.cpp:4145
bool isObject() const
Definition: univalue.h:86
bool CanSupportFeature(enum WalletFeature wf) const
check whether we are allowed to upgrade (or already support) to the named feature ...
Definition: wallet.h:836
UniValue listaccounts(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:1768
void UnlockAllCoins()
Definition: wallet.cpp:4335
void AcentryToJSON(const CAccountingEntry &acentry, const std::string &strAccount, UniValue &ret)
Definition: rpcwallet.cpp:1620
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:89
bool fPruneMode
True if we&#39;re running in -prune mode.
Definition: validation.cpp:89
CAmount GetImmatureBalance() const
Definition: wallet.cpp:2041
const std::vector< UniValue > & getValues() const
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
Definition: standard.cpp:210
Keypool ran out, call keypoolrefill first.
Definition: protocol.h:81
int64_t GetOldestKeyPoolTime()
Definition: wallet.cpp:4090
UniValue listaddressgroupings(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:508
UniValue resendwallettransactions(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2690
UniValue importwallet(const JSONRPCRequest &request)
Definition: rpcdump.cpp:450
UniValue bumpfee(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:3066
UniValue signmessage(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:562
bool fAllowWatchOnly
Includes watch only addresses which match the ISMINE_WATCH_SOLVABLE criteria.
Definition: coincontrol.h:24
Enter the wallet passphrase with walletpassphrase first.
Definition: protocol.h:82
Raven RPC command dispatcher.
Definition: server.h:143
CScript _createmultisig_redeemScript(CWallet *const pwallet, const UniValue &params)
Used by addmultisigaddress / createmultisig:
Definition: misc.cpp:262
bool FeeModeFromString(const std::string &mode_string, FeeEstimateMode &fee_estimate_mode)
Definition: fees.cpp:53
bool AccountMove(std::string strFrom, std::string strTo, CAmount nAmount, std::string strComment="")
Definition: wallet.cpp:774
CScript scriptPubKey
Definition: transaction.h:141
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: chain.h:179
uint32_t nStatus
Verification status of this block. See enum BlockStatus.
Definition: chain.h:209
bool get_bool() const
UniValue abandontransaction(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2092
Definition: block.h:73
boost::optional< unsigned int > m_confirm_target
Override the default confirmation target if set.
Definition: coincontrol.h:30
UniValue keypoolrefill(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2161
std::map< CTxDestination, CAddressBookData > mapAddressBook
Definition: wallet.h:829
std::set< uint256 > GetConflicts() const
Definition: wallet.cpp:1733
CCriticalSection cs_wallet
Definition: wallet.h:751
#define strprintf
Definition: tinyformat.h:1054
bool IsPayToScriptHash() const
Definition: script.cpp:221
UniValue getreceivedbyaddress(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:623
const uint256 & GetHash() const
Definition: wallet.h:277
bool IsFromMe(const isminefilter &filter) const
Definition: wallet.h:478
UniValue getrawchangeaddress(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:224
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, const CScriptWitness *witness, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
std::vector< uint256 > txids
Definition: rpcwallet.cpp:1261
int nIndex
Definition: wallet.h:219
bool IsCrypted() const
Definition: crypter.h:143
CScript scriptSig
Definition: sign.h:64
bool EnsureWalletIsAvailable(CWallet *const pwallet, bool avoidException)
Definition: rpcwallet.cpp:63
UniValue getaddressesbyaccount(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:346
std::string strFromAccount
Definition: wallet.h:336
std::string DateTimeStrFormat(const char *pszFormat, int64_t nTime)
Definition: utiltime.cpp:79
UniValue fundrawtransaction(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2886
TxItems wtxOrdered
Definition: wallet.h:823
CAmount GetDebit(const isminefilter &filter) const
filter decides which addresses will count towards the debit
Definition: wallet.cpp:1745
std::string urlDecode(const std::string &urlEncoded)
Definition: httpserver.cpp:672
bool GetCScript(const CScriptID &hash, CScript &redeemScriptOut) const override
Definition: keystore.cpp:56
bool FundTransaction(CMutableTransaction &tx, CAmount &nFeeRet, int &nChangePosInOut, std::string &strFailReason, bool lockUnspents, const std::set< int > &setSubtractFeeFromOutputs, CCoinControl)
Insert additional inputs into the transaction by calling CreateTransaction();.
Definition: wallet.cpp:3011
int Height() const
Return the maximal height in the chain.
Definition: chain.h:479
void StartShutdown()
Definition: init.cpp:128
uint256 hashBlock
Definition: wallet.h:212
CCriticalSection cs_main
Global state.
Definition: validation.cpp:72
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
Definition: standard.cpp:402
std::string AccountFromValue(const UniValue &value)
Definition: rpcwallet.cpp:126
CTxDestination DecodeDestination(const std::string &str)
Definition: base58.cpp:333
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
Definition: secure.h:57
bool fIsWatchonly
Definition: rpcwallet.cpp:1262
CBlockIndex * ScanForWalletTransactions(CBlockIndex *pindexStart, CBlockIndex *pindexStop, bool fUpdate=false)
Scan the block chain (starting in pindexStart) for transactions from or to us.
Definition: wallet.cpp:1627
isminetype IsMine(const CKeyStore &keystore, const CScript &scriptPubKey, SigVersion sigversion)
Definition: ismine.cpp:32
std::vector< CWalletRef > vpwallets
Definition: wallet.cpp:44
bool operator()(const CKeyID &keyID)
Definition: rpcwallet.cpp:1166
UniValue settxfee(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2567
const std::string & get_str() const
uint8_t isminefilter
used for bitflags of isminetype
Definition: ismine.h:30
CBlockIndex * Genesis() const
Returns the index entry for the genesis block of this chain, or nullptr if none.
Definition: chain.h:443
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: server.cpp:527
const UniValue & get_array() const
const std::string CURRENCY_UNIT
Definition: feerate.cpp:11
unsigned int GetKeyPoolSize()
Definition: wallet.h:1101
bool IsWitnessProgram(int &version, std::vector< unsigned char > &program) const
Definition: script.cpp:368
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: util.cpp:470
int64_t get_int64() const
UniValue listsinceblock(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:1851
UniValue ValueFromAmount(const CAmount &amount, const int8_t units)
Definition: core_write.cpp:38
const std::vector< std::string > & getKeys() const
UniValue getbalance(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:745
bool EncryptWallet(const SecureString &strWalletPassphrase)
Definition: wallet.cpp:594
UniValue getnewaddress(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:134
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:436
bool appendCommand(const std::string &name, const CRPCCommand *pcmd)
Appends a CRPCCommand to the dispatch table.
Definition: server.cpp:299
bool ProduceSignature(const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
Definition: sign.cpp:179
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:143
bool IsNull() const
Definition: uint256.h:33
const std::string strMessageMagic
Definition: validation.cpp:117
bool fOverrideFeeRate
Override automatic min/max checks on fee, m_feerate must be set if true.
Definition: coincontrol.h:26
std::string HelpRequiringPassphrase(CWallet *const pwallet)
Definition: rpcwallet.cpp:56
Coin Control Features.
Definition: coincontrol.h:17
CAmount GetBalance() const
Definition: wallet.cpp:2010
void RPCTypeCheck(const UniValue &params, const std::list< UniValue::VType > &typesExpected, bool fAllowNull)
Type-check arguments; throws JSONRPCError if wrong type given.
Definition: server.cpp:58
Invalid, missing or duplicate parameter.
Definition: protocol.h:54
std::map< CTxDestination, CAmount > GetAddressBalances()
Definition: wallet.cpp:4105
boost::optional< CFeeRate > m_feerate
Override the default payTxFee if set.
Definition: coincontrol.h:28
UniValue listreceivedbyaddress(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:1389
const UniValue & find_value(const UniValue &obj, const std::string &name)
Definition: univalue.cpp:236
UniValue generateBlocks(std::shared_ptr< CReserveScript > coinbaseScript, int nGenerate, uint64_t nMaxTries, bool keepScript)
Generate blocks (mine)
Definition: mining.cpp:111
RVN START.
Definition: wallet.h:191
mapValue_t mapValue
Key/value map with information about the transaction.
Definition: wallet.h:316
bool SignCompact(const uint256 &hash, std::vector< unsigned char > &vchSig) const
Create a compact signature (65 bytes), which allows reconstructing the used public key...
Definition: key.cpp:190
void WalletTxToJSON(const CWalletTx &wtx, UniValue &entry)
Definition: rpcwallet.cpp:87
UniValue getwalletinfo(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2596
std::list< CAccountingEntry > laccentries
Definition: wallet.h:819
int64_t CAmount
Amount in corbies (Can be negative)
Definition: amount.h:13
std::multimap< int64_t, TxPair > TxItems
Definition: wallet.h:822
uint256 GetBlockHash() const
Definition: chain.h:294
bool CreateTransaction(const std::vector< CRecipient > &vecSend, CWalletTx &wtxNew, CReserveKey &reservekey, CAmount &nFeeRet, int &nChangePosInOut, std::string &strFailReason, const CCoinControl &coin_control, bool sign=true)
Definition: wallet.cpp:3089
bool SetAddressBook(const CTxDestination &address, const std::string &strName, const std::string &purpose)
Definition: wallet.cpp:3832
UniValue sendmany(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:960
The wallet passphrase entered was incorrect.
Definition: protocol.h:83
iterator end()
Definition: prevector.h:293
std::string strComment
Definition: wallet.h:597
#define LOCK2(cs1, cs2)
Definition: sync.h:177
std::string name
Definition: server.h:135
size_t KeypoolCountExternalKeys()
Definition: wallet.cpp:3915
void push_back(const T &value)
Definition: prevector.h:412
bool push_back(const UniValue &val)
Definition: univalue.cpp:110
UniValue importaddress(const JSONRPCRequest &request)
Definition: rpcdump.cpp:220
bool CheckFinalTx(const CTransaction &tx, int flags)
Transaction validation functions.
Definition: validation.cpp:255
bool AbandonTransaction(const uint256 &hashTx)
Definition: wallet.cpp:1069
void UnlockCoin(const COutPoint &output)
Definition: wallet.cpp:4329
bool AreAssetsDeployed()
RVN START.
UniValue getreceivedbyaccount(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:685
std::string GetName() const
Get a name for this wallet for logging/debugging purposes.
Definition: wallet.h:763
CTransactionRef tx
Definition: wallet.h:211
UniValue params
Definition: server.h:45
bool AddCScript(const CScript &redeemScript) override
Support for BIP 0013 : see https://github.com/raven/bips/blob/master/bip-0013.mediawiki.
Definition: wallet.cpp:309
bool DecodeHexTx(CMutableTransaction &tx, const std::string &strHexTx, bool fTryNoWitness=false)
Definition: core_read.cpp:112
#define LOCK(cs)
Definition: sync.h:176
bool exists(const std::string &key) const
Definition: univalue.h:77
UniValue listwallets(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2657
bool IsLocked() const
Definition: crypter.h:148
int GetVersion()
get the current wallet format (the oldest client version guaranteed to understand this wallet) ...
Definition: wallet.h:1114
UniValue generate(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:3208
UniValue setaccount(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:262
CTxDestination destChange
Definition: coincontrol.h:20
void RPCTypeCheckArgument(const UniValue &value, UniValue::VType typeExpected)
Type-check one argument; throws JSONRPCError if wrong type given.
Definition: server.cpp:76
Witnessifier(CWallet *_pwallet)
Definition: rpcwallet.cpp:1162
uint256 uint256S(const char *str)
Definition: uint256.h:150
An encapsulated public key.
Definition: pubkey.h:40
void AvailableCoins(std::vector< COutput > &vCoins, bool fOnlySafe=true, const CCoinControl *coinControl=nullptr, const CAmount &nMinimumAmount=1, const CAmount &nMaximumAmount=MAX_MONEY, const CAmount &nMinimumSumAmount=MAX_MONEY, const uint64_t &nMaximumCount=0, const int &nMinDepth=0, const int &nMaxDepth=9999999) const
populate vCoins with vector of available COutputs.
Definition: wallet.cpp:2159
UniValue walletpassphrasechange(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2272
std::string GetRejectReason() const
Definition: validation.h:92
bool IsHex(const std::string &str)
Unexpected type was passed as parameter.
Definition: protocol.h:51
bool IsCoinBase() const
Definition: wallet.h:278
CAmount GetUnconfirmedBalance() const
Definition: wallet.cpp:2026
Command given in wrong wallet encryption state (encrypting an encrypted wallet etc.)
Definition: protocol.h:84
UniValue ListReceived(CWallet *const pwallet, const UniValue &params, bool fByAccounts)
Definition: rpcwallet.cpp:1271
UniValue importprunedfunds(const JSONRPCRequest &request)
Definition: rpcdump.cpp:291
int GetBlocksToMaturity() const
Definition: wallet.cpp:4783
UniValue dumpwallet(const JSONRPCRequest &request)
Definition: rpcdump.cpp:594
CAmount GetLegacyBalance(const isminefilter &filter, int minDepth, const std::string *account) const
Definition: wallet.cpp:2106
const char * GetTxnOutputType(txnouttype t)
Get the name of a txnouttype as a C string, or nullptr if unknown.
Definition: standard.cpp:24
bool IsTrusted() const
Definition: wallet.cpp:1911
UniValue sendfrom(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:888
bool GetReservedKey(CPubKey &pubkey, bool internal=false)
Definition: wallet.cpp:4252
UniValue getaccount(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:310
General application defined errors.
Definition: protocol.h:49
bool pushKV(const std::string &key, const UniValue &val)
Definition: univalue.cpp:135
bool GetKey(const CKeyID &address, CKey &keyOut) const override
Definition: crypter.cpp:242
An output of a transaction.
Definition: transaction.h:137
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).
Definition: validation.cpp:75
int get_int() const
Invalid address or key.
Definition: protocol.h:52
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Raven scriptPubKey for the given CTxDestination.
Definition: standard.cpp:347
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: server.cpp:522
CAmount AmountFromValue(const UniValue &value)
Definition: server.cpp:113
Invalid wallet specified.
Definition: protocol.h:87
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:22
Invalid account name.
Definition: protocol.h:80
std::vector< CTxOut > vout
Definition: transaction.h:392
std::string FormatMoney(const CAmount &n)
Money parsing/formatting utilities.
bool isNull() const
Definition: univalue.h:79
void LockCoin(const COutPoint &output)
Definition: wallet.cpp:4323
UniValue sendtoaddress(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:423
void RPCRunLater(const std::string &name, std::function< void(void)> func, int64_t nSeconds)
Run func nSeconds from now.
Definition: server.cpp:550
CScriptWitness scriptWitness
Definition: sign.h:65
UniValue rescanblockchain(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:3253
UniValue getaccountaddress(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:190
A transaction with a bunch of additional info that only the owner cares about.
Definition: wallet.h:285
void RegisterWalletRPCCommands(CRPCTable &t)
Definition: rpcwallet.cpp:3398
UniValue walletlock(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2323
bool GetBroadcastTransactions() const
Inquire whether this wallet broadcasts transactions.
Definition: wallet.h:1148
Database error.
Definition: protocol.h:55
void KeepKey()
Definition: wallet.cpp:4270
uint256 GetHash()
Definition: hash.h:250
Failed to encrypt the wallet.
Definition: protocol.h:85
bool fHelp
Definition: server.h:46
RVN END.
Definition: validation.h:30
std::vector< uint256 > ResendWalletTransactionsBefore(int64_t nTime, CConnman *connman)
Definition: wallet.cpp:1951
256-bit opaque blob.
Definition: uint256.h:123
void ListTransactions(CWallet *const pwallet, const CWalletTx &wtx, const std::string &strAccount, int nMinDepth, bool fLong, UniValue &ret, UniValue &retAssets, const isminefilter &filter)
List transactions based on the given criteria.
Definition: rpcwallet.cpp:1492
std::set< CTxDestination > GetAccountAddresses(const std::string &strAccount) const
Definition: wallet.cpp:4238
CWallet *const pwallet
Definition: rpcwallet.cpp:1159
ArgsManager gArgs
Definition: util.cpp:94
void GetScriptForMining(std::shared_ptr< CReserveScript > &script)
Definition: wallet.cpp:4310
enum VType type() const
Definition: univalue.h:175
std::vector< CTransactionRef > vtx
Definition: block.h:77
UniValue walletpassphrase(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2208
#define ARRAYLEN(array)
bool setArray()
Definition: univalue.cpp:96
std::string EncodeDestination(const CTxDestination &dest)
Definition: base58.cpp:326
CScriptID result
Definition: rpcwallet.cpp:1160
bool ChangeWalletPassphrase(const SecureString &strOldWalletPassphrase, const SecureString &strNewWalletPassphrase)
Definition: wallet.cpp:386
CAmount GetCredit(const isminefilter &filter) const
Definition: wallet.cpp:1776
int64_t GetTxTime() const
Definition: wallet.cpp:1458
A key allocated from the key pool.
Definition: wallet.h:1193
CAmount nAmount
Definition: rpcwallet.cpp:1259
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: chain.h:172
const CChainParams & Params()
Return the currently selected parameters.
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:396
int RPCSerializationFlags()
Definition: server.cpp:559
bool TopUpKeyPool(unsigned int kpSize=0)
Definition: wallet.cpp:3940
Not enough funds in wallet or account.
Definition: protocol.h:79
const UniValue & get_obj() const
bool push_backV(const std::vector< UniValue > &vec)
Definition: univalue.cpp:119
bool operator()(const CNoDestination &dest) const
Definition: rpcwallet.cpp:1164
std::string URI
Definition: server.h:47
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:30
Internal transfers.
Definition: wallet.h:590
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition: chain.h:448
std::string GetHex() const
Definition: uint256.cpp:22
bool GetAccountPubkey(CPubKey &pubKey, std::string strAccount, bool bForceNew=false)
Definition: wallet.cpp:808
CTxDestination GetAccountAddress(CWallet *const pwallet, std::string strAccount, bool bForceNew=false)
Definition: rpcwallet.cpp:180
UniValue addwitnessaddress(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:1211
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances...
Definition: wallet.h:673
unsigned int ParseConfirmTarget(const UniValue &value)
Check bounds on a command line confirm target.
Definition: mining.cpp:37
std::string EncodeHexTx(const CTransaction &tx, const int serializeFlags=0)
Definition: core_write.cpp:143
Fee rate in satoshis per kilobyte: CAmount / kB.
Definition: feerate.h:20
std::unique_ptr< CConnman > g_connman
Definition: init.cpp:81
const UniValue NullUniValue
Definition: univalue.cpp:15
CWallet * GetWalletForJSONRPCRequest(const JSONRPCRequest &request)
Figures out what wallet, if any, to use for a JSONRPCRequest.
Definition: rpcwallet.cpp:40
UniValue removeprunedfunds(const JSONRPCRequest &request)
Definition: rpcdump.cpp:352
CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE)
Transaction fee set by the user.
Definition: wallet.h:183
iterator begin()
Definition: prevector.h:291
bool IsWitnessEnabled(const CBlockIndex *pindexPrev, const Consensus::Params &params)
Check whether witness commitments are required for block.
std::map< uint256, CWalletTx > mapWallet
Definition: wallet.h:818
void ObserveSafeMode()
Definition: safemode.cpp:7
A reference to a CScript: the Hash160 of its serialization (see script.h)
Definition: standard.h:23
UniValue backupwallet(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2132
bool GetKeyFromPool(CPubKey &key, bool internal=false)
Definition: wallet.cpp:4056
A mutable version of CTransaction.
Definition: transaction.h:389
A writer stream (for serialization) that computes a 256-bit hash.
Definition: hash.h:231
Wallet errors.
Definition: protocol.h:78
bool IsAbortingRescan()
Definition: wallet.h:908
UniValue dumpprivkey(const JSONRPCRequest &request)
Definition: rpcdump.cpp:551
FeeEstimateMode m_fee_mode
Fee estimation mode to control arguments to estimateSmartFee.
Definition: coincontrol.h:34
UniValue JSONRPCError(int code, const std::string &message)
Definition: protocol.cpp:55
void clear()
Definition: univalue.cpp:17
No valid connection manager instance found.
Definition: protocol.h:75
size_t size() const
Definition: univalue.h:70
int64_t GetTime()
GetTimeMicros() and GetTimeMillis() both return the system time, but in different units...
Definition: utiltime.cpp:20
unsigned int nTimeReceived
time received by this node
Definition: wallet.h:319
An encapsulated private key.
Definition: key.h:36
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:185
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:61
bool ReadBlockFromDisk(CBlock &block, const CDiskBlockPos &pos, const Consensus::Params &consensusParams)
Functions for disk access for blocks.
void ListLockedCoins(std::vector< COutPoint > &vOutpts) const
Definition: wallet.cpp:4349
UniValue abortrescan(const JSONRPCRequest &request)
Definition: rpcdump.cpp:159
UniValue listunspent(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2725
full block available in blk*.dat
Definition: chain.h:156
UniValue gettransaction(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:1987
const CHDChain & GetHDChain() const
Definition: wallet.h:1174
CKeyID seed_id
seed hash160
Definition: walletdb.h:66
bool BackupWallet(const std::string &strDest)
Definition: wallet.cpp:4731
UniValue importmulti(const JSONRPCRequest &request)
Definition: rpcdump.cpp:1032
void SetHex(const char *psz)
Definition: uint256.cpp:28
UniValue lockunspent(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2425
UniValue importprivkey(const JSONRPCRequest &request)
Definition: rpcdump.cpp:75
UniValue importpubkey(const JSONRPCRequest &request)
Definition: rpcdump.cpp:390
UniValue listtransactions(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:1637
const CBlockIndex * FindFork(const CBlockIndex *pindex) const
Find the last common block between this chain and a block index entry.
Definition: chain.cpp:52
std::string strOtherAccount
Definition: wallet.h:596
CScript GetScriptForWitness(const CScript &redeemscript)
Generate a pay-to-witness script for the given redeem script.
Definition: standard.cpp:379
std::string EncodeAssetData(std::string decoded)
Definition: assets.cpp:3716
bool operator()(const CScriptID &scriptID)
Definition: rpcwallet.cpp:1185
int GetDepthInMainChain(const CBlockIndex *&pindexRet) const
Return depth of transaction in blockchain: <0 : conflicts with a transaction this deep in the blockch...
Definition: wallet.cpp:4764
BlockMap mapBlockIndex
Definition: validation.cpp:74
CAmount GetFeePerK() const
Return the fee in satoshis for a size of 1000 bytes.
Definition: feerate.h:42
UniValue listlockunspent(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2515
Wrapper for UniValue::VType, which includes typeAny: Used to denote don&#39;t care type.
Definition: server.h:33
UniValue movecmd(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:837
int64_t nRelockTime
Holds a timestamp at which point the wallet is scheduled (externally) to be relocked. Caller must arrange for actual relocking to occur via Lock().
Definition: wallet.h:952
CAmount nCreditDebit
Definition: wallet.h:594
int64_t nTime
Definition: wallet.h:595
UniValue encryptwallet(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2363
Error parsing or validating structure in raw format.
Definition: protocol.h:56
std::string EncodeBase64(const unsigned char *pch, size_t len)
A signature creator that just produces 72-byte empty signatures.
Definition: sign.h:56
bool Unlock(const SecureString &strWalletPassphrase)
Definition: wallet.cpp:366
void EnsureWalletIsUnlocked(CWallet *const pwallet)
Definition: rpcwallet.cpp:80
bool isAbandoned() const
Definition: wallet.h:274
UniValue listreceivedbyaccount(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:1434
bool CommitTransaction(CWalletTx &wtxNew, CReserveKey &reservekey, CConnman *connman, CValidationState &state)
RVN END.
Definition: wallet.cpp:3683
void GetAmounts(std::list< COutputEntry > &listReceived, std::list< COutputEntry > &listSent, CAmount &nFee, std::string &strSentAccount, const isminefilter &filter) const
Definition: wallet.cpp:1503
std::string strAccount
Definition: wallet.h:593
UniValue addmultisigaddress(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:1106