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.
9 #include "consensus/validation.h"
11 #include "httpserver.h"
12 #include "validation.h"
14 #include "policy/feerate.h"
15 #include "policy/fees.h"
16 #include "policy/policy.h"
17 #include "policy/rbf.h"
18 #include "rpc/mining.h"
19 #include "rpc/server.h"
20 #include "script/sign.h"
23 #include "utilmoneystr.h"
24 #include "wallet/coincontrol.h"
25 #include "wallet/feebumper.h"
26 #include "wallet/wallet.h"
27 #include "wallet/walletdb.h"
29 #include <init.h> // For StartShutdown
35 static const std::string WALLET_ENDPOINT_BASE
= "/wallet/";
37 CWallet
*GetWalletForJSONRPCRequest(const JSONRPCRequest
& request
)
39 if (request
.URI
.substr(0, WALLET_ENDPOINT_BASE
.size()) == WALLET_ENDPOINT_BASE
) {
40 // wallet endpoint was used
41 std::string requestedWallet
= urlDecode(request
.URI
.substr(WALLET_ENDPOINT_BASE
.size()));
42 for (CWalletRef pwallet
: ::vpwallets
) {
43 if (pwallet
->GetName() == requestedWallet
) {
47 throw JSONRPCError(RPC_WALLET_NOT_FOUND
, "Requested wallet does not exist or is not loaded");
49 return ::vpwallets
.size() == 1 || (request
.fHelp
&& ::vpwallets
.size() > 0) ? ::vpwallets
[0] : nullptr;
52 std::string
HelpRequiringPassphrase(CWallet
* const pwallet
)
54 return pwallet
&& pwallet
->IsCrypted()
55 ? "\nRequires wallet passphrase to be set with walletpassphrase call."
59 bool EnsureWalletIsAvailable(CWallet
* const pwallet
, bool avoidException
)
61 if (pwallet
) return true;
62 if (avoidException
) return false;
63 if (::vpwallets
.empty()) {
64 // Note: It isn't currently possible to trigger this error because
65 // wallet RPC methods aren't registered unless a wallet is loaded. But
66 // this error is being kept as a precaution, because it's possible in
67 // the future that wallet RPC methods might get or remain registered
68 // when no wallets are loaded.
70 RPC_METHOD_NOT_FOUND
, "Method not found (wallet method is disabled because no wallet is loaded)");
72 throw JSONRPCError(RPC_WALLET_NOT_SPECIFIED
,
73 "Wallet file not specified (must request wallet RPC through /wallet/<filename> uri-path).");
76 void EnsureWalletIsUnlocked(CWallet
* const pwallet
)
78 if (pwallet
->IsLocked()) {
79 throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED
, "Error: Please enter the wallet passphrase with walletpassphrase first.");
83 void WalletTxToJSON(const CWalletTx
& wtx
, UniValue
& entry
)
85 int confirms
= wtx
.GetDepthInMainChain();
86 entry
.push_back(Pair("confirmations", confirms
));
88 entry
.push_back(Pair("generated", true));
91 entry
.push_back(Pair("blockhash", wtx
.hashBlock
.GetHex()));
92 entry
.push_back(Pair("blockindex", wtx
.nIndex
));
93 entry
.push_back(Pair("blocktime", mapBlockIndex
[wtx
.hashBlock
]->GetBlockTime()));
95 entry
.push_back(Pair("trusted", wtx
.IsTrusted()));
97 uint256 hash
= wtx
.GetHash();
98 entry
.push_back(Pair("txid", hash
.GetHex()));
99 UniValue
conflicts(UniValue::VARR
);
100 for (const uint256
& conflict
: wtx
.GetConflicts())
101 conflicts
.push_back(conflict
.GetHex());
102 entry
.push_back(Pair("walletconflicts", conflicts
));
103 entry
.push_back(Pair("time", wtx
.GetTxTime()));
104 entry
.push_back(Pair("timereceived", (int64_t)wtx
.nTimeReceived
));
106 // Add opt-in RBF status
107 std::string rbfStatus
= "no";
110 RBFTransactionState rbfState
= IsRBFOptIn(wtx
, mempool
);
111 if (rbfState
== RBF_TRANSACTIONSTATE_UNKNOWN
)
112 rbfStatus
= "unknown";
113 else if (rbfState
== RBF_TRANSACTIONSTATE_REPLACEABLE_BIP125
)
116 entry
.push_back(Pair("bip125-replaceable", rbfStatus
));
118 for (const std::pair
<std::string
, std::string
>& item
: wtx
.mapValue
)
119 entry
.push_back(Pair(item
.first
, item
.second
));
122 std::string
AccountFromValue(const UniValue
& value
)
124 std::string strAccount
= value
.get_str();
125 if (strAccount
== "*")
126 throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME
, "Invalid account name");
130 UniValue
getnewaddress(const JSONRPCRequest
& request
)
132 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
133 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
137 if (request
.fHelp
|| request
.params
.size() > 1)
138 throw std::runtime_error(
139 "getnewaddress ( \"account\" )\n"
140 "\nReturns a new Bitcoin address for receiving payments.\n"
141 "If 'account' is specified (DEPRECATED), it is added to the address book \n"
142 "so payments received with the address will be credited to 'account'.\n"
144 "1. \"account\" (string, optional) DEPRECATED. The account name for the address to be linked to. If not provided, the default account \"\" is used. It can also be set to the empty string \"\" to represent the default account. The account does not need to exist, it will be created if there is no account by the given name.\n"
146 "\"address\" (string) The new bitcoin address\n"
148 + HelpExampleCli("getnewaddress", "")
149 + HelpExampleRpc("getnewaddress", "")
152 LOCK2(cs_main
, pwallet
->cs_wallet
);
154 // Parse the account first so we don't generate a key if there's an error
155 std::string strAccount
;
156 if (!request
.params
[0].isNull())
157 strAccount
= AccountFromValue(request
.params
[0]);
159 if (!pwallet
->IsLocked()) {
160 pwallet
->TopUpKeyPool();
163 // Generate a new key that is added to wallet
165 if (!pwallet
->GetKeyFromPool(newKey
)) {
166 throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT
, "Error: Keypool ran out, please call keypoolrefill first");
168 CKeyID keyID
= newKey
.GetID();
170 pwallet
->SetAddressBook(keyID
, strAccount
, "receive");
172 return CBitcoinAddress(keyID
).ToString();
176 CBitcoinAddress
GetAccountAddress(CWallet
* const pwallet
, std::string strAccount
, bool bForceNew
=false)
179 if (!pwallet
->GetAccountPubkey(pubKey
, strAccount
, bForceNew
)) {
180 throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT
, "Error: Keypool ran out, please call keypoolrefill first");
183 return CBitcoinAddress(pubKey
.GetID());
186 UniValue
getaccountaddress(const JSONRPCRequest
& request
)
188 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
189 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
193 if (request
.fHelp
|| request
.params
.size() != 1)
194 throw std::runtime_error(
195 "getaccountaddress \"account\"\n"
196 "\nDEPRECATED. Returns the current Bitcoin address for receiving payments to this account.\n"
198 "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"
200 "\"address\" (string) The account bitcoin address\n"
202 + HelpExampleCli("getaccountaddress", "")
203 + HelpExampleCli("getaccountaddress", "\"\"")
204 + HelpExampleCli("getaccountaddress", "\"myaccount\"")
205 + HelpExampleRpc("getaccountaddress", "\"myaccount\"")
208 LOCK2(cs_main
, pwallet
->cs_wallet
);
210 // Parse the account first so we don't generate a key if there's an error
211 std::string strAccount
= AccountFromValue(request
.params
[0]);
213 UniValue
ret(UniValue::VSTR
);
215 ret
= GetAccountAddress(pwallet
, strAccount
).ToString();
220 UniValue
getrawchangeaddress(const JSONRPCRequest
& request
)
222 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
223 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
227 if (request
.fHelp
|| request
.params
.size() > 0)
228 throw std::runtime_error(
229 "getrawchangeaddress\n"
230 "\nReturns a new Bitcoin address, for receiving change.\n"
231 "This is for use with raw transactions, NOT normal use.\n"
233 "\"address\" (string) The address\n"
235 + HelpExampleCli("getrawchangeaddress", "")
236 + HelpExampleRpc("getrawchangeaddress", "")
239 LOCK2(cs_main
, pwallet
->cs_wallet
);
241 if (!pwallet
->IsLocked()) {
242 pwallet
->TopUpKeyPool();
245 CReserveKey
reservekey(pwallet
);
247 if (!reservekey
.GetReservedKey(vchPubKey
, true))
248 throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT
, "Error: Keypool ran out, please call keypoolrefill first");
250 reservekey
.KeepKey();
252 CKeyID keyID
= vchPubKey
.GetID();
254 return CBitcoinAddress(keyID
).ToString();
258 UniValue
setaccount(const JSONRPCRequest
& request
)
260 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
261 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
265 if (request
.fHelp
|| request
.params
.size() < 1 || request
.params
.size() > 2)
266 throw std::runtime_error(
267 "setaccount \"address\" \"account\"\n"
268 "\nDEPRECATED. Sets the account associated with the given address.\n"
270 "1. \"address\" (string, required) The bitcoin address to be associated with an account.\n"
271 "2. \"account\" (string, required) The account to assign the address to.\n"
273 + HelpExampleCli("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"tabby\"")
274 + HelpExampleRpc("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"tabby\"")
277 LOCK2(cs_main
, pwallet
->cs_wallet
);
279 CBitcoinAddress
address(request
.params
[0].get_str());
280 if (!address
.IsValid())
281 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Invalid Bitcoin address");
283 std::string strAccount
;
284 if (!request
.params
[1].isNull())
285 strAccount
= AccountFromValue(request
.params
[1]);
287 // Only add the account if the address is yours.
288 if (IsMine(*pwallet
, address
.Get())) {
289 // Detect when changing the account of an address that is the 'unused current key' of another account:
290 if (pwallet
->mapAddressBook
.count(address
.Get())) {
291 std::string strOldAccount
= pwallet
->mapAddressBook
[address
.Get()].name
;
292 if (address
== GetAccountAddress(pwallet
, strOldAccount
)) {
293 GetAccountAddress(pwallet
, strOldAccount
, true);
296 pwallet
->SetAddressBook(address
.Get(), strAccount
, "receive");
299 throw JSONRPCError(RPC_MISC_ERROR
, "setaccount can only be used with own address");
305 UniValue
getaccount(const JSONRPCRequest
& request
)
307 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
308 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
312 if (request
.fHelp
|| request
.params
.size() != 1)
313 throw std::runtime_error(
314 "getaccount \"address\"\n"
315 "\nDEPRECATED. Returns the account associated with the given address.\n"
317 "1. \"address\" (string, required) The bitcoin address for account lookup.\n"
319 "\"accountname\" (string) the account address\n"
321 + HelpExampleCli("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"")
322 + HelpExampleRpc("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"")
325 LOCK2(cs_main
, pwallet
->cs_wallet
);
327 CBitcoinAddress
address(request
.params
[0].get_str());
328 if (!address
.IsValid())
329 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Invalid Bitcoin address");
331 std::string strAccount
;
332 std::map
<CTxDestination
, CAddressBookData
>::iterator mi
= pwallet
->mapAddressBook
.find(address
.Get());
333 if (mi
!= pwallet
->mapAddressBook
.end() && !(*mi
).second
.name
.empty()) {
334 strAccount
= (*mi
).second
.name
;
340 UniValue
getaddressesbyaccount(const JSONRPCRequest
& request
)
342 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
343 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
347 if (request
.fHelp
|| request
.params
.size() != 1)
348 throw std::runtime_error(
349 "getaddressesbyaccount \"account\"\n"
350 "\nDEPRECATED. Returns the list of addresses for the given account.\n"
352 "1. \"account\" (string, required) The account name.\n"
354 "[ (json array of string)\n"
355 " \"address\" (string) a bitcoin address associated with the given account\n"
359 + HelpExampleCli("getaddressesbyaccount", "\"tabby\"")
360 + HelpExampleRpc("getaddressesbyaccount", "\"tabby\"")
363 LOCK2(cs_main
, pwallet
->cs_wallet
);
365 std::string strAccount
= AccountFromValue(request
.params
[0]);
367 // Find all addresses that have the given account
368 UniValue
ret(UniValue::VARR
);
369 for (const std::pair
<CBitcoinAddress
, CAddressBookData
>& item
: pwallet
->mapAddressBook
) {
370 const CBitcoinAddress
& address
= item
.first
;
371 const std::string
& strName
= item
.second
.name
;
372 if (strName
== strAccount
)
373 ret
.push_back(address
.ToString());
378 static void SendMoney(CWallet
* const pwallet
, const CTxDestination
&address
, CAmount nValue
, bool fSubtractFeeFromAmount
, CWalletTx
& wtxNew
, const CCoinControl
& coin_control
)
380 CAmount curBalance
= pwallet
->GetBalance();
384 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Invalid amount");
386 if (nValue
> curBalance
)
387 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS
, "Insufficient funds");
389 if (pwallet
->GetBroadcastTransactions() && !g_connman
) {
390 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED
, "Error: Peer-to-peer functionality missing or disabled");
393 // Parse Bitcoin address
394 CScript scriptPubKey
= GetScriptForDestination(address
);
396 // Create and send the transaction
397 CReserveKey
reservekey(pwallet
);
398 CAmount nFeeRequired
;
399 std::string strError
;
400 std::vector
<CRecipient
> vecSend
;
401 int nChangePosRet
= -1;
402 CRecipient recipient
= {scriptPubKey
, nValue
, fSubtractFeeFromAmount
};
403 vecSend
.push_back(recipient
);
404 if (!pwallet
->CreateTransaction(vecSend
, wtxNew
, reservekey
, nFeeRequired
, nChangePosRet
, strError
, coin_control
)) {
405 if (!fSubtractFeeFromAmount
&& nValue
+ nFeeRequired
> curBalance
)
406 strError
= strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired
));
407 throw JSONRPCError(RPC_WALLET_ERROR
, strError
);
409 CValidationState state
;
410 if (!pwallet
->CommitTransaction(wtxNew
, reservekey
, g_connman
.get(), state
)) {
411 strError
= strprintf("Error: The transaction was rejected! Reason given: %s", state
.GetRejectReason());
412 throw JSONRPCError(RPC_WALLET_ERROR
, strError
);
416 UniValue
sendtoaddress(const JSONRPCRequest
& request
)
418 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
419 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
423 if (request
.fHelp
|| request
.params
.size() < 2 || request
.params
.size() > 8)
424 throw std::runtime_error(
425 "sendtoaddress \"address\" amount ( \"comment\" \"comment_to\" subtractfeefromamount replaceable conf_target \"estimate_mode\")\n"
426 "\nSend an amount to a given address.\n"
427 + HelpRequiringPassphrase(pwallet
) +
429 "1. \"address\" (string, required) The bitcoin address to send to.\n"
430 "2. \"amount\" (numeric or string, required) The amount in " + CURRENCY_UNIT
+ " to send. eg 0.1\n"
431 "3. \"comment\" (string, optional) A comment used to store what the transaction is for. \n"
432 " This is not part of the transaction, just kept in your wallet.\n"
433 "4. \"comment_to\" (string, optional) A comment to store the name of the person or organization \n"
434 " to which you're sending the transaction. This is not part of the \n"
435 " transaction, just kept in your wallet.\n"
436 "5. subtractfeefromamount (boolean, optional, default=false) The fee will be deducted from the amount being sent.\n"
437 " The recipient will receive less bitcoins than you enter in the amount field.\n"
438 "6. replaceable (boolean, optional) Allow this transaction to be replaced by a transaction with higher fees via BIP 125\n"
439 "7. conf_target (numeric, optional) Confirmation target (in blocks)\n"
440 "8. \"estimate_mode\" (string, optional, default=UNSET) The fee estimate mode, must be one of:\n"
443 " \"CONSERVATIVE\"\n"
445 "\"txid\" (string) The transaction id.\n"
447 + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1")
448 + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"donation\" \"seans outpost\"")
449 + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"\" \"\" true")
450 + HelpExampleRpc("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.1, \"donation\", \"seans outpost\"")
453 LOCK2(cs_main
, pwallet
->cs_wallet
);
455 CBitcoinAddress
address(request
.params
[0].get_str());
456 if (!address
.IsValid())
457 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Invalid Bitcoin address");
460 CAmount nAmount
= AmountFromValue(request
.params
[1]);
462 throw JSONRPCError(RPC_TYPE_ERROR
, "Invalid amount for send");
466 if (!request
.params
[2].isNull() && !request
.params
[2].get_str().empty())
467 wtx
.mapValue
["comment"] = request
.params
[2].get_str();
468 if (!request
.params
[3].isNull() && !request
.params
[3].get_str().empty())
469 wtx
.mapValue
["to"] = request
.params
[3].get_str();
471 bool fSubtractFeeFromAmount
= false;
472 if (!request
.params
[4].isNull()) {
473 fSubtractFeeFromAmount
= request
.params
[4].get_bool();
476 CCoinControl coin_control
;
477 if (!request
.params
[5].isNull()) {
478 coin_control
.signalRbf
= request
.params
[5].get_bool();
481 if (!request
.params
[6].isNull()) {
482 coin_control
.m_confirm_target
= ParseConfirmTarget(request
.params
[6]);
485 if (!request
.params
[7].isNull()) {
486 if (!FeeModeFromString(request
.params
[7].get_str(), coin_control
.m_fee_mode
)) {
487 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Invalid estimate_mode parameter");
492 EnsureWalletIsUnlocked(pwallet
);
494 SendMoney(pwallet
, address
.Get(), nAmount
, fSubtractFeeFromAmount
, wtx
, coin_control
);
496 return wtx
.GetHash().GetHex();
499 UniValue
listaddressgroupings(const JSONRPCRequest
& request
)
501 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
502 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
506 if (request
.fHelp
|| request
.params
.size() != 0)
507 throw std::runtime_error(
508 "listaddressgroupings\n"
509 "\nLists groups of addresses which have had their common ownership\n"
510 "made public by common use as inputs or as the resulting change\n"
511 "in past transactions\n"
516 " \"address\", (string) The bitcoin address\n"
517 " amount, (numeric) The amount in " + CURRENCY_UNIT
+ "\n"
518 " \"account\" (string, optional) DEPRECATED. The account\n"
525 + HelpExampleCli("listaddressgroupings", "")
526 + HelpExampleRpc("listaddressgroupings", "")
529 LOCK2(cs_main
, pwallet
->cs_wallet
);
531 UniValue
jsonGroupings(UniValue::VARR
);
532 std::map
<CTxDestination
, CAmount
> balances
= pwallet
->GetAddressBalances();
533 for (std::set
<CTxDestination
> grouping
: pwallet
->GetAddressGroupings()) {
534 UniValue
jsonGrouping(UniValue::VARR
);
535 for (CTxDestination address
: grouping
)
537 UniValue
addressInfo(UniValue::VARR
);
538 addressInfo
.push_back(CBitcoinAddress(address
).ToString());
539 addressInfo
.push_back(ValueFromAmount(balances
[address
]));
541 if (pwallet
->mapAddressBook
.find(CBitcoinAddress(address
).Get()) != pwallet
->mapAddressBook
.end()) {
542 addressInfo
.push_back(pwallet
->mapAddressBook
.find(CBitcoinAddress(address
).Get())->second
.name
);
545 jsonGrouping
.push_back(addressInfo
);
547 jsonGroupings
.push_back(jsonGrouping
);
549 return jsonGroupings
;
552 UniValue
signmessage(const JSONRPCRequest
& request
)
554 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
555 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
559 if (request
.fHelp
|| request
.params
.size() != 2)
560 throw std::runtime_error(
561 "signmessage \"address\" \"message\"\n"
562 "\nSign a message with the private key of an address"
563 + HelpRequiringPassphrase(pwallet
) + "\n"
565 "1. \"address\" (string, required) The bitcoin address to use for the private key.\n"
566 "2. \"message\" (string, required) The message to create a signature of.\n"
568 "\"signature\" (string) The signature of the message encoded in base 64\n"
570 "\nUnlock the wallet for 30 seconds\n"
571 + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
572 "\nCreate the signature\n"
573 + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") +
574 "\nVerify the signature\n"
575 + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") +
577 + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"my message\"")
580 LOCK2(cs_main
, pwallet
->cs_wallet
);
582 EnsureWalletIsUnlocked(pwallet
);
584 std::string strAddress
= request
.params
[0].get_str();
585 std::string strMessage
= request
.params
[1].get_str();
587 CBitcoinAddress
addr(strAddress
);
589 throw JSONRPCError(RPC_TYPE_ERROR
, "Invalid address");
592 if (!addr
.GetKeyID(keyID
))
593 throw JSONRPCError(RPC_TYPE_ERROR
, "Address does not refer to key");
596 if (!pwallet
->GetKey(keyID
, key
)) {
597 throw JSONRPCError(RPC_WALLET_ERROR
, "Private key not available");
600 CHashWriter
ss(SER_GETHASH
, 0);
601 ss
<< strMessageMagic
;
604 std::vector
<unsigned char> vchSig
;
605 if (!key
.SignCompact(ss
.GetHash(), vchSig
))
606 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Sign failed");
608 return EncodeBase64(&vchSig
[0], vchSig
.size());
611 UniValue
getreceivedbyaddress(const JSONRPCRequest
& request
)
613 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
614 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
618 if (request
.fHelp
|| request
.params
.size() < 1 || request
.params
.size() > 2)
619 throw std::runtime_error(
620 "getreceivedbyaddress \"address\" ( minconf )\n"
621 "\nReturns the total amount received by the given address in transactions with at least minconf confirmations.\n"
623 "1. \"address\" (string, required) The bitcoin address for transactions.\n"
624 "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
626 "amount (numeric) The total amount in " + CURRENCY_UNIT
+ " received at this address.\n"
628 "\nThe amount from transactions with at least 1 confirmation\n"
629 + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"") +
630 "\nThe amount including unconfirmed transactions, zero confirmations\n"
631 + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" 0") +
632 "\nThe amount with at least 6 confirmations\n"
633 + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" 6") +
634 "\nAs a json rpc call\n"
635 + HelpExampleRpc("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", 6")
638 LOCK2(cs_main
, pwallet
->cs_wallet
);
641 CBitcoinAddress address
= CBitcoinAddress(request
.params
[0].get_str());
642 if (!address
.IsValid())
643 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Invalid Bitcoin address");
644 CScript scriptPubKey
= GetScriptForDestination(address
.Get());
645 if (!IsMine(*pwallet
, scriptPubKey
)) {
646 return ValueFromAmount(0);
649 // Minimum confirmations
651 if (!request
.params
[1].isNull())
652 nMinDepth
= request
.params
[1].get_int();
656 for (const std::pair
<uint256
, CWalletTx
>& pairWtx
: pwallet
->mapWallet
) {
657 const CWalletTx
& wtx
= pairWtx
.second
;
658 if (wtx
.IsCoinBase() || !CheckFinalTx(*wtx
.tx
))
661 for (const CTxOut
& txout
: wtx
.tx
->vout
)
662 if (txout
.scriptPubKey
== scriptPubKey
)
663 if (wtx
.GetDepthInMainChain() >= nMinDepth
)
664 nAmount
+= txout
.nValue
;
667 return ValueFromAmount(nAmount
);
671 UniValue
getreceivedbyaccount(const JSONRPCRequest
& request
)
673 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
674 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
678 if (request
.fHelp
|| request
.params
.size() < 1 || request
.params
.size() > 2)
679 throw std::runtime_error(
680 "getreceivedbyaccount \"account\" ( minconf )\n"
681 "\nDEPRECATED. Returns the total amount received by addresses with <account> in transactions with at least [minconf] confirmations.\n"
683 "1. \"account\" (string, required) The selected account, may be the default account using \"\".\n"
684 "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
686 "amount (numeric) The total amount in " + CURRENCY_UNIT
+ " received for this account.\n"
688 "\nAmount received by the default account with at least 1 confirmation\n"
689 + HelpExampleCli("getreceivedbyaccount", "\"\"") +
690 "\nAmount received at the tabby account including unconfirmed amounts with zero confirmations\n"
691 + HelpExampleCli("getreceivedbyaccount", "\"tabby\" 0") +
692 "\nThe amount with at least 6 confirmations\n"
693 + HelpExampleCli("getreceivedbyaccount", "\"tabby\" 6") +
694 "\nAs a json rpc call\n"
695 + HelpExampleRpc("getreceivedbyaccount", "\"tabby\", 6")
698 LOCK2(cs_main
, pwallet
->cs_wallet
);
700 // Minimum confirmations
702 if (!request
.params
[1].isNull())
703 nMinDepth
= request
.params
[1].get_int();
705 // Get the set of pub keys assigned to account
706 std::string strAccount
= AccountFromValue(request
.params
[0]);
707 std::set
<CTxDestination
> setAddress
= pwallet
->GetAccountAddresses(strAccount
);
711 for (const std::pair
<uint256
, CWalletTx
>& pairWtx
: pwallet
->mapWallet
) {
712 const CWalletTx
& wtx
= pairWtx
.second
;
713 if (wtx
.IsCoinBase() || !CheckFinalTx(*wtx
.tx
))
716 for (const CTxOut
& txout
: wtx
.tx
->vout
)
718 CTxDestination address
;
719 if (ExtractDestination(txout
.scriptPubKey
, address
) && IsMine(*pwallet
, address
) && setAddress
.count(address
)) {
720 if (wtx
.GetDepthInMainChain() >= nMinDepth
)
721 nAmount
+= txout
.nValue
;
726 return ValueFromAmount(nAmount
);
730 UniValue
getbalance(const JSONRPCRequest
& request
)
732 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
733 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
737 if (request
.fHelp
|| request
.params
.size() > 3)
738 throw std::runtime_error(
739 "getbalance ( \"account\" minconf include_watchonly )\n"
740 "\nIf account is not specified, returns the server's total available balance.\n"
741 "If account is specified (DEPRECATED), returns the balance in the account.\n"
742 "Note that the account \"\" is not the same as leaving the parameter out.\n"
743 "The server total may be different to the balance in the default \"\" account.\n"
745 "1. \"account\" (string, optional) DEPRECATED. The account string may be given as a\n"
746 " specific account name to find the balance associated with wallet keys in\n"
747 " a named account, or as the empty string (\"\") to find the balance\n"
748 " associated with wallet keys not in any named account, or as \"*\" to find\n"
749 " the balance associated with all wallet keys regardless of account.\n"
750 " When this option is specified, it calculates the balance in a different\n"
751 " way than when it is not specified, and which can count spends twice when\n"
752 " there are conflicting pending transactions (such as those created by\n"
753 " the bumpfee command), temporarily resulting in low or even negative\n"
754 " balances. In general, account balance calculation is not considered\n"
755 " reliable and has resulted in confusing outcomes, so it is recommended to\n"
756 " avoid passing this argument.\n"
757 "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
758 "3. include_watchonly (bool, optional, default=false) Also include balance in watch-only addresses (see 'importaddress')\n"
760 "amount (numeric) The total amount in " + CURRENCY_UNIT
+ " received for this account.\n"
762 "\nThe total amount in the wallet with 1 or more confirmations\n"
763 + HelpExampleCli("getbalance", "") +
764 "\nThe total amount in the wallet at least 6 blocks confirmed\n"
765 + HelpExampleCli("getbalance", "\"*\" 6") +
766 "\nAs a json rpc call\n"
767 + HelpExampleRpc("getbalance", "\"*\", 6")
770 LOCK2(cs_main
, pwallet
->cs_wallet
);
772 const UniValue
& account_value
= request
.params
[0];
773 const UniValue
& minconf
= request
.params
[1];
774 const UniValue
& include_watchonly
= request
.params
[2];
776 if (account_value
.isNull()) {
777 if (!minconf
.isNull()) {
778 throw JSONRPCError(RPC_INVALID_PARAMETER
,
779 "getbalance minconf option is only currently supported if an account is specified");
781 if (!include_watchonly
.isNull()) {
782 throw JSONRPCError(RPC_INVALID_PARAMETER
,
783 "getbalance include_watchonly option is only currently supported if an account is specified");
785 return ValueFromAmount(pwallet
->GetBalance());
788 const std::string
& account_param
= account_value
.get_str();
789 const std::string
* account
= account_param
!= "*" ? &account_param
: nullptr;
792 if (!minconf
.isNull())
793 nMinDepth
= minconf
.get_int();
794 isminefilter filter
= ISMINE_SPENDABLE
;
795 if(!include_watchonly
.isNull())
796 if(include_watchonly
.get_bool())
797 filter
= filter
| ISMINE_WATCH_ONLY
;
799 return ValueFromAmount(pwallet
->GetLegacyBalance(filter
, nMinDepth
, account
));
802 UniValue
getunconfirmedbalance(const JSONRPCRequest
&request
)
804 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
805 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
809 if (request
.fHelp
|| request
.params
.size() > 0)
810 throw std::runtime_error(
811 "getunconfirmedbalance\n"
812 "Returns the server's total unconfirmed balance\n");
814 LOCK2(cs_main
, pwallet
->cs_wallet
);
816 return ValueFromAmount(pwallet
->GetUnconfirmedBalance());
820 UniValue
movecmd(const JSONRPCRequest
& request
)
822 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
823 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
827 if (request
.fHelp
|| request
.params
.size() < 3 || request
.params
.size() > 5)
828 throw std::runtime_error(
829 "move \"fromaccount\" \"toaccount\" amount ( minconf \"comment\" )\n"
830 "\nDEPRECATED. Move a specified amount from one account in your wallet to another.\n"
832 "1. \"fromaccount\" (string, required) The name of the account to move funds from. May be the default account using \"\".\n"
833 "2. \"toaccount\" (string, required) The name of the account to move funds to. May be the default account using \"\".\n"
834 "3. amount (numeric) Quantity of " + CURRENCY_UNIT
+ " to move between accounts.\n"
835 "4. (dummy) (numeric, optional) Ignored. Remains for backward compatibility.\n"
836 "5. \"comment\" (string, optional) An optional comment, stored in the wallet only.\n"
838 "true|false (boolean) true if successful.\n"
840 "\nMove 0.01 " + CURRENCY_UNIT
+ " from the default account to the account named tabby\n"
841 + HelpExampleCli("move", "\"\" \"tabby\" 0.01") +
842 "\nMove 0.01 " + CURRENCY_UNIT
+ " timotei to akiko with a comment and funds have 6 confirmations\n"
843 + HelpExampleCli("move", "\"timotei\" \"akiko\" 0.01 6 \"happy birthday!\"") +
844 "\nAs a json rpc call\n"
845 + HelpExampleRpc("move", "\"timotei\", \"akiko\", 0.01, 6, \"happy birthday!\"")
848 LOCK2(cs_main
, pwallet
->cs_wallet
);
850 std::string strFrom
= AccountFromValue(request
.params
[0]);
851 std::string strTo
= AccountFromValue(request
.params
[1]);
852 CAmount nAmount
= AmountFromValue(request
.params
[2]);
854 throw JSONRPCError(RPC_TYPE_ERROR
, "Invalid amount for send");
855 if (!request
.params
[3].isNull())
856 // unused parameter, used to be nMinDepth, keep type-checking it though
857 (void)request
.params
[3].get_int();
858 std::string strComment
;
859 if (!request
.params
[4].isNull())
860 strComment
= request
.params
[4].get_str();
862 if (!pwallet
->AccountMove(strFrom
, strTo
, nAmount
, strComment
)) {
863 throw JSONRPCError(RPC_DATABASE_ERROR
, "database error");
870 UniValue
sendfrom(const JSONRPCRequest
& request
)
872 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
873 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
877 if (request
.fHelp
|| request
.params
.size() < 3 || request
.params
.size() > 6)
878 throw std::runtime_error(
879 "sendfrom \"fromaccount\" \"toaddress\" amount ( minconf \"comment\" \"comment_to\" )\n"
880 "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a bitcoin address."
881 + HelpRequiringPassphrase(pwallet
) + "\n"
883 "1. \"fromaccount\" (string, required) The name of the account to send funds from. May be the default account using \"\".\n"
884 " Specifying an account does not influence coin selection, but it does associate the newly created\n"
885 " transaction with the account, so the account's balance computation and transaction history can reflect\n"
887 "2. \"toaddress\" (string, required) The bitcoin address to send funds to.\n"
888 "3. amount (numeric or string, required) The amount in " + CURRENCY_UNIT
+ " (transaction fee is added on top).\n"
889 "4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n"
890 "5. \"comment\" (string, optional) A comment used to store what the transaction is for. \n"
891 " This is not part of the transaction, just kept in your wallet.\n"
892 "6. \"comment_to\" (string, optional) An optional comment to store the name of the person or organization \n"
893 " to which you're sending the transaction. This is not part of the transaction, \n"
894 " it is just kept in your wallet.\n"
896 "\"txid\" (string) The transaction id.\n"
898 "\nSend 0.01 " + CURRENCY_UNIT
+ " from the default account to the address, must have at least 1 confirmation\n"
899 + HelpExampleCli("sendfrom", "\"\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01") +
900 "\nSend 0.01 from the tabby account to the given address, funds must have at least 6 confirmations\n"
901 + HelpExampleCli("sendfrom", "\"tabby\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01 6 \"donation\" \"seans outpost\"") +
902 "\nAs a json rpc call\n"
903 + HelpExampleRpc("sendfrom", "\"tabby\", \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.01, 6, \"donation\", \"seans outpost\"")
906 LOCK2(cs_main
, pwallet
->cs_wallet
);
908 std::string strAccount
= AccountFromValue(request
.params
[0]);
909 CBitcoinAddress
address(request
.params
[1].get_str());
910 if (!address
.IsValid())
911 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Invalid Bitcoin address");
912 CAmount nAmount
= AmountFromValue(request
.params
[2]);
914 throw JSONRPCError(RPC_TYPE_ERROR
, "Invalid amount for send");
916 if (!request
.params
[3].isNull())
917 nMinDepth
= request
.params
[3].get_int();
920 wtx
.strFromAccount
= strAccount
;
921 if (!request
.params
[4].isNull() && !request
.params
[4].get_str().empty())
922 wtx
.mapValue
["comment"] = request
.params
[4].get_str();
923 if (!request
.params
[5].isNull() && !request
.params
[5].get_str().empty())
924 wtx
.mapValue
["to"] = request
.params
[5].get_str();
926 EnsureWalletIsUnlocked(pwallet
);
929 CAmount nBalance
= pwallet
->GetLegacyBalance(ISMINE_SPENDABLE
, nMinDepth
, &strAccount
);
930 if (nAmount
> nBalance
)
931 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS
, "Account has insufficient funds");
933 CCoinControl no_coin_control
; // This is a deprecated API
934 SendMoney(pwallet
, address
.Get(), nAmount
, false, wtx
, no_coin_control
);
936 return wtx
.GetHash().GetHex();
940 UniValue
sendmany(const JSONRPCRequest
& request
)
942 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
943 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
947 if (request
.fHelp
|| request
.params
.size() < 2 || request
.params
.size() > 8)
948 throw std::runtime_error(
949 "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" [\"address\",...] replaceable conf_target \"estimate_mode\")\n"
950 "\nSend multiple times. Amounts are double-precision floating point numbers."
951 + HelpRequiringPassphrase(pwallet
) + "\n"
953 "1. \"fromaccount\" (string, required) DEPRECATED. The account to send the funds from. Should be \"\" for the default account\n"
954 "2. \"amounts\" (string, required) A json object with addresses and amounts\n"
956 " \"address\":amount (numeric or string) The bitcoin address is the key, the numeric amount (can be string) in " + CURRENCY_UNIT
+ " is the value\n"
959 "3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n"
960 "4. \"comment\" (string, optional) A comment\n"
961 "5. subtractfeefrom (array, optional) A json array with addresses.\n"
962 " The fee will be equally deducted from the amount of each selected address.\n"
963 " Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
964 " If no addresses are specified here, the sender pays the fee.\n"
966 " \"address\" (string) Subtract fee from this address\n"
969 "6. replaceable (boolean, optional) Allow this transaction to be replaced by a transaction with higher fees via BIP 125\n"
970 "7. conf_target (numeric, optional) Confirmation target (in blocks)\n"
971 "8. \"estimate_mode\" (string, optional, default=UNSET) The fee estimate mode, must be one of:\n"
974 " \"CONSERVATIVE\"\n"
976 "\"txid\" (string) The transaction id for the send. Only 1 transaction is created regardless of \n"
977 " the number of addresses.\n"
979 "\nSend two amounts to two different addresses:\n"
980 + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") +
981 "\nSend two amounts to two different addresses setting the confirmation and comment:\n"
982 + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 6 \"testing\"") +
983 "\nSend two amounts to two different addresses, subtract fee from amount:\n"
984 + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 1 \"\" \"[\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\",\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\"]\"") +
985 "\nAs a json rpc call\n"
986 + HelpExampleRpc("sendmany", "\"\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"")
989 LOCK2(cs_main
, pwallet
->cs_wallet
);
991 if (pwallet
->GetBroadcastTransactions() && !g_connman
) {
992 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED
, "Error: Peer-to-peer functionality missing or disabled");
995 std::string strAccount
= AccountFromValue(request
.params
[0]);
996 UniValue sendTo
= request
.params
[1].get_obj();
998 if (!request
.params
[2].isNull())
999 nMinDepth
= request
.params
[2].get_int();
1002 wtx
.strFromAccount
= strAccount
;
1003 if (!request
.params
[3].isNull() && !request
.params
[3].get_str().empty())
1004 wtx
.mapValue
["comment"] = request
.params
[3].get_str();
1006 UniValue
subtractFeeFromAmount(UniValue::VARR
);
1007 if (!request
.params
[4].isNull())
1008 subtractFeeFromAmount
= request
.params
[4].get_array();
1010 CCoinControl coin_control
;
1011 if (!request
.params
[5].isNull()) {
1012 coin_control
.signalRbf
= request
.params
[5].get_bool();
1015 if (!request
.params
[6].isNull()) {
1016 coin_control
.m_confirm_target
= ParseConfirmTarget(request
.params
[6]);
1019 if (!request
.params
[7].isNull()) {
1020 if (!FeeModeFromString(request
.params
[7].get_str(), coin_control
.m_fee_mode
)) {
1021 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Invalid estimate_mode parameter");
1025 std::set
<CBitcoinAddress
> setAddress
;
1026 std::vector
<CRecipient
> vecSend
;
1028 CAmount totalAmount
= 0;
1029 std::vector
<std::string
> keys
= sendTo
.getKeys();
1030 for (const std::string
& name_
: keys
)
1032 CBitcoinAddress
address(name_
);
1033 if (!address
.IsValid())
1034 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, std::string("Invalid Bitcoin address: ")+name_
);
1036 if (setAddress
.count(address
))
1037 throw JSONRPCError(RPC_INVALID_PARAMETER
, std::string("Invalid parameter, duplicated address: ")+name_
);
1038 setAddress
.insert(address
);
1040 CScript scriptPubKey
= GetScriptForDestination(address
.Get());
1041 CAmount nAmount
= AmountFromValue(sendTo
[name_
]);
1043 throw JSONRPCError(RPC_TYPE_ERROR
, "Invalid amount for send");
1044 totalAmount
+= nAmount
;
1046 bool fSubtractFeeFromAmount
= false;
1047 for (unsigned int idx
= 0; idx
< subtractFeeFromAmount
.size(); idx
++) {
1048 const UniValue
& addr
= subtractFeeFromAmount
[idx
];
1049 if (addr
.get_str() == name_
)
1050 fSubtractFeeFromAmount
= true;
1053 CRecipient recipient
= {scriptPubKey
, nAmount
, fSubtractFeeFromAmount
};
1054 vecSend
.push_back(recipient
);
1057 EnsureWalletIsUnlocked(pwallet
);
1060 CAmount nBalance
= pwallet
->GetLegacyBalance(ISMINE_SPENDABLE
, nMinDepth
, &strAccount
);
1061 if (totalAmount
> nBalance
)
1062 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS
, "Account has insufficient funds");
1065 CReserveKey
keyChange(pwallet
);
1066 CAmount nFeeRequired
= 0;
1067 int nChangePosRet
= -1;
1068 std::string strFailReason
;
1069 bool fCreated
= pwallet
->CreateTransaction(vecSend
, wtx
, keyChange
, nFeeRequired
, nChangePosRet
, strFailReason
, coin_control
);
1071 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS
, strFailReason
);
1072 CValidationState state
;
1073 if (!pwallet
->CommitTransaction(wtx
, keyChange
, g_connman
.get(), state
)) {
1074 strFailReason
= strprintf("Transaction commit failed:: %s", state
.GetRejectReason());
1075 throw JSONRPCError(RPC_WALLET_ERROR
, strFailReason
);
1078 return wtx
.GetHash().GetHex();
1081 // Defined in rpc/misc.cpp
1082 extern CScript
_createmultisig_redeemScript(CWallet
* const pwallet
, const UniValue
& params
);
1084 UniValue
addmultisigaddress(const JSONRPCRequest
& request
)
1086 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
1087 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
1088 return NullUniValue
;
1091 if (request
.fHelp
|| request
.params
.size() < 2 || request
.params
.size() > 3)
1093 std::string msg
= "addmultisigaddress nrequired [\"key\",...] ( \"account\" )\n"
1094 "\nAdd a nrequired-to-sign multisignature address to the wallet.\n"
1095 "Each key is a Bitcoin address or hex-encoded public key.\n"
1096 "If 'account' is specified (DEPRECATED), assign address to that account.\n"
1099 "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
1100 "2. \"keys\" (string, required) A json array of bitcoin addresses or hex-encoded public keys\n"
1102 " \"address\" (string) bitcoin address or hex-encoded public key\n"
1105 "3. \"account\" (string, optional) DEPRECATED. An account to assign the addresses to.\n"
1108 "\"address\" (string) A bitcoin address associated with the keys.\n"
1111 "\nAdd a multisig address from 2 addresses\n"
1112 + HelpExampleCli("addmultisigaddress", "2 \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") +
1113 "\nAs json rpc call\n"
1114 + HelpExampleRpc("addmultisigaddress", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"")
1116 throw std::runtime_error(msg
);
1119 LOCK2(cs_main
, pwallet
->cs_wallet
);
1121 std::string strAccount
;
1122 if (!request
.params
[2].isNull())
1123 strAccount
= AccountFromValue(request
.params
[2]);
1125 // Construct using pay-to-script-hash:
1126 CScript inner
= _createmultisig_redeemScript(pwallet
, request
.params
);
1127 CScriptID
innerID(inner
);
1128 pwallet
->AddCScript(inner
);
1130 pwallet
->SetAddressBook(innerID
, strAccount
, "send");
1131 return CBitcoinAddress(innerID
).ToString();
1134 class Witnessifier
: public boost::static_visitor
<bool>
1137 CWallet
* const pwallet
;
1140 explicit Witnessifier(CWallet
*_pwallet
) : pwallet(_pwallet
) {}
1142 bool operator()(const CNoDestination
&dest
) const { return false; }
1144 bool operator()(const CKeyID
&keyID
) {
1146 CScript basescript
= GetScriptForDestination(keyID
);
1147 CScript witscript
= GetScriptForWitness(basescript
);
1149 // This check is to make sure that the script we created can actually be solved for and signed by us
1150 // if we were to have the private keys. This is just to make sure that the script is valid and that,
1151 // if found in a transaction, we would still accept and relay that transaction.
1152 if (!ProduceSignature(DummySignatureCreator(pwallet
), witscript
, sigs
) ||
1153 !VerifyScript(sigs
.scriptSig
, witscript
, &sigs
.scriptWitness
, MANDATORY_SCRIPT_VERIFY_FLAGS
| SCRIPT_VERIFY_WITNESS_PUBKEYTYPE
, DummySignatureCreator(pwallet
).Checker())) {
1156 pwallet
->AddCScript(witscript
);
1157 result
= CScriptID(witscript
);
1163 bool operator()(const CScriptID
&scriptID
) {
1165 if (pwallet
&& pwallet
->GetCScript(scriptID
, subscript
)) {
1167 std::vector
<unsigned char> witprog
;
1168 if (subscript
.IsWitnessProgram(witnessversion
, witprog
)) {
1172 CScript witscript
= GetScriptForWitness(subscript
);
1174 // This check is to make sure that the script we created can actually be solved for and signed by us
1175 // if we were to have the private keys. This is just to make sure that the script is valid and that,
1176 // if found in a transaction, we would still accept and relay that transaction.
1177 if (!ProduceSignature(DummySignatureCreator(pwallet
), witscript
, sigs
) ||
1178 !VerifyScript(sigs
.scriptSig
, witscript
, &sigs
.scriptWitness
, MANDATORY_SCRIPT_VERIFY_FLAGS
| SCRIPT_VERIFY_WITNESS_PUBKEYTYPE
, DummySignatureCreator(pwallet
).Checker())) {
1181 pwallet
->AddCScript(witscript
);
1182 result
= CScriptID(witscript
);
1189 UniValue
addwitnessaddress(const JSONRPCRequest
& request
)
1191 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
1192 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
1193 return NullUniValue
;
1196 if (request
.fHelp
|| request
.params
.size() < 1 || request
.params
.size() > 1)
1198 std::string msg
= "addwitnessaddress \"address\"\n"
1199 "\nAdd a witness address for a script (with pubkey or redeemscript known).\n"
1200 "It returns the witness script.\n"
1203 "1. \"address\" (string, required) An address known to the wallet\n"
1206 "\"witnessaddress\", (string) The value of the new address (P2SH of witness script).\n"
1209 throw std::runtime_error(msg
);
1214 if (!IsWitnessEnabled(chainActive
.Tip(), Params().GetConsensus()) && !gArgs
.GetBoolArg("-walletprematurewitness", false)) {
1215 throw JSONRPCError(RPC_WALLET_ERROR
, "Segregated witness not enabled on network");
1219 CBitcoinAddress
address(request
.params
[0].get_str());
1220 if (!address
.IsValid())
1221 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Invalid Bitcoin address");
1223 Witnessifier
w(pwallet
);
1224 CTxDestination dest
= address
.Get();
1225 bool ret
= boost::apply_visitor(w
, dest
);
1227 throw JSONRPCError(RPC_WALLET_ERROR
, "Public key or redeemscript not known to wallet, or the key is uncompressed");
1230 pwallet
->SetAddressBook(w
.result
, "", "receive");
1232 return CBitcoinAddress(w
.result
).ToString();
1239 std::vector
<uint256
> txids
;
1244 nConf
= std::numeric_limits
<int>::max();
1245 fIsWatchonly
= false;
1249 UniValue
ListReceived(CWallet
* const pwallet
, const UniValue
& params
, bool fByAccounts
)
1251 // Minimum confirmations
1253 if (!params
[0].isNull())
1254 nMinDepth
= params
[0].get_int();
1256 // Whether to include empty accounts
1257 bool fIncludeEmpty
= false;
1258 if (!params
[1].isNull())
1259 fIncludeEmpty
= params
[1].get_bool();
1261 isminefilter filter
= ISMINE_SPENDABLE
;
1262 if(!params
[2].isNull())
1263 if(params
[2].get_bool())
1264 filter
= filter
| ISMINE_WATCH_ONLY
;
1267 std::map
<CBitcoinAddress
, tallyitem
> mapTally
;
1268 for (const std::pair
<uint256
, CWalletTx
>& pairWtx
: pwallet
->mapWallet
) {
1269 const CWalletTx
& wtx
= pairWtx
.second
;
1271 if (wtx
.IsCoinBase() || !CheckFinalTx(*wtx
.tx
))
1274 int nDepth
= wtx
.GetDepthInMainChain();
1275 if (nDepth
< nMinDepth
)
1278 for (const CTxOut
& txout
: wtx
.tx
->vout
)
1280 CTxDestination address
;
1281 if (!ExtractDestination(txout
.scriptPubKey
, address
))
1284 isminefilter mine
= IsMine(*pwallet
, address
);
1285 if(!(mine
& filter
))
1288 tallyitem
& item
= mapTally
[address
];
1289 item
.nAmount
+= txout
.nValue
;
1290 item
.nConf
= std::min(item
.nConf
, nDepth
);
1291 item
.txids
.push_back(wtx
.GetHash());
1292 if (mine
& ISMINE_WATCH_ONLY
)
1293 item
.fIsWatchonly
= true;
1298 UniValue
ret(UniValue::VARR
);
1299 std::map
<std::string
, tallyitem
> mapAccountTally
;
1300 for (const std::pair
<CBitcoinAddress
, CAddressBookData
>& item
: pwallet
->mapAddressBook
) {
1301 const CBitcoinAddress
& address
= item
.first
;
1302 const std::string
& strAccount
= item
.second
.name
;
1303 std::map
<CBitcoinAddress
, tallyitem
>::iterator it
= mapTally
.find(address
);
1304 if (it
== mapTally
.end() && !fIncludeEmpty
)
1307 CAmount nAmount
= 0;
1308 int nConf
= std::numeric_limits
<int>::max();
1309 bool fIsWatchonly
= false;
1310 if (it
!= mapTally
.end())
1312 nAmount
= (*it
).second
.nAmount
;
1313 nConf
= (*it
).second
.nConf
;
1314 fIsWatchonly
= (*it
).second
.fIsWatchonly
;
1319 tallyitem
& _item
= mapAccountTally
[strAccount
];
1320 _item
.nAmount
+= nAmount
;
1321 _item
.nConf
= std::min(_item
.nConf
, nConf
);
1322 _item
.fIsWatchonly
= fIsWatchonly
;
1326 UniValue
obj(UniValue::VOBJ
);
1328 obj
.push_back(Pair("involvesWatchonly", true));
1329 obj
.push_back(Pair("address", address
.ToString()));
1330 obj
.push_back(Pair("account", strAccount
));
1331 obj
.push_back(Pair("amount", ValueFromAmount(nAmount
)));
1332 obj
.push_back(Pair("confirmations", (nConf
== std::numeric_limits
<int>::max() ? 0 : nConf
)));
1334 obj
.push_back(Pair("label", strAccount
));
1335 UniValue
transactions(UniValue::VARR
);
1336 if (it
!= mapTally
.end())
1338 for (const uint256
& _item
: (*it
).second
.txids
)
1340 transactions
.push_back(_item
.GetHex());
1343 obj
.push_back(Pair("txids", transactions
));
1350 for (std::map
<std::string
, tallyitem
>::iterator it
= mapAccountTally
.begin(); it
!= mapAccountTally
.end(); ++it
)
1352 CAmount nAmount
= (*it
).second
.nAmount
;
1353 int nConf
= (*it
).second
.nConf
;
1354 UniValue
obj(UniValue::VOBJ
);
1355 if((*it
).second
.fIsWatchonly
)
1356 obj
.push_back(Pair("involvesWatchonly", true));
1357 obj
.push_back(Pair("account", (*it
).first
));
1358 obj
.push_back(Pair("amount", ValueFromAmount(nAmount
)));
1359 obj
.push_back(Pair("confirmations", (nConf
== std::numeric_limits
<int>::max() ? 0 : nConf
)));
1367 UniValue
listreceivedbyaddress(const JSONRPCRequest
& request
)
1369 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
1370 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
1371 return NullUniValue
;
1374 if (request
.fHelp
|| request
.params
.size() > 3)
1375 throw std::runtime_error(
1376 "listreceivedbyaddress ( minconf include_empty include_watchonly)\n"
1377 "\nList balances by receiving address.\n"
1379 "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
1380 "2. include_empty (bool, optional, default=false) Whether to include addresses that haven't received any payments.\n"
1381 "3. include_watchonly (bool, optional, default=false) Whether to include watch-only addresses (see 'importaddress').\n"
1386 " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n"
1387 " \"address\" : \"receivingaddress\", (string) The receiving address\n"
1388 " \"account\" : \"accountname\", (string) DEPRECATED. The account of the receiving address. The default account is \"\".\n"
1389 " \"amount\" : x.xxx, (numeric) The total amount in " + CURRENCY_UNIT
+ " received by the address\n"
1390 " \"confirmations\" : n, (numeric) The number of confirmations of the most recent transaction included\n"
1391 " \"label\" : \"label\", (string) A comment for the address/transaction, if any\n"
1393 " n, (numeric) The ids of transactions received with the address \n"
1401 + HelpExampleCli("listreceivedbyaddress", "")
1402 + HelpExampleCli("listreceivedbyaddress", "6 true")
1403 + HelpExampleRpc("listreceivedbyaddress", "6, true, true")
1406 LOCK2(cs_main
, pwallet
->cs_wallet
);
1408 return ListReceived(pwallet
, request
.params
, false);
1411 UniValue
listreceivedbyaccount(const JSONRPCRequest
& request
)
1413 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
1414 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
1415 return NullUniValue
;
1418 if (request
.fHelp
|| request
.params
.size() > 3)
1419 throw std::runtime_error(
1420 "listreceivedbyaccount ( minconf include_empty include_watchonly)\n"
1421 "\nDEPRECATED. List balances by account.\n"
1423 "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
1424 "2. include_empty (bool, optional, default=false) Whether to include accounts that haven't received any payments.\n"
1425 "3. include_watchonly (bool, optional, default=false) Whether to include watch-only addresses (see 'importaddress').\n"
1430 " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n"
1431 " \"account\" : \"accountname\", (string) The account name of the receiving account\n"
1432 " \"amount\" : x.xxx, (numeric) The total amount received by addresses with this account\n"
1433 " \"confirmations\" : n, (numeric) The number of confirmations of the most recent transaction included\n"
1434 " \"label\" : \"label\" (string) A comment for the address/transaction, if any\n"
1440 + HelpExampleCli("listreceivedbyaccount", "")
1441 + HelpExampleCli("listreceivedbyaccount", "6 true")
1442 + HelpExampleRpc("listreceivedbyaccount", "6, true, true")
1445 LOCK2(cs_main
, pwallet
->cs_wallet
);
1447 return ListReceived(pwallet
, request
.params
, true);
1450 static void MaybePushAddress(UniValue
& entry
, const CTxDestination
&dest
)
1452 CBitcoinAddress addr
;
1454 entry
.push_back(Pair("address", addr
.ToString()));
1458 * List transactions based on the given criteria.
1460 * @param pwallet The wallet.
1461 * @param wtx The wallet transaction.
1462 * @param strAccount The account, if any, or "*" for all.
1463 * @param nMinDepth The minimum confirmation depth.
1464 * @param fLong Whether to include the JSON version of the transaction.
1465 * @param ret The UniValue into which the result is stored.
1466 * @param filter The "is mine" filter bool.
1468 void ListTransactions(CWallet
* const pwallet
, const CWalletTx
& wtx
, const std::string
& strAccount
, int nMinDepth
, bool fLong
, UniValue
& ret
, const isminefilter
& filter
)
1471 std::string strSentAccount
;
1472 std::list
<COutputEntry
> listReceived
;
1473 std::list
<COutputEntry
> listSent
;
1475 wtx
.GetAmounts(listReceived
, listSent
, nFee
, strSentAccount
, filter
);
1477 bool fAllAccounts
= (strAccount
== std::string("*"));
1478 bool involvesWatchonly
= wtx
.IsFromMe(ISMINE_WATCH_ONLY
);
1481 if ((!listSent
.empty() || nFee
!= 0) && (fAllAccounts
|| strAccount
== strSentAccount
))
1483 for (const COutputEntry
& s
: listSent
)
1485 UniValue
entry(UniValue::VOBJ
);
1486 if (involvesWatchonly
|| (::IsMine(*pwallet
, s
.destination
) & ISMINE_WATCH_ONLY
)) {
1487 entry
.push_back(Pair("involvesWatchonly", true));
1489 entry
.push_back(Pair("account", strSentAccount
));
1490 MaybePushAddress(entry
, s
.destination
);
1491 entry
.push_back(Pair("category", "send"));
1492 entry
.push_back(Pair("amount", ValueFromAmount(-s
.amount
)));
1493 if (pwallet
->mapAddressBook
.count(s
.destination
)) {
1494 entry
.push_back(Pair("label", pwallet
->mapAddressBook
[s
.destination
].name
));
1496 entry
.push_back(Pair("vout", s
.vout
));
1497 entry
.push_back(Pair("fee", ValueFromAmount(-nFee
)));
1499 WalletTxToJSON(wtx
, entry
);
1500 entry
.push_back(Pair("abandoned", wtx
.isAbandoned()));
1501 ret
.push_back(entry
);
1506 if (listReceived
.size() > 0 && wtx
.GetDepthInMainChain() >= nMinDepth
)
1508 for (const COutputEntry
& r
: listReceived
)
1510 std::string account
;
1511 if (pwallet
->mapAddressBook
.count(r
.destination
)) {
1512 account
= pwallet
->mapAddressBook
[r
.destination
].name
;
1514 if (fAllAccounts
|| (account
== strAccount
))
1516 UniValue
entry(UniValue::VOBJ
);
1517 if (involvesWatchonly
|| (::IsMine(*pwallet
, r
.destination
) & ISMINE_WATCH_ONLY
)) {
1518 entry
.push_back(Pair("involvesWatchonly", true));
1520 entry
.push_back(Pair("account", account
));
1521 MaybePushAddress(entry
, r
.destination
);
1522 if (wtx
.IsCoinBase())
1524 if (wtx
.GetDepthInMainChain() < 1)
1525 entry
.push_back(Pair("category", "orphan"));
1526 else if (wtx
.GetBlocksToMaturity() > 0)
1527 entry
.push_back(Pair("category", "immature"));
1529 entry
.push_back(Pair("category", "generate"));
1533 entry
.push_back(Pair("category", "receive"));
1535 entry
.push_back(Pair("amount", ValueFromAmount(r
.amount
)));
1536 if (pwallet
->mapAddressBook
.count(r
.destination
)) {
1537 entry
.push_back(Pair("label", account
));
1539 entry
.push_back(Pair("vout", r
.vout
));
1541 WalletTxToJSON(wtx
, entry
);
1542 ret
.push_back(entry
);
1548 void AcentryToJSON(const CAccountingEntry
& acentry
, const std::string
& strAccount
, UniValue
& ret
)
1550 bool fAllAccounts
= (strAccount
== std::string("*"));
1552 if (fAllAccounts
|| acentry
.strAccount
== strAccount
)
1554 UniValue
entry(UniValue::VOBJ
);
1555 entry
.push_back(Pair("account", acentry
.strAccount
));
1556 entry
.push_back(Pair("category", "move"));
1557 entry
.push_back(Pair("time", acentry
.nTime
));
1558 entry
.push_back(Pair("amount", ValueFromAmount(acentry
.nCreditDebit
)));
1559 entry
.push_back(Pair("otheraccount", acentry
.strOtherAccount
));
1560 entry
.push_back(Pair("comment", acentry
.strComment
));
1561 ret
.push_back(entry
);
1565 UniValue
listtransactions(const JSONRPCRequest
& request
)
1567 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
1568 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
1569 return NullUniValue
;
1572 if (request
.fHelp
|| request
.params
.size() > 4)
1573 throw std::runtime_error(
1574 "listtransactions ( \"account\" count skip include_watchonly)\n"
1575 "\nReturns up to 'count' most recent transactions skipping the first 'from' transactions for account 'account'.\n"
1577 "1. \"account\" (string, optional) DEPRECATED. The account name. Should be \"*\".\n"
1578 "2. count (numeric, optional, default=10) The number of transactions to return\n"
1579 "3. skip (numeric, optional, default=0) The number of transactions to skip\n"
1580 "4. include_watchonly (bool, optional, default=false) Include transactions to watch-only addresses (see 'importaddress')\n"
1584 " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. \n"
1585 " It will be \"\" for the default account.\n"
1586 " \"address\":\"address\", (string) The bitcoin address of the transaction. Not present for \n"
1587 " move transactions (category = move).\n"
1588 " \"category\":\"send|receive|move\", (string) The transaction category. 'move' is a local (off blockchain)\n"
1589 " transaction between accounts, and not associated with an address,\n"
1590 " transaction id or block. 'send' and 'receive' transactions are \n"
1591 " associated with an address, transaction id and block details\n"
1592 " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT
+ ". This is negative for the 'send' category, and for the\n"
1593 " 'move' category for moves outbound. It is positive for the 'receive' category,\n"
1594 " and for the 'move' category for inbound funds.\n"
1595 " \"label\": \"label\", (string) A comment for the address/transaction, if any\n"
1596 " \"vout\": n, (numeric) the vout value\n"
1597 " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT
+ ". This is negative and only available for the \n"
1598 " 'send' category of transactions.\n"
1599 " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and \n"
1600 " 'receive' category of transactions. Negative confirmations indicate the\n"
1601 " transaction conflicts with the block chain\n"
1602 " \"trusted\": xxx, (bool) Whether we consider the outputs of this unconfirmed transaction safe to spend.\n"
1603 " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive'\n"
1604 " category of transactions.\n"
1605 " \"blockindex\": n, (numeric) The index of the transaction in the block that includes it. Available for 'send' and 'receive'\n"
1606 " category of transactions.\n"
1607 " \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n"
1608 " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
1609 " \"time\": xxx, (numeric) The transaction time in seconds since epoch (midnight Jan 1 1970 GMT).\n"
1610 " \"timereceived\": xxx, (numeric) The time received in seconds since epoch (midnight Jan 1 1970 GMT). Available \n"
1611 " for 'send' and 'receive' category of transactions.\n"
1612 " \"comment\": \"...\", (string) If a comment is associated with the transaction.\n"
1613 " \"otheraccount\": \"accountname\", (string) DEPRECATED. For the 'move' category of transactions, the account the funds came \n"
1614 " from (for receiving funds, positive amounts), or went to (for sending funds,\n"
1615 " negative amounts).\n"
1616 " \"bip125-replaceable\": \"yes|no|unknown\", (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n"
1617 " may be unknown for unconfirmed transactions not in the mempool\n"
1618 " \"abandoned\": xxx (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n"
1619 " 'send' category of transactions.\n"
1624 "\nList the most recent 10 transactions in the systems\n"
1625 + HelpExampleCli("listtransactions", "") +
1626 "\nList transactions 100 to 120\n"
1627 + HelpExampleCli("listtransactions", "\"*\" 20 100") +
1628 "\nAs a json rpc call\n"
1629 + HelpExampleRpc("listtransactions", "\"*\", 20, 100")
1632 LOCK2(cs_main
, pwallet
->cs_wallet
);
1634 std::string strAccount
= "*";
1635 if (!request
.params
[0].isNull())
1636 strAccount
= request
.params
[0].get_str();
1638 if (!request
.params
[1].isNull())
1639 nCount
= request
.params
[1].get_int();
1641 if (!request
.params
[2].isNull())
1642 nFrom
= request
.params
[2].get_int();
1643 isminefilter filter
= ISMINE_SPENDABLE
;
1644 if(!request
.params
[3].isNull())
1645 if(request
.params
[3].get_bool())
1646 filter
= filter
| ISMINE_WATCH_ONLY
;
1649 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Negative count");
1651 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Negative from");
1653 UniValue
ret(UniValue::VARR
);
1655 const CWallet::TxItems
& txOrdered
= pwallet
->wtxOrdered
;
1657 // iterate backwards until we have nCount items to return:
1658 for (CWallet::TxItems::const_reverse_iterator it
= txOrdered
.rbegin(); it
!= txOrdered
.rend(); ++it
)
1660 CWalletTx
*const pwtx
= (*it
).second
.first
;
1661 if (pwtx
!= nullptr)
1662 ListTransactions(pwallet
, *pwtx
, strAccount
, 0, true, ret
, filter
);
1663 CAccountingEntry
*const pacentry
= (*it
).second
.second
;
1664 if (pacentry
!= nullptr)
1665 AcentryToJSON(*pacentry
, strAccount
, ret
);
1667 if ((int)ret
.size() >= (nCount
+nFrom
)) break;
1669 // ret is newest to oldest
1671 if (nFrom
> (int)ret
.size())
1673 if ((nFrom
+ nCount
) > (int)ret
.size())
1674 nCount
= ret
.size() - nFrom
;
1676 std::vector
<UniValue
> arrTmp
= ret
.getValues();
1678 std::vector
<UniValue
>::iterator first
= arrTmp
.begin();
1679 std::advance(first
, nFrom
);
1680 std::vector
<UniValue
>::iterator last
= arrTmp
.begin();
1681 std::advance(last
, nFrom
+nCount
);
1683 if (last
!= arrTmp
.end()) arrTmp
.erase(last
, arrTmp
.end());
1684 if (first
!= arrTmp
.begin()) arrTmp
.erase(arrTmp
.begin(), first
);
1686 std::reverse(arrTmp
.begin(), arrTmp
.end()); // Return oldest to newest
1690 ret
.push_backV(arrTmp
);
1695 UniValue
listaccounts(const JSONRPCRequest
& request
)
1697 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
1698 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
1699 return NullUniValue
;
1702 if (request
.fHelp
|| request
.params
.size() > 2)
1703 throw std::runtime_error(
1704 "listaccounts ( minconf include_watchonly)\n"
1705 "\nDEPRECATED. Returns Object that has account names as keys, account balances as values.\n"
1707 "1. minconf (numeric, optional, default=1) Only include transactions with at least this many confirmations\n"
1708 "2. include_watchonly (bool, optional, default=false) Include balances in watch-only addresses (see 'importaddress')\n"
1710 "{ (json object where keys are account names, and values are numeric balances\n"
1711 " \"account\": x.xxx, (numeric) The property name is the account name, and the value is the total balance for the account.\n"
1715 "\nList account balances where there at least 1 confirmation\n"
1716 + HelpExampleCli("listaccounts", "") +
1717 "\nList account balances including zero confirmation transactions\n"
1718 + HelpExampleCli("listaccounts", "0") +
1719 "\nList account balances for 6 or more confirmations\n"
1720 + HelpExampleCli("listaccounts", "6") +
1721 "\nAs json rpc call\n"
1722 + HelpExampleRpc("listaccounts", "6")
1725 LOCK2(cs_main
, pwallet
->cs_wallet
);
1728 if (!request
.params
[0].isNull())
1729 nMinDepth
= request
.params
[0].get_int();
1730 isminefilter includeWatchonly
= ISMINE_SPENDABLE
;
1731 if(!request
.params
[1].isNull())
1732 if(request
.params
[1].get_bool())
1733 includeWatchonly
= includeWatchonly
| ISMINE_WATCH_ONLY
;
1735 std::map
<std::string
, CAmount
> mapAccountBalances
;
1736 for (const std::pair
<CTxDestination
, CAddressBookData
>& entry
: pwallet
->mapAddressBook
) {
1737 if (IsMine(*pwallet
, entry
.first
) & includeWatchonly
) { // This address belongs to me
1738 mapAccountBalances
[entry
.second
.name
] = 0;
1742 for (const std::pair
<uint256
, CWalletTx
>& pairWtx
: pwallet
->mapWallet
) {
1743 const CWalletTx
& wtx
= pairWtx
.second
;
1745 std::string strSentAccount
;
1746 std::list
<COutputEntry
> listReceived
;
1747 std::list
<COutputEntry
> listSent
;
1748 int nDepth
= wtx
.GetDepthInMainChain();
1749 if (wtx
.GetBlocksToMaturity() > 0 || nDepth
< 0)
1751 wtx
.GetAmounts(listReceived
, listSent
, nFee
, strSentAccount
, includeWatchonly
);
1752 mapAccountBalances
[strSentAccount
] -= nFee
;
1753 for (const COutputEntry
& s
: listSent
)
1754 mapAccountBalances
[strSentAccount
] -= s
.amount
;
1755 if (nDepth
>= nMinDepth
)
1757 for (const COutputEntry
& r
: listReceived
)
1758 if (pwallet
->mapAddressBook
.count(r
.destination
)) {
1759 mapAccountBalances
[pwallet
->mapAddressBook
[r
.destination
].name
] += r
.amount
;
1762 mapAccountBalances
[""] += r
.amount
;
1766 const std::list
<CAccountingEntry
>& acentries
= pwallet
->laccentries
;
1767 for (const CAccountingEntry
& entry
: acentries
)
1768 mapAccountBalances
[entry
.strAccount
] += entry
.nCreditDebit
;
1770 UniValue
ret(UniValue::VOBJ
);
1771 for (const std::pair
<std::string
, CAmount
>& accountBalance
: mapAccountBalances
) {
1772 ret
.push_back(Pair(accountBalance
.first
, ValueFromAmount(accountBalance
.second
)));
1777 UniValue
listsinceblock(const JSONRPCRequest
& request
)
1779 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
1780 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
1781 return NullUniValue
;
1784 if (request
.fHelp
|| request
.params
.size() > 4)
1785 throw std::runtime_error(
1786 "listsinceblock ( \"blockhash\" target_confirmations include_watchonly include_removed )\n"
1787 "\nGet all transactions in blocks since block [blockhash], or all transactions if omitted.\n"
1788 "If \"blockhash\" is no longer a part of the main chain, transactions from the fork point onward are included.\n"
1789 "Additionally, if include_removed is set, transactions affecting the wallet which were removed are returned in the \"removed\" array.\n"
1791 "1. \"blockhash\" (string, optional) The block hash to list transactions since\n"
1792 "2. target_confirmations: (numeric, optional, default=1) Return the nth block hash from the main chain. e.g. 1 would mean the best block hash. Note: this is not used as a filter, but only affects [lastblock] in the return value\n"
1793 "3. include_watchonly: (bool, optional, default=false) Include transactions to watch-only addresses (see 'importaddress')\n"
1794 "4. include_removed: (bool, optional, default=true) Show transactions that were removed due to a reorg in the \"removed\" array\n"
1795 " (not guaranteed to work on pruned nodes)\n"
1798 " \"transactions\": [\n"
1799 " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. Will be \"\" for the default account.\n"
1800 " \"address\":\"address\", (string) The bitcoin address of the transaction. Not present for move transactions (category = move).\n"
1801 " \"category\":\"send|receive\", (string) The transaction category. 'send' has negative amounts, 'receive' has positive amounts.\n"
1802 " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT
+ ". This is negative for the 'send' category, and for the 'move' category for moves \n"
1803 " outbound. It is positive for the 'receive' category, and for the 'move' category for inbound funds.\n"
1804 " \"vout\" : n, (numeric) the vout value\n"
1805 " \"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"
1806 " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and 'receive' category of transactions.\n"
1807 " When it's < 0, it means the transaction conflicted that many blocks ago.\n"
1808 " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive' category of transactions.\n"
1809 " \"blockindex\": n, (numeric) The index of the transaction in the block that includes it. Available for 'send' and 'receive' category of transactions.\n"
1810 " \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n"
1811 " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
1812 " \"time\": xxx, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT).\n"
1813 " \"timereceived\": xxx, (numeric) The time received in seconds since epoch (Jan 1 1970 GMT). Available for 'send' and 'receive' category of transactions.\n"
1814 " \"bip125-replaceable\": \"yes|no|unknown\", (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n"
1815 " may be unknown for unconfirmed transactions not in the mempool\n"
1816 " \"abandoned\": xxx, (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the 'send' category of transactions.\n"
1817 " \"comment\": \"...\", (string) If a comment is associated with the transaction.\n"
1818 " \"label\" : \"label\" (string) A comment for the address/transaction, if any\n"
1819 " \"to\": \"...\", (string) If a comment to is associated with the transaction.\n"
1822 " <structure is the same as \"transactions\" above, only present if include_removed=true>\n"
1823 " Note: transactions that were readded in the active chain will appear as-is in this array, and may thus have a positive confirmation count.\n"
1825 " \"lastblock\": \"lastblockhash\" (string) The hash of the block (target_confirmations-1) from the best block on the main chain. This is typically used to feed back into listsinceblock the next time you call it. So you would generally use a target_confirmations of say 6, so you will be continually re-notified of transactions until they've reached 6 confirmations plus any new ones\n"
1828 + HelpExampleCli("listsinceblock", "")
1829 + HelpExampleCli("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\" 6")
1830 + HelpExampleRpc("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\", 6")
1833 LOCK2(cs_main
, pwallet
->cs_wallet
);
1835 const CBlockIndex
* pindex
= nullptr; // Block index of the specified block or the common ancestor, if the block provided was in a deactivated chain.
1836 const CBlockIndex
* paltindex
= nullptr; // Block index of the specified block, even if it's in a deactivated chain.
1837 int target_confirms
= 1;
1838 isminefilter filter
= ISMINE_SPENDABLE
;
1840 if (!request
.params
[0].isNull()) {
1843 blockId
.SetHex(request
.params
[0].get_str());
1844 BlockMap::iterator it
= mapBlockIndex
.find(blockId
);
1845 if (it
!= mapBlockIndex
.end()) {
1846 paltindex
= pindex
= it
->second
;
1847 if (chainActive
[pindex
->nHeight
] != pindex
) {
1848 // the block being asked for is a part of a deactivated chain;
1849 // we don't want to depend on its perceived height in the block
1850 // chain, we want to instead use the last common ancestor
1851 pindex
= chainActive
.FindFork(pindex
);
1856 if (!request
.params
[1].isNull()) {
1857 target_confirms
= request
.params
[1].get_int();
1859 if (target_confirms
< 1) {
1860 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Invalid parameter");
1864 if (!request
.params
[2].isNull() && request
.params
[2].get_bool()) {
1865 filter
= filter
| ISMINE_WATCH_ONLY
;
1868 bool include_removed
= (request
.params
[3].isNull() || request
.params
[3].get_bool());
1870 int depth
= pindex
? (1 + chainActive
.Height() - pindex
->nHeight
) : -1;
1872 UniValue
transactions(UniValue::VARR
);
1874 for (const std::pair
<uint256
, CWalletTx
>& pairWtx
: pwallet
->mapWallet
) {
1875 CWalletTx tx
= pairWtx
.second
;
1877 if (depth
== -1 || tx
.GetDepthInMainChain() < depth
) {
1878 ListTransactions(pwallet
, tx
, "*", 0, true, transactions
, filter
);
1882 // when a reorg'd block is requested, we also list any relevant transactions
1883 // in the blocks of the chain that was detached
1884 UniValue
removed(UniValue::VARR
);
1885 while (include_removed
&& paltindex
&& paltindex
!= pindex
) {
1887 if (!ReadBlockFromDisk(block
, paltindex
, Params().GetConsensus())) {
1888 throw JSONRPCError(RPC_INTERNAL_ERROR
, "Can't read block from disk");
1890 for (const CTransactionRef
& tx
: block
.vtx
) {
1891 auto it
= pwallet
->mapWallet
.find(tx
->GetHash());
1892 if (it
!= pwallet
->mapWallet
.end()) {
1893 // We want all transactions regardless of confirmation count to appear here,
1894 // even negative confirmation ones, hence the big negative.
1895 ListTransactions(pwallet
, it
->second
, "*", -100000000, true, removed
, filter
);
1898 paltindex
= paltindex
->pprev
;
1901 CBlockIndex
*pblockLast
= chainActive
[chainActive
.Height() + 1 - target_confirms
];
1902 uint256 lastblock
= pblockLast
? pblockLast
->GetBlockHash() : uint256();
1904 UniValue
ret(UniValue::VOBJ
);
1905 ret
.push_back(Pair("transactions", transactions
));
1906 if (include_removed
) ret
.push_back(Pair("removed", removed
));
1907 ret
.push_back(Pair("lastblock", lastblock
.GetHex()));
1912 UniValue
gettransaction(const JSONRPCRequest
& request
)
1914 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
1915 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
1916 return NullUniValue
;
1919 if (request
.fHelp
|| request
.params
.size() < 1 || request
.params
.size() > 2)
1920 throw std::runtime_error(
1921 "gettransaction \"txid\" ( include_watchonly )\n"
1922 "\nGet detailed information about in-wallet transaction <txid>\n"
1924 "1. \"txid\" (string, required) The transaction id\n"
1925 "2. \"include_watchonly\" (bool, optional, default=false) Whether to include watch-only addresses in balance calculation and details[]\n"
1928 " \"amount\" : x.xxx, (numeric) The transaction amount in " + CURRENCY_UNIT
+ "\n"
1929 " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT
+ ". This is negative and only available for the \n"
1930 " 'send' category of transactions.\n"
1931 " \"confirmations\" : n, (numeric) The number of confirmations\n"
1932 " \"blockhash\" : \"hash\", (string) The block hash\n"
1933 " \"blockindex\" : xx, (numeric) The index of the transaction in the block that includes it\n"
1934 " \"blocktime\" : ttt, (numeric) The time in seconds since epoch (1 Jan 1970 GMT)\n"
1935 " \"txid\" : \"transactionid\", (string) The transaction id.\n"
1936 " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (1 Jan 1970 GMT)\n"
1937 " \"timereceived\" : ttt, (numeric) The time received in seconds since epoch (1 Jan 1970 GMT)\n"
1938 " \"bip125-replaceable\": \"yes|no|unknown\", (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n"
1939 " may be unknown for unconfirmed transactions not in the mempool\n"
1940 " \"details\" : [\n"
1942 " \"account\" : \"accountname\", (string) DEPRECATED. The account name involved in the transaction, can be \"\" for the default account.\n"
1943 " \"address\" : \"address\", (string) The bitcoin address involved in the transaction\n"
1944 " \"category\" : \"send|receive\", (string) The category, either 'send' or 'receive'\n"
1945 " \"amount\" : x.xxx, (numeric) The amount in " + CURRENCY_UNIT
+ "\n"
1946 " \"label\" : \"label\", (string) A comment for the address/transaction, if any\n"
1947 " \"vout\" : n, (numeric) the vout value\n"
1948 " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT
+ ". This is negative and only available for the \n"
1949 " 'send' category of transactions.\n"
1950 " \"abandoned\": xxx (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n"
1951 " 'send' category of transactions.\n"
1955 " \"hex\" : \"data\" (string) Raw data for transaction\n"
1959 + HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
1960 + HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\" true")
1961 + HelpExampleRpc("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
1964 LOCK2(cs_main
, pwallet
->cs_wallet
);
1967 hash
.SetHex(request
.params
[0].get_str());
1969 isminefilter filter
= ISMINE_SPENDABLE
;
1970 if(!request
.params
[1].isNull())
1971 if(request
.params
[1].get_bool())
1972 filter
= filter
| ISMINE_WATCH_ONLY
;
1974 UniValue
entry(UniValue::VOBJ
);
1975 auto it
= pwallet
->mapWallet
.find(hash
);
1976 if (it
== pwallet
->mapWallet
.end()) {
1977 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Invalid or non-wallet transaction id");
1979 const CWalletTx
& wtx
= it
->second
;
1981 CAmount nCredit
= wtx
.GetCredit(filter
);
1982 CAmount nDebit
= wtx
.GetDebit(filter
);
1983 CAmount nNet
= nCredit
- nDebit
;
1984 CAmount nFee
= (wtx
.IsFromMe(filter
) ? wtx
.tx
->GetValueOut() - nDebit
: 0);
1986 entry
.push_back(Pair("amount", ValueFromAmount(nNet
- nFee
)));
1987 if (wtx
.IsFromMe(filter
))
1988 entry
.push_back(Pair("fee", ValueFromAmount(nFee
)));
1990 WalletTxToJSON(wtx
, entry
);
1992 UniValue
details(UniValue::VARR
);
1993 ListTransactions(pwallet
, wtx
, "*", 0, false, details
, filter
);
1994 entry
.push_back(Pair("details", details
));
1996 std::string strHex
= EncodeHexTx(static_cast<CTransaction
>(wtx
), RPCSerializationFlags());
1997 entry
.push_back(Pair("hex", strHex
));
2002 UniValue
abandontransaction(const JSONRPCRequest
& request
)
2004 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
2005 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
2006 return NullUniValue
;
2009 if (request
.fHelp
|| request
.params
.size() != 1)
2010 throw std::runtime_error(
2011 "abandontransaction \"txid\"\n"
2012 "\nMark in-wallet transaction <txid> as abandoned\n"
2013 "This will mark this transaction and all its in-wallet descendants as abandoned which will allow\n"
2014 "for their inputs to be respent. It can be used to replace \"stuck\" or evicted transactions.\n"
2015 "It only works on transactions which are not included in a block and are not currently in the mempool.\n"
2016 "It has no effect on transactions which are already conflicted or abandoned.\n"
2018 "1. \"txid\" (string, required) The transaction id\n"
2021 + HelpExampleCli("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
2022 + HelpExampleRpc("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
2025 LOCK2(cs_main
, pwallet
->cs_wallet
);
2028 hash
.SetHex(request
.params
[0].get_str());
2030 if (!pwallet
->mapWallet
.count(hash
)) {
2031 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Invalid or non-wallet transaction id");
2033 if (!pwallet
->AbandonTransaction(hash
)) {
2034 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "Transaction not eligible for abandonment");
2037 return NullUniValue
;
2041 UniValue
backupwallet(const JSONRPCRequest
& request
)
2043 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
2044 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
2045 return NullUniValue
;
2048 if (request
.fHelp
|| request
.params
.size() != 1)
2049 throw std::runtime_error(
2050 "backupwallet \"destination\"\n"
2051 "\nSafely copies current wallet file to destination, which can be a directory or a path with filename.\n"
2053 "1. \"destination\" (string) The destination directory or file\n"
2055 + HelpExampleCli("backupwallet", "\"backup.dat\"")
2056 + HelpExampleRpc("backupwallet", "\"backup.dat\"")
2059 LOCK2(cs_main
, pwallet
->cs_wallet
);
2061 std::string strDest
= request
.params
[0].get_str();
2062 if (!pwallet
->BackupWallet(strDest
)) {
2063 throw JSONRPCError(RPC_WALLET_ERROR
, "Error: Wallet backup failed!");
2066 return NullUniValue
;
2070 UniValue
keypoolrefill(const JSONRPCRequest
& request
)
2072 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
2073 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
2074 return NullUniValue
;
2077 if (request
.fHelp
|| request
.params
.size() > 1)
2078 throw std::runtime_error(
2079 "keypoolrefill ( newsize )\n"
2080 "\nFills the keypool."
2081 + HelpRequiringPassphrase(pwallet
) + "\n"
2083 "1. newsize (numeric, optional, default=100) The new keypool size\n"
2085 + HelpExampleCli("keypoolrefill", "")
2086 + HelpExampleRpc("keypoolrefill", "")
2089 LOCK2(cs_main
, pwallet
->cs_wallet
);
2091 // 0 is interpreted by TopUpKeyPool() as the default keypool size given by -keypool
2092 unsigned int kpSize
= 0;
2093 if (!request
.params
[0].isNull()) {
2094 if (request
.params
[0].get_int() < 0)
2095 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Invalid parameter, expected valid size.");
2096 kpSize
= (unsigned int)request
.params
[0].get_int();
2099 EnsureWalletIsUnlocked(pwallet
);
2100 pwallet
->TopUpKeyPool(kpSize
);
2102 if (pwallet
->GetKeyPoolSize() < kpSize
) {
2103 throw JSONRPCError(RPC_WALLET_ERROR
, "Error refreshing keypool.");
2106 return NullUniValue
;
2110 static void LockWallet(CWallet
* pWallet
)
2112 LOCK(pWallet
->cs_wallet
);
2113 pWallet
->nRelockTime
= 0;
2117 UniValue
walletpassphrase(const JSONRPCRequest
& request
)
2119 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
2120 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
2121 return NullUniValue
;
2124 if (pwallet
->IsCrypted() && (request
.fHelp
|| request
.params
.size() != 2)) {
2125 throw std::runtime_error(
2126 "walletpassphrase \"passphrase\" timeout\n"
2127 "\nStores the wallet decryption key in memory for 'timeout' seconds.\n"
2128 "This is needed prior to performing transactions related to private keys such as sending bitcoins\n"
2130 "1. \"passphrase\" (string, required) The wallet passphrase\n"
2131 "2. timeout (numeric, required) The time to keep the decryption key in seconds.\n"
2133 "Issuing the walletpassphrase command while the wallet is already unlocked will set a new unlock\n"
2134 "time that overrides the old one.\n"
2136 "\nUnlock the wallet for 60 seconds\n"
2137 + HelpExampleCli("walletpassphrase", "\"my pass phrase\" 60") +
2138 "\nLock the wallet again (before 60 seconds)\n"
2139 + HelpExampleCli("walletlock", "") +
2140 "\nAs json rpc call\n"
2141 + HelpExampleRpc("walletpassphrase", "\"my pass phrase\", 60")
2145 LOCK2(cs_main
, pwallet
->cs_wallet
);
2149 if (!pwallet
->IsCrypted()) {
2150 throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE
, "Error: running with an unencrypted wallet, but walletpassphrase was called.");
2153 // Note that the walletpassphrase is stored in request.params[0] which is not mlock()ed
2154 SecureString strWalletPass
;
2155 strWalletPass
.reserve(100);
2156 // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
2157 // Alternately, find a way to make request.params[0] mlock()'d to begin with.
2158 strWalletPass
= request
.params
[0].get_str().c_str();
2160 if (strWalletPass
.length() > 0)
2162 if (!pwallet
->Unlock(strWalletPass
)) {
2163 throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT
, "Error: The wallet passphrase entered was incorrect.");
2167 throw std::runtime_error(
2168 "walletpassphrase <passphrase> <timeout>\n"
2169 "Stores the wallet decryption key in memory for <timeout> seconds.");
2171 pwallet
->TopUpKeyPool();
2173 int64_t nSleepTime
= request
.params
[1].get_int64();
2174 pwallet
->nRelockTime
= GetTime() + nSleepTime
;
2175 RPCRunLater(strprintf("lockwallet(%s)", pwallet
->GetName()), boost::bind(LockWallet
, pwallet
), nSleepTime
);
2177 return NullUniValue
;
2181 UniValue
walletpassphrasechange(const JSONRPCRequest
& request
)
2183 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
2184 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
2185 return NullUniValue
;
2188 if (pwallet
->IsCrypted() && (request
.fHelp
|| request
.params
.size() != 2)) {
2189 throw std::runtime_error(
2190 "walletpassphrasechange \"oldpassphrase\" \"newpassphrase\"\n"
2191 "\nChanges the wallet passphrase from 'oldpassphrase' to 'newpassphrase'.\n"
2193 "1. \"oldpassphrase\" (string) The current passphrase\n"
2194 "2. \"newpassphrase\" (string) The new passphrase\n"
2196 + HelpExampleCli("walletpassphrasechange", "\"old one\" \"new one\"")
2197 + HelpExampleRpc("walletpassphrasechange", "\"old one\", \"new one\"")
2201 LOCK2(cs_main
, pwallet
->cs_wallet
);
2205 if (!pwallet
->IsCrypted()) {
2206 throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE
, "Error: running with an unencrypted wallet, but walletpassphrasechange was called.");
2209 // TODO: get rid of these .c_str() calls by implementing SecureString::operator=(std::string)
2210 // Alternately, find a way to make request.params[0] mlock()'d to begin with.
2211 SecureString strOldWalletPass
;
2212 strOldWalletPass
.reserve(100);
2213 strOldWalletPass
= request
.params
[0].get_str().c_str();
2215 SecureString strNewWalletPass
;
2216 strNewWalletPass
.reserve(100);
2217 strNewWalletPass
= request
.params
[1].get_str().c_str();
2219 if (strOldWalletPass
.length() < 1 || strNewWalletPass
.length() < 1)
2220 throw std::runtime_error(
2221 "walletpassphrasechange <oldpassphrase> <newpassphrase>\n"
2222 "Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>.");
2224 if (!pwallet
->ChangeWalletPassphrase(strOldWalletPass
, strNewWalletPass
)) {
2225 throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT
, "Error: The wallet passphrase entered was incorrect.");
2228 return NullUniValue
;
2232 UniValue
walletlock(const JSONRPCRequest
& request
)
2234 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
2235 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
2236 return NullUniValue
;
2239 if (pwallet
->IsCrypted() && (request
.fHelp
|| request
.params
.size() != 0)) {
2240 throw std::runtime_error(
2242 "\nRemoves the wallet encryption key from memory, locking the wallet.\n"
2243 "After calling this method, you will need to call walletpassphrase again\n"
2244 "before being able to call any methods which require the wallet to be unlocked.\n"
2246 "\nSet the passphrase for 2 minutes to perform a transaction\n"
2247 + HelpExampleCli("walletpassphrase", "\"my pass phrase\" 120") +
2248 "\nPerform a send (requires passphrase set)\n"
2249 + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 1.0") +
2250 "\nClear the passphrase since we are done before 2 minutes is up\n"
2251 + HelpExampleCli("walletlock", "") +
2252 "\nAs json rpc call\n"
2253 + HelpExampleRpc("walletlock", "")
2257 LOCK2(cs_main
, pwallet
->cs_wallet
);
2261 if (!pwallet
->IsCrypted()) {
2262 throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE
, "Error: running with an unencrypted wallet, but walletlock was called.");
2266 pwallet
->nRelockTime
= 0;
2268 return NullUniValue
;
2272 UniValue
encryptwallet(const JSONRPCRequest
& request
)
2274 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
2275 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
2276 return NullUniValue
;
2279 if (!pwallet
->IsCrypted() && (request
.fHelp
|| request
.params
.size() != 1)) {
2280 throw std::runtime_error(
2281 "encryptwallet \"passphrase\"\n"
2282 "\nEncrypts the wallet with 'passphrase'. This is for first time encryption.\n"
2283 "After this, any calls that interact with private keys such as sending or signing \n"
2284 "will require the passphrase to be set prior the making these calls.\n"
2285 "Use the walletpassphrase call for this, and then walletlock call.\n"
2286 "If the wallet is already encrypted, use the walletpassphrasechange call.\n"
2287 "Note that this will shutdown the server.\n"
2289 "1. \"passphrase\" (string) The pass phrase to encrypt the wallet with. It must be at least 1 character, but should be long.\n"
2291 "\nEncrypt your wallet\n"
2292 + HelpExampleCli("encryptwallet", "\"my pass phrase\"") +
2293 "\nNow set the passphrase to use the wallet, such as for signing or sending bitcoin\n"
2294 + HelpExampleCli("walletpassphrase", "\"my pass phrase\"") +
2295 "\nNow we can do something like sign\n"
2296 + HelpExampleCli("signmessage", "\"address\" \"test message\"") +
2297 "\nNow lock the wallet again by removing the passphrase\n"
2298 + HelpExampleCli("walletlock", "") +
2299 "\nAs a json rpc call\n"
2300 + HelpExampleRpc("encryptwallet", "\"my pass phrase\"")
2304 LOCK2(cs_main
, pwallet
->cs_wallet
);
2308 if (pwallet
->IsCrypted()) {
2309 throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE
, "Error: running with an encrypted wallet, but encryptwallet was called.");
2312 // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
2313 // Alternately, find a way to make request.params[0] mlock()'d to begin with.
2314 SecureString strWalletPass
;
2315 strWalletPass
.reserve(100);
2316 strWalletPass
= request
.params
[0].get_str().c_str();
2318 if (strWalletPass
.length() < 1)
2319 throw std::runtime_error(
2320 "encryptwallet <passphrase>\n"
2321 "Encrypts the wallet with <passphrase>.");
2323 if (!pwallet
->EncryptWallet(strWalletPass
)) {
2324 throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED
, "Error: Failed to encrypt the wallet.");
2327 // BDB seems to have a bad habit of writing old data into
2328 // slack space in .dat files; that is bad if the old data is
2329 // unencrypted private keys. So:
2331 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.";
2334 UniValue
lockunspent(const JSONRPCRequest
& request
)
2336 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
2337 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
2338 return NullUniValue
;
2341 if (request
.fHelp
|| request
.params
.size() < 1 || request
.params
.size() > 2)
2342 throw std::runtime_error(
2343 "lockunspent unlock ([{\"txid\":\"txid\",\"vout\":n},...])\n"
2344 "\nUpdates list of temporarily unspendable outputs.\n"
2345 "Temporarily lock (unlock=false) or unlock (unlock=true) specified transaction outputs.\n"
2346 "If no transaction outputs are specified when unlocking then all current locked transaction outputs are unlocked.\n"
2347 "A locked transaction output will not be chosen by automatic coin selection, when spending bitcoins.\n"
2348 "Locks are stored in memory only. Nodes start with zero locked outputs, and the locked output list\n"
2349 "is always cleared (by virtue of process exit) when a node stops or fails.\n"
2350 "Also see the listunspent call\n"
2352 "1. unlock (boolean, required) Whether to unlock (true) or lock (false) the specified transactions\n"
2353 "2. \"transactions\" (string, optional) A json array of objects. Each object the txid (string) vout (numeric)\n"
2354 " [ (json array of json objects)\n"
2356 " \"txid\":\"id\", (string) The transaction id\n"
2357 " \"vout\": n (numeric) The output number\n"
2363 "true|false (boolean) Whether the command was successful or not\n"
2366 "\nList the unspent transactions\n"
2367 + HelpExampleCli("listunspent", "") +
2368 "\nLock an unspent transaction\n"
2369 + HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2370 "\nList the locked transactions\n"
2371 + HelpExampleCli("listlockunspent", "") +
2372 "\nUnlock the transaction again\n"
2373 + HelpExampleCli("lockunspent", "true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2374 "\nAs a json rpc call\n"
2375 + HelpExampleRpc("lockunspent", "false, \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"")
2378 LOCK2(cs_main
, pwallet
->cs_wallet
);
2380 RPCTypeCheckArgument(request
.params
[0], UniValue::VBOOL
);
2382 bool fUnlock
= request
.params
[0].get_bool();
2384 if (request
.params
[1].isNull()) {
2386 pwallet
->UnlockAllCoins();
2390 RPCTypeCheckArgument(request
.params
[1], UniValue::VARR
);
2392 UniValue outputs
= request
.params
[1].get_array();
2393 for (unsigned int idx
= 0; idx
< outputs
.size(); idx
++) {
2394 const UniValue
& output
= outputs
[idx
];
2395 if (!output
.isObject())
2396 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Invalid parameter, expected object");
2397 const UniValue
& o
= output
.get_obj();
2401 {"txid", UniValueType(UniValue::VSTR
)},
2402 {"vout", UniValueType(UniValue::VNUM
)},
2405 std::string txid
= find_value(o
, "txid").get_str();
2407 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Invalid parameter, expected hex txid");
2409 int nOutput
= find_value(o
, "vout").get_int();
2411 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Invalid parameter, vout must be positive");
2413 COutPoint
outpt(uint256S(txid
), nOutput
);
2416 pwallet
->UnlockCoin(outpt
);
2418 pwallet
->LockCoin(outpt
);
2424 UniValue
listlockunspent(const JSONRPCRequest
& request
)
2426 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
2427 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
2428 return NullUniValue
;
2431 if (request
.fHelp
|| request
.params
.size() > 0)
2432 throw std::runtime_error(
2434 "\nReturns list of temporarily unspendable outputs.\n"
2435 "See the lockunspent call to lock and unlock transactions for spending.\n"
2439 " \"txid\" : \"transactionid\", (string) The transaction id locked\n"
2440 " \"vout\" : n (numeric) The vout value\n"
2445 "\nList the unspent transactions\n"
2446 + HelpExampleCli("listunspent", "") +
2447 "\nLock an unspent transaction\n"
2448 + HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2449 "\nList the locked transactions\n"
2450 + HelpExampleCli("listlockunspent", "") +
2451 "\nUnlock the transaction again\n"
2452 + HelpExampleCli("lockunspent", "true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2453 "\nAs a json rpc call\n"
2454 + HelpExampleRpc("listlockunspent", "")
2457 LOCK2(cs_main
, pwallet
->cs_wallet
);
2459 std::vector
<COutPoint
> vOutpts
;
2460 pwallet
->ListLockedCoins(vOutpts
);
2462 UniValue
ret(UniValue::VARR
);
2464 for (COutPoint
&outpt
: vOutpts
) {
2465 UniValue
o(UniValue::VOBJ
);
2467 o
.push_back(Pair("txid", outpt
.hash
.GetHex()));
2468 o
.push_back(Pair("vout", (int)outpt
.n
));
2475 UniValue
settxfee(const JSONRPCRequest
& request
)
2477 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
2478 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
2479 return NullUniValue
;
2482 if (request
.fHelp
|| request
.params
.size() < 1 || request
.params
.size() > 1)
2483 throw std::runtime_error(
2485 "\nSet the transaction fee per kB. Overwrites the paytxfee parameter.\n"
2487 "1. amount (numeric or string, required) The transaction fee in " + CURRENCY_UNIT
+ "/kB\n"
2489 "true|false (boolean) Returns true if successful\n"
2491 + HelpExampleCli("settxfee", "0.00001")
2492 + HelpExampleRpc("settxfee", "0.00001")
2495 LOCK2(cs_main
, pwallet
->cs_wallet
);
2498 CAmount nAmount
= AmountFromValue(request
.params
[0]);
2500 payTxFee
= CFeeRate(nAmount
, 1000);
2504 UniValue
getwalletinfo(const JSONRPCRequest
& request
)
2506 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
2507 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
2508 return NullUniValue
;
2511 if (request
.fHelp
|| request
.params
.size() != 0)
2512 throw std::runtime_error(
2514 "Returns an object containing various wallet state info.\n"
2517 " \"walletname\": xxxxx, (string) the wallet name\n"
2518 " \"walletversion\": xxxxx, (numeric) the wallet version\n"
2519 " \"balance\": xxxxxxx, (numeric) the total confirmed balance of the wallet in " + CURRENCY_UNIT
+ "\n"
2520 " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed balance of the wallet in " + CURRENCY_UNIT
+ "\n"
2521 " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet in " + CURRENCY_UNIT
+ "\n"
2522 " \"txcount\": xxxxxxx, (numeric) the total number of transactions in the wallet\n"
2523 " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since Unix epoch) of the oldest pre-generated key in the key pool\n"
2524 " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated (only counts external keys)\n"
2525 " \"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"
2526 " \"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"
2527 " \"paytxfee\": x.xxxx, (numeric) the transaction fee configuration, set in " + CURRENCY_UNIT
+ "/kB\n"
2528 " \"hdmasterkeyid\": \"<hash160>\" (string) the Hash160 of the HD master pubkey\n"
2531 + HelpExampleCli("getwalletinfo", "")
2532 + HelpExampleRpc("getwalletinfo", "")
2535 LOCK2(cs_main
, pwallet
->cs_wallet
);
2537 UniValue
obj(UniValue::VOBJ
);
2539 size_t kpExternalSize
= pwallet
->KeypoolCountExternalKeys();
2540 obj
.push_back(Pair("walletname", pwallet
->GetName()));
2541 obj
.push_back(Pair("walletversion", pwallet
->GetVersion()));
2542 obj
.push_back(Pair("balance", ValueFromAmount(pwallet
->GetBalance())));
2543 obj
.push_back(Pair("unconfirmed_balance", ValueFromAmount(pwallet
->GetUnconfirmedBalance())));
2544 obj
.push_back(Pair("immature_balance", ValueFromAmount(pwallet
->GetImmatureBalance())));
2545 obj
.push_back(Pair("txcount", (int)pwallet
->mapWallet
.size()));
2546 obj
.push_back(Pair("keypoololdest", pwallet
->GetOldestKeyPoolTime()));
2547 obj
.push_back(Pair("keypoolsize", (int64_t)kpExternalSize
));
2548 CKeyID masterKeyID
= pwallet
->GetHDChain().masterKeyID
;
2549 if (!masterKeyID
.IsNull() && pwallet
->CanSupportFeature(FEATURE_HD_SPLIT
)) {
2550 obj
.push_back(Pair("keypoolsize_hd_internal", (int64_t)(pwallet
->GetKeyPoolSize() - kpExternalSize
)));
2552 if (pwallet
->IsCrypted()) {
2553 obj
.push_back(Pair("unlocked_until", pwallet
->nRelockTime
));
2555 obj
.push_back(Pair("paytxfee", ValueFromAmount(payTxFee
.GetFeePerK())));
2556 if (!masterKeyID
.IsNull())
2557 obj
.push_back(Pair("hdmasterkeyid", masterKeyID
.GetHex()));
2561 UniValue
listwallets(const JSONRPCRequest
& request
)
2563 if (request
.fHelp
|| request
.params
.size() != 0)
2564 throw std::runtime_error(
2566 "Returns a list of currently loaded wallets.\n"
2567 "For full information on the wallet, use \"getwalletinfo\"\n"
2569 "[ (json array of strings)\n"
2570 " \"walletname\" (string) the wallet name\n"
2574 + HelpExampleCli("listwallets", "")
2575 + HelpExampleRpc("listwallets", "")
2578 UniValue
obj(UniValue::VARR
);
2580 for (CWalletRef pwallet
: vpwallets
) {
2582 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
2583 return NullUniValue
;
2586 LOCK(pwallet
->cs_wallet
);
2588 obj
.push_back(pwallet
->GetName());
2594 UniValue
resendwallettransactions(const JSONRPCRequest
& request
)
2596 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
2597 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
2598 return NullUniValue
;
2601 if (request
.fHelp
|| request
.params
.size() != 0)
2602 throw std::runtime_error(
2603 "resendwallettransactions\n"
2604 "Immediately re-broadcast unconfirmed wallet transactions to all peers.\n"
2605 "Intended only for testing; the wallet code periodically re-broadcasts\n"
2607 "Returns an RPC error if -walletbroadcast is set to false.\n"
2608 "Returns array of transaction ids that were re-broadcast.\n"
2612 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED
, "Error: Peer-to-peer functionality missing or disabled");
2614 LOCK2(cs_main
, pwallet
->cs_wallet
);
2616 if (!pwallet
->GetBroadcastTransactions()) {
2617 throw JSONRPCError(RPC_WALLET_ERROR
, "Error: Wallet transaction broadcasting is disabled with -walletbroadcast");
2620 std::vector
<uint256
> txids
= pwallet
->ResendWalletTransactionsBefore(GetTime(), g_connman
.get());
2621 UniValue
result(UniValue::VARR
);
2622 for (const uint256
& txid
: txids
)
2624 result
.push_back(txid
.ToString());
2629 UniValue
listunspent(const JSONRPCRequest
& request
)
2631 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
2632 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
2633 return NullUniValue
;
2636 if (request
.fHelp
|| request
.params
.size() > 5)
2637 throw std::runtime_error(
2638 "listunspent ( minconf maxconf [\"addresses\",...] [include_unsafe] [query_options])\n"
2639 "\nReturns array of unspent transaction outputs\n"
2640 "with between minconf and maxconf (inclusive) confirmations.\n"
2641 "Optionally filter to only include txouts paid to specified addresses.\n"
2643 "1. minconf (numeric, optional, default=1) The minimum confirmations to filter\n"
2644 "2. maxconf (numeric, optional, default=9999999) The maximum confirmations to filter\n"
2645 "3. \"addresses\" (string) A json array of bitcoin addresses to filter\n"
2647 " \"address\" (string) bitcoin address\n"
2650 "4. include_unsafe (bool, optional, default=true) Include outputs that are not safe to spend\n"
2651 " See description of \"safe\" attribute below.\n"
2652 "5. query_options (json, optional) JSON with query options\n"
2654 " \"minimumAmount\" (numeric or string, default=0) Minimum value of each UTXO in " + CURRENCY_UNIT
+ "\n"
2655 " \"maximumAmount\" (numeric or string, default=unlimited) Maximum value of each UTXO in " + CURRENCY_UNIT
+ "\n"
2656 " \"maximumCount\" (numeric or string, default=unlimited) Maximum number of UTXOs\n"
2657 " \"minimumSumAmount\" (numeric or string, default=unlimited) Minimum sum value of all UTXOs in " + CURRENCY_UNIT
+ "\n"
2660 "[ (array of json object)\n"
2662 " \"txid\" : \"txid\", (string) the transaction id \n"
2663 " \"vout\" : n, (numeric) the vout value\n"
2664 " \"address\" : \"address\", (string) the bitcoin address\n"
2665 " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n"
2666 " \"scriptPubKey\" : \"key\", (string) the script key\n"
2667 " \"amount\" : x.xxx, (numeric) the transaction output amount in " + CURRENCY_UNIT
+ "\n"
2668 " \"confirmations\" : n, (numeric) The number of confirmations\n"
2669 " \"redeemScript\" : n (string) The redeemScript if scriptPubKey is P2SH\n"
2670 " \"spendable\" : xxx, (bool) Whether we have the private keys to spend this output\n"
2671 " \"solvable\" : xxx, (bool) Whether we know how to spend this output, ignoring the lack of keys\n"
2672 " \"safe\" : xxx (bool) Whether this output is considered safe to spend. Unconfirmed transactions\n"
2673 " from outside keys and unconfirmed replacement transactions are considered unsafe\n"
2674 " and are not eligible for spending by fundrawtransaction and sendtoaddress.\n"
2680 + HelpExampleCli("listunspent", "")
2681 + HelpExampleCli("listunspent", "6 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"")
2682 + HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"")
2683 + HelpExampleCli("listunspent", "6 9999999 '[]' true '{ \"minimumAmount\": 0.005 }'")
2684 + HelpExampleRpc("listunspent", "6, 9999999, [] , true, { \"minimumAmount\": 0.005 } ")
2688 if (!request
.params
[0].isNull()) {
2689 RPCTypeCheckArgument(request
.params
[0], UniValue::VNUM
);
2690 nMinDepth
= request
.params
[0].get_int();
2693 int nMaxDepth
= 9999999;
2694 if (!request
.params
[1].isNull()) {
2695 RPCTypeCheckArgument(request
.params
[1], UniValue::VNUM
);
2696 nMaxDepth
= request
.params
[1].get_int();
2699 std::set
<CBitcoinAddress
> setAddress
;
2700 if (!request
.params
[2].isNull()) {
2701 RPCTypeCheckArgument(request
.params
[2], UniValue::VARR
);
2702 UniValue inputs
= request
.params
[2].get_array();
2703 for (unsigned int idx
= 0; idx
< inputs
.size(); idx
++) {
2704 const UniValue
& input
= inputs
[idx
];
2705 CBitcoinAddress
address(input
.get_str());
2706 if (!address
.IsValid())
2707 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, std::string("Invalid Bitcoin address: ")+input
.get_str());
2708 if (setAddress
.count(address
))
2709 throw JSONRPCError(RPC_INVALID_PARAMETER
, std::string("Invalid parameter, duplicated address: ")+input
.get_str());
2710 setAddress
.insert(address
);
2714 bool include_unsafe
= true;
2715 if (!request
.params
[3].isNull()) {
2716 RPCTypeCheckArgument(request
.params
[3], UniValue::VBOOL
);
2717 include_unsafe
= request
.params
[3].get_bool();
2720 CAmount nMinimumAmount
= 0;
2721 CAmount nMaximumAmount
= MAX_MONEY
;
2722 CAmount nMinimumSumAmount
= MAX_MONEY
;
2723 uint64_t nMaximumCount
= 0;
2725 if (!request
.params
[4].isNull()) {
2726 const UniValue
& options
= request
.params
[4].get_obj();
2728 if (options
.exists("minimumAmount"))
2729 nMinimumAmount
= AmountFromValue(options
["minimumAmount"]);
2731 if (options
.exists("maximumAmount"))
2732 nMaximumAmount
= AmountFromValue(options
["maximumAmount"]);
2734 if (options
.exists("minimumSumAmount"))
2735 nMinimumSumAmount
= AmountFromValue(options
["minimumSumAmount"]);
2737 if (options
.exists("maximumCount"))
2738 nMaximumCount
= options
["maximumCount"].get_int64();
2741 UniValue
results(UniValue::VARR
);
2742 std::vector
<COutput
> vecOutputs
;
2743 assert(pwallet
!= nullptr);
2744 LOCK2(cs_main
, pwallet
->cs_wallet
);
2746 pwallet
->AvailableCoins(vecOutputs
, !include_unsafe
, nullptr, nMinimumAmount
, nMaximumAmount
, nMinimumSumAmount
, nMaximumCount
, nMinDepth
, nMaxDepth
);
2747 for (const COutput
& out
: vecOutputs
) {
2748 CTxDestination address
;
2749 const CScript
& scriptPubKey
= out
.tx
->tx
->vout
[out
.i
].scriptPubKey
;
2750 bool fValidAddress
= ExtractDestination(scriptPubKey
, address
);
2752 if (setAddress
.size() && (!fValidAddress
|| !setAddress
.count(address
)))
2755 UniValue
entry(UniValue::VOBJ
);
2756 entry
.push_back(Pair("txid", out
.tx
->GetHash().GetHex()));
2757 entry
.push_back(Pair("vout", out
.i
));
2759 if (fValidAddress
) {
2760 entry
.push_back(Pair("address", CBitcoinAddress(address
).ToString()));
2762 if (pwallet
->mapAddressBook
.count(address
)) {
2763 entry
.push_back(Pair("account", pwallet
->mapAddressBook
[address
].name
));
2766 if (scriptPubKey
.IsPayToScriptHash()) {
2767 const CScriptID
& hash
= boost::get
<CScriptID
>(address
);
2768 CScript redeemScript
;
2769 if (pwallet
->GetCScript(hash
, redeemScript
)) {
2770 entry
.push_back(Pair("redeemScript", HexStr(redeemScript
.begin(), redeemScript
.end())));
2775 entry
.push_back(Pair("scriptPubKey", HexStr(scriptPubKey
.begin(), scriptPubKey
.end())));
2776 entry
.push_back(Pair("amount", ValueFromAmount(out
.tx
->tx
->vout
[out
.i
].nValue
)));
2777 entry
.push_back(Pair("confirmations", out
.nDepth
));
2778 entry
.push_back(Pair("spendable", out
.fSpendable
));
2779 entry
.push_back(Pair("solvable", out
.fSolvable
));
2780 entry
.push_back(Pair("safe", out
.fSafe
));
2781 results
.push_back(entry
);
2787 UniValue
fundrawtransaction(const JSONRPCRequest
& request
)
2789 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
2790 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
2791 return NullUniValue
;
2794 if (request
.fHelp
|| request
.params
.size() < 1 || request
.params
.size() > 2)
2795 throw std::runtime_error(
2796 "fundrawtransaction \"hexstring\" ( options )\n"
2797 "\nAdd inputs to a transaction until it has enough in value to meet its out value.\n"
2798 "This will not modify existing inputs, and will add at most one change output to the outputs.\n"
2799 "No existing outputs will be modified unless \"subtractFeeFromOutputs\" is specified.\n"
2800 "Note that inputs which were signed may need to be resigned after completion since in/outputs have been added.\n"
2801 "The inputs added will not be signed, use signrawtransaction for that.\n"
2802 "Note that all existing inputs must have their previous output transaction be in the wallet.\n"
2803 "Note that all inputs selected must be of standard form and P2SH scripts must be\n"
2804 "in the wallet using importaddress or addmultisigaddress (to calculate fees).\n"
2805 "You can see whether this is the case by checking the \"solvable\" field in the listunspent output.\n"
2806 "Only pay-to-pubkey, multisig, and P2SH versions thereof are currently supported for watch-only\n"
2808 "1. \"hexstring\" (string, required) The hex string of the raw transaction\n"
2809 "2. options (object, optional)\n"
2811 " \"changeAddress\" (string, optional, default pool address) The bitcoin address to receive the change\n"
2812 " \"changePosition\" (numeric, optional, default random) The index of the change output\n"
2813 " \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n"
2814 " \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\n"
2815 " \"feeRate\" (numeric, optional, default not set: makes wallet determine the fee) Set a specific feerate (" + CURRENCY_UNIT
+ " per KB)\n"
2816 " \"subtractFeeFromOutputs\" (array, optional) A json array of integers.\n"
2817 " The fee will be equally deducted from the amount of each specified output.\n"
2818 " The outputs are specified by their zero-based index, before any change output is added.\n"
2819 " Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
2820 " If no outputs are specified here, the sender pays the fee.\n"
2821 " [vout_index,...]\n"
2822 " \"replaceable\" (boolean, optional) Marks this transaction as BIP125 replaceable.\n"
2823 " Allows this transaction to be replaced by a transaction with higher fees\n"
2824 " \"conf_target\" (numeric, optional) Confirmation target (in blocks)\n"
2825 " \"estimate_mode\" (string, optional, default=UNSET) The fee estimate mode, must be one of:\n"
2828 " \"CONSERVATIVE\"\n"
2830 " for backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}\n"
2833 " \"hex\": \"value\", (string) The resulting raw transaction (hex-encoded string)\n"
2834 " \"fee\": n, (numeric) Fee in " + CURRENCY_UNIT
+ " the resulting transaction pays\n"
2835 " \"changepos\": n (numeric) The position of the added change output, or -1\n"
2838 "\nCreate a transaction with no inputs\n"
2839 + HelpExampleCli("createrawtransaction", "\"[]\" \"{\\\"myaddress\\\":0.01}\"") +
2840 "\nAdd sufficient unsigned inputs to meet the output value\n"
2841 + HelpExampleCli("fundrawtransaction", "\"rawtransactionhex\"") +
2842 "\nSign the transaction\n"
2843 + HelpExampleCli("signrawtransaction", "\"fundedtransactionhex\"") +
2844 "\nSend the transaction\n"
2845 + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"")
2848 RPCTypeCheck(request
.params
, {UniValue::VSTR
});
2850 CCoinControl coinControl
;
2851 int changePosition
= -1;
2852 bool lockUnspents
= false;
2853 UniValue subtractFeeFromOutputs
;
2854 std::set
<int> setSubtractFeeFromOutputs
;
2856 if (!request
.params
[1].isNull()) {
2857 if (request
.params
[1].type() == UniValue::VBOOL
) {
2858 // backward compatibility bool only fallback
2859 coinControl
.fAllowWatchOnly
= request
.params
[1].get_bool();
2862 RPCTypeCheck(request
.params
, {UniValue::VSTR
, UniValue::VOBJ
});
2864 UniValue options
= request
.params
[1];
2866 RPCTypeCheckObj(options
,
2868 {"changeAddress", UniValueType(UniValue::VSTR
)},
2869 {"changePosition", UniValueType(UniValue::VNUM
)},
2870 {"includeWatching", UniValueType(UniValue::VBOOL
)},
2871 {"lockUnspents", UniValueType(UniValue::VBOOL
)},
2872 {"reserveChangeKey", UniValueType(UniValue::VBOOL
)}, // DEPRECATED (and ignored), should be removed in 0.16 or so.
2873 {"feeRate", UniValueType()}, // will be checked below
2874 {"subtractFeeFromOutputs", UniValueType(UniValue::VARR
)},
2875 {"replaceable", UniValueType(UniValue::VBOOL
)},
2876 {"conf_target", UniValueType(UniValue::VNUM
)},
2877 {"estimate_mode", UniValueType(UniValue::VSTR
)},
2881 if (options
.exists("changeAddress")) {
2882 CBitcoinAddress
address(options
["changeAddress"].get_str());
2884 if (!address
.IsValid())
2885 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, "changeAddress must be a valid bitcoin address");
2887 coinControl
.destChange
= address
.Get();
2890 if (options
.exists("changePosition"))
2891 changePosition
= options
["changePosition"].get_int();
2893 if (options
.exists("includeWatching"))
2894 coinControl
.fAllowWatchOnly
= options
["includeWatching"].get_bool();
2896 if (options
.exists("lockUnspents"))
2897 lockUnspents
= options
["lockUnspents"].get_bool();
2899 if (options
.exists("feeRate"))
2901 coinControl
.m_feerate
= CFeeRate(AmountFromValue(options
["feeRate"]));
2902 coinControl
.fOverrideFeeRate
= true;
2905 if (options
.exists("subtractFeeFromOutputs"))
2906 subtractFeeFromOutputs
= options
["subtractFeeFromOutputs"].get_array();
2908 if (options
.exists("replaceable")) {
2909 coinControl
.signalRbf
= options
["replaceable"].get_bool();
2911 if (options
.exists("conf_target")) {
2912 if (options
.exists("feeRate")) {
2913 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Cannot specify both conf_target and feeRate");
2915 coinControl
.m_confirm_target
= ParseConfirmTarget(options
["conf_target"]);
2917 if (options
.exists("estimate_mode")) {
2918 if (options
.exists("feeRate")) {
2919 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Cannot specify both estimate_mode and feeRate");
2921 if (!FeeModeFromString(options
["estimate_mode"].get_str(), coinControl
.m_fee_mode
)) {
2922 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Invalid estimate_mode parameter");
2928 // parse hex string from parameter
2929 CMutableTransaction tx
;
2930 if (!DecodeHexTx(tx
, request
.params
[0].get_str(), true))
2931 throw JSONRPCError(RPC_DESERIALIZATION_ERROR
, "TX decode failed");
2933 if (tx
.vout
.size() == 0)
2934 throw JSONRPCError(RPC_INVALID_PARAMETER
, "TX must have at least one output");
2936 if (changePosition
!= -1 && (changePosition
< 0 || (unsigned int)changePosition
> tx
.vout
.size()))
2937 throw JSONRPCError(RPC_INVALID_PARAMETER
, "changePosition out of bounds");
2939 for (unsigned int idx
= 0; idx
< subtractFeeFromOutputs
.size(); idx
++) {
2940 int pos
= subtractFeeFromOutputs
[idx
].get_int();
2941 if (setSubtractFeeFromOutputs
.count(pos
))
2942 throw JSONRPCError(RPC_INVALID_PARAMETER
, strprintf("Invalid parameter, duplicated position: %d", pos
));
2944 throw JSONRPCError(RPC_INVALID_PARAMETER
, strprintf("Invalid parameter, negative position: %d", pos
));
2945 if (pos
>= int(tx
.vout
.size()))
2946 throw JSONRPCError(RPC_INVALID_PARAMETER
, strprintf("Invalid parameter, position too large: %d", pos
));
2947 setSubtractFeeFromOutputs
.insert(pos
);
2951 std::string strFailReason
;
2953 if (!pwallet
->FundTransaction(tx
, nFeeOut
, changePosition
, strFailReason
, lockUnspents
, setSubtractFeeFromOutputs
, coinControl
)) {
2954 throw JSONRPCError(RPC_WALLET_ERROR
, strFailReason
);
2957 UniValue
result(UniValue::VOBJ
);
2958 result
.push_back(Pair("hex", EncodeHexTx(tx
)));
2959 result
.push_back(Pair("changepos", changePosition
));
2960 result
.push_back(Pair("fee", ValueFromAmount(nFeeOut
)));
2965 UniValue
bumpfee(const JSONRPCRequest
& request
)
2967 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
2969 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
))
2970 return NullUniValue
;
2972 if (request
.fHelp
|| request
.params
.size() < 1 || request
.params
.size() > 2) {
2973 throw std::runtime_error(
2974 "bumpfee \"txid\" ( options ) \n"
2975 "\nBumps the fee of an opt-in-RBF transaction T, replacing it with a new transaction B.\n"
2976 "An opt-in RBF transaction with the given txid must be in the wallet.\n"
2977 "The command will pay the additional fee by decreasing (or perhaps removing) its change output.\n"
2978 "If the change output is not big enough to cover the increased fee, the command will currently fail\n"
2979 "instead of adding new inputs to compensate. (A future implementation could improve this.)\n"
2980 "The command will fail if the wallet or mempool contains a transaction that spends one of T's outputs.\n"
2981 "By default, the new fee will be calculated automatically using estimatefee.\n"
2982 "The user can specify a confirmation target for estimatefee.\n"
2983 "Alternatively, the user can specify totalFee, or use RPC settxfee to set a higher fee rate.\n"
2984 "At a minimum, the new fee rate must be high enough to pay an additional new relay fee (incrementalfee\n"
2985 "returned by getnetworkinfo) to enter the node's mempool.\n"
2987 "1. txid (string, required) The txid to be bumped\n"
2988 "2. options (object, optional)\n"
2990 " \"confTarget\" (numeric, optional) Confirmation target (in blocks)\n"
2991 " \"totalFee\" (numeric, optional) Total fee (NOT feerate) to pay, in satoshis.\n"
2992 " In rare cases, the actual fee paid might be slightly higher than the specified\n"
2993 " totalFee if the tx change output has to be removed because it is too close to\n"
2994 " the dust threshold.\n"
2995 " \"replaceable\" (boolean, optional, default true) Whether the new transaction should still be\n"
2996 " marked bip-125 replaceable. If true, the sequence numbers in the transaction will\n"
2997 " be left unchanged from the original. If false, any input sequence numbers in the\n"
2998 " original transaction that were less than 0xfffffffe will be increased to 0xfffffffe\n"
2999 " so the new transaction will not be explicitly bip-125 replaceable (though it may\n"
3000 " still be replaceable in practice, for example if it has unconfirmed ancestors which\n"
3001 " are replaceable).\n"
3002 " \"estimate_mode\" (string, optional, default=UNSET) The fee estimate mode, must be one of:\n"
3005 " \"CONSERVATIVE\"\n"
3009 " \"txid\": \"value\", (string) The id of the new transaction\n"
3010 " \"origfee\": n, (numeric) Fee of the replaced transaction\n"
3011 " \"fee\": n, (numeric) Fee of the new transaction\n"
3012 " \"errors\": [ str... ] (json array of strings) Errors encountered during processing (may be empty)\n"
3015 "\nBump the fee, get the new transaction\'s txid\n" +
3016 HelpExampleCli("bumpfee", "<txid>"));
3019 RPCTypeCheck(request
.params
, {UniValue::VSTR
, UniValue::VOBJ
});
3021 hash
.SetHex(request
.params
[0].get_str());
3023 // optional parameters
3024 CAmount totalFee
= 0;
3025 CCoinControl coin_control
;
3026 coin_control
.signalRbf
= true;
3027 if (!request
.params
[1].isNull()) {
3028 UniValue options
= request
.params
[1];
3029 RPCTypeCheckObj(options
,
3031 {"confTarget", UniValueType(UniValue::VNUM
)},
3032 {"totalFee", UniValueType(UniValue::VNUM
)},
3033 {"replaceable", UniValueType(UniValue::VBOOL
)},
3034 {"estimate_mode", UniValueType(UniValue::VSTR
)},
3038 if (options
.exists("confTarget") && options
.exists("totalFee")) {
3039 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.");
3040 } else if (options
.exists("confTarget")) { // TODO: alias this to conf_target
3041 coin_control
.m_confirm_target
= ParseConfirmTarget(options
["confTarget"]);
3042 } else if (options
.exists("totalFee")) {
3043 totalFee
= options
["totalFee"].get_int64();
3044 if (totalFee
<= 0) {
3045 throw JSONRPCError(RPC_INVALID_PARAMETER
, strprintf("Invalid totalFee %s (must be greater than 0)", FormatMoney(totalFee
)));
3049 if (options
.exists("replaceable")) {
3050 coin_control
.signalRbf
= options
["replaceable"].get_bool();
3052 if (options
.exists("estimate_mode")) {
3053 if (!FeeModeFromString(options
["estimate_mode"].get_str(), coin_control
.m_fee_mode
)) {
3054 throw JSONRPCError(RPC_INVALID_PARAMETER
, "Invalid estimate_mode parameter");
3059 LOCK2(cs_main
, pwallet
->cs_wallet
);
3060 EnsureWalletIsUnlocked(pwallet
);
3062 CFeeBumper
feeBump(pwallet
, hash
, coin_control
, totalFee
);
3063 BumpFeeResult res
= feeBump
.getResult();
3064 if (res
!= BumpFeeResult::OK
)
3067 case BumpFeeResult::INVALID_ADDRESS_OR_KEY
:
3068 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY
, feeBump
.getErrors()[0]);
3070 case BumpFeeResult::INVALID_REQUEST
:
3071 throw JSONRPCError(RPC_INVALID_REQUEST
, feeBump
.getErrors()[0]);
3073 case BumpFeeResult::INVALID_PARAMETER
:
3074 throw JSONRPCError(RPC_INVALID_PARAMETER
, feeBump
.getErrors()[0]);
3076 case BumpFeeResult::WALLET_ERROR
:
3077 throw JSONRPCError(RPC_WALLET_ERROR
, feeBump
.getErrors()[0]);
3080 throw JSONRPCError(RPC_MISC_ERROR
, feeBump
.getErrors()[0]);
3085 // sign bumped transaction
3086 if (!feeBump
.signTransaction(pwallet
)) {
3087 throw JSONRPCError(RPC_WALLET_ERROR
, "Can't sign transaction.");
3089 // commit the bumped transaction
3090 if(!feeBump
.commit(pwallet
)) {
3091 throw JSONRPCError(RPC_WALLET_ERROR
, feeBump
.getErrors()[0]);
3093 UniValue
result(UniValue::VOBJ
);
3094 result
.push_back(Pair("txid", feeBump
.getBumpedTxId().GetHex()));
3095 result
.push_back(Pair("origfee", ValueFromAmount(feeBump
.getOldFee())));
3096 result
.push_back(Pair("fee", ValueFromAmount(feeBump
.getNewFee())));
3097 UniValue
errors(UniValue::VARR
);
3098 for (const std::string
& err
: feeBump
.getErrors())
3099 errors
.push_back(err
);
3100 result
.push_back(Pair("errors", errors
));
3105 UniValue
generate(const JSONRPCRequest
& request
)
3107 CWallet
* const pwallet
= GetWalletForJSONRPCRequest(request
);
3109 if (!EnsureWalletIsAvailable(pwallet
, request
.fHelp
)) {
3110 return NullUniValue
;
3113 if (request
.fHelp
|| request
.params
.size() < 1 || request
.params
.size() > 2) {
3114 throw std::runtime_error(
3115 "generate nblocks ( maxtries )\n"
3116 "\nMine up to nblocks blocks immediately (before the RPC call returns) to an address in the wallet.\n"
3118 "1. nblocks (numeric, required) How many blocks are generated immediately.\n"
3119 "2. maxtries (numeric, optional) How many iterations to try (default = 1000000).\n"
3121 "[ blockhashes ] (array) hashes of blocks generated\n"
3123 "\nGenerate 11 blocks\n"
3124 + HelpExampleCli("generate", "11")
3128 int num_generate
= request
.params
[0].get_int();
3129 uint64_t max_tries
= 1000000;
3130 if (!request
.params
[1].isNull()) {
3131 max_tries
= request
.params
[1].get_int();
3134 std::shared_ptr
<CReserveScript
> coinbase_script
;
3135 pwallet
->GetScriptForMining(coinbase_script
);
3137 // If the keypool is exhausted, no script is returned at all. Catch this.
3138 if (!coinbase_script
) {
3139 throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT
, "Error: Keypool ran out, please call keypoolrefill first");
3142 //throw an error if no script was provided
3143 if (coinbase_script
->reserveScript
.empty()) {
3144 throw JSONRPCError(RPC_INTERNAL_ERROR
, "No coinbase script available");
3147 return generateBlocks(coinbase_script
, num_generate
, max_tries
, true);
3150 extern UniValue
abortrescan(const JSONRPCRequest
& request
); // in rpcdump.cpp
3151 extern UniValue
dumpprivkey(const JSONRPCRequest
& request
); // in rpcdump.cpp
3152 extern UniValue
importprivkey(const JSONRPCRequest
& request
);
3153 extern UniValue
importaddress(const JSONRPCRequest
& request
);
3154 extern UniValue
importpubkey(const JSONRPCRequest
& request
);
3155 extern UniValue
dumpwallet(const JSONRPCRequest
& request
);
3156 extern UniValue
importwallet(const JSONRPCRequest
& request
);
3157 extern UniValue
importprunedfunds(const JSONRPCRequest
& request
);
3158 extern UniValue
removeprunedfunds(const JSONRPCRequest
& request
);
3159 extern UniValue
importmulti(const JSONRPCRequest
& request
);
3161 static const CRPCCommand commands
[] =
3162 { // category name actor (function) okSafeMode
3163 // --------------------- ------------------------ ----------------------- ----------
3164 { "rawtransactions", "fundrawtransaction", &fundrawtransaction
, false, {"hexstring","options"} },
3165 { "hidden", "resendwallettransactions", &resendwallettransactions
, true, {} },
3166 { "wallet", "abandontransaction", &abandontransaction
, false, {"txid"} },
3167 { "wallet", "abortrescan", &abortrescan
, false, {} },
3168 { "wallet", "addmultisigaddress", &addmultisigaddress
, true, {"nrequired","keys","account"} },
3169 { "wallet", "addwitnessaddress", &addwitnessaddress
, true, {"address"} },
3170 { "wallet", "backupwallet", &backupwallet
, true, {"destination"} },
3171 { "wallet", "bumpfee", &bumpfee
, true, {"txid", "options"} },
3172 { "wallet", "dumpprivkey", &dumpprivkey
, true, {"address"} },
3173 { "wallet", "dumpwallet", &dumpwallet
, true, {"filename"} },
3174 { "wallet", "encryptwallet", &encryptwallet
, true, {"passphrase"} },
3175 { "wallet", "getaccountaddress", &getaccountaddress
, true, {"account"} },
3176 { "wallet", "getaccount", &getaccount
, true, {"address"} },
3177 { "wallet", "getaddressesbyaccount", &getaddressesbyaccount
, true, {"account"} },
3178 { "wallet", "getbalance", &getbalance
, false, {"account","minconf","include_watchonly"} },
3179 { "wallet", "getnewaddress", &getnewaddress
, true, {"account"} },
3180 { "wallet", "getrawchangeaddress", &getrawchangeaddress
, true, {} },
3181 { "wallet", "getreceivedbyaccount", &getreceivedbyaccount
, false, {"account","minconf"} },
3182 { "wallet", "getreceivedbyaddress", &getreceivedbyaddress
, false, {"address","minconf"} },
3183 { "wallet", "gettransaction", &gettransaction
, false, {"txid","include_watchonly"} },
3184 { "wallet", "getunconfirmedbalance", &getunconfirmedbalance
, false, {} },
3185 { "wallet", "getwalletinfo", &getwalletinfo
, false, {} },
3186 { "wallet", "importmulti", &importmulti
, true, {"requests","options"} },
3187 { "wallet", "importprivkey", &importprivkey
, true, {"privkey","label","rescan"} },
3188 { "wallet", "importwallet", &importwallet
, true, {"filename"} },
3189 { "wallet", "importaddress", &importaddress
, true, {"address","label","rescan","p2sh"} },
3190 { "wallet", "importprunedfunds", &importprunedfunds
, true, {"rawtransaction","txoutproof"} },
3191 { "wallet", "importpubkey", &importpubkey
, true, {"pubkey","label","rescan"} },
3192 { "wallet", "keypoolrefill", &keypoolrefill
, true, {"newsize"} },
3193 { "wallet", "listaccounts", &listaccounts
, false, {"minconf","include_watchonly"} },
3194 { "wallet", "listaddressgroupings", &listaddressgroupings
, false, {} },
3195 { "wallet", "listlockunspent", &listlockunspent
, false, {} },
3196 { "wallet", "listreceivedbyaccount", &listreceivedbyaccount
, false, {"minconf","include_empty","include_watchonly"} },
3197 { "wallet", "listreceivedbyaddress", &listreceivedbyaddress
, false, {"minconf","include_empty","include_watchonly"} },
3198 { "wallet", "listsinceblock", &listsinceblock
, false, {"blockhash","target_confirmations","include_watchonly","include_removed"} },
3199 { "wallet", "listtransactions", &listtransactions
, false, {"account","count","skip","include_watchonly"} },
3200 { "wallet", "listunspent", &listunspent
, false, {"minconf","maxconf","addresses","include_unsafe","query_options"} },
3201 { "wallet", "listwallets", &listwallets
, true, {} },
3202 { "wallet", "lockunspent", &lockunspent
, true, {"unlock","transactions"} },
3203 { "wallet", "move", &movecmd
, false, {"fromaccount","toaccount","amount","minconf","comment"} },
3204 { "wallet", "sendfrom", &sendfrom
, false, {"fromaccount","toaddress","amount","minconf","comment","comment_to"} },
3205 { "wallet", "sendmany", &sendmany
, false, {"fromaccount","amounts","minconf","comment","subtractfeefrom","replaceable","conf_target","estimate_mode"} },
3206 { "wallet", "sendtoaddress", &sendtoaddress
, false, {"address","amount","comment","comment_to","subtractfeefromamount","replaceable","conf_target","estimate_mode"} },
3207 { "wallet", "setaccount", &setaccount
, true, {"address","account"} },
3208 { "wallet", "settxfee", &settxfee
, true, {"amount"} },
3209 { "wallet", "signmessage", &signmessage
, true, {"address","message"} },
3210 { "wallet", "walletlock", &walletlock
, true, {} },
3211 { "wallet", "walletpassphrasechange", &walletpassphrasechange
, true, {"oldpassphrase","newpassphrase"} },
3212 { "wallet", "walletpassphrase", &walletpassphrase
, true, {"passphrase","timeout"} },
3213 { "wallet", "removeprunedfunds", &removeprunedfunds
, true, {"txid"} },
3215 { "generating", "generate", &generate
, true, {"nblocks","maxtries"} },
3218 void RegisterWalletRPCCommands(CRPCTable
&t
)
3220 if (gArgs
.GetBoolArg("-disablewallet", false))
3223 for (unsigned int vcidx
= 0; vcidx
< ARRAYLEN(commands
); vcidx
++)
3224 t
.appendCommand(commands
[vcidx
].name
, &commands
[vcidx
]);