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