Wallet: Replace pwalletMain with a vector of wallet pointers
[bitcoinplatinum.git] / src / wallet / rpcwallet.cpp
blob7b9ed91947c52c80c413d45fd714842bbf141987
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 "wallet/coincontrol.h"
13 #include "validation.h"
14 #include "net.h"
15 #include "policy/feerate.h"
16 #include "policy/fees.h"
17 #include "policy/policy.h"
18 #include "policy/rbf.h"
19 #include "rpc/server.h"
20 #include "script/sign.h"
21 #include "timedata.h"
22 #include "util.h"
23 #include "utilmoneystr.h"
24 #include "wallet/feebumper.h"
25 #include "wallet/wallet.h"
26 #include "wallet/walletdb.h"
28 #include <stdint.h>
30 #include <boost/assign/list_of.hpp>
32 #include <univalue.h>
34 CWallet *GetWalletForJSONRPCRequest(const JSONRPCRequest& request)
36 // TODO: Some way to access secondary wallets
37 return vpwallets.empty() ? nullptr : vpwallets[0];
40 std::string HelpRequiringPassphrase(CWallet * const pwallet)
42 return pwallet && pwallet->IsCrypted()
43 ? "\nRequires wallet passphrase to be set with walletpassphrase call."
44 : "";
47 bool EnsureWalletIsAvailable(CWallet * const pwallet, bool avoidException)
49 if (!pwallet) {
50 if (!avoidException)
51 throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
52 else
53 return false;
55 return true;
58 void EnsureWalletIsUnlocked(CWallet * const pwallet)
60 if (pwallet->IsLocked()) {
61 throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first.");
65 void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry)
67 int confirms = wtx.GetDepthInMainChain();
68 entry.push_back(Pair("confirmations", confirms));
69 if (wtx.IsCoinBase())
70 entry.push_back(Pair("generated", true));
71 if (confirms > 0)
73 entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex()));
74 entry.push_back(Pair("blockindex", wtx.nIndex));
75 entry.push_back(Pair("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime()));
76 } else {
77 entry.push_back(Pair("trusted", wtx.IsTrusted()));
79 uint256 hash = wtx.GetHash();
80 entry.push_back(Pair("txid", hash.GetHex()));
81 UniValue conflicts(UniValue::VARR);
82 BOOST_FOREACH(const uint256& conflict, wtx.GetConflicts())
83 conflicts.push_back(conflict.GetHex());
84 entry.push_back(Pair("walletconflicts", conflicts));
85 entry.push_back(Pair("time", wtx.GetTxTime()));
86 entry.push_back(Pair("timereceived", (int64_t)wtx.nTimeReceived));
88 // Add opt-in RBF status
89 std::string rbfStatus = "no";
90 if (confirms <= 0) {
91 LOCK(mempool.cs);
92 RBFTransactionState rbfState = IsRBFOptIn(wtx, mempool);
93 if (rbfState == RBF_TRANSACTIONSTATE_UNKNOWN)
94 rbfStatus = "unknown";
95 else if (rbfState == RBF_TRANSACTIONSTATE_REPLACEABLE_BIP125)
96 rbfStatus = "yes";
98 entry.push_back(Pair("bip125-replaceable", rbfStatus));
100 BOOST_FOREACH(const PAIRTYPE(std::string, std::string)& item, wtx.mapValue)
101 entry.push_back(Pair(item.first, item.second));
104 std::string AccountFromValue(const UniValue& value)
106 std::string strAccount = value.get_str();
107 if (strAccount == "*")
108 throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Invalid account name");
109 return strAccount;
112 UniValue getnewaddress(const JSONRPCRequest& request)
114 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
115 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
116 return NullUniValue;
119 if (request.fHelp || request.params.size() > 1)
120 throw std::runtime_error(
121 "getnewaddress ( \"account\" )\n"
122 "\nReturns a new Bitcoin address for receiving payments.\n"
123 "If 'account' is specified (DEPRECATED), it is added to the address book \n"
124 "so payments received with the address will be credited to 'account'.\n"
125 "\nArguments:\n"
126 "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"
127 "\nResult:\n"
128 "\"address\" (string) The new bitcoin address\n"
129 "\nExamples:\n"
130 + HelpExampleCli("getnewaddress", "")
131 + HelpExampleRpc("getnewaddress", "")
134 LOCK2(cs_main, pwallet->cs_wallet);
136 // Parse the account first so we don't generate a key if there's an error
137 std::string strAccount;
138 if (request.params.size() > 0)
139 strAccount = AccountFromValue(request.params[0]);
141 if (!pwallet->IsLocked()) {
142 pwallet->TopUpKeyPool();
145 // Generate a new key that is added to wallet
146 CPubKey newKey;
147 if (!pwallet->GetKeyFromPool(newKey)) {
148 throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
150 CKeyID keyID = newKey.GetID();
152 pwallet->SetAddressBook(keyID, strAccount, "receive");
154 return CBitcoinAddress(keyID).ToString();
158 CBitcoinAddress GetAccountAddress(CWallet* const pwallet, std::string strAccount, bool bForceNew=false)
160 CPubKey pubKey;
161 if (!pwallet->GetAccountPubkey(pubKey, strAccount, bForceNew)) {
162 throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
165 return CBitcoinAddress(pubKey.GetID());
168 UniValue getaccountaddress(const JSONRPCRequest& request)
170 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
171 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
172 return NullUniValue;
175 if (request.fHelp || request.params.size() != 1)
176 throw std::runtime_error(
177 "getaccountaddress \"account\"\n"
178 "\nDEPRECATED. Returns the current Bitcoin address for receiving payments to this account.\n"
179 "\nArguments:\n"
180 "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"
181 "\nResult:\n"
182 "\"address\" (string) The account bitcoin address\n"
183 "\nExamples:\n"
184 + HelpExampleCli("getaccountaddress", "")
185 + HelpExampleCli("getaccountaddress", "\"\"")
186 + HelpExampleCli("getaccountaddress", "\"myaccount\"")
187 + HelpExampleRpc("getaccountaddress", "\"myaccount\"")
190 LOCK2(cs_main, pwallet->cs_wallet);
192 // Parse the account first so we don't generate a key if there's an error
193 std::string strAccount = AccountFromValue(request.params[0]);
195 UniValue ret(UniValue::VSTR);
197 ret = GetAccountAddress(pwallet, strAccount).ToString();
198 return ret;
202 UniValue getrawchangeaddress(const JSONRPCRequest& request)
204 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
205 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
206 return NullUniValue;
209 if (request.fHelp || request.params.size() > 1)
210 throw std::runtime_error(
211 "getrawchangeaddress\n"
212 "\nReturns a new Bitcoin address, for receiving change.\n"
213 "This is for use with raw transactions, NOT normal use.\n"
214 "\nResult:\n"
215 "\"address\" (string) The address\n"
216 "\nExamples:\n"
217 + HelpExampleCli("getrawchangeaddress", "")
218 + HelpExampleRpc("getrawchangeaddress", "")
221 LOCK2(cs_main, pwallet->cs_wallet);
223 if (!pwallet->IsLocked()) {
224 pwallet->TopUpKeyPool();
227 CReserveKey reservekey(pwallet);
228 CPubKey vchPubKey;
229 if (!reservekey.GetReservedKey(vchPubKey, true))
230 throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
232 reservekey.KeepKey();
234 CKeyID keyID = vchPubKey.GetID();
236 return CBitcoinAddress(keyID).ToString();
240 UniValue setaccount(const JSONRPCRequest& request)
242 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
243 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
244 return NullUniValue;
247 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
248 throw std::runtime_error(
249 "setaccount \"address\" \"account\"\n"
250 "\nDEPRECATED. Sets the account associated with the given address.\n"
251 "\nArguments:\n"
252 "1. \"address\" (string, required) The bitcoin address to be associated with an account.\n"
253 "2. \"account\" (string, required) The account to assign the address to.\n"
254 "\nExamples:\n"
255 + HelpExampleCli("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"tabby\"")
256 + HelpExampleRpc("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"tabby\"")
259 LOCK2(cs_main, pwallet->cs_wallet);
261 CBitcoinAddress address(request.params[0].get_str());
262 if (!address.IsValid())
263 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
265 std::string strAccount;
266 if (request.params.size() > 1)
267 strAccount = AccountFromValue(request.params[1]);
269 // Only add the account if the address is yours.
270 if (IsMine(*pwallet, address.Get())) {
271 // Detect when changing the account of an address that is the 'unused current key' of another account:
272 if (pwallet->mapAddressBook.count(address.Get())) {
273 std::string strOldAccount = pwallet->mapAddressBook[address.Get()].name;
274 if (address == GetAccountAddress(pwallet, strOldAccount)) {
275 GetAccountAddress(pwallet, strOldAccount, true);
278 pwallet->SetAddressBook(address.Get(), strAccount, "receive");
280 else
281 throw JSONRPCError(RPC_MISC_ERROR, "setaccount can only be used with own address");
283 return NullUniValue;
287 UniValue getaccount(const JSONRPCRequest& request)
289 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
290 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
291 return NullUniValue;
294 if (request.fHelp || request.params.size() != 1)
295 throw std::runtime_error(
296 "getaccount \"address\"\n"
297 "\nDEPRECATED. Returns the account associated with the given address.\n"
298 "\nArguments:\n"
299 "1. \"address\" (string, required) The bitcoin address for account lookup.\n"
300 "\nResult:\n"
301 "\"accountname\" (string) the account address\n"
302 "\nExamples:\n"
303 + HelpExampleCli("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"")
304 + HelpExampleRpc("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"")
307 LOCK2(cs_main, pwallet->cs_wallet);
309 CBitcoinAddress address(request.params[0].get_str());
310 if (!address.IsValid())
311 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
313 std::string strAccount;
314 std::map<CTxDestination, CAddressBookData>::iterator mi = pwallet->mapAddressBook.find(address.Get());
315 if (mi != pwallet->mapAddressBook.end() && !(*mi).second.name.empty()) {
316 strAccount = (*mi).second.name;
318 return strAccount;
322 UniValue getaddressesbyaccount(const JSONRPCRequest& request)
324 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
325 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
326 return NullUniValue;
329 if (request.fHelp || request.params.size() != 1)
330 throw std::runtime_error(
331 "getaddressesbyaccount \"account\"\n"
332 "\nDEPRECATED. Returns the list of addresses for the given account.\n"
333 "\nArguments:\n"
334 "1. \"account\" (string, required) The account name.\n"
335 "\nResult:\n"
336 "[ (json array of string)\n"
337 " \"address\" (string) a bitcoin address associated with the given account\n"
338 " ,...\n"
339 "]\n"
340 "\nExamples:\n"
341 + HelpExampleCli("getaddressesbyaccount", "\"tabby\"")
342 + HelpExampleRpc("getaddressesbyaccount", "\"tabby\"")
345 LOCK2(cs_main, pwallet->cs_wallet);
347 std::string strAccount = AccountFromValue(request.params[0]);
349 // Find all addresses that have the given account
350 UniValue ret(UniValue::VARR);
351 for (const std::pair<CBitcoinAddress, CAddressBookData>& item : pwallet->mapAddressBook) {
352 const CBitcoinAddress& address = item.first;
353 const std::string& strName = item.second.name;
354 if (strName == strAccount)
355 ret.push_back(address.ToString());
357 return ret;
360 static void SendMoney(CWallet * const pwallet, const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew)
362 CAmount curBalance = pwallet->GetBalance();
364 // Check amount
365 if (nValue <= 0)
366 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount");
368 if (nValue > curBalance)
369 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds");
371 if (pwallet->GetBroadcastTransactions() && !g_connman) {
372 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
375 // Parse Bitcoin address
376 CScript scriptPubKey = GetScriptForDestination(address);
378 // Create and send the transaction
379 CReserveKey reservekey(pwallet);
380 CAmount nFeeRequired;
381 std::string strError;
382 std::vector<CRecipient> vecSend;
383 int nChangePosRet = -1;
384 CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount};
385 vecSend.push_back(recipient);
386 if (!pwallet->CreateTransaction(vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError)) {
387 if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance)
388 strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired));
389 throw JSONRPCError(RPC_WALLET_ERROR, strError);
391 CValidationState state;
392 if (!pwallet->CommitTransaction(wtxNew, reservekey, g_connman.get(), state)) {
393 strError = strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason());
394 throw JSONRPCError(RPC_WALLET_ERROR, strError);
398 UniValue sendtoaddress(const JSONRPCRequest& request)
400 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
401 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
402 return NullUniValue;
405 if (request.fHelp || request.params.size() < 2 || request.params.size() > 5)
406 throw std::runtime_error(
407 "sendtoaddress \"address\" amount ( \"comment\" \"comment_to\" subtractfeefromamount )\n"
408 "\nSend an amount to a given address.\n"
409 + HelpRequiringPassphrase(pwallet) +
410 "\nArguments:\n"
411 "1. \"address\" (string, required) The bitcoin address to send to.\n"
412 "2. \"amount\" (numeric or string, required) The amount in " + CURRENCY_UNIT + " to send. eg 0.1\n"
413 "3. \"comment\" (string, optional) A comment used to store what the transaction is for. \n"
414 " This is not part of the transaction, just kept in your wallet.\n"
415 "4. \"comment_to\" (string, optional) A comment to store the name of the person or organization \n"
416 " to which you're sending the transaction. This is not part of the \n"
417 " transaction, just kept in your wallet.\n"
418 "5. subtractfeefromamount (boolean, optional, default=false) The fee will be deducted from the amount being sent.\n"
419 " The recipient will receive less bitcoins than you enter in the amount field.\n"
420 "\nResult:\n"
421 "\"txid\" (string) The transaction id.\n"
422 "\nExamples:\n"
423 + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1")
424 + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"donation\" \"seans outpost\"")
425 + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"\" \"\" true")
426 + HelpExampleRpc("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.1, \"donation\", \"seans outpost\"")
429 LOCK2(cs_main, pwallet->cs_wallet);
431 CBitcoinAddress address(request.params[0].get_str());
432 if (!address.IsValid())
433 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
435 // Amount
436 CAmount nAmount = AmountFromValue(request.params[1]);
437 if (nAmount <= 0)
438 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
440 // Wallet comments
441 CWalletTx wtx;
442 if (request.params.size() > 2 && !request.params[2].isNull() && !request.params[2].get_str().empty())
443 wtx.mapValue["comment"] = request.params[2].get_str();
444 if (request.params.size() > 3 && !request.params[3].isNull() && !request.params[3].get_str().empty())
445 wtx.mapValue["to"] = request.params[3].get_str();
447 bool fSubtractFeeFromAmount = false;
448 if (request.params.size() > 4)
449 fSubtractFeeFromAmount = request.params[4].get_bool();
451 EnsureWalletIsUnlocked(pwallet);
453 SendMoney(pwallet, address.Get(), nAmount, fSubtractFeeFromAmount, wtx);
455 return wtx.GetHash().GetHex();
458 UniValue listaddressgroupings(const JSONRPCRequest& request)
460 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
461 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
462 return NullUniValue;
465 if (request.fHelp)
466 throw std::runtime_error(
467 "listaddressgroupings\n"
468 "\nLists groups of addresses which have had their common ownership\n"
469 "made public by common use as inputs or as the resulting change\n"
470 "in past transactions\n"
471 "\nResult:\n"
472 "[\n"
473 " [\n"
474 " [\n"
475 " \"address\", (string) The bitcoin address\n"
476 " amount, (numeric) The amount in " + CURRENCY_UNIT + "\n"
477 " \"account\" (string, optional) DEPRECATED. The account\n"
478 " ]\n"
479 " ,...\n"
480 " ]\n"
481 " ,...\n"
482 "]\n"
483 "\nExamples:\n"
484 + HelpExampleCli("listaddressgroupings", "")
485 + HelpExampleRpc("listaddressgroupings", "")
488 LOCK2(cs_main, pwallet->cs_wallet);
490 UniValue jsonGroupings(UniValue::VARR);
491 std::map<CTxDestination, CAmount> balances = pwallet->GetAddressBalances();
492 for (std::set<CTxDestination> grouping : pwallet->GetAddressGroupings()) {
493 UniValue jsonGrouping(UniValue::VARR);
494 BOOST_FOREACH(CTxDestination address, grouping)
496 UniValue addressInfo(UniValue::VARR);
497 addressInfo.push_back(CBitcoinAddress(address).ToString());
498 addressInfo.push_back(ValueFromAmount(balances[address]));
500 if (pwallet->mapAddressBook.find(CBitcoinAddress(address).Get()) != pwallet->mapAddressBook.end()) {
501 addressInfo.push_back(pwallet->mapAddressBook.find(CBitcoinAddress(address).Get())->second.name);
504 jsonGrouping.push_back(addressInfo);
506 jsonGroupings.push_back(jsonGrouping);
508 return jsonGroupings;
511 UniValue signmessage(const JSONRPCRequest& request)
513 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
514 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
515 return NullUniValue;
518 if (request.fHelp || request.params.size() != 2)
519 throw std::runtime_error(
520 "signmessage \"address\" \"message\"\n"
521 "\nSign a message with the private key of an address"
522 + HelpRequiringPassphrase(pwallet) + "\n"
523 "\nArguments:\n"
524 "1. \"address\" (string, required) The bitcoin address to use for the private key.\n"
525 "2. \"message\" (string, required) The message to create a signature of.\n"
526 "\nResult:\n"
527 "\"signature\" (string) The signature of the message encoded in base 64\n"
528 "\nExamples:\n"
529 "\nUnlock the wallet for 30 seconds\n"
530 + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
531 "\nCreate the signature\n"
532 + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") +
533 "\nVerify the signature\n"
534 + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") +
535 "\nAs json rpc\n"
536 + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"my message\"")
539 LOCK2(cs_main, pwallet->cs_wallet);
541 EnsureWalletIsUnlocked(pwallet);
543 std::string strAddress = request.params[0].get_str();
544 std::string strMessage = request.params[1].get_str();
546 CBitcoinAddress addr(strAddress);
547 if (!addr.IsValid())
548 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
550 CKeyID keyID;
551 if (!addr.GetKeyID(keyID))
552 throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
554 CKey key;
555 if (!pwallet->GetKey(keyID, key)) {
556 throw JSONRPCError(RPC_WALLET_ERROR, "Private key not available");
559 CHashWriter ss(SER_GETHASH, 0);
560 ss << strMessageMagic;
561 ss << strMessage;
563 std::vector<unsigned char> vchSig;
564 if (!key.SignCompact(ss.GetHash(), vchSig))
565 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed");
567 return EncodeBase64(&vchSig[0], vchSig.size());
570 UniValue getreceivedbyaddress(const JSONRPCRequest& request)
572 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
573 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
574 return NullUniValue;
577 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
578 throw std::runtime_error(
579 "getreceivedbyaddress \"address\" ( minconf )\n"
580 "\nReturns the total amount received by the given address in transactions with at least minconf confirmations.\n"
581 "\nArguments:\n"
582 "1. \"address\" (string, required) The bitcoin address for transactions.\n"
583 "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
584 "\nResult:\n"
585 "amount (numeric) The total amount in " + CURRENCY_UNIT + " received at this address.\n"
586 "\nExamples:\n"
587 "\nThe amount from transactions with at least 1 confirmation\n"
588 + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"") +
589 "\nThe amount including unconfirmed transactions, zero confirmations\n"
590 + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" 0") +
591 "\nThe amount with at least 6 confirmation, very safe\n"
592 + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" 6") +
593 "\nAs a json rpc call\n"
594 + HelpExampleRpc("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", 6")
597 LOCK2(cs_main, pwallet->cs_wallet);
599 // Bitcoin address
600 CBitcoinAddress address = CBitcoinAddress(request.params[0].get_str());
601 if (!address.IsValid())
602 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
603 CScript scriptPubKey = GetScriptForDestination(address.Get());
604 if (!IsMine(*pwallet, scriptPubKey)) {
605 return ValueFromAmount(0);
608 // Minimum confirmations
609 int nMinDepth = 1;
610 if (request.params.size() > 1)
611 nMinDepth = request.params[1].get_int();
613 // Tally
614 CAmount nAmount = 0;
615 for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
616 const CWalletTx& wtx = pairWtx.second;
617 if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx))
618 continue;
620 BOOST_FOREACH(const CTxOut& txout, wtx.tx->vout)
621 if (txout.scriptPubKey == scriptPubKey)
622 if (wtx.GetDepthInMainChain() >= nMinDepth)
623 nAmount += txout.nValue;
626 return ValueFromAmount(nAmount);
630 UniValue getreceivedbyaccount(const JSONRPCRequest& request)
632 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
633 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
634 return NullUniValue;
637 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
638 throw std::runtime_error(
639 "getreceivedbyaccount \"account\" ( minconf )\n"
640 "\nDEPRECATED. Returns the total amount received by addresses with <account> in transactions with at least [minconf] confirmations.\n"
641 "\nArguments:\n"
642 "1. \"account\" (string, required) The selected account, may be the default account using \"\".\n"
643 "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
644 "\nResult:\n"
645 "amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n"
646 "\nExamples:\n"
647 "\nAmount received by the default account with at least 1 confirmation\n"
648 + HelpExampleCli("getreceivedbyaccount", "\"\"") +
649 "\nAmount received at the tabby account including unconfirmed amounts with zero confirmations\n"
650 + HelpExampleCli("getreceivedbyaccount", "\"tabby\" 0") +
651 "\nThe amount with at least 6 confirmation, very safe\n"
652 + HelpExampleCli("getreceivedbyaccount", "\"tabby\" 6") +
653 "\nAs a json rpc call\n"
654 + HelpExampleRpc("getreceivedbyaccount", "\"tabby\", 6")
657 LOCK2(cs_main, pwallet->cs_wallet);
659 // Minimum confirmations
660 int nMinDepth = 1;
661 if (request.params.size() > 1)
662 nMinDepth = request.params[1].get_int();
664 // Get the set of pub keys assigned to account
665 std::string strAccount = AccountFromValue(request.params[0]);
666 std::set<CTxDestination> setAddress = pwallet->GetAccountAddresses(strAccount);
668 // Tally
669 CAmount nAmount = 0;
670 for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
671 const CWalletTx& wtx = pairWtx.second;
672 if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx))
673 continue;
675 BOOST_FOREACH(const CTxOut& txout, wtx.tx->vout)
677 CTxDestination address;
678 if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*pwallet, address) && setAddress.count(address)) {
679 if (wtx.GetDepthInMainChain() >= nMinDepth)
680 nAmount += txout.nValue;
685 return ValueFromAmount(nAmount);
689 UniValue getbalance(const JSONRPCRequest& request)
691 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
692 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
693 return NullUniValue;
696 if (request.fHelp || request.params.size() > 3)
697 throw std::runtime_error(
698 "getbalance ( \"account\" minconf include_watchonly )\n"
699 "\nIf account is not specified, returns the server's total available balance.\n"
700 "If account is specified (DEPRECATED), returns the balance in the account.\n"
701 "Note that the account \"\" is not the same as leaving the parameter out.\n"
702 "The server total may be different to the balance in the default \"\" account.\n"
703 "\nArguments:\n"
704 "1. \"account\" (string, optional) DEPRECATED. The account string may be given as a\n"
705 " specific account name to find the balance associated with wallet keys in\n"
706 " a named account, or as the empty string (\"\") to find the balance\n"
707 " associated with wallet keys not in any named account, or as \"*\" to find\n"
708 " the balance associated with all wallet keys regardless of account.\n"
709 " When this option is specified, it calculates the balance in a different\n"
710 " way than when it is not specified, and which can count spends twice when\n"
711 " there are conflicting pending transactions (such as those created by\n"
712 " the bumpfee command), temporarily resulting in low or even negative\n"
713 " balances. In general, account balance calculation is not considered\n"
714 " reliable and has resulted in confusing outcomes, so it is recommended to\n"
715 " avoid passing this argument.\n"
716 "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
717 "3. include_watchonly (bool, optional, default=false) Also include balance in watch-only addresses (see 'importaddress')\n"
718 "\nResult:\n"
719 "amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n"
720 "\nExamples:\n"
721 "\nThe total amount in the wallet\n"
722 + HelpExampleCli("getbalance", "") +
723 "\nThe total amount in the wallet at least 5 blocks confirmed\n"
724 + HelpExampleCli("getbalance", "\"*\" 6") +
725 "\nAs a json rpc call\n"
726 + HelpExampleRpc("getbalance", "\"*\", 6")
729 LOCK2(cs_main, pwallet->cs_wallet);
731 if (request.params.size() == 0)
732 return ValueFromAmount(pwallet->GetBalance());
734 const std::string& account_param = request.params[0].get_str();
735 const std::string* account = account_param != "*" ? &account_param : nullptr;
737 int nMinDepth = 1;
738 if (request.params.size() > 1)
739 nMinDepth = request.params[1].get_int();
740 isminefilter filter = ISMINE_SPENDABLE;
741 if(request.params.size() > 2)
742 if(request.params[2].get_bool())
743 filter = filter | ISMINE_WATCH_ONLY;
745 return ValueFromAmount(pwallet->GetLegacyBalance(filter, nMinDepth, account));
748 UniValue getunconfirmedbalance(const JSONRPCRequest &request)
750 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
751 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
752 return NullUniValue;
755 if (request.fHelp || request.params.size() > 0)
756 throw std::runtime_error(
757 "getunconfirmedbalance\n"
758 "Returns the server's total unconfirmed balance\n");
760 LOCK2(cs_main, pwallet->cs_wallet);
762 return ValueFromAmount(pwallet->GetUnconfirmedBalance());
766 UniValue movecmd(const JSONRPCRequest& request)
768 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
769 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
770 return NullUniValue;
773 if (request.fHelp || request.params.size() < 3 || request.params.size() > 5)
774 throw std::runtime_error(
775 "move \"fromaccount\" \"toaccount\" amount ( minconf \"comment\" )\n"
776 "\nDEPRECATED. Move a specified amount from one account in your wallet to another.\n"
777 "\nArguments:\n"
778 "1. \"fromaccount\" (string, required) The name of the account to move funds from. May be the default account using \"\".\n"
779 "2. \"toaccount\" (string, required) The name of the account to move funds to. May be the default account using \"\".\n"
780 "3. amount (numeric) Quantity of " + CURRENCY_UNIT + " to move between accounts.\n"
781 "4. (dummy) (numeric, optional) Ignored. Remains for backward compatibility.\n"
782 "5. \"comment\" (string, optional) An optional comment, stored in the wallet only.\n"
783 "\nResult:\n"
784 "true|false (boolean) true if successful.\n"
785 "\nExamples:\n"
786 "\nMove 0.01 " + CURRENCY_UNIT + " from the default account to the account named tabby\n"
787 + HelpExampleCli("move", "\"\" \"tabby\" 0.01") +
788 "\nMove 0.01 " + CURRENCY_UNIT + " timotei to akiko with a comment and funds have 6 confirmations\n"
789 + HelpExampleCli("move", "\"timotei\" \"akiko\" 0.01 6 \"happy birthday!\"") +
790 "\nAs a json rpc call\n"
791 + HelpExampleRpc("move", "\"timotei\", \"akiko\", 0.01, 6, \"happy birthday!\"")
794 LOCK2(cs_main, pwallet->cs_wallet);
796 std::string strFrom = AccountFromValue(request.params[0]);
797 std::string strTo = AccountFromValue(request.params[1]);
798 CAmount nAmount = AmountFromValue(request.params[2]);
799 if (nAmount <= 0)
800 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
801 if (request.params.size() > 3)
802 // unused parameter, used to be nMinDepth, keep type-checking it though
803 (void)request.params[3].get_int();
804 std::string strComment;
805 if (request.params.size() > 4)
806 strComment = request.params[4].get_str();
808 if (!pwallet->AccountMove(strFrom, strTo, nAmount, strComment)) {
809 throw JSONRPCError(RPC_DATABASE_ERROR, "database error");
812 return true;
816 UniValue sendfrom(const JSONRPCRequest& request)
818 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
819 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
820 return NullUniValue;
823 if (request.fHelp || request.params.size() < 3 || request.params.size() > 6)
824 throw std::runtime_error(
825 "sendfrom \"fromaccount\" \"toaddress\" amount ( minconf \"comment\" \"comment_to\" )\n"
826 "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a bitcoin address."
827 + HelpRequiringPassphrase(pwallet) + "\n"
828 "\nArguments:\n"
829 "1. \"fromaccount\" (string, required) The name of the account to send funds from. May be the default account using \"\".\n"
830 " Specifying an account does not influence coin selection, but it does associate the newly created\n"
831 " transaction with the account, so the account's balance computation and transaction history can reflect\n"
832 " the spend.\n"
833 "2. \"toaddress\" (string, required) The bitcoin address to send funds to.\n"
834 "3. amount (numeric or string, required) The amount in " + CURRENCY_UNIT + " (transaction fee is added on top).\n"
835 "4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n"
836 "5. \"comment\" (string, optional) A comment used to store what the transaction is for. \n"
837 " This is not part of the transaction, just kept in your wallet.\n"
838 "6. \"comment_to\" (string, optional) An optional comment to store the name of the person or organization \n"
839 " to which you're sending the transaction. This is not part of the transaction, \n"
840 " it is just kept in your wallet.\n"
841 "\nResult:\n"
842 "\"txid\" (string) The transaction id.\n"
843 "\nExamples:\n"
844 "\nSend 0.01 " + CURRENCY_UNIT + " from the default account to the address, must have at least 1 confirmation\n"
845 + HelpExampleCli("sendfrom", "\"\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01") +
846 "\nSend 0.01 from the tabby account to the given address, funds must have at least 6 confirmations\n"
847 + HelpExampleCli("sendfrom", "\"tabby\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01 6 \"donation\" \"seans outpost\"") +
848 "\nAs a json rpc call\n"
849 + HelpExampleRpc("sendfrom", "\"tabby\", \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.01, 6, \"donation\", \"seans outpost\"")
852 LOCK2(cs_main, pwallet->cs_wallet);
854 std::string strAccount = AccountFromValue(request.params[0]);
855 CBitcoinAddress address(request.params[1].get_str());
856 if (!address.IsValid())
857 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
858 CAmount nAmount = AmountFromValue(request.params[2]);
859 if (nAmount <= 0)
860 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
861 int nMinDepth = 1;
862 if (request.params.size() > 3)
863 nMinDepth = request.params[3].get_int();
865 CWalletTx wtx;
866 wtx.strFromAccount = strAccount;
867 if (request.params.size() > 4 && !request.params[4].isNull() && !request.params[4].get_str().empty())
868 wtx.mapValue["comment"] = request.params[4].get_str();
869 if (request.params.size() > 5 && !request.params[5].isNull() && !request.params[5].get_str().empty())
870 wtx.mapValue["to"] = request.params[5].get_str();
872 EnsureWalletIsUnlocked(pwallet);
874 // Check funds
875 CAmount nBalance = pwallet->GetLegacyBalance(ISMINE_SPENDABLE, nMinDepth, &strAccount);
876 if (nAmount > nBalance)
877 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
879 SendMoney(pwallet, address.Get(), nAmount, false, wtx);
881 return wtx.GetHash().GetHex();
885 UniValue sendmany(const JSONRPCRequest& request)
887 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
888 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
889 return NullUniValue;
892 if (request.fHelp || request.params.size() < 2 || request.params.size() > 5)
893 throw std::runtime_error(
894 "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" [\"address\",...] )\n"
895 "\nSend multiple times. Amounts are double-precision floating point numbers."
896 + HelpRequiringPassphrase(pwallet) + "\n"
897 "\nArguments:\n"
898 "1. \"fromaccount\" (string, required) DEPRECATED. The account to send the funds from. Should be \"\" for the default account\n"
899 "2. \"amounts\" (string, required) A json object with addresses and amounts\n"
900 " {\n"
901 " \"address\":amount (numeric or string) The bitcoin address is the key, the numeric amount (can be string) in " + CURRENCY_UNIT + " is the value\n"
902 " ,...\n"
903 " }\n"
904 "3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n"
905 "4. \"comment\" (string, optional) A comment\n"
906 "5. subtractfeefrom (array, optional) A json array with addresses.\n"
907 " The fee will be equally deducted from the amount of each selected address.\n"
908 " Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
909 " If no addresses are specified here, the sender pays the fee.\n"
910 " [\n"
911 " \"address\" (string) Subtract fee from this address\n"
912 " ,...\n"
913 " ]\n"
914 "\nResult:\n"
915 "\"txid\" (string) The transaction id for the send. Only 1 transaction is created regardless of \n"
916 " the number of addresses.\n"
917 "\nExamples:\n"
918 "\nSend two amounts to two different addresses:\n"
919 + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") +
920 "\nSend two amounts to two different addresses setting the confirmation and comment:\n"
921 + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 6 \"testing\"") +
922 "\nSend two amounts to two different addresses, subtract fee from amount:\n"
923 + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 1 \"\" \"[\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\",\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\"]\"") +
924 "\nAs a json rpc call\n"
925 + HelpExampleRpc("sendmany", "\"\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"")
928 LOCK2(cs_main, pwallet->cs_wallet);
930 if (pwallet->GetBroadcastTransactions() && !g_connman) {
931 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
934 std::string strAccount = AccountFromValue(request.params[0]);
935 UniValue sendTo = request.params[1].get_obj();
936 int nMinDepth = 1;
937 if (request.params.size() > 2)
938 nMinDepth = request.params[2].get_int();
940 CWalletTx wtx;
941 wtx.strFromAccount = strAccount;
942 if (request.params.size() > 3 && !request.params[3].isNull() && !request.params[3].get_str().empty())
943 wtx.mapValue["comment"] = request.params[3].get_str();
945 UniValue subtractFeeFromAmount(UniValue::VARR);
946 if (request.params.size() > 4)
947 subtractFeeFromAmount = request.params[4].get_array();
949 std::set<CBitcoinAddress> setAddress;
950 std::vector<CRecipient> vecSend;
952 CAmount totalAmount = 0;
953 std::vector<std::string> keys = sendTo.getKeys();
954 BOOST_FOREACH(const std::string& name_, keys)
956 CBitcoinAddress address(name_);
957 if (!address.IsValid())
958 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Bitcoin address: ")+name_);
960 if (setAddress.count(address))
961 throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ")+name_);
962 setAddress.insert(address);
964 CScript scriptPubKey = GetScriptForDestination(address.Get());
965 CAmount nAmount = AmountFromValue(sendTo[name_]);
966 if (nAmount <= 0)
967 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
968 totalAmount += nAmount;
970 bool fSubtractFeeFromAmount = false;
971 for (unsigned int idx = 0; idx < subtractFeeFromAmount.size(); idx++) {
972 const UniValue& addr = subtractFeeFromAmount[idx];
973 if (addr.get_str() == name_)
974 fSubtractFeeFromAmount = true;
977 CRecipient recipient = {scriptPubKey, nAmount, fSubtractFeeFromAmount};
978 vecSend.push_back(recipient);
981 EnsureWalletIsUnlocked(pwallet);
983 // Check funds
984 CAmount nBalance = pwallet->GetLegacyBalance(ISMINE_SPENDABLE, nMinDepth, &strAccount);
985 if (totalAmount > nBalance)
986 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
988 // Send
989 CReserveKey keyChange(pwallet);
990 CAmount nFeeRequired = 0;
991 int nChangePosRet = -1;
992 std::string strFailReason;
993 bool fCreated = pwallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, nChangePosRet, strFailReason);
994 if (!fCreated)
995 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
996 CValidationState state;
997 if (!pwallet->CommitTransaction(wtx, keyChange, g_connman.get(), state)) {
998 strFailReason = strprintf("Transaction commit failed:: %s", state.GetRejectReason());
999 throw JSONRPCError(RPC_WALLET_ERROR, strFailReason);
1002 return wtx.GetHash().GetHex();
1005 // Defined in rpc/misc.cpp
1006 extern CScript _createmultisig_redeemScript(CWallet * const pwallet, const UniValue& params);
1008 UniValue addmultisigaddress(const JSONRPCRequest& request)
1010 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1011 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1012 return NullUniValue;
1015 if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
1017 std::string msg = "addmultisigaddress nrequired [\"key\",...] ( \"account\" )\n"
1018 "\nAdd a nrequired-to-sign multisignature address to the wallet.\n"
1019 "Each key is a Bitcoin address or hex-encoded public key.\n"
1020 "If 'account' is specified (DEPRECATED), assign address to that account.\n"
1022 "\nArguments:\n"
1023 "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
1024 "2. \"keys\" (string, required) A json array of bitcoin addresses or hex-encoded public keys\n"
1025 " [\n"
1026 " \"address\" (string) bitcoin address or hex-encoded public key\n"
1027 " ...,\n"
1028 " ]\n"
1029 "3. \"account\" (string, optional) DEPRECATED. An account to assign the addresses to.\n"
1031 "\nResult:\n"
1032 "\"address\" (string) A bitcoin address associated with the keys.\n"
1034 "\nExamples:\n"
1035 "\nAdd a multisig address from 2 addresses\n"
1036 + HelpExampleCli("addmultisigaddress", "2 \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") +
1037 "\nAs json rpc call\n"
1038 + HelpExampleRpc("addmultisigaddress", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"")
1040 throw std::runtime_error(msg);
1043 LOCK2(cs_main, pwallet->cs_wallet);
1045 std::string strAccount;
1046 if (request.params.size() > 2)
1047 strAccount = AccountFromValue(request.params[2]);
1049 // Construct using pay-to-script-hash:
1050 CScript inner = _createmultisig_redeemScript(pwallet, request.params);
1051 CScriptID innerID(inner);
1052 pwallet->AddCScript(inner);
1054 pwallet->SetAddressBook(innerID, strAccount, "send");
1055 return CBitcoinAddress(innerID).ToString();
1058 class Witnessifier : public boost::static_visitor<bool>
1060 public:
1061 CWallet * const pwallet;
1062 CScriptID result;
1064 Witnessifier(CWallet *_pwallet) : pwallet(_pwallet) {}
1066 bool operator()(const CNoDestination &dest) const { return false; }
1068 bool operator()(const CKeyID &keyID) {
1069 CPubKey pubkey;
1070 if (pwallet) {
1071 CScript basescript = GetScriptForDestination(keyID);
1072 isminetype typ;
1073 typ = IsMine(*pwallet, basescript, SIGVERSION_WITNESS_V0);
1074 if (typ != ISMINE_SPENDABLE && typ != ISMINE_WATCH_SOLVABLE)
1075 return false;
1076 CScript witscript = GetScriptForWitness(basescript);
1077 pwallet->AddCScript(witscript);
1078 result = CScriptID(witscript);
1079 return true;
1081 return false;
1084 bool operator()(const CScriptID &scriptID) {
1085 CScript subscript;
1086 if (pwallet && pwallet->GetCScript(scriptID, subscript)) {
1087 int witnessversion;
1088 std::vector<unsigned char> witprog;
1089 if (subscript.IsWitnessProgram(witnessversion, witprog)) {
1090 result = scriptID;
1091 return true;
1093 isminetype typ;
1094 typ = IsMine(*pwallet, subscript, SIGVERSION_WITNESS_V0);
1095 if (typ != ISMINE_SPENDABLE && typ != ISMINE_WATCH_SOLVABLE)
1096 return false;
1097 CScript witscript = GetScriptForWitness(subscript);
1098 pwallet->AddCScript(witscript);
1099 result = CScriptID(witscript);
1100 return true;
1102 return false;
1106 UniValue addwitnessaddress(const JSONRPCRequest& request)
1108 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1109 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1110 return NullUniValue;
1113 if (request.fHelp || request.params.size() < 1 || request.params.size() > 1)
1115 std::string msg = "addwitnessaddress \"address\"\n"
1116 "\nAdd a witness address for a script (with pubkey or redeemscript known).\n"
1117 "It returns the witness script.\n"
1119 "\nArguments:\n"
1120 "1. \"address\" (string, required) An address known to the wallet\n"
1122 "\nResult:\n"
1123 "\"witnessaddress\", (string) The value of the new address (P2SH of witness script).\n"
1124 "}\n"
1126 throw std::runtime_error(msg);
1130 LOCK(cs_main);
1131 if (!IsWitnessEnabled(chainActive.Tip(), Params().GetConsensus()) && !GetBoolArg("-walletprematurewitness", false)) {
1132 throw JSONRPCError(RPC_WALLET_ERROR, "Segregated witness not enabled on network");
1136 CBitcoinAddress address(request.params[0].get_str());
1137 if (!address.IsValid())
1138 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
1140 Witnessifier w(pwallet);
1141 CTxDestination dest = address.Get();
1142 bool ret = boost::apply_visitor(w, dest);
1143 if (!ret) {
1144 throw JSONRPCError(RPC_WALLET_ERROR, "Public key or redeemscript not known to wallet, or the key is uncompressed");
1147 pwallet->SetAddressBook(w.result, "", "receive");
1149 return CBitcoinAddress(w.result).ToString();
1152 struct tallyitem
1154 CAmount nAmount;
1155 int nConf;
1156 std::vector<uint256> txids;
1157 bool fIsWatchonly;
1158 tallyitem()
1160 nAmount = 0;
1161 nConf = std::numeric_limits<int>::max();
1162 fIsWatchonly = false;
1166 UniValue ListReceived(CWallet * const pwallet, const UniValue& params, bool fByAccounts)
1168 // Minimum confirmations
1169 int nMinDepth = 1;
1170 if (params.size() > 0)
1171 nMinDepth = params[0].get_int();
1173 // Whether to include empty accounts
1174 bool fIncludeEmpty = false;
1175 if (params.size() > 1)
1176 fIncludeEmpty = params[1].get_bool();
1178 isminefilter filter = ISMINE_SPENDABLE;
1179 if(params.size() > 2)
1180 if(params[2].get_bool())
1181 filter = filter | ISMINE_WATCH_ONLY;
1183 // Tally
1184 std::map<CBitcoinAddress, tallyitem> mapTally;
1185 for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
1186 const CWalletTx& wtx = pairWtx.second;
1188 if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx))
1189 continue;
1191 int nDepth = wtx.GetDepthInMainChain();
1192 if (nDepth < nMinDepth)
1193 continue;
1195 BOOST_FOREACH(const CTxOut& txout, wtx.tx->vout)
1197 CTxDestination address;
1198 if (!ExtractDestination(txout.scriptPubKey, address))
1199 continue;
1201 isminefilter mine = IsMine(*pwallet, address);
1202 if(!(mine & filter))
1203 continue;
1205 tallyitem& item = mapTally[address];
1206 item.nAmount += txout.nValue;
1207 item.nConf = std::min(item.nConf, nDepth);
1208 item.txids.push_back(wtx.GetHash());
1209 if (mine & ISMINE_WATCH_ONLY)
1210 item.fIsWatchonly = true;
1214 // Reply
1215 UniValue ret(UniValue::VARR);
1216 std::map<std::string, tallyitem> mapAccountTally;
1217 for (const std::pair<CBitcoinAddress, CAddressBookData>& item : pwallet->mapAddressBook) {
1218 const CBitcoinAddress& address = item.first;
1219 const std::string& strAccount = item.second.name;
1220 std::map<CBitcoinAddress, tallyitem>::iterator it = mapTally.find(address);
1221 if (it == mapTally.end() && !fIncludeEmpty)
1222 continue;
1224 CAmount nAmount = 0;
1225 int nConf = std::numeric_limits<int>::max();
1226 bool fIsWatchonly = false;
1227 if (it != mapTally.end())
1229 nAmount = (*it).second.nAmount;
1230 nConf = (*it).second.nConf;
1231 fIsWatchonly = (*it).second.fIsWatchonly;
1234 if (fByAccounts)
1236 tallyitem& _item = mapAccountTally[strAccount];
1237 _item.nAmount += nAmount;
1238 _item.nConf = std::min(_item.nConf, nConf);
1239 _item.fIsWatchonly = fIsWatchonly;
1241 else
1243 UniValue obj(UniValue::VOBJ);
1244 if(fIsWatchonly)
1245 obj.push_back(Pair("involvesWatchonly", true));
1246 obj.push_back(Pair("address", address.ToString()));
1247 obj.push_back(Pair("account", strAccount));
1248 obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
1249 obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
1250 if (!fByAccounts)
1251 obj.push_back(Pair("label", strAccount));
1252 UniValue transactions(UniValue::VARR);
1253 if (it != mapTally.end())
1255 BOOST_FOREACH(const uint256& _item, (*it).second.txids)
1257 transactions.push_back(_item.GetHex());
1260 obj.push_back(Pair("txids", transactions));
1261 ret.push_back(obj);
1265 if (fByAccounts)
1267 for (std::map<std::string, tallyitem>::iterator it = mapAccountTally.begin(); it != mapAccountTally.end(); ++it)
1269 CAmount nAmount = (*it).second.nAmount;
1270 int nConf = (*it).second.nConf;
1271 UniValue obj(UniValue::VOBJ);
1272 if((*it).second.fIsWatchonly)
1273 obj.push_back(Pair("involvesWatchonly", true));
1274 obj.push_back(Pair("account", (*it).first));
1275 obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
1276 obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
1277 ret.push_back(obj);
1281 return ret;
1284 UniValue listreceivedbyaddress(const JSONRPCRequest& request)
1286 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1287 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1288 return NullUniValue;
1291 if (request.fHelp || request.params.size() > 3)
1292 throw std::runtime_error(
1293 "listreceivedbyaddress ( minconf include_empty include_watchonly)\n"
1294 "\nList balances by receiving address.\n"
1295 "\nArguments:\n"
1296 "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
1297 "2. include_empty (bool, optional, default=false) Whether to include addresses that haven't received any payments.\n"
1298 "3. include_watchonly (bool, optional, default=false) Whether to include watch-only addresses (see 'importaddress').\n"
1300 "\nResult:\n"
1301 "[\n"
1302 " {\n"
1303 " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n"
1304 " \"address\" : \"receivingaddress\", (string) The receiving address\n"
1305 " \"account\" : \"accountname\", (string) DEPRECATED. The account of the receiving address. The default account is \"\".\n"
1306 " \"amount\" : x.xxx, (numeric) The total amount in " + CURRENCY_UNIT + " received by the address\n"
1307 " \"confirmations\" : n, (numeric) The number of confirmations of the most recent transaction included\n"
1308 " \"label\" : \"label\", (string) A comment for the address/transaction, if any\n"
1309 " \"txids\": [\n"
1310 " n, (numeric) The ids of transactions received with the address \n"
1311 " ...\n"
1312 " ]\n"
1313 " }\n"
1314 " ,...\n"
1315 "]\n"
1317 "\nExamples:\n"
1318 + HelpExampleCli("listreceivedbyaddress", "")
1319 + HelpExampleCli("listreceivedbyaddress", "6 true")
1320 + HelpExampleRpc("listreceivedbyaddress", "6, true, true")
1323 LOCK2(cs_main, pwallet->cs_wallet);
1325 return ListReceived(pwallet, request.params, false);
1328 UniValue listreceivedbyaccount(const JSONRPCRequest& request)
1330 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1331 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1332 return NullUniValue;
1335 if (request.fHelp || request.params.size() > 3)
1336 throw std::runtime_error(
1337 "listreceivedbyaccount ( minconf include_empty include_watchonly)\n"
1338 "\nDEPRECATED. List balances by account.\n"
1339 "\nArguments:\n"
1340 "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
1341 "2. include_empty (bool, optional, default=false) Whether to include accounts that haven't received any payments.\n"
1342 "3. include_watchonly (bool, optional, default=false) Whether to include watch-only addresses (see 'importaddress').\n"
1344 "\nResult:\n"
1345 "[\n"
1346 " {\n"
1347 " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n"
1348 " \"account\" : \"accountname\", (string) The account name of the receiving account\n"
1349 " \"amount\" : x.xxx, (numeric) The total amount received by addresses with this account\n"
1350 " \"confirmations\" : n, (numeric) The number of confirmations of the most recent transaction included\n"
1351 " \"label\" : \"label\" (string) A comment for the address/transaction, if any\n"
1352 " }\n"
1353 " ,...\n"
1354 "]\n"
1356 "\nExamples:\n"
1357 + HelpExampleCli("listreceivedbyaccount", "")
1358 + HelpExampleCli("listreceivedbyaccount", "6 true")
1359 + HelpExampleRpc("listreceivedbyaccount", "6, true, true")
1362 LOCK2(cs_main, pwallet->cs_wallet);
1364 return ListReceived(pwallet, request.params, true);
1367 static void MaybePushAddress(UniValue & entry, const CTxDestination &dest)
1369 CBitcoinAddress addr;
1370 if (addr.Set(dest))
1371 entry.push_back(Pair("address", addr.ToString()));
1374 void ListTransactions(CWallet* const pwallet, const CWalletTx& wtx, const std::string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter)
1376 CAmount nFee;
1377 std::string strSentAccount;
1378 std::list<COutputEntry> listReceived;
1379 std::list<COutputEntry> listSent;
1381 wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount, filter);
1383 bool fAllAccounts = (strAccount == std::string("*"));
1384 bool involvesWatchonly = wtx.IsFromMe(ISMINE_WATCH_ONLY);
1386 // Sent
1387 if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount))
1389 BOOST_FOREACH(const COutputEntry& s, listSent)
1391 UniValue entry(UniValue::VOBJ);
1392 if (involvesWatchonly || (::IsMine(*pwallet, s.destination) & ISMINE_WATCH_ONLY)) {
1393 entry.push_back(Pair("involvesWatchonly", true));
1395 entry.push_back(Pair("account", strSentAccount));
1396 MaybePushAddress(entry, s.destination);
1397 entry.push_back(Pair("category", "send"));
1398 entry.push_back(Pair("amount", ValueFromAmount(-s.amount)));
1399 if (pwallet->mapAddressBook.count(s.destination)) {
1400 entry.push_back(Pair("label", pwallet->mapAddressBook[s.destination].name));
1402 entry.push_back(Pair("vout", s.vout));
1403 entry.push_back(Pair("fee", ValueFromAmount(-nFee)));
1404 if (fLong)
1405 WalletTxToJSON(wtx, entry);
1406 entry.push_back(Pair("abandoned", wtx.isAbandoned()));
1407 ret.push_back(entry);
1411 // Received
1412 if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth)
1414 BOOST_FOREACH(const COutputEntry& r, listReceived)
1416 std::string account;
1417 if (pwallet->mapAddressBook.count(r.destination)) {
1418 account = pwallet->mapAddressBook[r.destination].name;
1420 if (fAllAccounts || (account == strAccount))
1422 UniValue entry(UniValue::VOBJ);
1423 if (involvesWatchonly || (::IsMine(*pwallet, r.destination) & ISMINE_WATCH_ONLY)) {
1424 entry.push_back(Pair("involvesWatchonly", true));
1426 entry.push_back(Pair("account", account));
1427 MaybePushAddress(entry, r.destination);
1428 if (wtx.IsCoinBase())
1430 if (wtx.GetDepthInMainChain() < 1)
1431 entry.push_back(Pair("category", "orphan"));
1432 else if (wtx.GetBlocksToMaturity() > 0)
1433 entry.push_back(Pair("category", "immature"));
1434 else
1435 entry.push_back(Pair("category", "generate"));
1437 else
1439 entry.push_back(Pair("category", "receive"));
1441 entry.push_back(Pair("amount", ValueFromAmount(r.amount)));
1442 if (pwallet->mapAddressBook.count(r.destination)) {
1443 entry.push_back(Pair("label", account));
1445 entry.push_back(Pair("vout", r.vout));
1446 if (fLong)
1447 WalletTxToJSON(wtx, entry);
1448 ret.push_back(entry);
1454 void AcentryToJSON(const CAccountingEntry& acentry, const std::string& strAccount, UniValue& ret)
1456 bool fAllAccounts = (strAccount == std::string("*"));
1458 if (fAllAccounts || acentry.strAccount == strAccount)
1460 UniValue entry(UniValue::VOBJ);
1461 entry.push_back(Pair("account", acentry.strAccount));
1462 entry.push_back(Pair("category", "move"));
1463 entry.push_back(Pair("time", acentry.nTime));
1464 entry.push_back(Pair("amount", ValueFromAmount(acentry.nCreditDebit)));
1465 entry.push_back(Pair("otheraccount", acentry.strOtherAccount));
1466 entry.push_back(Pair("comment", acentry.strComment));
1467 ret.push_back(entry);
1471 UniValue listtransactions(const JSONRPCRequest& request)
1473 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1474 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1475 return NullUniValue;
1478 if (request.fHelp || request.params.size() > 4)
1479 throw std::runtime_error(
1480 "listtransactions ( \"account\" count skip include_watchonly)\n"
1481 "\nReturns up to 'count' most recent transactions skipping the first 'from' transactions for account 'account'.\n"
1482 "\nArguments:\n"
1483 "1. \"account\" (string, optional) DEPRECATED. The account name. Should be \"*\".\n"
1484 "2. count (numeric, optional, default=10) The number of transactions to return\n"
1485 "3. skip (numeric, optional, default=0) The number of transactions to skip\n"
1486 "4. include_watchonly (bool, optional, default=false) Include transactions to watch-only addresses (see 'importaddress')\n"
1487 "\nResult:\n"
1488 "[\n"
1489 " {\n"
1490 " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. \n"
1491 " It will be \"\" for the default account.\n"
1492 " \"address\":\"address\", (string) The bitcoin address of the transaction. Not present for \n"
1493 " move transactions (category = move).\n"
1494 " \"category\":\"send|receive|move\", (string) The transaction category. 'move' is a local (off blockchain)\n"
1495 " transaction between accounts, and not associated with an address,\n"
1496 " transaction id or block. 'send' and 'receive' transactions are \n"
1497 " associated with an address, transaction id and block details\n"
1498 " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the\n"
1499 " 'move' category for moves outbound. It is positive for the 'receive' category,\n"
1500 " and for the 'move' category for inbound funds.\n"
1501 " \"label\": \"label\", (string) A comment for the address/transaction, if any\n"
1502 " \"vout\": n, (numeric) the vout value\n"
1503 " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n"
1504 " 'send' category of transactions.\n"
1505 " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and \n"
1506 " 'receive' category of transactions. Negative confirmations indicate the\n"
1507 " transaction conflicts with the block chain\n"
1508 " \"trusted\": xxx, (bool) Whether we consider the outputs of this unconfirmed transaction safe to spend.\n"
1509 " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive'\n"
1510 " category of transactions.\n"
1511 " \"blockindex\": n, (numeric) The index of the transaction in the block that includes it. Available for 'send' and 'receive'\n"
1512 " category of transactions.\n"
1513 " \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n"
1514 " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
1515 " \"time\": xxx, (numeric) The transaction time in seconds since epoch (midnight Jan 1 1970 GMT).\n"
1516 " \"timereceived\": xxx, (numeric) The time received in seconds since epoch (midnight Jan 1 1970 GMT). Available \n"
1517 " for 'send' and 'receive' category of transactions.\n"
1518 " \"comment\": \"...\", (string) If a comment is associated with the transaction.\n"
1519 " \"otheraccount\": \"accountname\", (string) DEPRECATED. For the 'move' category of transactions, the account the funds came \n"
1520 " from (for receiving funds, positive amounts), or went to (for sending funds,\n"
1521 " negative amounts).\n"
1522 " \"bip125-replaceable\": \"yes|no|unknown\", (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n"
1523 " may be unknown for unconfirmed transactions not in the mempool\n"
1524 " \"abandoned\": xxx (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n"
1525 " 'send' category of transactions.\n"
1526 " }\n"
1527 "]\n"
1529 "\nExamples:\n"
1530 "\nList the most recent 10 transactions in the systems\n"
1531 + HelpExampleCli("listtransactions", "") +
1532 "\nList transactions 100 to 120\n"
1533 + HelpExampleCli("listtransactions", "\"*\" 20 100") +
1534 "\nAs a json rpc call\n"
1535 + HelpExampleRpc("listtransactions", "\"*\", 20, 100")
1538 LOCK2(cs_main, pwallet->cs_wallet);
1540 std::string strAccount = "*";
1541 if (request.params.size() > 0)
1542 strAccount = request.params[0].get_str();
1543 int nCount = 10;
1544 if (request.params.size() > 1)
1545 nCount = request.params[1].get_int();
1546 int nFrom = 0;
1547 if (request.params.size() > 2)
1548 nFrom = request.params[2].get_int();
1549 isminefilter filter = ISMINE_SPENDABLE;
1550 if(request.params.size() > 3)
1551 if(request.params[3].get_bool())
1552 filter = filter | ISMINE_WATCH_ONLY;
1554 if (nCount < 0)
1555 throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count");
1556 if (nFrom < 0)
1557 throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from");
1559 UniValue ret(UniValue::VARR);
1561 const CWallet::TxItems & txOrdered = pwallet->wtxOrdered;
1563 // iterate backwards until we have nCount items to return:
1564 for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
1566 CWalletTx *const pwtx = (*it).second.first;
1567 if (pwtx != 0)
1568 ListTransactions(pwallet, *pwtx, strAccount, 0, true, ret, filter);
1569 CAccountingEntry *const pacentry = (*it).second.second;
1570 if (pacentry != 0)
1571 AcentryToJSON(*pacentry, strAccount, ret);
1573 if ((int)ret.size() >= (nCount+nFrom)) break;
1575 // ret is newest to oldest
1577 if (nFrom > (int)ret.size())
1578 nFrom = ret.size();
1579 if ((nFrom + nCount) > (int)ret.size())
1580 nCount = ret.size() - nFrom;
1582 std::vector<UniValue> arrTmp = ret.getValues();
1584 std::vector<UniValue>::iterator first = arrTmp.begin();
1585 std::advance(first, nFrom);
1586 std::vector<UniValue>::iterator last = arrTmp.begin();
1587 std::advance(last, nFrom+nCount);
1589 if (last != arrTmp.end()) arrTmp.erase(last, arrTmp.end());
1590 if (first != arrTmp.begin()) arrTmp.erase(arrTmp.begin(), first);
1592 std::reverse(arrTmp.begin(), arrTmp.end()); // Return oldest to newest
1594 ret.clear();
1595 ret.setArray();
1596 ret.push_backV(arrTmp);
1598 return ret;
1601 UniValue listaccounts(const JSONRPCRequest& request)
1603 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1604 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1605 return NullUniValue;
1608 if (request.fHelp || request.params.size() > 2)
1609 throw std::runtime_error(
1610 "listaccounts ( minconf include_watchonly)\n"
1611 "\nDEPRECATED. Returns Object that has account names as keys, account balances as values.\n"
1612 "\nArguments:\n"
1613 "1. minconf (numeric, optional, default=1) Only include transactions with at least this many confirmations\n"
1614 "2. include_watchonly (bool, optional, default=false) Include balances in watch-only addresses (see 'importaddress')\n"
1615 "\nResult:\n"
1616 "{ (json object where keys are account names, and values are numeric balances\n"
1617 " \"account\": x.xxx, (numeric) The property name is the account name, and the value is the total balance for the account.\n"
1618 " ...\n"
1619 "}\n"
1620 "\nExamples:\n"
1621 "\nList account balances where there at least 1 confirmation\n"
1622 + HelpExampleCli("listaccounts", "") +
1623 "\nList account balances including zero confirmation transactions\n"
1624 + HelpExampleCli("listaccounts", "0") +
1625 "\nList account balances for 6 or more confirmations\n"
1626 + HelpExampleCli("listaccounts", "6") +
1627 "\nAs json rpc call\n"
1628 + HelpExampleRpc("listaccounts", "6")
1631 LOCK2(cs_main, pwallet->cs_wallet);
1633 int nMinDepth = 1;
1634 if (request.params.size() > 0)
1635 nMinDepth = request.params[0].get_int();
1636 isminefilter includeWatchonly = ISMINE_SPENDABLE;
1637 if(request.params.size() > 1)
1638 if(request.params[1].get_bool())
1639 includeWatchonly = includeWatchonly | ISMINE_WATCH_ONLY;
1641 std::map<std::string, CAmount> mapAccountBalances;
1642 for (const std::pair<CTxDestination, CAddressBookData>& entry : pwallet->mapAddressBook) {
1643 if (IsMine(*pwallet, entry.first) & includeWatchonly) { // This address belongs to me
1644 mapAccountBalances[entry.second.name] = 0;
1648 for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
1649 const CWalletTx& wtx = pairWtx.second;
1650 CAmount nFee;
1651 std::string strSentAccount;
1652 std::list<COutputEntry> listReceived;
1653 std::list<COutputEntry> listSent;
1654 int nDepth = wtx.GetDepthInMainChain();
1655 if (wtx.GetBlocksToMaturity() > 0 || nDepth < 0)
1656 continue;
1657 wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount, includeWatchonly);
1658 mapAccountBalances[strSentAccount] -= nFee;
1659 BOOST_FOREACH(const COutputEntry& s, listSent)
1660 mapAccountBalances[strSentAccount] -= s.amount;
1661 if (nDepth >= nMinDepth)
1663 BOOST_FOREACH(const COutputEntry& r, listReceived)
1664 if (pwallet->mapAddressBook.count(r.destination)) {
1665 mapAccountBalances[pwallet->mapAddressBook[r.destination].name] += r.amount;
1667 else
1668 mapAccountBalances[""] += r.amount;
1672 const std::list<CAccountingEntry>& acentries = pwallet->laccentries;
1673 BOOST_FOREACH(const CAccountingEntry& entry, acentries)
1674 mapAccountBalances[entry.strAccount] += entry.nCreditDebit;
1676 UniValue ret(UniValue::VOBJ);
1677 BOOST_FOREACH(const PAIRTYPE(std::string, CAmount)& accountBalance, mapAccountBalances) {
1678 ret.push_back(Pair(accountBalance.first, ValueFromAmount(accountBalance.second)));
1680 return ret;
1683 UniValue listsinceblock(const JSONRPCRequest& request)
1685 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1686 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1687 return NullUniValue;
1690 if (request.fHelp)
1691 throw std::runtime_error(
1692 "listsinceblock ( \"blockhash\" target_confirmations include_watchonly)\n"
1693 "\nGet all transactions in blocks since block [blockhash], or all transactions if omitted\n"
1694 "\nArguments:\n"
1695 "1. \"blockhash\" (string, optional) The block hash to list transactions since\n"
1696 "2. target_confirmations: (numeric, optional) The confirmations required, must be 1 or more\n"
1697 "3. include_watchonly: (bool, optional, default=false) Include transactions to watch-only addresses (see 'importaddress')"
1698 "\nResult:\n"
1699 "{\n"
1700 " \"transactions\": [\n"
1701 " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. Will be \"\" for the default account.\n"
1702 " \"address\":\"address\", (string) The bitcoin address of the transaction. Not present for move transactions (category = move).\n"
1703 " \"category\":\"send|receive\", (string) The transaction category. 'send' has negative amounts, 'receive' has positive amounts.\n"
1704 " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the 'move' category for moves \n"
1705 " outbound. It is positive for the 'receive' category, and for the 'move' category for inbound funds.\n"
1706 " \"vout\" : n, (numeric) the vout value\n"
1707 " \"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"
1708 " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and 'receive' category of transactions.\n"
1709 " When it's < 0, it means the transaction conflicted that many blocks ago.\n"
1710 " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive' category of transactions.\n"
1711 " \"blockindex\": n, (numeric) The index of the transaction in the block that includes it. Available for 'send' and 'receive' category of transactions.\n"
1712 " \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n"
1713 " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
1714 " \"time\": xxx, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT).\n"
1715 " \"timereceived\": xxx, (numeric) The time received in seconds since epoch (Jan 1 1970 GMT). Available for 'send' and 'receive' category of transactions.\n"
1716 " \"bip125-replaceable\": \"yes|no|unknown\", (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n"
1717 " may be unknown for unconfirmed transactions not in the mempool\n"
1718 " \"abandoned\": xxx, (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the 'send' category of transactions.\n"
1719 " \"comment\": \"...\", (string) If a comment is associated with the transaction.\n"
1720 " \"label\" : \"label\" (string) A comment for the address/transaction, if any\n"
1721 " \"to\": \"...\", (string) If a comment to is associated with the transaction.\n"
1722 " ],\n"
1723 " \"lastblock\": \"lastblockhash\" (string) The hash of the last block\n"
1724 "}\n"
1725 "\nExamples:\n"
1726 + HelpExampleCli("listsinceblock", "")
1727 + HelpExampleCli("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\" 6")
1728 + HelpExampleRpc("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\", 6")
1731 LOCK2(cs_main, pwallet->cs_wallet);
1733 const CBlockIndex *pindex = NULL;
1734 int target_confirms = 1;
1735 isminefilter filter = ISMINE_SPENDABLE;
1737 if (request.params.size() > 0)
1739 uint256 blockId;
1741 blockId.SetHex(request.params[0].get_str());
1742 BlockMap::iterator it = mapBlockIndex.find(blockId);
1743 if (it != mapBlockIndex.end())
1745 pindex = it->second;
1746 if (chainActive[pindex->nHeight] != pindex)
1748 // the block being asked for is a part of a deactivated chain;
1749 // we don't want to depend on its perceived height in the block
1750 // chain, we want to instead use the last common ancestor
1751 pindex = chainActive.FindFork(pindex);
1756 if (request.params.size() > 1)
1758 target_confirms = request.params[1].get_int();
1760 if (target_confirms < 1)
1761 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter");
1764 if (request.params.size() > 2 && request.params[2].get_bool())
1766 filter = filter | ISMINE_WATCH_ONLY;
1769 int depth = pindex ? (1 + chainActive.Height() - pindex->nHeight) : -1;
1771 UniValue transactions(UniValue::VARR);
1773 for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
1774 CWalletTx tx = pairWtx.second;
1776 if (depth == -1 || tx.GetDepthInMainChain() < depth)
1777 ListTransactions(pwallet, tx, "*", 0, true, transactions, filter);
1780 CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms];
1781 uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : uint256();
1783 UniValue ret(UniValue::VOBJ);
1784 ret.push_back(Pair("transactions", transactions));
1785 ret.push_back(Pair("lastblock", lastblock.GetHex()));
1787 return ret;
1790 UniValue gettransaction(const JSONRPCRequest& request)
1792 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1793 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1794 return NullUniValue;
1797 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
1798 throw std::runtime_error(
1799 "gettransaction \"txid\" ( include_watchonly )\n"
1800 "\nGet detailed information about in-wallet transaction <txid>\n"
1801 "\nArguments:\n"
1802 "1. \"txid\" (string, required) The transaction id\n"
1803 "2. \"include_watchonly\" (bool, optional, default=false) Whether to include watch-only addresses in balance calculation and details[]\n"
1804 "\nResult:\n"
1805 "{\n"
1806 " \"amount\" : x.xxx, (numeric) The transaction amount in " + CURRENCY_UNIT + "\n"
1807 " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n"
1808 " 'send' category of transactions.\n"
1809 " \"confirmations\" : n, (numeric) The number of confirmations\n"
1810 " \"blockhash\" : \"hash\", (string) The block hash\n"
1811 " \"blockindex\" : xx, (numeric) The index of the transaction in the block that includes it\n"
1812 " \"blocktime\" : ttt, (numeric) The time in seconds since epoch (1 Jan 1970 GMT)\n"
1813 " \"txid\" : \"transactionid\", (string) The transaction id.\n"
1814 " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (1 Jan 1970 GMT)\n"
1815 " \"timereceived\" : ttt, (numeric) The time received in seconds since epoch (1 Jan 1970 GMT)\n"
1816 " \"bip125-replaceable\": \"yes|no|unknown\", (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n"
1817 " may be unknown for unconfirmed transactions not in the mempool\n"
1818 " \"details\" : [\n"
1819 " {\n"
1820 " \"account\" : \"accountname\", (string) DEPRECATED. The account name involved in the transaction, can be \"\" for the default account.\n"
1821 " \"address\" : \"address\", (string) The bitcoin address involved in the transaction\n"
1822 " \"category\" : \"send|receive\", (string) The category, either 'send' or 'receive'\n"
1823 " \"amount\" : x.xxx, (numeric) The amount in " + CURRENCY_UNIT + "\n"
1824 " \"label\" : \"label\", (string) A comment for the address/transaction, if any\n"
1825 " \"vout\" : n, (numeric) the vout value\n"
1826 " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n"
1827 " 'send' category of transactions.\n"
1828 " \"abandoned\": xxx (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n"
1829 " 'send' category of transactions.\n"
1830 " }\n"
1831 " ,...\n"
1832 " ],\n"
1833 " \"hex\" : \"data\" (string) Raw data for transaction\n"
1834 "}\n"
1836 "\nExamples:\n"
1837 + HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
1838 + HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\" true")
1839 + HelpExampleRpc("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
1842 LOCK2(cs_main, pwallet->cs_wallet);
1844 uint256 hash;
1845 hash.SetHex(request.params[0].get_str());
1847 isminefilter filter = ISMINE_SPENDABLE;
1848 if(request.params.size() > 1)
1849 if(request.params[1].get_bool())
1850 filter = filter | ISMINE_WATCH_ONLY;
1852 UniValue entry(UniValue::VOBJ);
1853 if (!pwallet->mapWallet.count(hash)) {
1854 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
1856 const CWalletTx& wtx = pwallet->mapWallet[hash];
1858 CAmount nCredit = wtx.GetCredit(filter);
1859 CAmount nDebit = wtx.GetDebit(filter);
1860 CAmount nNet = nCredit - nDebit;
1861 CAmount nFee = (wtx.IsFromMe(filter) ? wtx.tx->GetValueOut() - nDebit : 0);
1863 entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
1864 if (wtx.IsFromMe(filter))
1865 entry.push_back(Pair("fee", ValueFromAmount(nFee)));
1867 WalletTxToJSON(wtx, entry);
1869 UniValue details(UniValue::VARR);
1870 ListTransactions(pwallet, wtx, "*", 0, false, details, filter);
1871 entry.push_back(Pair("details", details));
1873 std::string strHex = EncodeHexTx(static_cast<CTransaction>(wtx), RPCSerializationFlags());
1874 entry.push_back(Pair("hex", strHex));
1876 return entry;
1879 UniValue abandontransaction(const JSONRPCRequest& request)
1881 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1882 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1883 return NullUniValue;
1886 if (request.fHelp || request.params.size() != 1)
1887 throw std::runtime_error(
1888 "abandontransaction \"txid\"\n"
1889 "\nMark in-wallet transaction <txid> as abandoned\n"
1890 "This will mark this transaction and all its in-wallet descendants as abandoned which will allow\n"
1891 "for their inputs to be respent. It can be used to replace \"stuck\" or evicted transactions.\n"
1892 "It only works on transactions which are not included in a block and are not currently in the mempool.\n"
1893 "It has no effect on transactions which are already conflicted or abandoned.\n"
1894 "\nArguments:\n"
1895 "1. \"txid\" (string, required) The transaction id\n"
1896 "\nResult:\n"
1897 "\nExamples:\n"
1898 + HelpExampleCli("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
1899 + HelpExampleRpc("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
1902 LOCK2(cs_main, pwallet->cs_wallet);
1904 uint256 hash;
1905 hash.SetHex(request.params[0].get_str());
1907 if (!pwallet->mapWallet.count(hash)) {
1908 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
1910 if (!pwallet->AbandonTransaction(hash)) {
1911 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not eligible for abandonment");
1914 return NullUniValue;
1918 UniValue backupwallet(const JSONRPCRequest& request)
1920 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1921 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1922 return NullUniValue;
1925 if (request.fHelp || request.params.size() != 1)
1926 throw std::runtime_error(
1927 "backupwallet \"destination\"\n"
1928 "\nSafely copies current wallet file to destination, which can be a directory or a path with filename.\n"
1929 "\nArguments:\n"
1930 "1. \"destination\" (string) The destination directory or file\n"
1931 "\nExamples:\n"
1932 + HelpExampleCli("backupwallet", "\"backup.dat\"")
1933 + HelpExampleRpc("backupwallet", "\"backup.dat\"")
1936 LOCK2(cs_main, pwallet->cs_wallet);
1938 std::string strDest = request.params[0].get_str();
1939 if (!pwallet->BackupWallet(strDest)) {
1940 throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!");
1943 return NullUniValue;
1947 UniValue keypoolrefill(const JSONRPCRequest& request)
1949 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1950 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1951 return NullUniValue;
1954 if (request.fHelp || request.params.size() > 1)
1955 throw std::runtime_error(
1956 "keypoolrefill ( newsize )\n"
1957 "\nFills the keypool."
1958 + HelpRequiringPassphrase(pwallet) + "\n"
1959 "\nArguments\n"
1960 "1. newsize (numeric, optional, default=100) The new keypool size\n"
1961 "\nExamples:\n"
1962 + HelpExampleCli("keypoolrefill", "")
1963 + HelpExampleRpc("keypoolrefill", "")
1966 LOCK2(cs_main, pwallet->cs_wallet);
1968 // 0 is interpreted by TopUpKeyPool() as the default keypool size given by -keypool
1969 unsigned int kpSize = 0;
1970 if (request.params.size() > 0) {
1971 if (request.params[0].get_int() < 0)
1972 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected valid size.");
1973 kpSize = (unsigned int)request.params[0].get_int();
1976 EnsureWalletIsUnlocked(pwallet);
1977 pwallet->TopUpKeyPool(kpSize);
1979 if (pwallet->GetKeyPoolSize() < kpSize) {
1980 throw JSONRPCError(RPC_WALLET_ERROR, "Error refreshing keypool.");
1983 return NullUniValue;
1987 static void LockWallet(CWallet* pWallet)
1989 LOCK(pWallet->cs_wallet);
1990 pWallet->nRelockTime = 0;
1991 pWallet->Lock();
1994 UniValue walletpassphrase(const JSONRPCRequest& request)
1996 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1997 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1998 return NullUniValue;
2001 if (pwallet->IsCrypted() && (request.fHelp || request.params.size() != 2)) {
2002 throw std::runtime_error(
2003 "walletpassphrase \"passphrase\" timeout\n"
2004 "\nStores the wallet decryption key in memory for 'timeout' seconds.\n"
2005 "This is needed prior to performing transactions related to private keys such as sending bitcoins\n"
2006 "\nArguments:\n"
2007 "1. \"passphrase\" (string, required) The wallet passphrase\n"
2008 "2. timeout (numeric, required) The time to keep the decryption key in seconds.\n"
2009 "\nNote:\n"
2010 "Issuing the walletpassphrase command while the wallet is already unlocked will set a new unlock\n"
2011 "time that overrides the old one.\n"
2012 "\nExamples:\n"
2013 "\nunlock the wallet for 60 seconds\n"
2014 + HelpExampleCli("walletpassphrase", "\"my pass phrase\" 60") +
2015 "\nLock the wallet again (before 60 seconds)\n"
2016 + HelpExampleCli("walletlock", "") +
2017 "\nAs json rpc call\n"
2018 + HelpExampleRpc("walletpassphrase", "\"my pass phrase\", 60")
2022 LOCK2(cs_main, pwallet->cs_wallet);
2024 if (request.fHelp)
2025 return true;
2026 if (!pwallet->IsCrypted()) {
2027 throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrase was called.");
2030 // Note that the walletpassphrase is stored in request.params[0] which is not mlock()ed
2031 SecureString strWalletPass;
2032 strWalletPass.reserve(100);
2033 // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
2034 // Alternately, find a way to make request.params[0] mlock()'d to begin with.
2035 strWalletPass = request.params[0].get_str().c_str();
2037 if (strWalletPass.length() > 0)
2039 if (!pwallet->Unlock(strWalletPass)) {
2040 throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect.");
2043 else
2044 throw std::runtime_error(
2045 "walletpassphrase <passphrase> <timeout>\n"
2046 "Stores the wallet decryption key in memory for <timeout> seconds.");
2048 pwallet->TopUpKeyPool();
2050 int64_t nSleepTime = request.params[1].get_int64();
2051 pwallet->nRelockTime = GetTime() + nSleepTime;
2052 RPCRunLater(strprintf("lockwallet(%s)", pwallet->GetName()), boost::bind(LockWallet, pwallet), nSleepTime);
2054 return NullUniValue;
2058 UniValue walletpassphrasechange(const JSONRPCRequest& request)
2060 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2061 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2062 return NullUniValue;
2065 if (pwallet->IsCrypted() && (request.fHelp || request.params.size() != 2)) {
2066 throw std::runtime_error(
2067 "walletpassphrasechange \"oldpassphrase\" \"newpassphrase\"\n"
2068 "\nChanges the wallet passphrase from 'oldpassphrase' to 'newpassphrase'.\n"
2069 "\nArguments:\n"
2070 "1. \"oldpassphrase\" (string) The current passphrase\n"
2071 "2. \"newpassphrase\" (string) The new passphrase\n"
2072 "\nExamples:\n"
2073 + HelpExampleCli("walletpassphrasechange", "\"old one\" \"new one\"")
2074 + HelpExampleRpc("walletpassphrasechange", "\"old one\", \"new one\"")
2078 LOCK2(cs_main, pwallet->cs_wallet);
2080 if (request.fHelp)
2081 return true;
2082 if (!pwallet->IsCrypted()) {
2083 throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrasechange was called.");
2086 // TODO: get rid of these .c_str() calls by implementing SecureString::operator=(std::string)
2087 // Alternately, find a way to make request.params[0] mlock()'d to begin with.
2088 SecureString strOldWalletPass;
2089 strOldWalletPass.reserve(100);
2090 strOldWalletPass = request.params[0].get_str().c_str();
2092 SecureString strNewWalletPass;
2093 strNewWalletPass.reserve(100);
2094 strNewWalletPass = request.params[1].get_str().c_str();
2096 if (strOldWalletPass.length() < 1 || strNewWalletPass.length() < 1)
2097 throw std::runtime_error(
2098 "walletpassphrasechange <oldpassphrase> <newpassphrase>\n"
2099 "Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>.");
2101 if (!pwallet->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass)) {
2102 throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect.");
2105 return NullUniValue;
2109 UniValue walletlock(const JSONRPCRequest& request)
2111 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2112 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2113 return NullUniValue;
2116 if (pwallet->IsCrypted() && (request.fHelp || request.params.size() != 0)) {
2117 throw std::runtime_error(
2118 "walletlock\n"
2119 "\nRemoves the wallet encryption key from memory, locking the wallet.\n"
2120 "After calling this method, you will need to call walletpassphrase again\n"
2121 "before being able to call any methods which require the wallet to be unlocked.\n"
2122 "\nExamples:\n"
2123 "\nSet the passphrase for 2 minutes to perform a transaction\n"
2124 + HelpExampleCli("walletpassphrase", "\"my pass phrase\" 120") +
2125 "\nPerform a send (requires passphrase set)\n"
2126 + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 1.0") +
2127 "\nClear the passphrase since we are done before 2 minutes is up\n"
2128 + HelpExampleCli("walletlock", "") +
2129 "\nAs json rpc call\n"
2130 + HelpExampleRpc("walletlock", "")
2134 LOCK2(cs_main, pwallet->cs_wallet);
2136 if (request.fHelp)
2137 return true;
2138 if (!pwallet->IsCrypted()) {
2139 throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletlock was called.");
2142 pwallet->Lock();
2143 pwallet->nRelockTime = 0;
2145 return NullUniValue;
2149 UniValue encryptwallet(const JSONRPCRequest& request)
2151 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2152 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2153 return NullUniValue;
2156 if (!pwallet->IsCrypted() && (request.fHelp || request.params.size() != 1)) {
2157 throw std::runtime_error(
2158 "encryptwallet \"passphrase\"\n"
2159 "\nEncrypts the wallet with 'passphrase'. This is for first time encryption.\n"
2160 "After this, any calls that interact with private keys such as sending or signing \n"
2161 "will require the passphrase to be set prior the making these calls.\n"
2162 "Use the walletpassphrase call for this, and then walletlock call.\n"
2163 "If the wallet is already encrypted, use the walletpassphrasechange call.\n"
2164 "Note that this will shutdown the server.\n"
2165 "\nArguments:\n"
2166 "1. \"passphrase\" (string) The pass phrase to encrypt the wallet with. It must be at least 1 character, but should be long.\n"
2167 "\nExamples:\n"
2168 "\nEncrypt you wallet\n"
2169 + HelpExampleCli("encryptwallet", "\"my pass phrase\"") +
2170 "\nNow set the passphrase to use the wallet, such as for signing or sending bitcoin\n"
2171 + HelpExampleCli("walletpassphrase", "\"my pass phrase\"") +
2172 "\nNow we can so something like sign\n"
2173 + HelpExampleCli("signmessage", "\"address\" \"test message\"") +
2174 "\nNow lock the wallet again by removing the passphrase\n"
2175 + HelpExampleCli("walletlock", "") +
2176 "\nAs a json rpc call\n"
2177 + HelpExampleRpc("encryptwallet", "\"my pass phrase\"")
2181 LOCK2(cs_main, pwallet->cs_wallet);
2183 if (request.fHelp)
2184 return true;
2185 if (pwallet->IsCrypted()) {
2186 throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an encrypted wallet, but encryptwallet was called.");
2189 // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
2190 // Alternately, find a way to make request.params[0] mlock()'d to begin with.
2191 SecureString strWalletPass;
2192 strWalletPass.reserve(100);
2193 strWalletPass = request.params[0].get_str().c_str();
2195 if (strWalletPass.length() < 1)
2196 throw std::runtime_error(
2197 "encryptwallet <passphrase>\n"
2198 "Encrypts the wallet with <passphrase>.");
2200 if (!pwallet->EncryptWallet(strWalletPass)) {
2201 throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Error: Failed to encrypt the wallet.");
2204 // BDB seems to have a bad habit of writing old data into
2205 // slack space in .dat files; that is bad if the old data is
2206 // unencrypted private keys. So:
2207 StartShutdown();
2208 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.";
2211 UniValue lockunspent(const JSONRPCRequest& request)
2213 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2214 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2215 return NullUniValue;
2218 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
2219 throw std::runtime_error(
2220 "lockunspent unlock ([{\"txid\":\"txid\",\"vout\":n},...])\n"
2221 "\nUpdates list of temporarily unspendable outputs.\n"
2222 "Temporarily lock (unlock=false) or unlock (unlock=true) specified transaction outputs.\n"
2223 "If no transaction outputs are specified when unlocking then all current locked transaction outputs are unlocked.\n"
2224 "A locked transaction output will not be chosen by automatic coin selection, when spending bitcoins.\n"
2225 "Locks are stored in memory only. Nodes start with zero locked outputs, and the locked output list\n"
2226 "is always cleared (by virtue of process exit) when a node stops or fails.\n"
2227 "Also see the listunspent call\n"
2228 "\nArguments:\n"
2229 "1. unlock (boolean, required) Whether to unlock (true) or lock (false) the specified transactions\n"
2230 "2. \"transactions\" (string, optional) A json array of objects. Each object the txid (string) vout (numeric)\n"
2231 " [ (json array of json objects)\n"
2232 " {\n"
2233 " \"txid\":\"id\", (string) The transaction id\n"
2234 " \"vout\": n (numeric) The output number\n"
2235 " }\n"
2236 " ,...\n"
2237 " ]\n"
2239 "\nResult:\n"
2240 "true|false (boolean) Whether the command was successful or not\n"
2242 "\nExamples:\n"
2243 "\nList the unspent transactions\n"
2244 + HelpExampleCli("listunspent", "") +
2245 "\nLock an unspent transaction\n"
2246 + HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2247 "\nList the locked transactions\n"
2248 + HelpExampleCli("listlockunspent", "") +
2249 "\nUnlock the transaction again\n"
2250 + HelpExampleCli("lockunspent", "true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2251 "\nAs a json rpc call\n"
2252 + HelpExampleRpc("lockunspent", "false, \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"")
2255 LOCK2(cs_main, pwallet->cs_wallet);
2257 if (request.params.size() == 1)
2258 RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VBOOL));
2259 else
2260 RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VBOOL)(UniValue::VARR));
2262 bool fUnlock = request.params[0].get_bool();
2264 if (request.params.size() == 1) {
2265 if (fUnlock)
2266 pwallet->UnlockAllCoins();
2267 return true;
2270 UniValue outputs = request.params[1].get_array();
2271 for (unsigned int idx = 0; idx < outputs.size(); idx++) {
2272 const UniValue& output = outputs[idx];
2273 if (!output.isObject())
2274 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected object");
2275 const UniValue& o = output.get_obj();
2277 RPCTypeCheckObj(o,
2279 {"txid", UniValueType(UniValue::VSTR)},
2280 {"vout", UniValueType(UniValue::VNUM)},
2283 std::string txid = find_value(o, "txid").get_str();
2284 if (!IsHex(txid))
2285 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected hex txid");
2287 int nOutput = find_value(o, "vout").get_int();
2288 if (nOutput < 0)
2289 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
2291 COutPoint outpt(uint256S(txid), nOutput);
2293 if (fUnlock)
2294 pwallet->UnlockCoin(outpt);
2295 else
2296 pwallet->LockCoin(outpt);
2299 return true;
2302 UniValue listlockunspent(const JSONRPCRequest& request)
2304 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2305 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2306 return NullUniValue;
2309 if (request.fHelp || request.params.size() > 0)
2310 throw std::runtime_error(
2311 "listlockunspent\n"
2312 "\nReturns list of temporarily unspendable outputs.\n"
2313 "See the lockunspent call to lock and unlock transactions for spending.\n"
2314 "\nResult:\n"
2315 "[\n"
2316 " {\n"
2317 " \"txid\" : \"transactionid\", (string) The transaction id locked\n"
2318 " \"vout\" : n (numeric) The vout value\n"
2319 " }\n"
2320 " ,...\n"
2321 "]\n"
2322 "\nExamples:\n"
2323 "\nList the unspent transactions\n"
2324 + HelpExampleCli("listunspent", "") +
2325 "\nLock an unspent transaction\n"
2326 + HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2327 "\nList the locked transactions\n"
2328 + HelpExampleCli("listlockunspent", "") +
2329 "\nUnlock the transaction again\n"
2330 + HelpExampleCli("lockunspent", "true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2331 "\nAs a json rpc call\n"
2332 + HelpExampleRpc("listlockunspent", "")
2335 LOCK2(cs_main, pwallet->cs_wallet);
2337 std::vector<COutPoint> vOutpts;
2338 pwallet->ListLockedCoins(vOutpts);
2340 UniValue ret(UniValue::VARR);
2342 BOOST_FOREACH(COutPoint &outpt, vOutpts) {
2343 UniValue o(UniValue::VOBJ);
2345 o.push_back(Pair("txid", outpt.hash.GetHex()));
2346 o.push_back(Pair("vout", (int)outpt.n));
2347 ret.push_back(o);
2350 return ret;
2353 UniValue settxfee(const JSONRPCRequest& request)
2355 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2356 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2357 return NullUniValue;
2360 if (request.fHelp || request.params.size() < 1 || request.params.size() > 1)
2361 throw std::runtime_error(
2362 "settxfee amount\n"
2363 "\nSet the transaction fee per kB. Overwrites the paytxfee parameter.\n"
2364 "\nArguments:\n"
2365 "1. amount (numeric or string, required) The transaction fee in " + CURRENCY_UNIT + "/kB\n"
2366 "\nResult\n"
2367 "true|false (boolean) Returns true if successful\n"
2368 "\nExamples:\n"
2369 + HelpExampleCli("settxfee", "0.00001")
2370 + HelpExampleRpc("settxfee", "0.00001")
2373 LOCK2(cs_main, pwallet->cs_wallet);
2375 // Amount
2376 CAmount nAmount = AmountFromValue(request.params[0]);
2378 payTxFee = CFeeRate(nAmount, 1000);
2379 return true;
2382 UniValue getwalletinfo(const JSONRPCRequest& request)
2384 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2385 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2386 return NullUniValue;
2389 if (request.fHelp || request.params.size() != 0)
2390 throw std::runtime_error(
2391 "getwalletinfo\n"
2392 "Returns an object containing various wallet state info.\n"
2393 "\nResult:\n"
2394 "{\n"
2395 " \"walletversion\": xxxxx, (numeric) the wallet version\n"
2396 " \"balance\": xxxxxxx, (numeric) the total confirmed balance of the wallet in " + CURRENCY_UNIT + "\n"
2397 " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed balance of the wallet in " + CURRENCY_UNIT + "\n"
2398 " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet in " + CURRENCY_UNIT + "\n"
2399 " \"txcount\": xxxxxxx, (numeric) the total number of transactions in the wallet\n"
2400 " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since Unix epoch) of the oldest pre-generated key in the key pool\n"
2401 " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated (only counts external keys)\n"
2402 " \"keypoolsize_hd_internal\": xxxx, (numeric) how many new keys are pre-generated for internal use (used for change outputs, only appears if the wallet is using this feature, otherwise external keys are used)\n"
2403 " \"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"
2404 " \"paytxfee\": x.xxxx, (numeric) the transaction fee configuration, set in " + CURRENCY_UNIT + "/kB\n"
2405 " \"hdmasterkeyid\": \"<hash160>\" (string) the Hash160 of the HD master pubkey\n"
2406 "}\n"
2407 "\nExamples:\n"
2408 + HelpExampleCli("getwalletinfo", "")
2409 + HelpExampleRpc("getwalletinfo", "")
2412 LOCK2(cs_main, pwallet->cs_wallet);
2414 UniValue obj(UniValue::VOBJ);
2416 size_t kpExternalSize = pwallet->KeypoolCountExternalKeys();
2417 obj.push_back(Pair("walletversion", pwallet->GetVersion()));
2418 obj.push_back(Pair("balance", ValueFromAmount(pwallet->GetBalance())));
2419 obj.push_back(Pair("unconfirmed_balance", ValueFromAmount(pwallet->GetUnconfirmedBalance())));
2420 obj.push_back(Pair("immature_balance", ValueFromAmount(pwallet->GetImmatureBalance())));
2421 obj.push_back(Pair("txcount", (int)pwallet->mapWallet.size()));
2422 obj.push_back(Pair("keypoololdest", pwallet->GetOldestKeyPoolTime()));
2423 obj.push_back(Pair("keypoolsize", (int64_t)kpExternalSize));
2424 CKeyID masterKeyID = pwallet->GetHDChain().masterKeyID;
2425 if (!masterKeyID.IsNull() && pwallet->CanSupportFeature(FEATURE_HD_SPLIT)) {
2426 obj.push_back(Pair("keypoolsize_hd_internal", (int64_t)(pwallet->GetKeyPoolSize() - kpExternalSize)));
2428 if (pwallet->IsCrypted()) {
2429 obj.push_back(Pair("unlocked_until", pwallet->nRelockTime));
2431 obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())));
2432 if (!masterKeyID.IsNull())
2433 obj.push_back(Pair("hdmasterkeyid", masterKeyID.GetHex()));
2434 return obj;
2437 UniValue resendwallettransactions(const JSONRPCRequest& request)
2439 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2440 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2441 return NullUniValue;
2444 if (request.fHelp || request.params.size() != 0)
2445 throw std::runtime_error(
2446 "resendwallettransactions\n"
2447 "Immediately re-broadcast unconfirmed wallet transactions to all peers.\n"
2448 "Intended only for testing; the wallet code periodically re-broadcasts\n"
2449 "automatically.\n"
2450 "Returns array of transaction ids that were re-broadcast.\n"
2453 if (!g_connman)
2454 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
2456 LOCK2(cs_main, pwallet->cs_wallet);
2458 std::vector<uint256> txids = pwallet->ResendWalletTransactionsBefore(GetTime(), g_connman.get());
2459 UniValue result(UniValue::VARR);
2460 BOOST_FOREACH(const uint256& txid, txids)
2462 result.push_back(txid.ToString());
2464 return result;
2467 UniValue listunspent(const JSONRPCRequest& request)
2469 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2470 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2471 return NullUniValue;
2474 if (request.fHelp || request.params.size() > 5)
2475 throw std::runtime_error(
2476 "listunspent ( minconf maxconf [\"addresses\",...] [include_unsafe] [query_options])\n"
2477 "\nReturns array of unspent transaction outputs\n"
2478 "with between minconf and maxconf (inclusive) confirmations.\n"
2479 "Optionally filter to only include txouts paid to specified addresses.\n"
2480 "\nArguments:\n"
2481 "1. minconf (numeric, optional, default=1) The minimum confirmations to filter\n"
2482 "2. maxconf (numeric, optional, default=9999999) The maximum confirmations to filter\n"
2483 "3. \"addresses\" (string) A json array of bitcoin addresses to filter\n"
2484 " [\n"
2485 " \"address\" (string) bitcoin address\n"
2486 " ,...\n"
2487 " ]\n"
2488 "4. include_unsafe (bool, optional, default=true) Include outputs that are not safe to spend\n"
2489 " See description of \"safe\" attribute below.\n"
2490 "5. query_options (json, optional) JSON with query options\n"
2491 " {\n"
2492 " \"minimumAmount\" (numeric or string, default=0) Minimum value of each UTXO in " + CURRENCY_UNIT + "\n"
2493 " \"maximumAmount\" (numeric or string, default=unlimited) Maximum value of each UTXO in " + CURRENCY_UNIT + "\n"
2494 " \"maximumCount\" (numeric or string, default=unlimited) Maximum number of UTXOs\n"
2495 " \"minimumSumAmount\" (numeric or string, default=unlimited) Minimum sum value of all UTXOs in " + CURRENCY_UNIT + "\n"
2496 " }\n"
2497 "\nResult\n"
2498 "[ (array of json object)\n"
2499 " {\n"
2500 " \"txid\" : \"txid\", (string) the transaction id \n"
2501 " \"vout\" : n, (numeric) the vout value\n"
2502 " \"address\" : \"address\", (string) the bitcoin address\n"
2503 " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n"
2504 " \"scriptPubKey\" : \"key\", (string) the script key\n"
2505 " \"amount\" : x.xxx, (numeric) the transaction output amount in " + CURRENCY_UNIT + "\n"
2506 " \"confirmations\" : n, (numeric) The number of confirmations\n"
2507 " \"redeemScript\" : n (string) The redeemScript if scriptPubKey is P2SH\n"
2508 " \"spendable\" : xxx, (bool) Whether we have the private keys to spend this output\n"
2509 " \"solvable\" : xxx, (bool) Whether we know how to spend this output, ignoring the lack of keys\n"
2510 " \"safe\" : xxx (bool) Whether this output is considered safe to spend. Unconfirmed transactions\n"
2511 " from outside keys and unconfirmed replacement transactions are considered unsafe\n"
2512 " and are not eligible for spending by fundrawtransaction and sendtoaddress.\n"
2513 " }\n"
2514 " ,...\n"
2515 "]\n"
2517 "\nExamples\n"
2518 + HelpExampleCli("listunspent", "")
2519 + HelpExampleCli("listunspent", "6 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"")
2520 + HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"")
2521 + HelpExampleCli("listunspent", "6 9999999 '[]' true '{ \"minimumAmount\": 0.005 }'")
2522 + HelpExampleRpc("listunspent", "6, 9999999, [] , true, { \"minimumAmount\": 0.005 } ")
2525 int nMinDepth = 1;
2526 if (request.params.size() > 0 && !request.params[0].isNull()) {
2527 RPCTypeCheckArgument(request.params[0], UniValue::VNUM);
2528 nMinDepth = request.params[0].get_int();
2531 int nMaxDepth = 9999999;
2532 if (request.params.size() > 1 && !request.params[1].isNull()) {
2533 RPCTypeCheckArgument(request.params[1], UniValue::VNUM);
2534 nMaxDepth = request.params[1].get_int();
2537 std::set<CBitcoinAddress> setAddress;
2538 if (request.params.size() > 2 && !request.params[2].isNull()) {
2539 RPCTypeCheckArgument(request.params[2], UniValue::VARR);
2540 UniValue inputs = request.params[2].get_array();
2541 for (unsigned int idx = 0; idx < inputs.size(); idx++) {
2542 const UniValue& input = inputs[idx];
2543 CBitcoinAddress address(input.get_str());
2544 if (!address.IsValid())
2545 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Bitcoin address: ")+input.get_str());
2546 if (setAddress.count(address))
2547 throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ")+input.get_str());
2548 setAddress.insert(address);
2552 bool include_unsafe = true;
2553 if (request.params.size() > 3 && !request.params[3].isNull()) {
2554 RPCTypeCheckArgument(request.params[3], UniValue::VBOOL);
2555 include_unsafe = request.params[3].get_bool();
2558 CAmount nMinimumAmount = 0;
2559 CAmount nMaximumAmount = MAX_MONEY;
2560 CAmount nMinimumSumAmount = MAX_MONEY;
2561 uint64_t nMaximumCount = 0;
2563 if (request.params.size() > 4) {
2564 const UniValue& options = request.params[4].get_obj();
2566 if (options.exists("minimumAmount"))
2567 nMinimumAmount = AmountFromValue(options["minimumAmount"]);
2569 if (options.exists("maximumAmount"))
2570 nMaximumAmount = AmountFromValue(options["maximumAmount"]);
2572 if (options.exists("minimumSumAmount"))
2573 nMinimumSumAmount = AmountFromValue(options["minimumSumAmount"]);
2575 if (options.exists("maximumCount"))
2576 nMaximumCount = options["maximumCount"].get_int64();
2579 UniValue results(UniValue::VARR);
2580 std::vector<COutput> vecOutputs;
2581 assert(pwallet != NULL);
2582 LOCK2(cs_main, pwallet->cs_wallet);
2584 pwallet->AvailableCoins(vecOutputs, !include_unsafe, NULL, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount, nMinDepth, nMaxDepth);
2585 BOOST_FOREACH(const COutput& out, vecOutputs) {
2586 CTxDestination address;
2587 const CScript& scriptPubKey = out.tx->tx->vout[out.i].scriptPubKey;
2588 bool fValidAddress = ExtractDestination(scriptPubKey, address);
2590 if (setAddress.size() && (!fValidAddress || !setAddress.count(address)))
2591 continue;
2593 UniValue entry(UniValue::VOBJ);
2594 entry.push_back(Pair("txid", out.tx->GetHash().GetHex()));
2595 entry.push_back(Pair("vout", out.i));
2597 if (fValidAddress) {
2598 entry.push_back(Pair("address", CBitcoinAddress(address).ToString()));
2600 if (pwallet->mapAddressBook.count(address)) {
2601 entry.push_back(Pair("account", pwallet->mapAddressBook[address].name));
2604 if (scriptPubKey.IsPayToScriptHash()) {
2605 const CScriptID& hash = boost::get<CScriptID>(address);
2606 CScript redeemScript;
2607 if (pwallet->GetCScript(hash, redeemScript)) {
2608 entry.push_back(Pair("redeemScript", HexStr(redeemScript.begin(), redeemScript.end())));
2613 entry.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
2614 entry.push_back(Pair("amount", ValueFromAmount(out.tx->tx->vout[out.i].nValue)));
2615 entry.push_back(Pair("confirmations", out.nDepth));
2616 entry.push_back(Pair("spendable", out.fSpendable));
2617 entry.push_back(Pair("solvable", out.fSolvable));
2618 entry.push_back(Pair("safe", out.fSafe));
2619 results.push_back(entry);
2622 return results;
2625 UniValue fundrawtransaction(const JSONRPCRequest& request)
2627 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2628 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2629 return NullUniValue;
2632 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
2633 throw std::runtime_error(
2634 "fundrawtransaction \"hexstring\" ( options )\n"
2635 "\nAdd inputs to a transaction until it has enough in value to meet its out value.\n"
2636 "This will not modify existing inputs, and will add at most one change output to the outputs.\n"
2637 "No existing outputs will be modified unless \"subtractFeeFromOutputs\" is specified.\n"
2638 "Note that inputs which were signed may need to be resigned after completion since in/outputs have been added.\n"
2639 "The inputs added will not be signed, use signrawtransaction for that.\n"
2640 "Note that all existing inputs must have their previous output transaction be in the wallet.\n"
2641 "Note that all inputs selected must be of standard form and P2SH scripts must be\n"
2642 "in the wallet using importaddress or addmultisigaddress (to calculate fees).\n"
2643 "You can see whether this is the case by checking the \"solvable\" field in the listunspent output.\n"
2644 "Only pay-to-pubkey, multisig, and P2SH versions thereof are currently supported for watch-only\n"
2645 "\nArguments:\n"
2646 "1. \"hexstring\" (string, required) The hex string of the raw transaction\n"
2647 "2. options (object, optional)\n"
2648 " {\n"
2649 " \"changeAddress\" (string, optional, default pool address) The bitcoin address to receive the change\n"
2650 " \"changePosition\" (numeric, optional, default random) The index of the change output\n"
2651 " \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n"
2652 " \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\n"
2653 " \"reserveChangeKey\" (boolean, optional, default true) Reserves the change output key from the keypool\n"
2654 " \"feeRate\" (numeric, optional, default not set: makes wallet determine the fee) Set a specific feerate (" + CURRENCY_UNIT + " per KB)\n"
2655 " \"subtractFeeFromOutputs\" (array, optional) A json array of integers.\n"
2656 " The fee will be equally deducted from the amount of each specified output.\n"
2657 " The outputs are specified by their zero-based index, before any change output is added.\n"
2658 " Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
2659 " If no outputs are specified here, the sender pays the fee.\n"
2660 " [vout_index,...]\n"
2661 " }\n"
2662 " for backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}\n"
2663 "\nResult:\n"
2664 "{\n"
2665 " \"hex\": \"value\", (string) The resulting raw transaction (hex-encoded string)\n"
2666 " \"fee\": n, (numeric) Fee in " + CURRENCY_UNIT + " the resulting transaction pays\n"
2667 " \"changepos\": n (numeric) The position of the added change output, or -1\n"
2668 "}\n"
2669 "\nExamples:\n"
2670 "\nCreate a transaction with no inputs\n"
2671 + HelpExampleCli("createrawtransaction", "\"[]\" \"{\\\"myaddress\\\":0.01}\"") +
2672 "\nAdd sufficient unsigned inputs to meet the output value\n"
2673 + HelpExampleCli("fundrawtransaction", "\"rawtransactionhex\"") +
2674 "\nSign the transaction\n"
2675 + HelpExampleCli("signrawtransaction", "\"fundedtransactionhex\"") +
2676 "\nSend the transaction\n"
2677 + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"")
2680 RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR));
2682 CTxDestination changeAddress = CNoDestination();
2683 int changePosition = -1;
2684 bool includeWatching = false;
2685 bool lockUnspents = false;
2686 bool reserveChangeKey = true;
2687 CFeeRate feeRate = CFeeRate(0);
2688 bool overrideEstimatedFeerate = false;
2689 UniValue subtractFeeFromOutputs;
2690 std::set<int> setSubtractFeeFromOutputs;
2692 if (request.params.size() > 1) {
2693 if (request.params[1].type() == UniValue::VBOOL) {
2694 // backward compatibility bool only fallback
2695 includeWatching = request.params[1].get_bool();
2697 else {
2698 RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR)(UniValue::VOBJ));
2700 UniValue options = request.params[1];
2702 RPCTypeCheckObj(options,
2704 {"changeAddress", UniValueType(UniValue::VSTR)},
2705 {"changePosition", UniValueType(UniValue::VNUM)},
2706 {"includeWatching", UniValueType(UniValue::VBOOL)},
2707 {"lockUnspents", UniValueType(UniValue::VBOOL)},
2708 {"reserveChangeKey", UniValueType(UniValue::VBOOL)},
2709 {"feeRate", UniValueType()}, // will be checked below
2710 {"subtractFeeFromOutputs", UniValueType(UniValue::VARR)},
2712 true, true);
2714 if (options.exists("changeAddress")) {
2715 CBitcoinAddress address(options["changeAddress"].get_str());
2717 if (!address.IsValid())
2718 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "changeAddress must be a valid bitcoin address");
2720 changeAddress = address.Get();
2723 if (options.exists("changePosition"))
2724 changePosition = options["changePosition"].get_int();
2726 if (options.exists("includeWatching"))
2727 includeWatching = options["includeWatching"].get_bool();
2729 if (options.exists("lockUnspents"))
2730 lockUnspents = options["lockUnspents"].get_bool();
2732 if (options.exists("reserveChangeKey"))
2733 reserveChangeKey = options["reserveChangeKey"].get_bool();
2735 if (options.exists("feeRate"))
2737 feeRate = CFeeRate(AmountFromValue(options["feeRate"]));
2738 overrideEstimatedFeerate = true;
2741 if (options.exists("subtractFeeFromOutputs"))
2742 subtractFeeFromOutputs = options["subtractFeeFromOutputs"].get_array();
2746 // parse hex string from parameter
2747 CMutableTransaction tx;
2748 if (!DecodeHexTx(tx, request.params[0].get_str(), true))
2749 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
2751 if (tx.vout.size() == 0)
2752 throw JSONRPCError(RPC_INVALID_PARAMETER, "TX must have at least one output");
2754 if (changePosition != -1 && (changePosition < 0 || (unsigned int)changePosition > tx.vout.size()))
2755 throw JSONRPCError(RPC_INVALID_PARAMETER, "changePosition out of bounds");
2757 for (unsigned int idx = 0; idx < subtractFeeFromOutputs.size(); idx++) {
2758 int pos = subtractFeeFromOutputs[idx].get_int();
2759 if (setSubtractFeeFromOutputs.count(pos))
2760 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, duplicated position: %d", pos));
2761 if (pos < 0)
2762 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, negative position: %d", pos));
2763 if (pos >= int(tx.vout.size()))
2764 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, position too large: %d", pos));
2765 setSubtractFeeFromOutputs.insert(pos);
2768 CAmount nFeeOut;
2769 std::string strFailReason;
2771 if (!pwallet->FundTransaction(tx, nFeeOut, overrideEstimatedFeerate, feeRate, changePosition, strFailReason, includeWatching, lockUnspents, setSubtractFeeFromOutputs, reserveChangeKey, changeAddress)) {
2772 throw JSONRPCError(RPC_WALLET_ERROR, strFailReason);
2775 UniValue result(UniValue::VOBJ);
2776 result.push_back(Pair("hex", EncodeHexTx(tx)));
2777 result.push_back(Pair("changepos", changePosition));
2778 result.push_back(Pair("fee", ValueFromAmount(nFeeOut)));
2780 return result;
2783 UniValue bumpfee(const JSONRPCRequest& request)
2785 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2787 if (!EnsureWalletIsAvailable(pwallet, request.fHelp))
2788 return NullUniValue;
2790 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
2791 throw std::runtime_error(
2792 "bumpfee \"txid\" ( options ) \n"
2793 "\nBumps the fee of an opt-in-RBF transaction T, replacing it with a new transaction B.\n"
2794 "An opt-in RBF transaction with the given txid must be in the wallet.\n"
2795 "The command will pay the additional fee by decreasing (or perhaps removing) its change output.\n"
2796 "If the change output is not big enough to cover the increased fee, the command will currently fail\n"
2797 "instead of adding new inputs to compensate. (A future implementation could improve this.)\n"
2798 "The command will fail if the wallet or mempool contains a transaction that spends one of T's outputs.\n"
2799 "By default, the new fee will be calculated automatically using estimatefee.\n"
2800 "The user can specify a confirmation target for estimatefee.\n"
2801 "Alternatively, the user can specify totalFee, or use RPC settxfee to set a higher fee rate.\n"
2802 "At a minimum, the new fee rate must be high enough to pay an additional new relay fee (incrementalfee\n"
2803 "returned by getnetworkinfo) to enter the node's mempool.\n"
2804 "\nArguments:\n"
2805 "1. txid (string, required) The txid to be bumped\n"
2806 "2. options (object, optional)\n"
2807 " {\n"
2808 " \"confTarget\" (numeric, optional) Confirmation target (in blocks)\n"
2809 " \"totalFee\" (numeric, optional) Total fee (NOT feerate) to pay, in satoshis.\n"
2810 " In rare cases, the actual fee paid might be slightly higher than the specified\n"
2811 " totalFee if the tx change output has to be removed because it is too close to\n"
2812 " the dust threshold.\n"
2813 " \"replaceable\" (boolean, optional, default true) Whether the new transaction should still be\n"
2814 " marked bip-125 replaceable. If true, the sequence numbers in the transaction will\n"
2815 " be left unchanged from the original. If false, any input sequence numbers in the\n"
2816 " original transaction that were less than 0xfffffffe will be increased to 0xfffffffe\n"
2817 " so the new transaction will not be explicitly bip-125 replaceable (though it may\n"
2818 " still be replaceable in practice, for example if it has unconfirmed ancestors which\n"
2819 " are replaceable).\n"
2820 " }\n"
2821 "\nResult:\n"
2822 "{\n"
2823 " \"txid\": \"value\", (string) The id of the new transaction\n"
2824 " \"origfee\": n, (numeric) Fee of the replaced transaction\n"
2825 " \"fee\": n, (numeric) Fee of the new transaction\n"
2826 " \"errors\": [ str... ] (json array of strings) Errors encountered during processing (may be empty)\n"
2827 "}\n"
2828 "\nExamples:\n"
2829 "\nBump the fee, get the new transaction\'s txid\n" +
2830 HelpExampleCli("bumpfee", "<txid>"));
2833 RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR)(UniValue::VOBJ));
2834 uint256 hash;
2835 hash.SetHex(request.params[0].get_str());
2837 // optional parameters
2838 bool ignoreGlobalPayTxFee = false;
2839 int newConfirmTarget = nTxConfirmTarget;
2840 CAmount totalFee = 0;
2841 bool replaceable = true;
2842 if (request.params.size() > 1) {
2843 UniValue options = request.params[1];
2844 RPCTypeCheckObj(options,
2846 {"confTarget", UniValueType(UniValue::VNUM)},
2847 {"totalFee", UniValueType(UniValue::VNUM)},
2848 {"replaceable", UniValueType(UniValue::VBOOL)},
2850 true, true);
2852 if (options.exists("confTarget") && options.exists("totalFee")) {
2853 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.");
2854 } else if (options.exists("confTarget")) {
2855 // If the user has explicitly set a confTarget in this rpc call,
2856 // then override the default logic that uses the global payTxFee
2857 // instead of the confirmation target.
2858 ignoreGlobalPayTxFee = true;
2859 newConfirmTarget = options["confTarget"].get_int();
2860 if (newConfirmTarget <= 0) { // upper-bound will be checked by estimatefee/smartfee
2861 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid confTarget (cannot be <= 0)");
2863 } else if (options.exists("totalFee")) {
2864 totalFee = options["totalFee"].get_int64();
2865 if (totalFee <= 0) {
2866 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid totalFee %s (must be greater than 0)", FormatMoney(totalFee)));
2870 if (options.exists("replaceable")) {
2871 replaceable = options["replaceable"].get_bool();
2875 LOCK2(cs_main, pwallet->cs_wallet);
2876 EnsureWalletIsUnlocked(pwallet);
2878 CFeeBumper feeBump(pwallet, hash, newConfirmTarget, ignoreGlobalPayTxFee, totalFee, replaceable);
2879 BumpFeeResult res = feeBump.getResult();
2880 if (res != BumpFeeResult::OK)
2882 switch(res) {
2883 case BumpFeeResult::INVALID_ADDRESS_OR_KEY:
2884 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, feeBump.getErrors()[0]);
2885 break;
2886 case BumpFeeResult::INVALID_REQUEST:
2887 throw JSONRPCError(RPC_INVALID_REQUEST, feeBump.getErrors()[0]);
2888 break;
2889 case BumpFeeResult::INVALID_PARAMETER:
2890 throw JSONRPCError(RPC_INVALID_PARAMETER, feeBump.getErrors()[0]);
2891 break;
2892 case BumpFeeResult::WALLET_ERROR:
2893 throw JSONRPCError(RPC_WALLET_ERROR, feeBump.getErrors()[0]);
2894 break;
2895 default:
2896 throw JSONRPCError(RPC_MISC_ERROR, feeBump.getErrors()[0]);
2897 break;
2901 // sign bumped transaction
2902 if (!feeBump.signTransaction(pwallet)) {
2903 throw JSONRPCError(RPC_WALLET_ERROR, "Can't sign transaction.");
2905 // commit the bumped transaction
2906 if(!feeBump.commit(pwallet)) {
2907 throw JSONRPCError(RPC_WALLET_ERROR, feeBump.getErrors()[0]);
2909 UniValue result(UniValue::VOBJ);
2910 result.push_back(Pair("txid", feeBump.getBumpedTxId().GetHex()));
2911 result.push_back(Pair("origfee", ValueFromAmount(feeBump.getOldFee())));
2912 result.push_back(Pair("fee", ValueFromAmount(feeBump.getNewFee())));
2913 UniValue errors(UniValue::VARR);
2914 for (const std::string& err: feeBump.getErrors())
2915 errors.push_back(err);
2916 result.push_back(Pair("errors", errors));
2918 return result;
2921 extern UniValue abortrescan(const JSONRPCRequest& request); // in rpcdump.cpp
2922 extern UniValue dumpprivkey(const JSONRPCRequest& request); // in rpcdump.cpp
2923 extern UniValue importprivkey(const JSONRPCRequest& request);
2924 extern UniValue importaddress(const JSONRPCRequest& request);
2925 extern UniValue importpubkey(const JSONRPCRequest& request);
2926 extern UniValue dumpwallet(const JSONRPCRequest& request);
2927 extern UniValue importwallet(const JSONRPCRequest& request);
2928 extern UniValue importprunedfunds(const JSONRPCRequest& request);
2929 extern UniValue removeprunedfunds(const JSONRPCRequest& request);
2930 extern UniValue importmulti(const JSONRPCRequest& request);
2932 static const CRPCCommand commands[] =
2933 { // category name actor (function) okSafeMode
2934 // --------------------- ------------------------ ----------------------- ----------
2935 { "rawtransactions", "fundrawtransaction", &fundrawtransaction, false, {"hexstring","options"} },
2936 { "hidden", "resendwallettransactions", &resendwallettransactions, true, {} },
2937 { "wallet", "abandontransaction", &abandontransaction, false, {"txid"} },
2938 { "wallet", "abortrescan", &abortrescan, false, {} },
2939 { "wallet", "addmultisigaddress", &addmultisigaddress, true, {"nrequired","keys","account"} },
2940 { "wallet", "addwitnessaddress", &addwitnessaddress, true, {"address"} },
2941 { "wallet", "backupwallet", &backupwallet, true, {"destination"} },
2942 { "wallet", "bumpfee", &bumpfee, true, {"txid", "options"} },
2943 { "wallet", "dumpprivkey", &dumpprivkey, true, {"address"} },
2944 { "wallet", "dumpwallet", &dumpwallet, true, {"filename"} },
2945 { "wallet", "encryptwallet", &encryptwallet, true, {"passphrase"} },
2946 { "wallet", "getaccountaddress", &getaccountaddress, true, {"account"} },
2947 { "wallet", "getaccount", &getaccount, true, {"address"} },
2948 { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true, {"account"} },
2949 { "wallet", "getbalance", &getbalance, false, {"account","minconf","include_watchonly"} },
2950 { "wallet", "getnewaddress", &getnewaddress, true, {"account"} },
2951 { "wallet", "getrawchangeaddress", &getrawchangeaddress, true, {} },
2952 { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false, {"account","minconf"} },
2953 { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false, {"address","minconf"} },
2954 { "wallet", "gettransaction", &gettransaction, false, {"txid","include_watchonly"} },
2955 { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false, {} },
2956 { "wallet", "getwalletinfo", &getwalletinfo, false, {} },
2957 { "wallet", "importmulti", &importmulti, true, {"requests","options"} },
2958 { "wallet", "importprivkey", &importprivkey, true, {"privkey","label","rescan"} },
2959 { "wallet", "importwallet", &importwallet, true, {"filename"} },
2960 { "wallet", "importaddress", &importaddress, true, {"address","label","rescan","p2sh"} },
2961 { "wallet", "importprunedfunds", &importprunedfunds, true, {"rawtransaction","txoutproof"} },
2962 { "wallet", "importpubkey", &importpubkey, true, {"pubkey","label","rescan"} },
2963 { "wallet", "keypoolrefill", &keypoolrefill, true, {"newsize"} },
2964 { "wallet", "listaccounts", &listaccounts, false, {"minconf","include_watchonly"} },
2965 { "wallet", "listaddressgroupings", &listaddressgroupings, false, {} },
2966 { "wallet", "listlockunspent", &listlockunspent, false, {} },
2967 { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, false, {"minconf","include_empty","include_watchonly"} },
2968 { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false, {"minconf","include_empty","include_watchonly"} },
2969 { "wallet", "listsinceblock", &listsinceblock, false, {"blockhash","target_confirmations","include_watchonly"} },
2970 { "wallet", "listtransactions", &listtransactions, false, {"account","count","skip","include_watchonly"} },
2971 { "wallet", "listunspent", &listunspent, false, {"minconf","maxconf","addresses","include_unsafe","query_options"} },
2972 { "wallet", "lockunspent", &lockunspent, true, {"unlock","transactions"} },
2973 { "wallet", "move", &movecmd, false, {"fromaccount","toaccount","amount","minconf","comment"} },
2974 { "wallet", "sendfrom", &sendfrom, false, {"fromaccount","toaddress","amount","minconf","comment","comment_to"} },
2975 { "wallet", "sendmany", &sendmany, false, {"fromaccount","amounts","minconf","comment","subtractfeefrom"} },
2976 { "wallet", "sendtoaddress", &sendtoaddress, false, {"address","amount","comment","comment_to","subtractfeefromamount"} },
2977 { "wallet", "setaccount", &setaccount, true, {"address","account"} },
2978 { "wallet", "settxfee", &settxfee, true, {"amount"} },
2979 { "wallet", "signmessage", &signmessage, true, {"address","message"} },
2980 { "wallet", "walletlock", &walletlock, true, {} },
2981 { "wallet", "walletpassphrasechange", &walletpassphrasechange, true, {"oldpassphrase","newpassphrase"} },
2982 { "wallet", "walletpassphrase", &walletpassphrase, true, {"passphrase","timeout"} },
2983 { "wallet", "removeprunedfunds", &removeprunedfunds, true, {"txid"} },
2986 void RegisterWalletRPCCommands(CRPCTable &t)
2988 if (GetBoolArg("-disablewallet", false))
2989 return;
2991 for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
2992 t.appendCommand(commands[vcidx].name, &commands[vcidx]);