Merge #10027: Set to nullptr after delete
[bitcoinplatinum.git] / src / wallet / rpcwallet.cpp
blob84e7eb60d70d9fae3bdaae7f04f9f08fecaf2052
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 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.
6 #include "amount.h"
7 #include "base58.h"
8 #include "chain.h"
9 #include "consensus/validation.h"
10 #include "core_io.h"
11 #include "init.h"
12 #include "validation.h"
13 #include "net.h"
14 #include "policy/policy.h"
15 #include "policy/rbf.h"
16 #include "rpc/server.h"
17 #include "script/sign.h"
18 #include "timedata.h"
19 #include "util.h"
20 #include "utilmoneystr.h"
21 #include "wallet.h"
22 #include "walletdb.h"
24 #include <stdint.h>
26 #include <boost/assign/list_of.hpp>
28 #include <univalue.h>
30 CWallet *GetWalletForJSONRPCRequest(const JSONRPCRequest& request)
32 return pwalletMain;
35 std::string HelpRequiringPassphrase(CWallet * const pwallet)
37 return pwallet && pwallet->IsCrypted()
38 ? "\nRequires wallet passphrase to be set with walletpassphrase call."
39 : "";
42 bool EnsureWalletIsAvailable(CWallet * const pwallet, bool avoidException)
44 if (!pwallet) {
45 if (!avoidException)
46 throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
47 else
48 return false;
50 return true;
53 void EnsureWalletIsUnlocked(CWallet * const pwallet)
55 if (pwallet->IsLocked()) {
56 throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first.");
60 void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry)
62 int confirms = wtx.GetDepthInMainChain();
63 entry.push_back(Pair("confirmations", confirms));
64 if (wtx.IsCoinBase())
65 entry.push_back(Pair("generated", true));
66 if (confirms > 0)
68 entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex()));
69 entry.push_back(Pair("blockindex", wtx.nIndex));
70 entry.push_back(Pair("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime()));
71 } else {
72 entry.push_back(Pair("trusted", wtx.IsTrusted()));
74 uint256 hash = wtx.GetHash();
75 entry.push_back(Pair("txid", hash.GetHex()));
76 UniValue conflicts(UniValue::VARR);
77 BOOST_FOREACH(const uint256& conflict, wtx.GetConflicts())
78 conflicts.push_back(conflict.GetHex());
79 entry.push_back(Pair("walletconflicts", conflicts));
80 entry.push_back(Pair("time", wtx.GetTxTime()));
81 entry.push_back(Pair("timereceived", (int64_t)wtx.nTimeReceived));
83 // Add opt-in RBF status
84 std::string rbfStatus = "no";
85 if (confirms <= 0) {
86 LOCK(mempool.cs);
87 RBFTransactionState rbfState = IsRBFOptIn(wtx, mempool);
88 if (rbfState == RBF_TRANSACTIONSTATE_UNKNOWN)
89 rbfStatus = "unknown";
90 else if (rbfState == RBF_TRANSACTIONSTATE_REPLACEABLE_BIP125)
91 rbfStatus = "yes";
93 entry.push_back(Pair("bip125-replaceable", rbfStatus));
95 BOOST_FOREACH(const PAIRTYPE(std::string, std::string)& item, wtx.mapValue)
96 entry.push_back(Pair(item.first, item.second));
99 std::string AccountFromValue(const UniValue& value)
101 std::string strAccount = value.get_str();
102 if (strAccount == "*")
103 throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Invalid account name");
104 return strAccount;
107 UniValue getnewaddress(const JSONRPCRequest& request)
109 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
110 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
111 return NullUniValue;
114 if (request.fHelp || request.params.size() > 1)
115 throw std::runtime_error(
116 "getnewaddress ( \"account\" )\n"
117 "\nReturns a new Bitcoin address for receiving payments.\n"
118 "If 'account' is specified (DEPRECATED), it is added to the address book \n"
119 "so payments received with the address will be credited to 'account'.\n"
120 "\nArguments:\n"
121 "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"
122 "\nResult:\n"
123 "\"address\" (string) The new bitcoin address\n"
124 "\nExamples:\n"
125 + HelpExampleCli("getnewaddress", "")
126 + HelpExampleRpc("getnewaddress", "")
129 LOCK2(cs_main, pwallet->cs_wallet);
131 // Parse the account first so we don't generate a key if there's an error
132 std::string strAccount;
133 if (request.params.size() > 0)
134 strAccount = AccountFromValue(request.params[0]);
136 if (!pwallet->IsLocked()) {
137 pwallet->TopUpKeyPool();
140 // Generate a new key that is added to wallet
141 CPubKey newKey;
142 if (!pwallet->GetKeyFromPool(newKey)) {
143 throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
145 CKeyID keyID = newKey.GetID();
147 pwallet->SetAddressBook(keyID, strAccount, "receive");
149 return CBitcoinAddress(keyID).ToString();
153 CBitcoinAddress GetAccountAddress(CWallet* const pwallet, std::string strAccount, bool bForceNew=false)
155 CPubKey pubKey;
156 if (!pwallet->GetAccountPubkey(pubKey, strAccount, bForceNew)) {
157 throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
160 return CBitcoinAddress(pubKey.GetID());
163 UniValue getaccountaddress(const JSONRPCRequest& request)
165 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
166 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
167 return NullUniValue;
170 if (request.fHelp || request.params.size() != 1)
171 throw std::runtime_error(
172 "getaccountaddress \"account\"\n"
173 "\nDEPRECATED. Returns the current Bitcoin address for receiving payments to this account.\n"
174 "\nArguments:\n"
175 "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"
176 "\nResult:\n"
177 "\"address\" (string) The account bitcoin address\n"
178 "\nExamples:\n"
179 + HelpExampleCli("getaccountaddress", "")
180 + HelpExampleCli("getaccountaddress", "\"\"")
181 + HelpExampleCli("getaccountaddress", "\"myaccount\"")
182 + HelpExampleRpc("getaccountaddress", "\"myaccount\"")
185 LOCK2(cs_main, pwallet->cs_wallet);
187 // Parse the account first so we don't generate a key if there's an error
188 std::string strAccount = AccountFromValue(request.params[0]);
190 UniValue ret(UniValue::VSTR);
192 ret = GetAccountAddress(pwallet, strAccount).ToString();
193 return ret;
197 UniValue getrawchangeaddress(const JSONRPCRequest& request)
199 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
200 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
201 return NullUniValue;
204 if (request.fHelp || request.params.size() > 1)
205 throw std::runtime_error(
206 "getrawchangeaddress\n"
207 "\nReturns a new Bitcoin address, for receiving change.\n"
208 "This is for use with raw transactions, NOT normal use.\n"
209 "\nResult:\n"
210 "\"address\" (string) The address\n"
211 "\nExamples:\n"
212 + HelpExampleCli("getrawchangeaddress", "")
213 + HelpExampleRpc("getrawchangeaddress", "")
216 LOCK2(cs_main, pwallet->cs_wallet);
218 if (!pwallet->IsLocked()) {
219 pwallet->TopUpKeyPool();
222 CReserveKey reservekey(pwallet);
223 CPubKey vchPubKey;
224 if (!reservekey.GetReservedKey(vchPubKey))
225 throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
227 reservekey.KeepKey();
229 CKeyID keyID = vchPubKey.GetID();
231 return CBitcoinAddress(keyID).ToString();
235 UniValue setaccount(const JSONRPCRequest& request)
237 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
238 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
239 return NullUniValue;
242 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
243 throw std::runtime_error(
244 "setaccount \"address\" \"account\"\n"
245 "\nDEPRECATED. Sets the account associated with the given address.\n"
246 "\nArguments:\n"
247 "1. \"address\" (string, required) The bitcoin address to be associated with an account.\n"
248 "2. \"account\" (string, required) The account to assign the address to.\n"
249 "\nExamples:\n"
250 + HelpExampleCli("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"tabby\"")
251 + HelpExampleRpc("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"tabby\"")
254 LOCK2(cs_main, pwallet->cs_wallet);
256 CBitcoinAddress address(request.params[0].get_str());
257 if (!address.IsValid())
258 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
260 std::string strAccount;
261 if (request.params.size() > 1)
262 strAccount = AccountFromValue(request.params[1]);
264 // Only add the account if the address is yours.
265 if (IsMine(*pwallet, address.Get())) {
266 // Detect when changing the account of an address that is the 'unused current key' of another account:
267 if (pwallet->mapAddressBook.count(address.Get())) {
268 std::string strOldAccount = pwallet->mapAddressBook[address.Get()].name;
269 if (address == GetAccountAddress(pwallet, strOldAccount)) {
270 GetAccountAddress(pwallet, strOldAccount, true);
273 pwallet->SetAddressBook(address.Get(), strAccount, "receive");
275 else
276 throw JSONRPCError(RPC_MISC_ERROR, "setaccount can only be used with own address");
278 return NullUniValue;
282 UniValue getaccount(const JSONRPCRequest& request)
284 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
285 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
286 return NullUniValue;
289 if (request.fHelp || request.params.size() != 1)
290 throw std::runtime_error(
291 "getaccount \"address\"\n"
292 "\nDEPRECATED. Returns the account associated with the given address.\n"
293 "\nArguments:\n"
294 "1. \"address\" (string, required) The bitcoin address for account lookup.\n"
295 "\nResult:\n"
296 "\"accountname\" (string) the account address\n"
297 "\nExamples:\n"
298 + HelpExampleCli("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"")
299 + HelpExampleRpc("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"")
302 LOCK2(cs_main, pwallet->cs_wallet);
304 CBitcoinAddress address(request.params[0].get_str());
305 if (!address.IsValid())
306 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
308 std::string strAccount;
309 std::map<CTxDestination, CAddressBookData>::iterator mi = pwallet->mapAddressBook.find(address.Get());
310 if (mi != pwallet->mapAddressBook.end() && !(*mi).second.name.empty()) {
311 strAccount = (*mi).second.name;
313 return strAccount;
317 UniValue getaddressesbyaccount(const JSONRPCRequest& request)
319 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
320 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
321 return NullUniValue;
324 if (request.fHelp || request.params.size() != 1)
325 throw std::runtime_error(
326 "getaddressesbyaccount \"account\"\n"
327 "\nDEPRECATED. Returns the list of addresses for the given account.\n"
328 "\nArguments:\n"
329 "1. \"account\" (string, required) The account name.\n"
330 "\nResult:\n"
331 "[ (json array of string)\n"
332 " \"address\" (string) a bitcoin address associated with the given account\n"
333 " ,...\n"
334 "]\n"
335 "\nExamples:\n"
336 + HelpExampleCli("getaddressesbyaccount", "\"tabby\"")
337 + HelpExampleRpc("getaddressesbyaccount", "\"tabby\"")
340 LOCK2(cs_main, pwallet->cs_wallet);
342 std::string strAccount = AccountFromValue(request.params[0]);
344 // Find all addresses that have the given account
345 UniValue ret(UniValue::VARR);
346 for (const std::pair<CBitcoinAddress, CAddressBookData>& item : pwallet->mapAddressBook) {
347 const CBitcoinAddress& address = item.first;
348 const std::string& strName = item.second.name;
349 if (strName == strAccount)
350 ret.push_back(address.ToString());
352 return ret;
355 static void SendMoney(CWallet * const pwallet, const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew)
357 CAmount curBalance = pwallet->GetBalance();
359 // Check amount
360 if (nValue <= 0)
361 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount");
363 if (nValue > curBalance)
364 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds");
366 if (pwallet->GetBroadcastTransactions() && !g_connman) {
367 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
370 // Parse Bitcoin address
371 CScript scriptPubKey = GetScriptForDestination(address);
373 // Create and send the transaction
374 CReserveKey reservekey(pwallet);
375 CAmount nFeeRequired;
376 std::string strError;
377 std::vector<CRecipient> vecSend;
378 int nChangePosRet = -1;
379 CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount};
380 vecSend.push_back(recipient);
381 if (!pwallet->CreateTransaction(vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError)) {
382 if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance)
383 strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired));
384 throw JSONRPCError(RPC_WALLET_ERROR, strError);
386 CValidationState state;
387 if (!pwallet->CommitTransaction(wtxNew, reservekey, g_connman.get(), state)) {
388 strError = strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason());
389 throw JSONRPCError(RPC_WALLET_ERROR, strError);
393 UniValue sendtoaddress(const JSONRPCRequest& request)
395 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
396 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
397 return NullUniValue;
400 if (request.fHelp || request.params.size() < 2 || request.params.size() > 5)
401 throw std::runtime_error(
402 "sendtoaddress \"address\" amount ( \"comment\" \"comment_to\" subtractfeefromamount )\n"
403 "\nSend an amount to a given address.\n"
404 + HelpRequiringPassphrase(pwallet) +
405 "\nArguments:\n"
406 "1. \"address\" (string, required) The bitcoin address to send to.\n"
407 "2. \"amount\" (numeric or string, required) The amount in " + CURRENCY_UNIT + " to send. eg 0.1\n"
408 "3. \"comment\" (string, optional) A comment used to store what the transaction is for. \n"
409 " This is not part of the transaction, just kept in your wallet.\n"
410 "4. \"comment_to\" (string, optional) A comment to store the name of the person or organization \n"
411 " to which you're sending the transaction. This is not part of the \n"
412 " transaction, just kept in your wallet.\n"
413 "5. subtractfeefromamount (boolean, optional, default=false) The fee will be deducted from the amount being sent.\n"
414 " The recipient will receive less bitcoins than you enter in the amount field.\n"
415 "\nResult:\n"
416 "\"txid\" (string) The transaction id.\n"
417 "\nExamples:\n"
418 + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1")
419 + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"donation\" \"seans outpost\"")
420 + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"\" \"\" true")
421 + HelpExampleRpc("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.1, \"donation\", \"seans outpost\"")
424 LOCK2(cs_main, pwallet->cs_wallet);
426 CBitcoinAddress address(request.params[0].get_str());
427 if (!address.IsValid())
428 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
430 // Amount
431 CAmount nAmount = AmountFromValue(request.params[1]);
432 if (nAmount <= 0)
433 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
435 // Wallet comments
436 CWalletTx wtx;
437 if (request.params.size() > 2 && !request.params[2].isNull() && !request.params[2].get_str().empty())
438 wtx.mapValue["comment"] = request.params[2].get_str();
439 if (request.params.size() > 3 && !request.params[3].isNull() && !request.params[3].get_str().empty())
440 wtx.mapValue["to"] = request.params[3].get_str();
442 bool fSubtractFeeFromAmount = false;
443 if (request.params.size() > 4)
444 fSubtractFeeFromAmount = request.params[4].get_bool();
446 EnsureWalletIsUnlocked(pwallet);
448 SendMoney(pwallet, address.Get(), nAmount, fSubtractFeeFromAmount, wtx);
450 return wtx.GetHash().GetHex();
453 UniValue listaddressgroupings(const JSONRPCRequest& request)
455 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
456 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
457 return NullUniValue;
460 if (request.fHelp)
461 throw std::runtime_error(
462 "listaddressgroupings\n"
463 "\nLists groups of addresses which have had their common ownership\n"
464 "made public by common use as inputs or as the resulting change\n"
465 "in past transactions\n"
466 "\nResult:\n"
467 "[\n"
468 " [\n"
469 " [\n"
470 " \"address\", (string) The bitcoin address\n"
471 " amount, (numeric) The amount in " + CURRENCY_UNIT + "\n"
472 " \"account\" (string, optional) DEPRECATED. The account\n"
473 " ]\n"
474 " ,...\n"
475 " ]\n"
476 " ,...\n"
477 "]\n"
478 "\nExamples:\n"
479 + HelpExampleCli("listaddressgroupings", "")
480 + HelpExampleRpc("listaddressgroupings", "")
483 LOCK2(cs_main, pwallet->cs_wallet);
485 UniValue jsonGroupings(UniValue::VARR);
486 std::map<CTxDestination, CAmount> balances = pwallet->GetAddressBalances();
487 for (std::set<CTxDestination> grouping : pwallet->GetAddressGroupings()) {
488 UniValue jsonGrouping(UniValue::VARR);
489 BOOST_FOREACH(CTxDestination address, grouping)
491 UniValue addressInfo(UniValue::VARR);
492 addressInfo.push_back(CBitcoinAddress(address).ToString());
493 addressInfo.push_back(ValueFromAmount(balances[address]));
495 if (pwallet->mapAddressBook.find(CBitcoinAddress(address).Get()) != pwallet->mapAddressBook.end()) {
496 addressInfo.push_back(pwallet->mapAddressBook.find(CBitcoinAddress(address).Get())->second.name);
499 jsonGrouping.push_back(addressInfo);
501 jsonGroupings.push_back(jsonGrouping);
503 return jsonGroupings;
506 UniValue signmessage(const JSONRPCRequest& request)
508 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
509 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
510 return NullUniValue;
513 if (request.fHelp || request.params.size() != 2)
514 throw std::runtime_error(
515 "signmessage \"address\" \"message\"\n"
516 "\nSign a message with the private key of an address"
517 + HelpRequiringPassphrase(pwallet) + "\n"
518 "\nArguments:\n"
519 "1. \"address\" (string, required) The bitcoin address to use for the private key.\n"
520 "2. \"message\" (string, required) The message to create a signature of.\n"
521 "\nResult:\n"
522 "\"signature\" (string) The signature of the message encoded in base 64\n"
523 "\nExamples:\n"
524 "\nUnlock the wallet for 30 seconds\n"
525 + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
526 "\nCreate the signature\n"
527 + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") +
528 "\nVerify the signature\n"
529 + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") +
530 "\nAs json rpc\n"
531 + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"my message\"")
534 LOCK2(cs_main, pwallet->cs_wallet);
536 EnsureWalletIsUnlocked(pwallet);
538 std::string strAddress = request.params[0].get_str();
539 std::string strMessage = request.params[1].get_str();
541 CBitcoinAddress addr(strAddress);
542 if (!addr.IsValid())
543 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
545 CKeyID keyID;
546 if (!addr.GetKeyID(keyID))
547 throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
549 CKey key;
550 if (!pwallet->GetKey(keyID, key)) {
551 throw JSONRPCError(RPC_WALLET_ERROR, "Private key not available");
554 CHashWriter ss(SER_GETHASH, 0);
555 ss << strMessageMagic;
556 ss << strMessage;
558 std::vector<unsigned char> vchSig;
559 if (!key.SignCompact(ss.GetHash(), vchSig))
560 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed");
562 return EncodeBase64(&vchSig[0], vchSig.size());
565 UniValue getreceivedbyaddress(const JSONRPCRequest& request)
567 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
568 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
569 return NullUniValue;
572 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
573 throw std::runtime_error(
574 "getreceivedbyaddress \"address\" ( minconf )\n"
575 "\nReturns the total amount received by the given address in transactions with at least minconf confirmations.\n"
576 "\nArguments:\n"
577 "1. \"address\" (string, required) The bitcoin address for transactions.\n"
578 "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
579 "\nResult:\n"
580 "amount (numeric) The total amount in " + CURRENCY_UNIT + " received at this address.\n"
581 "\nExamples:\n"
582 "\nThe amount from transactions with at least 1 confirmation\n"
583 + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"") +
584 "\nThe amount including unconfirmed transactions, zero confirmations\n"
585 + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" 0") +
586 "\nThe amount with at least 6 confirmation, very safe\n"
587 + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" 6") +
588 "\nAs a json rpc call\n"
589 + HelpExampleRpc("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", 6")
592 LOCK2(cs_main, pwallet->cs_wallet);
594 // Bitcoin address
595 CBitcoinAddress address = CBitcoinAddress(request.params[0].get_str());
596 if (!address.IsValid())
597 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
598 CScript scriptPubKey = GetScriptForDestination(address.Get());
599 if (!IsMine(*pwallet, scriptPubKey)) {
600 return ValueFromAmount(0);
603 // Minimum confirmations
604 int nMinDepth = 1;
605 if (request.params.size() > 1)
606 nMinDepth = request.params[1].get_int();
608 // Tally
609 CAmount nAmount = 0;
610 for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
611 const CWalletTx& wtx = pairWtx.second;
612 if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx))
613 continue;
615 BOOST_FOREACH(const CTxOut& txout, wtx.tx->vout)
616 if (txout.scriptPubKey == scriptPubKey)
617 if (wtx.GetDepthInMainChain() >= nMinDepth)
618 nAmount += txout.nValue;
621 return ValueFromAmount(nAmount);
625 UniValue getreceivedbyaccount(const JSONRPCRequest& request)
627 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
628 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
629 return NullUniValue;
632 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
633 throw std::runtime_error(
634 "getreceivedbyaccount \"account\" ( minconf )\n"
635 "\nDEPRECATED. Returns the total amount received by addresses with <account> in transactions with at least [minconf] confirmations.\n"
636 "\nArguments:\n"
637 "1. \"account\" (string, required) The selected account, may be the default account using \"\".\n"
638 "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
639 "\nResult:\n"
640 "amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n"
641 "\nExamples:\n"
642 "\nAmount received by the default account with at least 1 confirmation\n"
643 + HelpExampleCli("getreceivedbyaccount", "\"\"") +
644 "\nAmount received at the tabby account including unconfirmed amounts with zero confirmations\n"
645 + HelpExampleCli("getreceivedbyaccount", "\"tabby\" 0") +
646 "\nThe amount with at least 6 confirmation, very safe\n"
647 + HelpExampleCli("getreceivedbyaccount", "\"tabby\" 6") +
648 "\nAs a json rpc call\n"
649 + HelpExampleRpc("getreceivedbyaccount", "\"tabby\", 6")
652 LOCK2(cs_main, pwallet->cs_wallet);
654 // Minimum confirmations
655 int nMinDepth = 1;
656 if (request.params.size() > 1)
657 nMinDepth = request.params[1].get_int();
659 // Get the set of pub keys assigned to account
660 std::string strAccount = AccountFromValue(request.params[0]);
661 std::set<CTxDestination> setAddress = pwallet->GetAccountAddresses(strAccount);
663 // Tally
664 CAmount nAmount = 0;
665 for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
666 const CWalletTx& wtx = pairWtx.second;
667 if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx))
668 continue;
670 BOOST_FOREACH(const CTxOut& txout, wtx.tx->vout)
672 CTxDestination address;
673 if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*pwallet, address) && setAddress.count(address)) {
674 if (wtx.GetDepthInMainChain() >= nMinDepth)
675 nAmount += txout.nValue;
680 return ValueFromAmount(nAmount);
684 UniValue getbalance(const JSONRPCRequest& request)
686 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
687 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
688 return NullUniValue;
691 if (request.fHelp || request.params.size() > 3)
692 throw std::runtime_error(
693 "getbalance ( \"account\" minconf include_watchonly )\n"
694 "\nIf account is not specified, returns the server's total available balance.\n"
695 "If account is specified (DEPRECATED), returns the balance in the account.\n"
696 "Note that the account \"\" is not the same as leaving the parameter out.\n"
697 "The server total may be different to the balance in the default \"\" account.\n"
698 "\nArguments:\n"
699 "1. \"account\" (string, optional) DEPRECATED. The account string may be given as a\n"
700 " specific account name to find the balance associated with wallet keys in\n"
701 " a named account, or as the empty string (\"\") to find the balance\n"
702 " associated with wallet keys not in any named account, or as \"*\" to find\n"
703 " the balance associated with all wallet keys regardless of account.\n"
704 " When this option is specified, it calculates the balance in a different\n"
705 " way than when it is not specified, and which can count spends twice when\n"
706 " there are conflicting pending transactions (such as those created by\n"
707 " the bumpfee command), temporarily resulting in low or even negative\n"
708 " balances. In general, account balance calculation is not considered\n"
709 " reliable and has resulted in confusing outcomes, so it is recommended to\n"
710 " avoid passing this argument.\n"
711 "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
712 "3. include_watchonly (bool, optional, default=false) Also include balance in watch-only addresses (see 'importaddress')\n"
713 "\nResult:\n"
714 "amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n"
715 "\nExamples:\n"
716 "\nThe total amount in the wallet\n"
717 + HelpExampleCli("getbalance", "") +
718 "\nThe total amount in the wallet at least 5 blocks confirmed\n"
719 + HelpExampleCli("getbalance", "\"*\" 6") +
720 "\nAs a json rpc call\n"
721 + HelpExampleRpc("getbalance", "\"*\", 6")
724 LOCK2(cs_main, pwallet->cs_wallet);
726 if (request.params.size() == 0)
727 return ValueFromAmount(pwallet->GetBalance());
729 int nMinDepth = 1;
730 if (request.params.size() > 1)
731 nMinDepth = request.params[1].get_int();
732 isminefilter filter = ISMINE_SPENDABLE;
733 if(request.params.size() > 2)
734 if(request.params[2].get_bool())
735 filter = filter | ISMINE_WATCH_ONLY;
737 if (request.params[0].get_str() == "*") {
738 // Calculate total balance in a very different way from GetBalance().
739 // The biggest difference is that GetBalance() sums up all unspent
740 // TxOuts paying to the wallet, while this sums up both spent and
741 // unspent TxOuts paying to the wallet, and then subtracts the values of
742 // TxIns spending from the wallet. This also has fewer restrictions on
743 // which unconfirmed transactions are considered trusted.
744 CAmount nBalance = 0;
745 for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
746 const CWalletTx& wtx = pairWtx.second;
747 if (!CheckFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0 || wtx.GetDepthInMainChain() < 0)
748 continue;
750 CAmount allFee;
751 std::string strSentAccount;
752 std::list<COutputEntry> listReceived;
753 std::list<COutputEntry> listSent;
754 wtx.GetAmounts(listReceived, listSent, allFee, strSentAccount, filter);
755 if (wtx.GetDepthInMainChain() >= nMinDepth)
757 BOOST_FOREACH(const COutputEntry& r, listReceived)
758 nBalance += r.amount;
760 BOOST_FOREACH(const COutputEntry& s, listSent)
761 nBalance -= s.amount;
762 nBalance -= allFee;
764 return ValueFromAmount(nBalance);
767 std::string strAccount = AccountFromValue(request.params[0]);
769 CAmount nBalance = pwallet->GetAccountBalance(strAccount, nMinDepth, filter);
771 return ValueFromAmount(nBalance);
774 UniValue getunconfirmedbalance(const JSONRPCRequest &request)
776 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
777 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
778 return NullUniValue;
781 if (request.fHelp || request.params.size() > 0)
782 throw std::runtime_error(
783 "getunconfirmedbalance\n"
784 "Returns the server's total unconfirmed balance\n");
786 LOCK2(cs_main, pwallet->cs_wallet);
788 return ValueFromAmount(pwallet->GetUnconfirmedBalance());
792 UniValue movecmd(const JSONRPCRequest& request)
794 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
795 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
796 return NullUniValue;
799 if (request.fHelp || request.params.size() < 3 || request.params.size() > 5)
800 throw std::runtime_error(
801 "move \"fromaccount\" \"toaccount\" amount ( minconf \"comment\" )\n"
802 "\nDEPRECATED. Move a specified amount from one account in your wallet to another.\n"
803 "\nArguments:\n"
804 "1. \"fromaccount\" (string, required) The name of the account to move funds from. May be the default account using \"\".\n"
805 "2. \"toaccount\" (string, required) The name of the account to move funds to. May be the default account using \"\".\n"
806 "3. amount (numeric) Quantity of " + CURRENCY_UNIT + " to move between accounts.\n"
807 "4. (dummy) (numeric, optional) Ignored. Remains for backward compatibility.\n"
808 "5. \"comment\" (string, optional) An optional comment, stored in the wallet only.\n"
809 "\nResult:\n"
810 "true|false (boolean) true if successful.\n"
811 "\nExamples:\n"
812 "\nMove 0.01 " + CURRENCY_UNIT + " from the default account to the account named tabby\n"
813 + HelpExampleCli("move", "\"\" \"tabby\" 0.01") +
814 "\nMove 0.01 " + CURRENCY_UNIT + " timotei to akiko with a comment and funds have 6 confirmations\n"
815 + HelpExampleCli("move", "\"timotei\" \"akiko\" 0.01 6 \"happy birthday!\"") +
816 "\nAs a json rpc call\n"
817 + HelpExampleRpc("move", "\"timotei\", \"akiko\", 0.01, 6, \"happy birthday!\"")
820 LOCK2(cs_main, pwallet->cs_wallet);
822 std::string strFrom = AccountFromValue(request.params[0]);
823 std::string strTo = AccountFromValue(request.params[1]);
824 CAmount nAmount = AmountFromValue(request.params[2]);
825 if (nAmount <= 0)
826 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
827 if (request.params.size() > 3)
828 // unused parameter, used to be nMinDepth, keep type-checking it though
829 (void)request.params[3].get_int();
830 std::string strComment;
831 if (request.params.size() > 4)
832 strComment = request.params[4].get_str();
834 if (!pwallet->AccountMove(strFrom, strTo, nAmount, strComment)) {
835 throw JSONRPCError(RPC_DATABASE_ERROR, "database error");
838 return true;
842 UniValue sendfrom(const JSONRPCRequest& request)
844 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
845 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
846 return NullUniValue;
849 if (request.fHelp || request.params.size() < 3 || request.params.size() > 6)
850 throw std::runtime_error(
851 "sendfrom \"fromaccount\" \"toaddress\" amount ( minconf \"comment\" \"comment_to\" )\n"
852 "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a bitcoin address."
853 + HelpRequiringPassphrase(pwallet) + "\n"
854 "\nArguments:\n"
855 "1. \"fromaccount\" (string, required) The name of the account to send funds from. May be the default account using \"\".\n"
856 " Specifying an account does not influence coin selection, but it does associate the newly created\n"
857 " transaction with the account, so the account's balance computation and transaction history can reflect\n"
858 " the spend.\n"
859 "2. \"toaddress\" (string, required) The bitcoin address to send funds to.\n"
860 "3. amount (numeric or string, required) The amount in " + CURRENCY_UNIT + " (transaction fee is added on top).\n"
861 "4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n"
862 "5. \"comment\" (string, optional) A comment used to store what the transaction is for. \n"
863 " This is not part of the transaction, just kept in your wallet.\n"
864 "6. \"comment_to\" (string, optional) An optional comment to store the name of the person or organization \n"
865 " to which you're sending the transaction. This is not part of the transaction, \n"
866 " it is just kept in your wallet.\n"
867 "\nResult:\n"
868 "\"txid\" (string) The transaction id.\n"
869 "\nExamples:\n"
870 "\nSend 0.01 " + CURRENCY_UNIT + " from the default account to the address, must have at least 1 confirmation\n"
871 + HelpExampleCli("sendfrom", "\"\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01") +
872 "\nSend 0.01 from the tabby account to the given address, funds must have at least 6 confirmations\n"
873 + HelpExampleCli("sendfrom", "\"tabby\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01 6 \"donation\" \"seans outpost\"") +
874 "\nAs a json rpc call\n"
875 + HelpExampleRpc("sendfrom", "\"tabby\", \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.01, 6, \"donation\", \"seans outpost\"")
878 LOCK2(cs_main, pwallet->cs_wallet);
880 std::string strAccount = AccountFromValue(request.params[0]);
881 CBitcoinAddress address(request.params[1].get_str());
882 if (!address.IsValid())
883 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
884 CAmount nAmount = AmountFromValue(request.params[2]);
885 if (nAmount <= 0)
886 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
887 int nMinDepth = 1;
888 if (request.params.size() > 3)
889 nMinDepth = request.params[3].get_int();
891 CWalletTx wtx;
892 wtx.strFromAccount = strAccount;
893 if (request.params.size() > 4 && !request.params[4].isNull() && !request.params[4].get_str().empty())
894 wtx.mapValue["comment"] = request.params[4].get_str();
895 if (request.params.size() > 5 && !request.params[5].isNull() && !request.params[5].get_str().empty())
896 wtx.mapValue["to"] = request.params[5].get_str();
898 EnsureWalletIsUnlocked(pwallet);
900 // Check funds
901 CAmount nBalance = pwallet->GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE);
902 if (nAmount > nBalance)
903 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
905 SendMoney(pwallet, address.Get(), nAmount, false, wtx);
907 return wtx.GetHash().GetHex();
911 UniValue sendmany(const JSONRPCRequest& request)
913 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
914 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
915 return NullUniValue;
918 if (request.fHelp || request.params.size() < 2 || request.params.size() > 5)
919 throw std::runtime_error(
920 "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" [\"address\",...] )\n"
921 "\nSend multiple times. Amounts are double-precision floating point numbers."
922 + HelpRequiringPassphrase(pwallet) + "\n"
923 "\nArguments:\n"
924 "1. \"fromaccount\" (string, required) DEPRECATED. The account to send the funds from. Should be \"\" for the default account\n"
925 "2. \"amounts\" (string, required) A json object with addresses and amounts\n"
926 " {\n"
927 " \"address\":amount (numeric or string) The bitcoin address is the key, the numeric amount (can be string) in " + CURRENCY_UNIT + " is the value\n"
928 " ,...\n"
929 " }\n"
930 "3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n"
931 "4. \"comment\" (string, optional) A comment\n"
932 "5. subtractfeefrom (array, optional) A json array with addresses.\n"
933 " The fee will be equally deducted from the amount of each selected address.\n"
934 " Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
935 " If no addresses are specified here, the sender pays the fee.\n"
936 " [\n"
937 " \"address\" (string) Subtract fee from this address\n"
938 " ,...\n"
939 " ]\n"
940 "\nResult:\n"
941 "\"txid\" (string) The transaction id for the send. Only 1 transaction is created regardless of \n"
942 " the number of addresses.\n"
943 "\nExamples:\n"
944 "\nSend two amounts to two different addresses:\n"
945 + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") +
946 "\nSend two amounts to two different addresses setting the confirmation and comment:\n"
947 + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 6 \"testing\"") +
948 "\nSend two amounts to two different addresses, subtract fee from amount:\n"
949 + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 1 \"\" \"[\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\",\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\"]\"") +
950 "\nAs a json rpc call\n"
951 + HelpExampleRpc("sendmany", "\"\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"")
954 LOCK2(cs_main, pwallet->cs_wallet);
956 if (pwallet->GetBroadcastTransactions() && !g_connman) {
957 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
960 std::string strAccount = AccountFromValue(request.params[0]);
961 UniValue sendTo = request.params[1].get_obj();
962 int nMinDepth = 1;
963 if (request.params.size() > 2)
964 nMinDepth = request.params[2].get_int();
966 CWalletTx wtx;
967 wtx.strFromAccount = strAccount;
968 if (request.params.size() > 3 && !request.params[3].isNull() && !request.params[3].get_str().empty())
969 wtx.mapValue["comment"] = request.params[3].get_str();
971 UniValue subtractFeeFromAmount(UniValue::VARR);
972 if (request.params.size() > 4)
973 subtractFeeFromAmount = request.params[4].get_array();
975 std::set<CBitcoinAddress> setAddress;
976 std::vector<CRecipient> vecSend;
978 CAmount totalAmount = 0;
979 std::vector<std::string> keys = sendTo.getKeys();
980 BOOST_FOREACH(const std::string& name_, keys)
982 CBitcoinAddress address(name_);
983 if (!address.IsValid())
984 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Bitcoin address: ")+name_);
986 if (setAddress.count(address))
987 throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ")+name_);
988 setAddress.insert(address);
990 CScript scriptPubKey = GetScriptForDestination(address.Get());
991 CAmount nAmount = AmountFromValue(sendTo[name_]);
992 if (nAmount <= 0)
993 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
994 totalAmount += nAmount;
996 bool fSubtractFeeFromAmount = false;
997 for (unsigned int idx = 0; idx < subtractFeeFromAmount.size(); idx++) {
998 const UniValue& addr = subtractFeeFromAmount[idx];
999 if (addr.get_str() == name_)
1000 fSubtractFeeFromAmount = true;
1003 CRecipient recipient = {scriptPubKey, nAmount, fSubtractFeeFromAmount};
1004 vecSend.push_back(recipient);
1007 EnsureWalletIsUnlocked(pwallet);
1009 // Check funds
1010 CAmount nBalance = pwallet->GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE);
1011 if (totalAmount > nBalance)
1012 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
1014 // Send
1015 CReserveKey keyChange(pwallet);
1016 CAmount nFeeRequired = 0;
1017 int nChangePosRet = -1;
1018 std::string strFailReason;
1019 bool fCreated = pwallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, nChangePosRet, strFailReason);
1020 if (!fCreated)
1021 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
1022 CValidationState state;
1023 if (!pwallet->CommitTransaction(wtx, keyChange, g_connman.get(), state)) {
1024 strFailReason = strprintf("Transaction commit failed:: %s", state.GetRejectReason());
1025 throw JSONRPCError(RPC_WALLET_ERROR, strFailReason);
1028 return wtx.GetHash().GetHex();
1031 // Defined in rpc/misc.cpp
1032 extern CScript _createmultisig_redeemScript(CWallet * const pwallet, const UniValue& params);
1034 UniValue addmultisigaddress(const JSONRPCRequest& request)
1036 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1037 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1038 return NullUniValue;
1041 if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
1043 std::string msg = "addmultisigaddress nrequired [\"key\",...] ( \"account\" )\n"
1044 "\nAdd a nrequired-to-sign multisignature address to the wallet.\n"
1045 "Each key is a Bitcoin address or hex-encoded public key.\n"
1046 "If 'account' is specified (DEPRECATED), assign address to that account.\n"
1048 "\nArguments:\n"
1049 "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
1050 "2. \"keys\" (string, required) A json array of bitcoin addresses or hex-encoded public keys\n"
1051 " [\n"
1052 " \"address\" (string) bitcoin address or hex-encoded public key\n"
1053 " ...,\n"
1054 " ]\n"
1055 "3. \"account\" (string, optional) DEPRECATED. An account to assign the addresses to.\n"
1057 "\nResult:\n"
1058 "\"address\" (string) A bitcoin address associated with the keys.\n"
1060 "\nExamples:\n"
1061 "\nAdd a multisig address from 2 addresses\n"
1062 + HelpExampleCli("addmultisigaddress", "2 \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") +
1063 "\nAs json rpc call\n"
1064 + HelpExampleRpc("addmultisigaddress", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"")
1066 throw std::runtime_error(msg);
1069 LOCK2(cs_main, pwallet->cs_wallet);
1071 std::string strAccount;
1072 if (request.params.size() > 2)
1073 strAccount = AccountFromValue(request.params[2]);
1075 // Construct using pay-to-script-hash:
1076 CScript inner = _createmultisig_redeemScript(pwallet, request.params);
1077 CScriptID innerID(inner);
1078 pwallet->AddCScript(inner);
1080 pwallet->SetAddressBook(innerID, strAccount, "send");
1081 return CBitcoinAddress(innerID).ToString();
1084 class Witnessifier : public boost::static_visitor<bool>
1086 public:
1087 CWallet * const pwallet;
1088 CScriptID result;
1090 Witnessifier(CWallet *_pwallet) : pwallet(_pwallet) {}
1092 bool operator()(const CNoDestination &dest) const { return false; }
1094 bool operator()(const CKeyID &keyID) {
1095 CPubKey pubkey;
1096 if (pwallet) {
1097 CScript basescript = GetScriptForDestination(keyID);
1098 isminetype typ;
1099 typ = IsMine(*pwallet, basescript, SIGVERSION_WITNESS_V0);
1100 if (typ != ISMINE_SPENDABLE && typ != ISMINE_WATCH_SOLVABLE)
1101 return false;
1102 CScript witscript = GetScriptForWitness(basescript);
1103 pwallet->AddCScript(witscript);
1104 result = CScriptID(witscript);
1105 return true;
1107 return false;
1110 bool operator()(const CScriptID &scriptID) {
1111 CScript subscript;
1112 if (pwallet && pwallet->GetCScript(scriptID, subscript)) {
1113 int witnessversion;
1114 std::vector<unsigned char> witprog;
1115 if (subscript.IsWitnessProgram(witnessversion, witprog)) {
1116 result = scriptID;
1117 return true;
1119 isminetype typ;
1120 typ = IsMine(*pwallet, subscript, SIGVERSION_WITNESS_V0);
1121 if (typ != ISMINE_SPENDABLE && typ != ISMINE_WATCH_SOLVABLE)
1122 return false;
1123 CScript witscript = GetScriptForWitness(subscript);
1124 pwallet->AddCScript(witscript);
1125 result = CScriptID(witscript);
1126 return true;
1128 return false;
1132 UniValue addwitnessaddress(const JSONRPCRequest& request)
1134 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1135 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1136 return NullUniValue;
1139 if (request.fHelp || request.params.size() < 1 || request.params.size() > 1)
1141 std::string msg = "addwitnessaddress \"address\"\n"
1142 "\nAdd a witness address for a script (with pubkey or redeemscript known).\n"
1143 "It returns the witness script.\n"
1145 "\nArguments:\n"
1146 "1. \"address\" (string, required) An address known to the wallet\n"
1148 "\nResult:\n"
1149 "\"witnessaddress\", (string) The value of the new address (P2SH of witness script).\n"
1150 "}\n"
1152 throw std::runtime_error(msg);
1156 LOCK(cs_main);
1157 if (!IsWitnessEnabled(chainActive.Tip(), Params().GetConsensus()) && !GetBoolArg("-walletprematurewitness", false)) {
1158 throw JSONRPCError(RPC_WALLET_ERROR, "Segregated witness not enabled on network");
1162 CBitcoinAddress address(request.params[0].get_str());
1163 if (!address.IsValid())
1164 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
1166 Witnessifier w(pwallet);
1167 CTxDestination dest = address.Get();
1168 bool ret = boost::apply_visitor(w, dest);
1169 if (!ret) {
1170 throw JSONRPCError(RPC_WALLET_ERROR, "Public key or redeemscript not known to wallet, or the key is uncompressed");
1173 pwallet->SetAddressBook(w.result, "", "receive");
1175 return CBitcoinAddress(w.result).ToString();
1178 struct tallyitem
1180 CAmount nAmount;
1181 int nConf;
1182 std::vector<uint256> txids;
1183 bool fIsWatchonly;
1184 tallyitem()
1186 nAmount = 0;
1187 nConf = std::numeric_limits<int>::max();
1188 fIsWatchonly = false;
1192 UniValue ListReceived(CWallet * const pwallet, const UniValue& params, bool fByAccounts)
1194 // Minimum confirmations
1195 int nMinDepth = 1;
1196 if (params.size() > 0)
1197 nMinDepth = params[0].get_int();
1199 // Whether to include empty accounts
1200 bool fIncludeEmpty = false;
1201 if (params.size() > 1)
1202 fIncludeEmpty = params[1].get_bool();
1204 isminefilter filter = ISMINE_SPENDABLE;
1205 if(params.size() > 2)
1206 if(params[2].get_bool())
1207 filter = filter | ISMINE_WATCH_ONLY;
1209 // Tally
1210 std::map<CBitcoinAddress, tallyitem> mapTally;
1211 for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
1212 const CWalletTx& wtx = pairWtx.second;
1214 if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx))
1215 continue;
1217 int nDepth = wtx.GetDepthInMainChain();
1218 if (nDepth < nMinDepth)
1219 continue;
1221 BOOST_FOREACH(const CTxOut& txout, wtx.tx->vout)
1223 CTxDestination address;
1224 if (!ExtractDestination(txout.scriptPubKey, address))
1225 continue;
1227 isminefilter mine = IsMine(*pwallet, address);
1228 if(!(mine & filter))
1229 continue;
1231 tallyitem& item = mapTally[address];
1232 item.nAmount += txout.nValue;
1233 item.nConf = std::min(item.nConf, nDepth);
1234 item.txids.push_back(wtx.GetHash());
1235 if (mine & ISMINE_WATCH_ONLY)
1236 item.fIsWatchonly = true;
1240 // Reply
1241 UniValue ret(UniValue::VARR);
1242 std::map<std::string, tallyitem> mapAccountTally;
1243 for (const std::pair<CBitcoinAddress, CAddressBookData>& item : pwallet->mapAddressBook) {
1244 const CBitcoinAddress& address = item.first;
1245 const std::string& strAccount = item.second.name;
1246 std::map<CBitcoinAddress, tallyitem>::iterator it = mapTally.find(address);
1247 if (it == mapTally.end() && !fIncludeEmpty)
1248 continue;
1250 CAmount nAmount = 0;
1251 int nConf = std::numeric_limits<int>::max();
1252 bool fIsWatchonly = false;
1253 if (it != mapTally.end())
1255 nAmount = (*it).second.nAmount;
1256 nConf = (*it).second.nConf;
1257 fIsWatchonly = (*it).second.fIsWatchonly;
1260 if (fByAccounts)
1262 tallyitem& _item = mapAccountTally[strAccount];
1263 _item.nAmount += nAmount;
1264 _item.nConf = std::min(_item.nConf, nConf);
1265 _item.fIsWatchonly = fIsWatchonly;
1267 else
1269 UniValue obj(UniValue::VOBJ);
1270 if(fIsWatchonly)
1271 obj.push_back(Pair("involvesWatchonly", true));
1272 obj.push_back(Pair("address", address.ToString()));
1273 obj.push_back(Pair("account", strAccount));
1274 obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
1275 obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
1276 if (!fByAccounts)
1277 obj.push_back(Pair("label", strAccount));
1278 UniValue transactions(UniValue::VARR);
1279 if (it != mapTally.end())
1281 BOOST_FOREACH(const uint256& _item, (*it).second.txids)
1283 transactions.push_back(_item.GetHex());
1286 obj.push_back(Pair("txids", transactions));
1287 ret.push_back(obj);
1291 if (fByAccounts)
1293 for (std::map<std::string, tallyitem>::iterator it = mapAccountTally.begin(); it != mapAccountTally.end(); ++it)
1295 CAmount nAmount = (*it).second.nAmount;
1296 int nConf = (*it).second.nConf;
1297 UniValue obj(UniValue::VOBJ);
1298 if((*it).second.fIsWatchonly)
1299 obj.push_back(Pair("involvesWatchonly", true));
1300 obj.push_back(Pair("account", (*it).first));
1301 obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
1302 obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
1303 ret.push_back(obj);
1307 return ret;
1310 UniValue listreceivedbyaddress(const JSONRPCRequest& request)
1312 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1313 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1314 return NullUniValue;
1317 if (request.fHelp || request.params.size() > 3)
1318 throw std::runtime_error(
1319 "listreceivedbyaddress ( minconf include_empty include_watchonly)\n"
1320 "\nList balances by receiving address.\n"
1321 "\nArguments:\n"
1322 "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
1323 "2. include_empty (bool, optional, default=false) Whether to include addresses that haven't received any payments.\n"
1324 "3. include_watchonly (bool, optional, default=false) Whether to include watch-only addresses (see 'importaddress').\n"
1326 "\nResult:\n"
1327 "[\n"
1328 " {\n"
1329 " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n"
1330 " \"address\" : \"receivingaddress\", (string) The receiving address\n"
1331 " \"account\" : \"accountname\", (string) DEPRECATED. The account of the receiving address. The default account is \"\".\n"
1332 " \"amount\" : x.xxx, (numeric) The total amount in " + CURRENCY_UNIT + " received by the address\n"
1333 " \"confirmations\" : n, (numeric) The number of confirmations of the most recent transaction included\n"
1334 " \"label\" : \"label\", (string) A comment for the address/transaction, if any\n"
1335 " \"txids\": [\n"
1336 " n, (numeric) The ids of transactions received with the address \n"
1337 " ...\n"
1338 " ]\n"
1339 " }\n"
1340 " ,...\n"
1341 "]\n"
1343 "\nExamples:\n"
1344 + HelpExampleCli("listreceivedbyaddress", "")
1345 + HelpExampleCli("listreceivedbyaddress", "6 true")
1346 + HelpExampleRpc("listreceivedbyaddress", "6, true, true")
1349 LOCK2(cs_main, pwallet->cs_wallet);
1351 return ListReceived(pwallet, request.params, false);
1354 UniValue listreceivedbyaccount(const JSONRPCRequest& request)
1356 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1357 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1358 return NullUniValue;
1361 if (request.fHelp || request.params.size() > 3)
1362 throw std::runtime_error(
1363 "listreceivedbyaccount ( minconf include_empty include_watchonly)\n"
1364 "\nDEPRECATED. List balances by account.\n"
1365 "\nArguments:\n"
1366 "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
1367 "2. include_empty (bool, optional, default=false) Whether to include accounts that haven't received any payments.\n"
1368 "3. include_watchonly (bool, optional, default=false) Whether to include watch-only addresses (see 'importaddress').\n"
1370 "\nResult:\n"
1371 "[\n"
1372 " {\n"
1373 " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n"
1374 " \"account\" : \"accountname\", (string) The account name of the receiving account\n"
1375 " \"amount\" : x.xxx, (numeric) The total amount received by addresses with this account\n"
1376 " \"confirmations\" : n, (numeric) The number of confirmations of the most recent transaction included\n"
1377 " \"label\" : \"label\" (string) A comment for the address/transaction, if any\n"
1378 " }\n"
1379 " ,...\n"
1380 "]\n"
1382 "\nExamples:\n"
1383 + HelpExampleCli("listreceivedbyaccount", "")
1384 + HelpExampleCli("listreceivedbyaccount", "6 true")
1385 + HelpExampleRpc("listreceivedbyaccount", "6, true, true")
1388 LOCK2(cs_main, pwallet->cs_wallet);
1390 return ListReceived(pwallet, request.params, true);
1393 static void MaybePushAddress(UniValue & entry, const CTxDestination &dest)
1395 CBitcoinAddress addr;
1396 if (addr.Set(dest))
1397 entry.push_back(Pair("address", addr.ToString()));
1400 void ListTransactions(CWallet* const pwallet, const CWalletTx& wtx, const std::string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter)
1402 CAmount nFee;
1403 std::string strSentAccount;
1404 std::list<COutputEntry> listReceived;
1405 std::list<COutputEntry> listSent;
1407 wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount, filter);
1409 bool fAllAccounts = (strAccount == std::string("*"));
1410 bool involvesWatchonly = wtx.IsFromMe(ISMINE_WATCH_ONLY);
1412 // Sent
1413 if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount))
1415 BOOST_FOREACH(const COutputEntry& s, listSent)
1417 UniValue entry(UniValue::VOBJ);
1418 if (involvesWatchonly || (::IsMine(*pwallet, s.destination) & ISMINE_WATCH_ONLY)) {
1419 entry.push_back(Pair("involvesWatchonly", true));
1421 entry.push_back(Pair("account", strSentAccount));
1422 MaybePushAddress(entry, s.destination);
1423 entry.push_back(Pair("category", "send"));
1424 entry.push_back(Pair("amount", ValueFromAmount(-s.amount)));
1425 if (pwallet->mapAddressBook.count(s.destination)) {
1426 entry.push_back(Pair("label", pwallet->mapAddressBook[s.destination].name));
1428 entry.push_back(Pair("vout", s.vout));
1429 entry.push_back(Pair("fee", ValueFromAmount(-nFee)));
1430 if (fLong)
1431 WalletTxToJSON(wtx, entry);
1432 entry.push_back(Pair("abandoned", wtx.isAbandoned()));
1433 ret.push_back(entry);
1437 // Received
1438 if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth)
1440 BOOST_FOREACH(const COutputEntry& r, listReceived)
1442 std::string account;
1443 if (pwallet->mapAddressBook.count(r.destination)) {
1444 account = pwallet->mapAddressBook[r.destination].name;
1446 if (fAllAccounts || (account == strAccount))
1448 UniValue entry(UniValue::VOBJ);
1449 if (involvesWatchonly || (::IsMine(*pwallet, r.destination) & ISMINE_WATCH_ONLY)) {
1450 entry.push_back(Pair("involvesWatchonly", true));
1452 entry.push_back(Pair("account", account));
1453 MaybePushAddress(entry, r.destination);
1454 if (wtx.IsCoinBase())
1456 if (wtx.GetDepthInMainChain() < 1)
1457 entry.push_back(Pair("category", "orphan"));
1458 else if (wtx.GetBlocksToMaturity() > 0)
1459 entry.push_back(Pair("category", "immature"));
1460 else
1461 entry.push_back(Pair("category", "generate"));
1463 else
1465 entry.push_back(Pair("category", "receive"));
1467 entry.push_back(Pair("amount", ValueFromAmount(r.amount)));
1468 if (pwallet->mapAddressBook.count(r.destination)) {
1469 entry.push_back(Pair("label", account));
1471 entry.push_back(Pair("vout", r.vout));
1472 if (fLong)
1473 WalletTxToJSON(wtx, entry);
1474 ret.push_back(entry);
1480 void AcentryToJSON(const CAccountingEntry& acentry, const std::string& strAccount, UniValue& ret)
1482 bool fAllAccounts = (strAccount == std::string("*"));
1484 if (fAllAccounts || acentry.strAccount == strAccount)
1486 UniValue entry(UniValue::VOBJ);
1487 entry.push_back(Pair("account", acentry.strAccount));
1488 entry.push_back(Pair("category", "move"));
1489 entry.push_back(Pair("time", acentry.nTime));
1490 entry.push_back(Pair("amount", ValueFromAmount(acentry.nCreditDebit)));
1491 entry.push_back(Pair("otheraccount", acentry.strOtherAccount));
1492 entry.push_back(Pair("comment", acentry.strComment));
1493 ret.push_back(entry);
1497 UniValue listtransactions(const JSONRPCRequest& request)
1499 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1500 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1501 return NullUniValue;
1504 if (request.fHelp || request.params.size() > 4)
1505 throw std::runtime_error(
1506 "listtransactions ( \"account\" count skip include_watchonly)\n"
1507 "\nReturns up to 'count' most recent transactions skipping the first 'from' transactions for account 'account'.\n"
1508 "\nArguments:\n"
1509 "1. \"account\" (string, optional) DEPRECATED. The account name. Should be \"*\".\n"
1510 "2. count (numeric, optional, default=10) The number of transactions to return\n"
1511 "3. skip (numeric, optional, default=0) The number of transactions to skip\n"
1512 "4. include_watchonly (bool, optional, default=false) Include transactions to watch-only addresses (see 'importaddress')\n"
1513 "\nResult:\n"
1514 "[\n"
1515 " {\n"
1516 " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. \n"
1517 " It will be \"\" for the default account.\n"
1518 " \"address\":\"address\", (string) The bitcoin address of the transaction. Not present for \n"
1519 " move transactions (category = move).\n"
1520 " \"category\":\"send|receive|move\", (string) The transaction category. 'move' is a local (off blockchain)\n"
1521 " transaction between accounts, and not associated with an address,\n"
1522 " transaction id or block. 'send' and 'receive' transactions are \n"
1523 " associated with an address, transaction id and block details\n"
1524 " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the\n"
1525 " 'move' category for moves outbound. It is positive for the 'receive' category,\n"
1526 " and for the 'move' category for inbound funds.\n"
1527 " \"label\": \"label\", (string) A comment for the address/transaction, if any\n"
1528 " \"vout\": n, (numeric) the vout value\n"
1529 " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n"
1530 " 'send' category of transactions.\n"
1531 " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and \n"
1532 " 'receive' category of transactions. Negative confirmations indicate the\n"
1533 " transaction conflicts with the block chain\n"
1534 " \"trusted\": xxx, (bool) Whether we consider the outputs of this unconfirmed transaction safe to spend.\n"
1535 " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive'\n"
1536 " category of transactions.\n"
1537 " \"blockindex\": n, (numeric) The index of the transaction in the block that includes it. Available for 'send' and 'receive'\n"
1538 " category of transactions.\n"
1539 " \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n"
1540 " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
1541 " \"time\": xxx, (numeric) The transaction time in seconds since epoch (midnight Jan 1 1970 GMT).\n"
1542 " \"timereceived\": xxx, (numeric) The time received in seconds since epoch (midnight Jan 1 1970 GMT). Available \n"
1543 " for 'send' and 'receive' category of transactions.\n"
1544 " \"comment\": \"...\", (string) If a comment is associated with the transaction.\n"
1545 " \"otheraccount\": \"accountname\", (string) DEPRECATED. For the 'move' category of transactions, the account the funds came \n"
1546 " from (for receiving funds, positive amounts), or went to (for sending funds,\n"
1547 " negative amounts).\n"
1548 " \"bip125-replaceable\": \"yes|no|unknown\", (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n"
1549 " may be unknown for unconfirmed transactions not in the mempool\n"
1550 " \"abandoned\": xxx (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n"
1551 " 'send' category of transactions.\n"
1552 " }\n"
1553 "]\n"
1555 "\nExamples:\n"
1556 "\nList the most recent 10 transactions in the systems\n"
1557 + HelpExampleCli("listtransactions", "") +
1558 "\nList transactions 100 to 120\n"
1559 + HelpExampleCli("listtransactions", "\"*\" 20 100") +
1560 "\nAs a json rpc call\n"
1561 + HelpExampleRpc("listtransactions", "\"*\", 20, 100")
1564 LOCK2(cs_main, pwallet->cs_wallet);
1566 std::string strAccount = "*";
1567 if (request.params.size() > 0)
1568 strAccount = request.params[0].get_str();
1569 int nCount = 10;
1570 if (request.params.size() > 1)
1571 nCount = request.params[1].get_int();
1572 int nFrom = 0;
1573 if (request.params.size() > 2)
1574 nFrom = request.params[2].get_int();
1575 isminefilter filter = ISMINE_SPENDABLE;
1576 if(request.params.size() > 3)
1577 if(request.params[3].get_bool())
1578 filter = filter | ISMINE_WATCH_ONLY;
1580 if (nCount < 0)
1581 throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count");
1582 if (nFrom < 0)
1583 throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from");
1585 UniValue ret(UniValue::VARR);
1587 const CWallet::TxItems & txOrdered = pwallet->wtxOrdered;
1589 // iterate backwards until we have nCount items to return:
1590 for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
1592 CWalletTx *const pwtx = (*it).second.first;
1593 if (pwtx != 0)
1594 ListTransactions(pwallet, *pwtx, strAccount, 0, true, ret, filter);
1595 CAccountingEntry *const pacentry = (*it).second.second;
1596 if (pacentry != 0)
1597 AcentryToJSON(*pacentry, strAccount, ret);
1599 if ((int)ret.size() >= (nCount+nFrom)) break;
1601 // ret is newest to oldest
1603 if (nFrom > (int)ret.size())
1604 nFrom = ret.size();
1605 if ((nFrom + nCount) > (int)ret.size())
1606 nCount = ret.size() - nFrom;
1608 std::vector<UniValue> arrTmp = ret.getValues();
1610 std::vector<UniValue>::iterator first = arrTmp.begin();
1611 std::advance(first, nFrom);
1612 std::vector<UniValue>::iterator last = arrTmp.begin();
1613 std::advance(last, nFrom+nCount);
1615 if (last != arrTmp.end()) arrTmp.erase(last, arrTmp.end());
1616 if (first != arrTmp.begin()) arrTmp.erase(arrTmp.begin(), first);
1618 std::reverse(arrTmp.begin(), arrTmp.end()); // Return oldest to newest
1620 ret.clear();
1621 ret.setArray();
1622 ret.push_backV(arrTmp);
1624 return ret;
1627 UniValue listaccounts(const JSONRPCRequest& request)
1629 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1630 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1631 return NullUniValue;
1634 if (request.fHelp || request.params.size() > 2)
1635 throw std::runtime_error(
1636 "listaccounts ( minconf include_watchonly)\n"
1637 "\nDEPRECATED. Returns Object that has account names as keys, account balances as values.\n"
1638 "\nArguments:\n"
1639 "1. minconf (numeric, optional, default=1) Only include transactions with at least this many confirmations\n"
1640 "2. include_watchonly (bool, optional, default=false) Include balances in watch-only addresses (see 'importaddress')\n"
1641 "\nResult:\n"
1642 "{ (json object where keys are account names, and values are numeric balances\n"
1643 " \"account\": x.xxx, (numeric) The property name is the account name, and the value is the total balance for the account.\n"
1644 " ...\n"
1645 "}\n"
1646 "\nExamples:\n"
1647 "\nList account balances where there at least 1 confirmation\n"
1648 + HelpExampleCli("listaccounts", "") +
1649 "\nList account balances including zero confirmation transactions\n"
1650 + HelpExampleCli("listaccounts", "0") +
1651 "\nList account balances for 6 or more confirmations\n"
1652 + HelpExampleCli("listaccounts", "6") +
1653 "\nAs json rpc call\n"
1654 + HelpExampleRpc("listaccounts", "6")
1657 LOCK2(cs_main, pwallet->cs_wallet);
1659 int nMinDepth = 1;
1660 if (request.params.size() > 0)
1661 nMinDepth = request.params[0].get_int();
1662 isminefilter includeWatchonly = ISMINE_SPENDABLE;
1663 if(request.params.size() > 1)
1664 if(request.params[1].get_bool())
1665 includeWatchonly = includeWatchonly | ISMINE_WATCH_ONLY;
1667 std::map<std::string, CAmount> mapAccountBalances;
1668 for (const std::pair<CTxDestination, CAddressBookData>& entry : pwallet->mapAddressBook) {
1669 if (IsMine(*pwallet, entry.first) & includeWatchonly) { // This address belongs to me
1670 mapAccountBalances[entry.second.name] = 0;
1674 for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
1675 const CWalletTx& wtx = pairWtx.second;
1676 CAmount nFee;
1677 std::string strSentAccount;
1678 std::list<COutputEntry> listReceived;
1679 std::list<COutputEntry> listSent;
1680 int nDepth = wtx.GetDepthInMainChain();
1681 if (wtx.GetBlocksToMaturity() > 0 || nDepth < 0)
1682 continue;
1683 wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount, includeWatchonly);
1684 mapAccountBalances[strSentAccount] -= nFee;
1685 BOOST_FOREACH(const COutputEntry& s, listSent)
1686 mapAccountBalances[strSentAccount] -= s.amount;
1687 if (nDepth >= nMinDepth)
1689 BOOST_FOREACH(const COutputEntry& r, listReceived)
1690 if (pwallet->mapAddressBook.count(r.destination)) {
1691 mapAccountBalances[pwallet->mapAddressBook[r.destination].name] += r.amount;
1693 else
1694 mapAccountBalances[""] += r.amount;
1698 const std::list<CAccountingEntry>& acentries = pwallet->laccentries;
1699 BOOST_FOREACH(const CAccountingEntry& entry, acentries)
1700 mapAccountBalances[entry.strAccount] += entry.nCreditDebit;
1702 UniValue ret(UniValue::VOBJ);
1703 BOOST_FOREACH(const PAIRTYPE(std::string, CAmount)& accountBalance, mapAccountBalances) {
1704 ret.push_back(Pair(accountBalance.first, ValueFromAmount(accountBalance.second)));
1706 return ret;
1709 UniValue listsinceblock(const JSONRPCRequest& request)
1711 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1712 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1713 return NullUniValue;
1716 if (request.fHelp)
1717 throw std::runtime_error(
1718 "listsinceblock ( \"blockhash\" target_confirmations include_watchonly)\n"
1719 "\nGet all transactions in blocks since block [blockhash], or all transactions if omitted\n"
1720 "\nArguments:\n"
1721 "1. \"blockhash\" (string, optional) The block hash to list transactions since\n"
1722 "2. target_confirmations: (numeric, optional) The confirmations required, must be 1 or more\n"
1723 "3. include_watchonly: (bool, optional, default=false) Include transactions to watch-only addresses (see 'importaddress')"
1724 "\nResult:\n"
1725 "{\n"
1726 " \"transactions\": [\n"
1727 " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. Will be \"\" for the default account.\n"
1728 " \"address\":\"address\", (string) The bitcoin address of the transaction. Not present for move transactions (category = move).\n"
1729 " \"category\":\"send|receive\", (string) The transaction category. 'send' has negative amounts, 'receive' has positive amounts.\n"
1730 " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the 'move' category for moves \n"
1731 " outbound. It is positive for the 'receive' category, and for the 'move' category for inbound funds.\n"
1732 " \"vout\" : n, (numeric) the vout value\n"
1733 " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the 'send' category of transactions.\n"
1734 " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and 'receive' category of transactions.\n"
1735 " When it's < 0, it means the transaction conflicted that many blocks ago.\n"
1736 " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive' category of transactions.\n"
1737 " \"blockindex\": n, (numeric) The index of the transaction in the block that includes it. Available for 'send' and 'receive' category of transactions.\n"
1738 " \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n"
1739 " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
1740 " \"time\": xxx, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT).\n"
1741 " \"timereceived\": xxx, (numeric) The time received in seconds since epoch (Jan 1 1970 GMT). Available for 'send' and 'receive' category of transactions.\n"
1742 " \"bip125-replaceable\": \"yes|no|unknown\", (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n"
1743 " may be unknown for unconfirmed transactions not in the mempool\n"
1744 " \"abandoned\": xxx, (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the 'send' category of transactions.\n"
1745 " \"comment\": \"...\", (string) If a comment is associated with the transaction.\n"
1746 " \"label\" : \"label\" (string) A comment for the address/transaction, if any\n"
1747 " \"to\": \"...\", (string) If a comment to is associated with the transaction.\n"
1748 " ],\n"
1749 " \"lastblock\": \"lastblockhash\" (string) The hash of the last block\n"
1750 "}\n"
1751 "\nExamples:\n"
1752 + HelpExampleCli("listsinceblock", "")
1753 + HelpExampleCli("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\" 6")
1754 + HelpExampleRpc("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\", 6")
1757 LOCK2(cs_main, pwallet->cs_wallet);
1759 const CBlockIndex *pindex = NULL;
1760 int target_confirms = 1;
1761 isminefilter filter = ISMINE_SPENDABLE;
1763 if (request.params.size() > 0)
1765 uint256 blockId;
1767 blockId.SetHex(request.params[0].get_str());
1768 BlockMap::iterator it = mapBlockIndex.find(blockId);
1769 if (it != mapBlockIndex.end())
1771 pindex = it->second;
1772 if (chainActive[pindex->nHeight] != pindex)
1774 // the block being asked for is a part of a deactivated chain;
1775 // we don't want to depend on its perceived height in the block
1776 // chain, we want to instead use the last common ancestor
1777 pindex = chainActive.FindFork(pindex);
1782 if (request.params.size() > 1)
1784 target_confirms = request.params[1].get_int();
1786 if (target_confirms < 1)
1787 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter");
1790 if (request.params.size() > 2 && request.params[2].get_bool())
1792 filter = filter | ISMINE_WATCH_ONLY;
1795 int depth = pindex ? (1 + chainActive.Height() - pindex->nHeight) : -1;
1797 UniValue transactions(UniValue::VARR);
1799 for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
1800 CWalletTx tx = pairWtx.second;
1802 if (depth == -1 || tx.GetDepthInMainChain() < depth)
1803 ListTransactions(pwallet, tx, "*", 0, true, transactions, filter);
1806 CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms];
1807 uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : uint256();
1809 UniValue ret(UniValue::VOBJ);
1810 ret.push_back(Pair("transactions", transactions));
1811 ret.push_back(Pair("lastblock", lastblock.GetHex()));
1813 return ret;
1816 UniValue gettransaction(const JSONRPCRequest& request)
1818 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1819 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1820 return NullUniValue;
1823 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
1824 throw std::runtime_error(
1825 "gettransaction \"txid\" ( include_watchonly )\n"
1826 "\nGet detailed information about in-wallet transaction <txid>\n"
1827 "\nArguments:\n"
1828 "1. \"txid\" (string, required) The transaction id\n"
1829 "2. \"include_watchonly\" (bool, optional, default=false) Whether to include watch-only addresses in balance calculation and details[]\n"
1830 "\nResult:\n"
1831 "{\n"
1832 " \"amount\" : x.xxx, (numeric) The transaction amount in " + CURRENCY_UNIT + "\n"
1833 " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n"
1834 " 'send' category of transactions.\n"
1835 " \"confirmations\" : n, (numeric) The number of confirmations\n"
1836 " \"blockhash\" : \"hash\", (string) The block hash\n"
1837 " \"blockindex\" : xx, (numeric) The index of the transaction in the block that includes it\n"
1838 " \"blocktime\" : ttt, (numeric) The time in seconds since epoch (1 Jan 1970 GMT)\n"
1839 " \"txid\" : \"transactionid\", (string) The transaction id.\n"
1840 " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (1 Jan 1970 GMT)\n"
1841 " \"timereceived\" : ttt, (numeric) The time received in seconds since epoch (1 Jan 1970 GMT)\n"
1842 " \"bip125-replaceable\": \"yes|no|unknown\", (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n"
1843 " may be unknown for unconfirmed transactions not in the mempool\n"
1844 " \"details\" : [\n"
1845 " {\n"
1846 " \"account\" : \"accountname\", (string) DEPRECATED. The account name involved in the transaction, can be \"\" for the default account.\n"
1847 " \"address\" : \"address\", (string) The bitcoin address involved in the transaction\n"
1848 " \"category\" : \"send|receive\", (string) The category, either 'send' or 'receive'\n"
1849 " \"amount\" : x.xxx, (numeric) The amount in " + CURRENCY_UNIT + "\n"
1850 " \"label\" : \"label\", (string) A comment for the address/transaction, if any\n"
1851 " \"vout\" : n, (numeric) the vout value\n"
1852 " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n"
1853 " 'send' category of transactions.\n"
1854 " \"abandoned\": xxx (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n"
1855 " 'send' category of transactions.\n"
1856 " }\n"
1857 " ,...\n"
1858 " ],\n"
1859 " \"hex\" : \"data\" (string) Raw data for transaction\n"
1860 "}\n"
1862 "\nExamples:\n"
1863 + HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
1864 + HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\" true")
1865 + HelpExampleRpc("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
1868 LOCK2(cs_main, pwallet->cs_wallet);
1870 uint256 hash;
1871 hash.SetHex(request.params[0].get_str());
1873 isminefilter filter = ISMINE_SPENDABLE;
1874 if(request.params.size() > 1)
1875 if(request.params[1].get_bool())
1876 filter = filter | ISMINE_WATCH_ONLY;
1878 UniValue entry(UniValue::VOBJ);
1879 if (!pwallet->mapWallet.count(hash)) {
1880 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
1882 const CWalletTx& wtx = pwallet->mapWallet[hash];
1884 CAmount nCredit = wtx.GetCredit(filter);
1885 CAmount nDebit = wtx.GetDebit(filter);
1886 CAmount nNet = nCredit - nDebit;
1887 CAmount nFee = (wtx.IsFromMe(filter) ? wtx.tx->GetValueOut() - nDebit : 0);
1889 entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
1890 if (wtx.IsFromMe(filter))
1891 entry.push_back(Pair("fee", ValueFromAmount(nFee)));
1893 WalletTxToJSON(wtx, entry);
1895 UniValue details(UniValue::VARR);
1896 ListTransactions(pwallet, wtx, "*", 0, false, details, filter);
1897 entry.push_back(Pair("details", details));
1899 std::string strHex = EncodeHexTx(static_cast<CTransaction>(wtx), RPCSerializationFlags());
1900 entry.push_back(Pair("hex", strHex));
1902 return entry;
1905 UniValue abandontransaction(const JSONRPCRequest& request)
1907 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1908 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1909 return NullUniValue;
1912 if (request.fHelp || request.params.size() != 1)
1913 throw std::runtime_error(
1914 "abandontransaction \"txid\"\n"
1915 "\nMark in-wallet transaction <txid> as abandoned\n"
1916 "This will mark this transaction and all its in-wallet descendants as abandoned which will allow\n"
1917 "for their inputs to be respent. It can be used to replace \"stuck\" or evicted transactions.\n"
1918 "It only works on transactions which are not included in a block and are not currently in the mempool.\n"
1919 "It has no effect on transactions which are already conflicted or abandoned.\n"
1920 "\nArguments:\n"
1921 "1. \"txid\" (string, required) The transaction id\n"
1922 "\nResult:\n"
1923 "\nExamples:\n"
1924 + HelpExampleCli("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
1925 + HelpExampleRpc("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
1928 LOCK2(cs_main, pwallet->cs_wallet);
1930 uint256 hash;
1931 hash.SetHex(request.params[0].get_str());
1933 if (!pwallet->mapWallet.count(hash)) {
1934 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
1936 if (!pwallet->AbandonTransaction(hash)) {
1937 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not eligible for abandonment");
1940 return NullUniValue;
1944 UniValue backupwallet(const JSONRPCRequest& request)
1946 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1947 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1948 return NullUniValue;
1951 if (request.fHelp || request.params.size() != 1)
1952 throw std::runtime_error(
1953 "backupwallet \"destination\"\n"
1954 "\nSafely copies current wallet file to destination, which can be a directory or a path with filename.\n"
1955 "\nArguments:\n"
1956 "1. \"destination\" (string) The destination directory or file\n"
1957 "\nExamples:\n"
1958 + HelpExampleCli("backupwallet", "\"backup.dat\"")
1959 + HelpExampleRpc("backupwallet", "\"backup.dat\"")
1962 LOCK2(cs_main, pwallet->cs_wallet);
1964 std::string strDest = request.params[0].get_str();
1965 if (!pwallet->BackupWallet(strDest)) {
1966 throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!");
1969 return NullUniValue;
1973 UniValue keypoolrefill(const JSONRPCRequest& request)
1975 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1976 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1977 return NullUniValue;
1980 if (request.fHelp || request.params.size() > 1)
1981 throw std::runtime_error(
1982 "keypoolrefill ( newsize )\n"
1983 "\nFills the keypool."
1984 + HelpRequiringPassphrase(pwallet) + "\n"
1985 "\nArguments\n"
1986 "1. newsize (numeric, optional, default=100) The new keypool size\n"
1987 "\nExamples:\n"
1988 + HelpExampleCli("keypoolrefill", "")
1989 + HelpExampleRpc("keypoolrefill", "")
1992 LOCK2(cs_main, pwallet->cs_wallet);
1994 // 0 is interpreted by TopUpKeyPool() as the default keypool size given by -keypool
1995 unsigned int kpSize = 0;
1996 if (request.params.size() > 0) {
1997 if (request.params[0].get_int() < 0)
1998 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected valid size.");
1999 kpSize = (unsigned int)request.params[0].get_int();
2002 EnsureWalletIsUnlocked(pwallet);
2003 pwallet->TopUpKeyPool(kpSize);
2005 if (pwallet->GetKeyPoolSize() < kpSize) {
2006 throw JSONRPCError(RPC_WALLET_ERROR, "Error refreshing keypool.");
2009 return NullUniValue;
2013 static void LockWallet(CWallet* pWallet)
2015 LOCK(pWallet->cs_wallet);
2016 pWallet->nRelockTime = 0;
2017 pWallet->Lock();
2020 UniValue walletpassphrase(const JSONRPCRequest& request)
2022 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2023 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2024 return NullUniValue;
2027 if (pwallet->IsCrypted() && (request.fHelp || request.params.size() != 2)) {
2028 throw std::runtime_error(
2029 "walletpassphrase \"passphrase\" timeout\n"
2030 "\nStores the wallet decryption key in memory for 'timeout' seconds.\n"
2031 "This is needed prior to performing transactions related to private keys such as sending bitcoins\n"
2032 "\nArguments:\n"
2033 "1. \"passphrase\" (string, required) The wallet passphrase\n"
2034 "2. timeout (numeric, required) The time to keep the decryption key in seconds.\n"
2035 "\nNote:\n"
2036 "Issuing the walletpassphrase command while the wallet is already unlocked will set a new unlock\n"
2037 "time that overrides the old one.\n"
2038 "\nExamples:\n"
2039 "\nunlock the wallet for 60 seconds\n"
2040 + HelpExampleCli("walletpassphrase", "\"my pass phrase\" 60") +
2041 "\nLock the wallet again (before 60 seconds)\n"
2042 + HelpExampleCli("walletlock", "") +
2043 "\nAs json rpc call\n"
2044 + HelpExampleRpc("walletpassphrase", "\"my pass phrase\", 60")
2048 LOCK2(cs_main, pwallet->cs_wallet);
2050 if (request.fHelp)
2051 return true;
2052 if (!pwallet->IsCrypted()) {
2053 throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrase was called.");
2056 // Note that the walletpassphrase is stored in request.params[0] which is not mlock()ed
2057 SecureString strWalletPass;
2058 strWalletPass.reserve(100);
2059 // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
2060 // Alternately, find a way to make request.params[0] mlock()'d to begin with.
2061 strWalletPass = request.params[0].get_str().c_str();
2063 if (strWalletPass.length() > 0)
2065 if (!pwallet->Unlock(strWalletPass)) {
2066 throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect.");
2069 else
2070 throw std::runtime_error(
2071 "walletpassphrase <passphrase> <timeout>\n"
2072 "Stores the wallet decryption key in memory for <timeout> seconds.");
2074 pwallet->TopUpKeyPool();
2076 int64_t nSleepTime = request.params[1].get_int64();
2077 pwallet->nRelockTime = GetTime() + nSleepTime;
2078 RPCRunLater(strprintf("lockwallet(%s)", pwallet->strWalletFile), boost::bind(LockWallet, pwallet), nSleepTime);
2080 return NullUniValue;
2084 UniValue walletpassphrasechange(const JSONRPCRequest& request)
2086 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2087 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2088 return NullUniValue;
2091 if (pwallet->IsCrypted() && (request.fHelp || request.params.size() != 2)) {
2092 throw std::runtime_error(
2093 "walletpassphrasechange \"oldpassphrase\" \"newpassphrase\"\n"
2094 "\nChanges the wallet passphrase from 'oldpassphrase' to 'newpassphrase'.\n"
2095 "\nArguments:\n"
2096 "1. \"oldpassphrase\" (string) The current passphrase\n"
2097 "2. \"newpassphrase\" (string) The new passphrase\n"
2098 "\nExamples:\n"
2099 + HelpExampleCli("walletpassphrasechange", "\"old one\" \"new one\"")
2100 + HelpExampleRpc("walletpassphrasechange", "\"old one\", \"new one\"")
2104 LOCK2(cs_main, pwallet->cs_wallet);
2106 if (request.fHelp)
2107 return true;
2108 if (!pwallet->IsCrypted()) {
2109 throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrasechange was called.");
2112 // TODO: get rid of these .c_str() calls by implementing SecureString::operator=(std::string)
2113 // Alternately, find a way to make request.params[0] mlock()'d to begin with.
2114 SecureString strOldWalletPass;
2115 strOldWalletPass.reserve(100);
2116 strOldWalletPass = request.params[0].get_str().c_str();
2118 SecureString strNewWalletPass;
2119 strNewWalletPass.reserve(100);
2120 strNewWalletPass = request.params[1].get_str().c_str();
2122 if (strOldWalletPass.length() < 1 || strNewWalletPass.length() < 1)
2123 throw std::runtime_error(
2124 "walletpassphrasechange <oldpassphrase> <newpassphrase>\n"
2125 "Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>.");
2127 if (!pwallet->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass)) {
2128 throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect.");
2131 return NullUniValue;
2135 UniValue walletlock(const JSONRPCRequest& request)
2137 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2138 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2139 return NullUniValue;
2142 if (pwallet->IsCrypted() && (request.fHelp || request.params.size() != 0)) {
2143 throw std::runtime_error(
2144 "walletlock\n"
2145 "\nRemoves the wallet encryption key from memory, locking the wallet.\n"
2146 "After calling this method, you will need to call walletpassphrase again\n"
2147 "before being able to call any methods which require the wallet to be unlocked.\n"
2148 "\nExamples:\n"
2149 "\nSet the passphrase for 2 minutes to perform a transaction\n"
2150 + HelpExampleCli("walletpassphrase", "\"my pass phrase\" 120") +
2151 "\nPerform a send (requires passphrase set)\n"
2152 + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 1.0") +
2153 "\nClear the passphrase since we are done before 2 minutes is up\n"
2154 + HelpExampleCli("walletlock", "") +
2155 "\nAs json rpc call\n"
2156 + HelpExampleRpc("walletlock", "")
2160 LOCK2(cs_main, pwallet->cs_wallet);
2162 if (request.fHelp)
2163 return true;
2164 if (!pwallet->IsCrypted()) {
2165 throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletlock was called.");
2168 pwallet->Lock();
2169 pwallet->nRelockTime = 0;
2171 return NullUniValue;
2175 UniValue encryptwallet(const JSONRPCRequest& request)
2177 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2178 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2179 return NullUniValue;
2182 if (!pwallet->IsCrypted() && (request.fHelp || request.params.size() != 1)) {
2183 throw std::runtime_error(
2184 "encryptwallet \"passphrase\"\n"
2185 "\nEncrypts the wallet with 'passphrase'. This is for first time encryption.\n"
2186 "After this, any calls that interact with private keys such as sending or signing \n"
2187 "will require the passphrase to be set prior the making these calls.\n"
2188 "Use the walletpassphrase call for this, and then walletlock call.\n"
2189 "If the wallet is already encrypted, use the walletpassphrasechange call.\n"
2190 "Note that this will shutdown the server.\n"
2191 "\nArguments:\n"
2192 "1. \"passphrase\" (string) The pass phrase to encrypt the wallet with. It must be at least 1 character, but should be long.\n"
2193 "\nExamples:\n"
2194 "\nEncrypt you wallet\n"
2195 + HelpExampleCli("encryptwallet", "\"my pass phrase\"") +
2196 "\nNow set the passphrase to use the wallet, such as for signing or sending bitcoin\n"
2197 + HelpExampleCli("walletpassphrase", "\"my pass phrase\"") +
2198 "\nNow we can so something like sign\n"
2199 + HelpExampleCli("signmessage", "\"address\" \"test message\"") +
2200 "\nNow lock the wallet again by removing the passphrase\n"
2201 + HelpExampleCli("walletlock", "") +
2202 "\nAs a json rpc call\n"
2203 + HelpExampleRpc("encryptwallet", "\"my pass phrase\"")
2207 LOCK2(cs_main, pwallet->cs_wallet);
2209 if (request.fHelp)
2210 return true;
2211 if (pwallet->IsCrypted()) {
2212 throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an encrypted wallet, but encryptwallet was called.");
2215 // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
2216 // Alternately, find a way to make request.params[0] mlock()'d to begin with.
2217 SecureString strWalletPass;
2218 strWalletPass.reserve(100);
2219 strWalletPass = request.params[0].get_str().c_str();
2221 if (strWalletPass.length() < 1)
2222 throw std::runtime_error(
2223 "encryptwallet <passphrase>\n"
2224 "Encrypts the wallet with <passphrase>.");
2226 if (!pwallet->EncryptWallet(strWalletPass)) {
2227 throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Error: Failed to encrypt the wallet.");
2230 // BDB seems to have a bad habit of writing old data into
2231 // slack space in .dat files; that is bad if the old data is
2232 // unencrypted private keys. So:
2233 StartShutdown();
2234 return "wallet encrypted; Bitcoin 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.";
2237 UniValue lockunspent(const JSONRPCRequest& request)
2239 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2240 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2241 return NullUniValue;
2244 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
2245 throw std::runtime_error(
2246 "lockunspent unlock ([{\"txid\":\"txid\",\"vout\":n},...])\n"
2247 "\nUpdates list of temporarily unspendable outputs.\n"
2248 "Temporarily lock (unlock=false) or unlock (unlock=true) specified transaction outputs.\n"
2249 "If no transaction outputs are specified when unlocking then all current locked transaction outputs are unlocked.\n"
2250 "A locked transaction output will not be chosen by automatic coin selection, when spending bitcoins.\n"
2251 "Locks are stored in memory only. Nodes start with zero locked outputs, and the locked output list\n"
2252 "is always cleared (by virtue of process exit) when a node stops or fails.\n"
2253 "Also see the listunspent call\n"
2254 "\nArguments:\n"
2255 "1. unlock (boolean, required) Whether to unlock (true) or lock (false) the specified transactions\n"
2256 "2. \"transactions\" (string, optional) A json array of objects. Each object the txid (string) vout (numeric)\n"
2257 " [ (json array of json objects)\n"
2258 " {\n"
2259 " \"txid\":\"id\", (string) The transaction id\n"
2260 " \"vout\": n (numeric) The output number\n"
2261 " }\n"
2262 " ,...\n"
2263 " ]\n"
2265 "\nResult:\n"
2266 "true|false (boolean) Whether the command was successful or not\n"
2268 "\nExamples:\n"
2269 "\nList the unspent transactions\n"
2270 + HelpExampleCli("listunspent", "") +
2271 "\nLock an unspent transaction\n"
2272 + HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2273 "\nList the locked transactions\n"
2274 + HelpExampleCli("listlockunspent", "") +
2275 "\nUnlock the transaction again\n"
2276 + HelpExampleCli("lockunspent", "true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2277 "\nAs a json rpc call\n"
2278 + HelpExampleRpc("lockunspent", "false, \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"")
2281 LOCK2(cs_main, pwallet->cs_wallet);
2283 if (request.params.size() == 1)
2284 RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VBOOL));
2285 else
2286 RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VBOOL)(UniValue::VARR));
2288 bool fUnlock = request.params[0].get_bool();
2290 if (request.params.size() == 1) {
2291 if (fUnlock)
2292 pwallet->UnlockAllCoins();
2293 return true;
2296 UniValue outputs = request.params[1].get_array();
2297 for (unsigned int idx = 0; idx < outputs.size(); idx++) {
2298 const UniValue& output = outputs[idx];
2299 if (!output.isObject())
2300 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected object");
2301 const UniValue& o = output.get_obj();
2303 RPCTypeCheckObj(o,
2305 {"txid", UniValueType(UniValue::VSTR)},
2306 {"vout", UniValueType(UniValue::VNUM)},
2309 std::string txid = find_value(o, "txid").get_str();
2310 if (!IsHex(txid))
2311 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected hex txid");
2313 int nOutput = find_value(o, "vout").get_int();
2314 if (nOutput < 0)
2315 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
2317 COutPoint outpt(uint256S(txid), nOutput);
2319 if (fUnlock)
2320 pwallet->UnlockCoin(outpt);
2321 else
2322 pwallet->LockCoin(outpt);
2325 return true;
2328 UniValue listlockunspent(const JSONRPCRequest& request)
2330 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2331 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2332 return NullUniValue;
2335 if (request.fHelp || request.params.size() > 0)
2336 throw std::runtime_error(
2337 "listlockunspent\n"
2338 "\nReturns list of temporarily unspendable outputs.\n"
2339 "See the lockunspent call to lock and unlock transactions for spending.\n"
2340 "\nResult:\n"
2341 "[\n"
2342 " {\n"
2343 " \"txid\" : \"transactionid\", (string) The transaction id locked\n"
2344 " \"vout\" : n (numeric) The vout value\n"
2345 " }\n"
2346 " ,...\n"
2347 "]\n"
2348 "\nExamples:\n"
2349 "\nList the unspent transactions\n"
2350 + HelpExampleCli("listunspent", "") +
2351 "\nLock an unspent transaction\n"
2352 + HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2353 "\nList the locked transactions\n"
2354 + HelpExampleCli("listlockunspent", "") +
2355 "\nUnlock the transaction again\n"
2356 + HelpExampleCli("lockunspent", "true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2357 "\nAs a json rpc call\n"
2358 + HelpExampleRpc("listlockunspent", "")
2361 LOCK2(cs_main, pwallet->cs_wallet);
2363 std::vector<COutPoint> vOutpts;
2364 pwallet->ListLockedCoins(vOutpts);
2366 UniValue ret(UniValue::VARR);
2368 BOOST_FOREACH(COutPoint &outpt, vOutpts) {
2369 UniValue o(UniValue::VOBJ);
2371 o.push_back(Pair("txid", outpt.hash.GetHex()));
2372 o.push_back(Pair("vout", (int)outpt.n));
2373 ret.push_back(o);
2376 return ret;
2379 UniValue settxfee(const JSONRPCRequest& request)
2381 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2382 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2383 return NullUniValue;
2386 if (request.fHelp || request.params.size() < 1 || request.params.size() > 1)
2387 throw std::runtime_error(
2388 "settxfee amount\n"
2389 "\nSet the transaction fee per kB. Overwrites the paytxfee parameter.\n"
2390 "\nArguments:\n"
2391 "1. amount (numeric or string, required) The transaction fee in " + CURRENCY_UNIT + "/kB\n"
2392 "\nResult\n"
2393 "true|false (boolean) Returns true if successful\n"
2394 "\nExamples:\n"
2395 + HelpExampleCli("settxfee", "0.00001")
2396 + HelpExampleRpc("settxfee", "0.00001")
2399 LOCK2(cs_main, pwallet->cs_wallet);
2401 // Amount
2402 CAmount nAmount = AmountFromValue(request.params[0]);
2404 payTxFee = CFeeRate(nAmount, 1000);
2405 return true;
2408 UniValue getwalletinfo(const JSONRPCRequest& request)
2410 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2411 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2412 return NullUniValue;
2415 if (request.fHelp || request.params.size() != 0)
2416 throw std::runtime_error(
2417 "getwalletinfo\n"
2418 "Returns an object containing various wallet state info.\n"
2419 "\nResult:\n"
2420 "{\n"
2421 " \"walletversion\": xxxxx, (numeric) the wallet version\n"
2422 " \"balance\": xxxxxxx, (numeric) the total confirmed balance of the wallet in " + CURRENCY_UNIT + "\n"
2423 " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed balance of the wallet in " + CURRENCY_UNIT + "\n"
2424 " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet in " + CURRENCY_UNIT + "\n"
2425 " \"txcount\": xxxxxxx, (numeric) the total number of transactions in the wallet\n"
2426 " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since Unix epoch) of the oldest pre-generated key in the key pool\n"
2427 " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n"
2428 " \"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"
2429 " \"paytxfee\": x.xxxx, (numeric) the transaction fee configuration, set in " + CURRENCY_UNIT + "/kB\n"
2430 " \"hdmasterkeyid\": \"<hash160>\" (string) the Hash160 of the HD master pubkey\n"
2431 "}\n"
2432 "\nExamples:\n"
2433 + HelpExampleCli("getwalletinfo", "")
2434 + HelpExampleRpc("getwalletinfo", "")
2437 LOCK2(cs_main, pwallet->cs_wallet);
2439 UniValue obj(UniValue::VOBJ);
2440 obj.push_back(Pair("walletversion", pwallet->GetVersion()));
2441 obj.push_back(Pair("balance", ValueFromAmount(pwallet->GetBalance())));
2442 obj.push_back(Pair("unconfirmed_balance", ValueFromAmount(pwallet->GetUnconfirmedBalance())));
2443 obj.push_back(Pair("immature_balance", ValueFromAmount(pwallet->GetImmatureBalance())));
2444 obj.push_back(Pair("txcount", (int)pwallet->mapWallet.size()));
2445 obj.push_back(Pair("keypoololdest", pwallet->GetOldestKeyPoolTime()));
2446 obj.push_back(Pair("keypoolsize", (int)pwallet->GetKeyPoolSize()));
2447 if (pwallet->IsCrypted()) {
2448 obj.push_back(Pair("unlocked_until", pwallet->nRelockTime));
2450 obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())));
2451 CKeyID masterKeyID = pwallet->GetHDChain().masterKeyID;
2452 if (!masterKeyID.IsNull())
2453 obj.push_back(Pair("hdmasterkeyid", masterKeyID.GetHex()));
2454 return obj;
2457 UniValue resendwallettransactions(const JSONRPCRequest& request)
2459 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2460 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2461 return NullUniValue;
2464 if (request.fHelp || request.params.size() != 0)
2465 throw std::runtime_error(
2466 "resendwallettransactions\n"
2467 "Immediately re-broadcast unconfirmed wallet transactions to all peers.\n"
2468 "Intended only for testing; the wallet code periodically re-broadcasts\n"
2469 "automatically.\n"
2470 "Returns array of transaction ids that were re-broadcast.\n"
2473 if (!g_connman)
2474 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
2476 LOCK2(cs_main, pwallet->cs_wallet);
2478 std::vector<uint256> txids = pwallet->ResendWalletTransactionsBefore(GetTime(), g_connman.get());
2479 UniValue result(UniValue::VARR);
2480 BOOST_FOREACH(const uint256& txid, txids)
2482 result.push_back(txid.ToString());
2484 return result;
2487 UniValue listunspent(const JSONRPCRequest& request)
2489 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2490 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2491 return NullUniValue;
2494 if (request.fHelp || request.params.size() > 4)
2495 throw std::runtime_error(
2496 "listunspent ( minconf maxconf [\"addresses\",...] [include_unsafe] )\n"
2497 "\nReturns array of unspent transaction outputs\n"
2498 "with between minconf and maxconf (inclusive) confirmations.\n"
2499 "Optionally filter to only include txouts paid to specified addresses.\n"
2500 "\nArguments:\n"
2501 "1. minconf (numeric, optional, default=1) The minimum confirmations to filter\n"
2502 "2. maxconf (numeric, optional, default=9999999) The maximum confirmations to filter\n"
2503 "3. \"addresses\" (string) A json array of bitcoin addresses to filter\n"
2504 " [\n"
2505 " \"address\" (string) bitcoin address\n"
2506 " ,...\n"
2507 " ]\n"
2508 "4. include_unsafe (bool, optional, default=true) Include outputs that are not safe to spend\n"
2509 " See description of \"safe\" attribute below.\n"
2510 "\nResult\n"
2511 "[ (array of json object)\n"
2512 " {\n"
2513 " \"txid\" : \"txid\", (string) the transaction id \n"
2514 " \"vout\" : n, (numeric) the vout value\n"
2515 " \"address\" : \"address\", (string) the bitcoin address\n"
2516 " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n"
2517 " \"scriptPubKey\" : \"key\", (string) the script key\n"
2518 " \"amount\" : x.xxx, (numeric) the transaction output amount in " + CURRENCY_UNIT + "\n"
2519 " \"confirmations\" : n, (numeric) The number of confirmations\n"
2520 " \"redeemScript\" : n (string) The redeemScript if scriptPubKey is P2SH\n"
2521 " \"spendable\" : xxx, (bool) Whether we have the private keys to spend this output\n"
2522 " \"solvable\" : xxx, (bool) Whether we know how to spend this output, ignoring the lack of keys\n"
2523 " \"safe\" : xxx (bool) Whether this output is considered safe to spend. Unconfirmed transactions\n"
2524 " from outside keys and unconfirmed replacement transactions are considered unsafe\n"
2525 " and are not eligible for spending by fundrawtransaction and sendtoaddress.\n"
2526 " }\n"
2527 " ,...\n"
2528 "]\n"
2530 "\nExamples\n"
2531 + HelpExampleCli("listunspent", "")
2532 + HelpExampleCli("listunspent", "6 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"")
2533 + HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"")
2536 int nMinDepth = 1;
2537 if (request.params.size() > 0 && !request.params[0].isNull()) {
2538 RPCTypeCheckArgument(request.params[0], UniValue::VNUM);
2539 nMinDepth = request.params[0].get_int();
2542 int nMaxDepth = 9999999;
2543 if (request.params.size() > 1 && !request.params[1].isNull()) {
2544 RPCTypeCheckArgument(request.params[1], UniValue::VNUM);
2545 nMaxDepth = request.params[1].get_int();
2548 std::set<CBitcoinAddress> setAddress;
2549 if (request.params.size() > 2 && !request.params[2].isNull()) {
2550 RPCTypeCheckArgument(request.params[2], UniValue::VARR);
2551 UniValue inputs = request.params[2].get_array();
2552 for (unsigned int idx = 0; idx < inputs.size(); idx++) {
2553 const UniValue& input = inputs[idx];
2554 CBitcoinAddress address(input.get_str());
2555 if (!address.IsValid())
2556 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Bitcoin address: ")+input.get_str());
2557 if (setAddress.count(address))
2558 throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ")+input.get_str());
2559 setAddress.insert(address);
2563 bool include_unsafe = true;
2564 if (request.params.size() > 3 && !request.params[3].isNull()) {
2565 RPCTypeCheckArgument(request.params[3], UniValue::VBOOL);
2566 include_unsafe = request.params[3].get_bool();
2569 UniValue results(UniValue::VARR);
2570 std::vector<COutput> vecOutputs;
2571 assert(pwallet != NULL);
2572 LOCK2(cs_main, pwallet->cs_wallet);
2573 pwallet->AvailableCoins(vecOutputs, !include_unsafe, NULL, true);
2574 BOOST_FOREACH(const COutput& out, vecOutputs) {
2575 if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth)
2576 continue;
2578 CTxDestination address;
2579 const CScript& scriptPubKey = out.tx->tx->vout[out.i].scriptPubKey;
2580 bool fValidAddress = ExtractDestination(scriptPubKey, address);
2582 if (setAddress.size() && (!fValidAddress || !setAddress.count(address)))
2583 continue;
2585 UniValue entry(UniValue::VOBJ);
2586 entry.push_back(Pair("txid", out.tx->GetHash().GetHex()));
2587 entry.push_back(Pair("vout", out.i));
2589 if (fValidAddress) {
2590 entry.push_back(Pair("address", CBitcoinAddress(address).ToString()));
2592 if (pwallet->mapAddressBook.count(address)) {
2593 entry.push_back(Pair("account", pwallet->mapAddressBook[address].name));
2596 if (scriptPubKey.IsPayToScriptHash()) {
2597 const CScriptID& hash = boost::get<CScriptID>(address);
2598 CScript redeemScript;
2599 if (pwallet->GetCScript(hash, redeemScript)) {
2600 entry.push_back(Pair("redeemScript", HexStr(redeemScript.begin(), redeemScript.end())));
2605 entry.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
2606 entry.push_back(Pair("amount", ValueFromAmount(out.tx->tx->vout[out.i].nValue)));
2607 entry.push_back(Pair("confirmations", out.nDepth));
2608 entry.push_back(Pair("spendable", out.fSpendable));
2609 entry.push_back(Pair("solvable", out.fSolvable));
2610 entry.push_back(Pair("safe", out.fSafe));
2611 results.push_back(entry);
2614 return results;
2617 UniValue fundrawtransaction(const JSONRPCRequest& request)
2619 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2620 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2621 return NullUniValue;
2624 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
2625 throw std::runtime_error(
2626 "fundrawtransaction \"hexstring\" ( options )\n"
2627 "\nAdd inputs to a transaction until it has enough in value to meet its out value.\n"
2628 "This will not modify existing inputs, and will add at most one change output to the outputs.\n"
2629 "No existing outputs will be modified unless \"subtractFeeFromOutputs\" is specified.\n"
2630 "Note that inputs which were signed may need to be resigned after completion since in/outputs have been added.\n"
2631 "The inputs added will not be signed, use signrawtransaction for that.\n"
2632 "Note that all existing inputs must have their previous output transaction be in the wallet.\n"
2633 "Note that all inputs selected must be of standard form and P2SH scripts must be\n"
2634 "in the wallet using importaddress or addmultisigaddress (to calculate fees).\n"
2635 "You can see whether this is the case by checking the \"solvable\" field in the listunspent output.\n"
2636 "Only pay-to-pubkey, multisig, and P2SH versions thereof are currently supported for watch-only\n"
2637 "\nArguments:\n"
2638 "1. \"hexstring\" (string, required) The hex string of the raw transaction\n"
2639 "2. options (object, optional)\n"
2640 " {\n"
2641 " \"changeAddress\" (string, optional, default pool address) The bitcoin address to receive the change\n"
2642 " \"changePosition\" (numeric, optional, default random) The index of the change output\n"
2643 " \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n"
2644 " \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\n"
2645 " \"reserveChangeKey\" (boolean, optional, default true) Reserves the change output key from the keypool\n"
2646 " \"feeRate\" (numeric, optional, default not set: makes wallet determine the fee) Set a specific feerate (" + CURRENCY_UNIT + " per KB)\n"
2647 " \"subtractFeeFromOutputs\" (array, optional) A json array of integers.\n"
2648 " The fee will be equally deducted from the amount of each specified output.\n"
2649 " The outputs are specified by their zero-based index, before any change output is added.\n"
2650 " Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
2651 " If no outputs are specified here, the sender pays the fee.\n"
2652 " [vout_index,...]\n"
2653 " }\n"
2654 " for backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}\n"
2655 "\nResult:\n"
2656 "{\n"
2657 " \"hex\": \"value\", (string) The resulting raw transaction (hex-encoded string)\n"
2658 " \"fee\": n, (numeric) Fee in " + CURRENCY_UNIT + " the resulting transaction pays\n"
2659 " \"changepos\": n (numeric) The position of the added change output, or -1\n"
2660 "}\n"
2661 "\nExamples:\n"
2662 "\nCreate a transaction with no inputs\n"
2663 + HelpExampleCli("createrawtransaction", "\"[]\" \"{\\\"myaddress\\\":0.01}\"") +
2664 "\nAdd sufficient unsigned inputs to meet the output value\n"
2665 + HelpExampleCli("fundrawtransaction", "\"rawtransactionhex\"") +
2666 "\nSign the transaction\n"
2667 + HelpExampleCli("signrawtransaction", "\"fundedtransactionhex\"") +
2668 "\nSend the transaction\n"
2669 + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"")
2672 RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR));
2674 CTxDestination changeAddress = CNoDestination();
2675 int changePosition = -1;
2676 bool includeWatching = false;
2677 bool lockUnspents = false;
2678 bool reserveChangeKey = true;
2679 CFeeRate feeRate = CFeeRate(0);
2680 bool overrideEstimatedFeerate = false;
2681 UniValue subtractFeeFromOutputs;
2682 std::set<int> setSubtractFeeFromOutputs;
2684 if (request.params.size() > 1) {
2685 if (request.params[1].type() == UniValue::VBOOL) {
2686 // backward compatibility bool only fallback
2687 includeWatching = request.params[1].get_bool();
2689 else {
2690 RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR)(UniValue::VOBJ));
2692 UniValue options = request.params[1];
2694 RPCTypeCheckObj(options,
2696 {"changeAddress", UniValueType(UniValue::VSTR)},
2697 {"changePosition", UniValueType(UniValue::VNUM)},
2698 {"includeWatching", UniValueType(UniValue::VBOOL)},
2699 {"lockUnspents", UniValueType(UniValue::VBOOL)},
2700 {"reserveChangeKey", UniValueType(UniValue::VBOOL)},
2701 {"feeRate", UniValueType()}, // will be checked below
2702 {"subtractFeeFromOutputs", UniValueType(UniValue::VARR)},
2704 true, true);
2706 if (options.exists("changeAddress")) {
2707 CBitcoinAddress address(options["changeAddress"].get_str());
2709 if (!address.IsValid())
2710 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "changeAddress must be a valid bitcoin address");
2712 changeAddress = address.Get();
2715 if (options.exists("changePosition"))
2716 changePosition = options["changePosition"].get_int();
2718 if (options.exists("includeWatching"))
2719 includeWatching = options["includeWatching"].get_bool();
2721 if (options.exists("lockUnspents"))
2722 lockUnspents = options["lockUnspents"].get_bool();
2724 if (options.exists("reserveChangeKey"))
2725 reserveChangeKey = options["reserveChangeKey"].get_bool();
2727 if (options.exists("feeRate"))
2729 feeRate = CFeeRate(AmountFromValue(options["feeRate"]));
2730 overrideEstimatedFeerate = true;
2733 if (options.exists("subtractFeeFromOutputs"))
2734 subtractFeeFromOutputs = options["subtractFeeFromOutputs"].get_array();
2738 // parse hex string from parameter
2739 CMutableTransaction tx;
2740 if (!DecodeHexTx(tx, request.params[0].get_str(), true))
2741 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
2743 if (tx.vout.size() == 0)
2744 throw JSONRPCError(RPC_INVALID_PARAMETER, "TX must have at least one output");
2746 if (changePosition != -1 && (changePosition < 0 || (unsigned int)changePosition > tx.vout.size()))
2747 throw JSONRPCError(RPC_INVALID_PARAMETER, "changePosition out of bounds");
2749 for (unsigned int idx = 0; idx < subtractFeeFromOutputs.size(); idx++) {
2750 int pos = subtractFeeFromOutputs[idx].get_int();
2751 if (setSubtractFeeFromOutputs.count(pos))
2752 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, duplicated position: %d", pos));
2753 if (pos < 0)
2754 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, negative position: %d", pos));
2755 if (pos >= int(tx.vout.size()))
2756 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, position too large: %d", pos));
2757 setSubtractFeeFromOutputs.insert(pos);
2760 CAmount nFeeOut;
2761 std::string strFailReason;
2763 if (!pwallet->FundTransaction(tx, nFeeOut, overrideEstimatedFeerate, feeRate, changePosition, strFailReason, includeWatching, lockUnspents, setSubtractFeeFromOutputs, reserveChangeKey, changeAddress)) {
2764 throw JSONRPCError(RPC_WALLET_ERROR, strFailReason);
2767 UniValue result(UniValue::VOBJ);
2768 result.push_back(Pair("hex", EncodeHexTx(tx)));
2769 result.push_back(Pair("changepos", changePosition));
2770 result.push_back(Pair("fee", ValueFromAmount(nFeeOut)));
2772 return result;
2775 // Calculate the size of the transaction assuming all signatures are max size
2776 // Use DummySignatureCreator, which inserts 72 byte signatures everywhere.
2777 // TODO: re-use this in CWallet::CreateTransaction (right now
2778 // CreateTransaction uses the constructed dummy-signed tx to do a priority
2779 // calculation, but we should be able to refactor after priority is removed).
2780 // NOTE: this requires that all inputs must be in mapWallet (eg the tx should
2781 // be IsAllFromMe).
2782 int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, CWallet &wallet)
2784 CMutableTransaction txNew(tx);
2785 std::vector<std::pair<CWalletTx*, unsigned int>> vCoins;
2786 // Look up the inputs. We should have already checked that this transaction
2787 // IsAllFromMe(ISMINE_SPENDABLE), so every input should already be in our
2788 // wallet, with a valid index into the vout array.
2789 for (auto& input : tx.vin) {
2790 const auto mi = wallet.mapWallet.find(input.prevout.hash);
2791 assert(mi != wallet.mapWallet.end() && input.prevout.n < mi->second.tx->vout.size());
2792 vCoins.emplace_back(std::make_pair(&(mi->second), input.prevout.n));
2794 if (!wallet.DummySignTx(txNew, vCoins)) {
2795 // This should never happen, because IsAllFromMe(ISMINE_SPENDABLE)
2796 // implies that we can sign for every input.
2797 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction contains inputs that cannot be signed");
2799 return GetVirtualTransactionSize(txNew);
2802 UniValue bumpfee(const JSONRPCRequest& request)
2804 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2806 if (!EnsureWalletIsAvailable(pwallet, request.fHelp))
2807 return NullUniValue;
2809 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
2810 throw std::runtime_error(
2811 "bumpfee \"txid\" ( options ) \n"
2812 "\nBumps the fee of an opt-in-RBF transaction T, replacing it with a new transaction B.\n"
2813 "An opt-in RBF transaction with the given txid must be in the wallet.\n"
2814 "The command will pay the additional fee by decreasing (or perhaps removing) its change output.\n"
2815 "If the change output is not big enough to cover the increased fee, the command will currently fail\n"
2816 "instead of adding new inputs to compensate. (A future implementation could improve this.)\n"
2817 "The command will fail if the wallet or mempool contains a transaction that spends one of T's outputs.\n"
2818 "By default, the new fee will be calculated automatically using estimatefee.\n"
2819 "The user can specify a confirmation target for estimatefee.\n"
2820 "Alternatively, the user can specify totalFee, or use RPC setpaytxfee to set a higher fee rate.\n"
2821 "At a minimum, the new fee rate must be high enough to pay an additional new relay fee (incrementalfee\n"
2822 "returned by getnetworkinfo) to enter the node's mempool.\n"
2823 "\nArguments:\n"
2824 "1. txid (string, required) The txid to be bumped\n"
2825 "2. options (object, optional)\n"
2826 " {\n"
2827 " \"confTarget\" (numeric, optional) Confirmation target (in blocks)\n"
2828 " \"totalFee\" (numeric, optional) Total fee (NOT feerate) to pay, in satoshis.\n"
2829 " In rare cases, the actual fee paid might be slightly higher than the specified\n"
2830 " totalFee if the tx change output has to be removed because it is too close to\n"
2831 " the dust threshold.\n"
2832 " \"replaceable\" (boolean, optional, default true) Whether the new transaction should still be\n"
2833 " marked bip-125 replaceable. If true, the sequence numbers in the transaction will\n"
2834 " be left unchanged from the original. If false, any input sequence numbers in the\n"
2835 " original transaction that were less than 0xfffffffe will be increased to 0xfffffffe\n"
2836 " so the new transaction will not be explicitly bip-125 replaceable (though it may\n"
2837 " still be replaceable in practice, for example if it has unconfirmed ancestors which\n"
2838 " are replaceable).\n"
2839 " }\n"
2840 "\nResult:\n"
2841 "{\n"
2842 " \"txid\": \"value\", (string) The id of the new transaction\n"
2843 " \"origfee\": n, (numeric) Fee of the replaced transaction\n"
2844 " \"fee\": n, (numeric) Fee of the new transaction\n"
2845 " \"errors\": [ str... ] (json array of strings) Errors encountered during processing (may be empty)\n"
2846 "}\n"
2847 "\nExamples:\n"
2848 "\nBump the fee, get the new transaction\'s txid\n" +
2849 HelpExampleCli("bumpfee", "<txid>"));
2852 RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR)(UniValue::VOBJ));
2853 uint256 hash;
2854 hash.SetHex(request.params[0].get_str());
2856 // retrieve the original tx from the wallet
2857 LOCK2(cs_main, pwallet->cs_wallet);
2858 EnsureWalletIsUnlocked(pwallet);
2859 if (!pwallet->mapWallet.count(hash)) {
2860 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
2862 CWalletTx& wtx = pwallet->mapWallet[hash];
2864 if (pwallet->HasWalletSpend(hash)) {
2865 throw JSONRPCError(RPC_INVALID_PARAMETER, "Transaction has descendants in the wallet");
2869 LOCK(mempool.cs);
2870 auto it = mempool.mapTx.find(hash);
2871 if (it != mempool.mapTx.end() && it->GetCountWithDescendants() > 1) {
2872 throw JSONRPCError(RPC_INVALID_PARAMETER, "Transaction has descendants in the mempool");
2876 if (wtx.GetDepthInMainChain() != 0) {
2877 throw JSONRPCError(RPC_WALLET_ERROR, "Transaction has been mined, or is conflicted with a mined transaction");
2880 if (!SignalsOptInRBF(wtx)) {
2881 throw JSONRPCError(RPC_WALLET_ERROR, "Transaction is not BIP 125 replaceable");
2884 if (wtx.mapValue.count("replaced_by_txid")) {
2885 throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Cannot bump transaction %s which was already bumped by transaction %s", hash.ToString(), wtx.mapValue.at("replaced_by_txid")));
2888 // check that original tx consists entirely of our inputs
2889 // if not, we can't bump the fee, because the wallet has no way of knowing the value of the other inputs (thus the fee)
2890 if (!pwallet->IsAllFromMe(wtx, ISMINE_SPENDABLE)) {
2891 throw JSONRPCError(RPC_WALLET_ERROR, "Transaction contains inputs that don't belong to this wallet");
2894 // figure out which output was change
2895 // if there was no change output or multiple change outputs, fail
2896 int nOutput = -1;
2897 for (size_t i = 0; i < wtx.tx->vout.size(); ++i) {
2898 if (pwallet->IsChange(wtx.tx->vout[i])) {
2899 if (nOutput != -1) {
2900 throw JSONRPCError(RPC_WALLET_ERROR, "Transaction has multiple change outputs");
2902 nOutput = i;
2905 if (nOutput == -1) {
2906 throw JSONRPCError(RPC_WALLET_ERROR, "Transaction does not have a change output");
2909 // Calculate the expected size of the new transaction.
2910 int64_t txSize = GetVirtualTransactionSize(*(wtx.tx));
2911 const int64_t maxNewTxSize = CalculateMaximumSignedTxSize(*wtx.tx, *pwallet);
2913 // optional parameters
2914 bool specifiedConfirmTarget = false;
2915 int newConfirmTarget = nTxConfirmTarget;
2916 CAmount totalFee = 0;
2917 bool replaceable = true;
2918 if (request.params.size() > 1) {
2919 UniValue options = request.params[1];
2920 RPCTypeCheckObj(options,
2922 {"confTarget", UniValueType(UniValue::VNUM)},
2923 {"totalFee", UniValueType(UniValue::VNUM)},
2924 {"replaceable", UniValueType(UniValue::VBOOL)},
2926 true, true);
2928 if (options.exists("confTarget") && options.exists("totalFee")) {
2929 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.");
2930 } else if (options.exists("confTarget")) {
2931 specifiedConfirmTarget = true;
2932 newConfirmTarget = options["confTarget"].get_int();
2933 if (newConfirmTarget <= 0) { // upper-bound will be checked by estimatefee/smartfee
2934 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid confTarget (cannot be <= 0)");
2936 } else if (options.exists("totalFee")) {
2937 totalFee = options["totalFee"].get_int64();
2938 CAmount requiredFee = CWallet::GetRequiredFee(maxNewTxSize);
2939 if (totalFee < requiredFee ) {
2940 throw JSONRPCError(RPC_INVALID_PARAMETER,
2941 strprintf("Insufficient totalFee (cannot be less than required fee %s)",
2942 FormatMoney(requiredFee)));
2946 if (options.exists("replaceable")) {
2947 replaceable = options["replaceable"].get_bool();
2951 // calculate the old fee and fee-rate
2952 CAmount nOldFee = wtx.GetDebit(ISMINE_SPENDABLE) - wtx.tx->GetValueOut();
2953 CFeeRate nOldFeeRate(nOldFee, txSize);
2954 CAmount nNewFee;
2955 CFeeRate nNewFeeRate;
2956 // The wallet uses a conservative WALLET_INCREMENTAL_RELAY_FEE value to
2957 // future proof against changes to network wide policy for incremental relay
2958 // fee that our node may not be aware of.
2959 CFeeRate walletIncrementalRelayFee = CFeeRate(WALLET_INCREMENTAL_RELAY_FEE);
2960 if (::incrementalRelayFee > walletIncrementalRelayFee) {
2961 walletIncrementalRelayFee = ::incrementalRelayFee;
2964 if (totalFee > 0) {
2965 CAmount minTotalFee = nOldFeeRate.GetFee(maxNewTxSize) + ::incrementalRelayFee.GetFee(maxNewTxSize);
2966 if (totalFee < minTotalFee) {
2967 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Insufficient totalFee, must be at least %s (oldFee %s + incrementalFee %s)",
2968 FormatMoney(minTotalFee), FormatMoney(nOldFeeRate.GetFee(maxNewTxSize)), FormatMoney(::incrementalRelayFee.GetFee(maxNewTxSize))));
2970 nNewFee = totalFee;
2971 nNewFeeRate = CFeeRate(totalFee, maxNewTxSize);
2972 } else {
2973 // if user specified a confirm target then don't consider any global payTxFee
2974 if (specifiedConfirmTarget) {
2975 nNewFee = CWallet::GetMinimumFee(maxNewTxSize, newConfirmTarget, mempool, CAmount(0));
2977 // otherwise use the regular wallet logic to select payTxFee or default confirm target
2978 else {
2979 nNewFee = CWallet::GetMinimumFee(maxNewTxSize, newConfirmTarget, mempool);
2982 nNewFeeRate = CFeeRate(nNewFee, maxNewTxSize);
2984 // New fee rate must be at least old rate + minimum incremental relay rate
2985 // walletIncrementalRelayFee.GetFeePerK() should be exact, because it's initialized
2986 // in that unit (fee per kb).
2987 // However, nOldFeeRate is a calculated value from the tx fee/size, so
2988 // add 1 satoshi to the result, because it may have been rounded down.
2989 if (nNewFeeRate.GetFeePerK() < nOldFeeRate.GetFeePerK() + 1 + walletIncrementalRelayFee.GetFeePerK()) {
2990 nNewFeeRate = CFeeRate(nOldFeeRate.GetFeePerK() + 1 + walletIncrementalRelayFee.GetFeePerK());
2991 nNewFee = nNewFeeRate.GetFee(maxNewTxSize);
2995 // Check that in all cases the new fee doesn't violate maxTxFee
2996 if (nNewFee > maxTxFee) {
2997 throw JSONRPCError(RPC_WALLET_ERROR,
2998 strprintf("Specified or calculated fee %s is too high (cannot be higher than maxTxFee %s)",
2999 FormatMoney(nNewFee), FormatMoney(maxTxFee)));
3002 // check that fee rate is higher than mempool's minimum fee
3003 // (no point in bumping fee if we know that the new tx won't be accepted to the mempool)
3004 // This may occur if the user set TotalFee or paytxfee too low, if fallbackfee is too low, or, perhaps,
3005 // in a rare situation where the mempool minimum fee increased significantly since the fee estimation just a
3006 // moment earlier. In this case, we report an error to the user, who may use totalFee to make an adjustment.
3007 CFeeRate minMempoolFeeRate = mempool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000);
3008 if (nNewFeeRate.GetFeePerK() < minMempoolFeeRate.GetFeePerK()) {
3009 throw JSONRPCError(RPC_WALLET_ERROR, strprintf("New fee rate (%s) is less than the minimum fee rate (%s) to get into the mempool. totalFee value should to be at least %s or settxfee value should be at least %s to add transaction.", FormatMoney(nNewFeeRate.GetFeePerK()), FormatMoney(minMempoolFeeRate.GetFeePerK()), FormatMoney(minMempoolFeeRate.GetFee(maxNewTxSize)), FormatMoney(minMempoolFeeRate.GetFeePerK())));
3012 // Now modify the output to increase the fee.
3013 // If the output is not large enough to pay the fee, fail.
3014 CAmount nDelta = nNewFee - nOldFee;
3015 assert(nDelta > 0);
3016 CMutableTransaction tx(*(wtx.tx));
3017 CTxOut* poutput = &(tx.vout[nOutput]);
3018 if (poutput->nValue < nDelta) {
3019 throw JSONRPCError(RPC_WALLET_ERROR, "Change output is too small to bump the fee");
3022 // If the output would become dust, discard it (converting the dust to fee)
3023 poutput->nValue -= nDelta;
3024 if (poutput->nValue <= poutput->GetDustThreshold(::dustRelayFee)) {
3025 LogPrint("rpc", "Bumping fee and discarding dust output\n");
3026 nNewFee += poutput->nValue;
3027 tx.vout.erase(tx.vout.begin() + nOutput);
3030 // Mark new tx not replaceable, if requested.
3031 if (!replaceable) {
3032 for (auto& input : tx.vin) {
3033 if (input.nSequence < 0xfffffffe) input.nSequence = 0xfffffffe;
3037 // sign the new tx
3038 CTransaction txNewConst(tx);
3039 int nIn = 0;
3040 for (auto& input : tx.vin) {
3041 std::map<uint256, CWalletTx>::const_iterator mi = pwallet->mapWallet.find(input.prevout.hash);
3042 assert(mi != pwallet->mapWallet.end() && input.prevout.n < mi->second.tx->vout.size());
3043 const CScript& scriptPubKey = mi->second.tx->vout[input.prevout.n].scriptPubKey;
3044 const CAmount& amount = mi->second.tx->vout[input.prevout.n].nValue;
3045 SignatureData sigdata;
3046 if (!ProduceSignature(TransactionSignatureCreator(pwallet, &txNewConst, nIn, amount, SIGHASH_ALL), scriptPubKey, sigdata)) {
3047 throw JSONRPCError(RPC_WALLET_ERROR, "Can't sign transaction.");
3049 UpdateTransaction(tx, nIn, sigdata);
3050 nIn++;
3053 // commit/broadcast the tx
3054 CReserveKey reservekey(pwallet);
3055 CWalletTx wtxBumped(pwallet, MakeTransactionRef(std::move(tx)));
3056 wtxBumped.mapValue = wtx.mapValue;
3057 wtxBumped.mapValue["replaces_txid"] = hash.ToString();
3058 wtxBumped.vOrderForm = wtx.vOrderForm;
3059 wtxBumped.strFromAccount = wtx.strFromAccount;
3060 wtxBumped.fTimeReceivedIsTxTime = true;
3061 wtxBumped.fFromMe = true;
3062 CValidationState state;
3063 if (!pwallet->CommitTransaction(wtxBumped, reservekey, g_connman.get(), state)) {
3064 // NOTE: CommitTransaction never returns false, so this should never happen.
3065 throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason()));
3068 UniValue vErrors(UniValue::VARR);
3069 if (state.IsInvalid()) {
3070 // This can happen if the mempool rejected the transaction. Report
3071 // what happened in the "errors" response.
3072 vErrors.push_back(strprintf("Error: The transaction was rejected: %s", FormatStateMessage(state)));
3075 // mark the original tx as bumped
3076 if (!pwallet->MarkReplaced(wtx.GetHash(), wtxBumped.GetHash())) {
3077 // TODO: see if JSON-RPC has a standard way of returning a response
3078 // along with an exception. It would be good to return information about
3079 // wtxBumped to the caller even if marking the original transaction
3080 // replaced does not succeed for some reason.
3081 vErrors.push_back("Error: Created new bumpfee transaction but could not mark the original transaction as replaced.");
3084 UniValue result(UniValue::VOBJ);
3085 result.push_back(Pair("txid", wtxBumped.GetHash().GetHex()));
3086 result.push_back(Pair("origfee", ValueFromAmount(nOldFee)));
3087 result.push_back(Pair("fee", ValueFromAmount(nNewFee)));
3088 result.push_back(Pair("errors", vErrors));
3090 return result;
3093 extern UniValue dumpprivkey(const JSONRPCRequest& request); // in rpcdump.cpp
3094 extern UniValue importprivkey(const JSONRPCRequest& request);
3095 extern UniValue importaddress(const JSONRPCRequest& request);
3096 extern UniValue importpubkey(const JSONRPCRequest& request);
3097 extern UniValue dumpwallet(const JSONRPCRequest& request);
3098 extern UniValue importwallet(const JSONRPCRequest& request);
3099 extern UniValue importprunedfunds(const JSONRPCRequest& request);
3100 extern UniValue removeprunedfunds(const JSONRPCRequest& request);
3101 extern UniValue importmulti(const JSONRPCRequest& request);
3103 static const CRPCCommand commands[] =
3104 { // category name actor (function) okSafeMode
3105 // --------------------- ------------------------ ----------------------- ----------
3106 { "rawtransactions", "fundrawtransaction", &fundrawtransaction, false, {"hexstring","options"} },
3107 { "hidden", "resendwallettransactions", &resendwallettransactions, true, {} },
3108 { "wallet", "abandontransaction", &abandontransaction, false, {"txid"} },
3109 { "wallet", "addmultisigaddress", &addmultisigaddress, true, {"nrequired","keys","account"} },
3110 { "wallet", "addwitnessaddress", &addwitnessaddress, true, {"address"} },
3111 { "wallet", "backupwallet", &backupwallet, true, {"destination"} },
3112 { "wallet", "bumpfee", &bumpfee, true, {"txid", "options"} },
3113 { "wallet", "dumpprivkey", &dumpprivkey, true, {"address"} },
3114 { "wallet", "dumpwallet", &dumpwallet, true, {"filename"} },
3115 { "wallet", "encryptwallet", &encryptwallet, true, {"passphrase"} },
3116 { "wallet", "getaccountaddress", &getaccountaddress, true, {"account"} },
3117 { "wallet", "getaccount", &getaccount, true, {"address"} },
3118 { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true, {"account"} },
3119 { "wallet", "getbalance", &getbalance, false, {"account","minconf","include_watchonly"} },
3120 { "wallet", "getnewaddress", &getnewaddress, true, {"account"} },
3121 { "wallet", "getrawchangeaddress", &getrawchangeaddress, true, {} },
3122 { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false, {"account","minconf"} },
3123 { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false, {"address","minconf"} },
3124 { "wallet", "gettransaction", &gettransaction, false, {"txid","include_watchonly"} },
3125 { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false, {} },
3126 { "wallet", "getwalletinfo", &getwalletinfo, false, {} },
3127 { "wallet", "importmulti", &importmulti, true, {"requests","options"} },
3128 { "wallet", "importprivkey", &importprivkey, true, {"privkey","label","rescan"} },
3129 { "wallet", "importwallet", &importwallet, true, {"filename"} },
3130 { "wallet", "importaddress", &importaddress, true, {"address","label","rescan","p2sh"} },
3131 { "wallet", "importprunedfunds", &importprunedfunds, true, {"rawtransaction","txoutproof"} },
3132 { "wallet", "importpubkey", &importpubkey, true, {"pubkey","label","rescan"} },
3133 { "wallet", "keypoolrefill", &keypoolrefill, true, {"newsize"} },
3134 { "wallet", "listaccounts", &listaccounts, false, {"minconf","include_watchonly"} },
3135 { "wallet", "listaddressgroupings", &listaddressgroupings, false, {} },
3136 { "wallet", "listlockunspent", &listlockunspent, false, {} },
3137 { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, false, {"minconf","include_empty","include_watchonly"} },
3138 { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false, {"minconf","include_empty","include_watchonly"} },
3139 { "wallet", "listsinceblock", &listsinceblock, false, {"blockhash","target_confirmations","include_watchonly"} },
3140 { "wallet", "listtransactions", &listtransactions, false, {"account","count","skip","include_watchonly"} },
3141 { "wallet", "listunspent", &listunspent, false, {"minconf","maxconf","addresses","include_unsafe"} },
3142 { "wallet", "lockunspent", &lockunspent, true, {"unlock","transactions"} },
3143 { "wallet", "move", &movecmd, false, {"fromaccount","toaccount","amount","minconf","comment"} },
3144 { "wallet", "sendfrom", &sendfrom, false, {"fromaccount","toaddress","amount","minconf","comment","comment_to"} },
3145 { "wallet", "sendmany", &sendmany, false, {"fromaccount","amounts","minconf","comment","subtractfeefrom"} },
3146 { "wallet", "sendtoaddress", &sendtoaddress, false, {"address","amount","comment","comment_to","subtractfeefromamount"} },
3147 { "wallet", "setaccount", &setaccount, true, {"address","account"} },
3148 { "wallet", "settxfee", &settxfee, true, {"amount"} },
3149 { "wallet", "signmessage", &signmessage, true, {"address","message"} },
3150 { "wallet", "walletlock", &walletlock, true, {} },
3151 { "wallet", "walletpassphrasechange", &walletpassphrasechange, true, {"oldpassphrase","newpassphrase"} },
3152 { "wallet", "walletpassphrase", &walletpassphrase, true, {"passphrase","timeout"} },
3153 { "wallet", "removeprunedfunds", &removeprunedfunds, true, {"txid"} },
3156 void RegisterWalletRPCCommands(CRPCTable &t)
3158 if (GetBoolArg("-disablewallet", false))
3159 return;
3161 for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
3162 t.appendCommand(commands[vcidx].name, &commands[vcidx]);