Browse Source

Merge #8811: rpc: Add support for JSON-RPC named arguments

4e7e2e1 Update RPC argument names (John Newbery)
481f289 rpc: Named argument support for bitcoin-cli (Wladimir J. van der Laan)
9adb4e1 rpc: Argument name consistency (Wladimir J. van der Laan)
8d713f7 rpc: Named arguments for rawtransaction calls (Wladimir J. van der Laan)
37a166f rpc: Named arguments for wallet calls (Wladimir J. van der Laan)
78b684f rpc: Named arguments for mining calls (Wladimir J. van der Laan)
b8ebc59 rpc: Named arguments for net calls (Wladimir J. van der Laan)
2ca9dcd test: Add test for RPC named arguments (Wladimir J. van der Laan)
fba1a61 rpc: Named arguments for misc calls (Wladimir J. van der Laan)
286ec08 rpc: Add 'echo' call for testing (Wladimir J. van der Laan)
495eb44 rpc: Named arguments for blockchain calls (Wladimir J. van der Laan)
6f1c76a rpc: Support named arguments (Wladimir J. van der Laan)
5865d41 authproxy: Add support for RPC named arguments (Wladimir J. van der Laan)
0.14
Wladimir J. van der Laan 8 years ago
parent
commit
5754e0341b
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 1
      qa/pull-tester/rpc-tests.py
  2. 52
      qa/rpc-tests/rpcnamedargs.py
  3. 6
      qa/rpc-tests/test_framework/authproxy.py
  4. 12
      qa/rpc-tests/test_framework/util.py
  5. 12
      src/bitcoin-cli.cpp
  6. 102
      src/rpc/blockchain.cpp
  7. 225
      src/rpc/client.cpp
  8. 5
      src/rpc/client.h
  9. 62
      src/rpc/mining.cpp
  10. 39
      src/rpc/misc.cpp
  11. 32
      src/rpc/net.cpp
  12. 50
      src/rpc/rawtransaction.cpp
  13. 65
      src/rpc/server.cpp
  14. 1
      src/rpc/server.h
  15. 14
      src/wallet/rpcdump.cpp
  16. 210
      src/wallet/rpcwallet.cpp

1
qa/pull-tester/rpc-tests.py

@ -151,6 +151,7 @@ testScripts = [
'signmessages.py', 'signmessages.py',
'nulldummy.py', 'nulldummy.py',
'import-rescan.py', 'import-rescan.py',
'rpcnamedargs.py',
] ]
if ENABLE_ZMQ: if ENABLE_ZMQ:
testScripts.append('zmq_test.py') testScripts.append('zmq_test.py')

52
qa/rpc-tests/rpcnamedargs.py

@ -0,0 +1,52 @@
#!/usr/bin/env python3
# Copyright (c) 2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
from decimal import Decimal
from test_framework.test_framework import BitcoinTestFramework
from test_framework.authproxy import JSONRPCException
from test_framework.util import (
assert_equal,
assert_raises_jsonrpc,
assert_is_hex_string,
assert_is_hash_string,
start_nodes,
connect_nodes_bi,
)
class NamedArgumentTest(BitcoinTestFramework):
"""
Test named arguments on RPC calls.
"""
def __init__(self):
super().__init__()
self.setup_clean_chain = False
self.num_nodes = 1
def setup_network(self, split=False):
self.nodes = start_nodes(self.num_nodes, self.options.tmpdir)
self.is_network_split = False
self.sync_all()
def run_test(self):
node = self.nodes[0]
h = node.help(command='getinfo')
assert(h.startswith('getinfo\n'))
assert_raises_jsonrpc(-8, node.help, random='getinfo')
h = node.getblockhash(height=0)
node.getblock(blockhash=h)
assert_equal(node.echo(), [])
assert_equal(node.echo(arg0=0,arg9=9), [0] + [None]*8 + [9])
assert_equal(node.echo(arg1=1), [None, 1])
assert_equal(node.echo(arg9=None), [None]*10)
assert_equal(node.echo(arg0=0,arg3=3,arg9=9), [0] + [None]*2 + [3] + [None]*5 + [9])
if __name__ == '__main__':
NamedArgumentTest().main()

6
qa/rpc-tests/test_framework/authproxy.py

@ -138,14 +138,16 @@ class AuthServiceProxy(object):
self.__conn.request(method, path, postdata, headers) self.__conn.request(method, path, postdata, headers)
return self._get_response() return self._get_response()
def __call__(self, *args): def __call__(self, *args, **argsn):
AuthServiceProxy.__id_count += 1 AuthServiceProxy.__id_count += 1
log.debug("-%s-> %s %s"%(AuthServiceProxy.__id_count, self._service_name, log.debug("-%s-> %s %s"%(AuthServiceProxy.__id_count, self._service_name,
json.dumps(args, default=EncodeDecimal, ensure_ascii=self.ensure_ascii))) json.dumps(args, default=EncodeDecimal, ensure_ascii=self.ensure_ascii)))
if args and argsn:
raise ValueError('Cannot handle both named and positional arguments')
postdata = json.dumps({'version': '1.1', postdata = json.dumps({'version': '1.1',
'method': self._service_name, 'method': self._service_name,
'params': args, 'params': args or argsn,
'id': AuthServiceProxy.__id_count}, default=EncodeDecimal, ensure_ascii=self.ensure_ascii) 'id': AuthServiceProxy.__id_count}, default=EncodeDecimal, ensure_ascii=self.ensure_ascii)
response = self._request('POST', self.__url.path, postdata.encode('utf-8')) response = self._request('POST', self.__url.path, postdata.encode('utf-8'))
if response['error'] is not None: if response['error'] is not None:

12
qa/rpc-tests/test_framework/util.py

@ -546,6 +546,18 @@ def assert_raises_message(exc, message, fun, *args, **kwds):
else: else:
raise AssertionError("No exception raised") raise AssertionError("No exception raised")
def assert_raises_jsonrpc(code, fun, *args, **kwds):
'''Check for specific JSONRPC exception code'''
try:
fun(*args, **kwds)
except JSONRPCException as e:
if e.error["code"] != code:
raise AssertionError("Unexpected JSONRPC error code %i" % e.error["code"])
except Exception as e:
raise AssertionError("Unexpected exception raised: "+type(e).__name__)
else:
raise AssertionError("No exception raised")
def assert_is_hex_string(string): def assert_is_hex_string(string):
try: try:
int(string, 16) int(string, 16)

12
src/bitcoin-cli.cpp

@ -25,6 +25,7 @@
static const char DEFAULT_RPCCONNECT[] = "127.0.0.1"; static const char DEFAULT_RPCCONNECT[] = "127.0.0.1";
static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900; static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900;
static const bool DEFAULT_NAMED=false;
static const int CONTINUE_EXECUTION=-1; static const int CONTINUE_EXECUTION=-1;
std::string HelpMessageCli() std::string HelpMessageCli()
@ -35,6 +36,7 @@ std::string HelpMessageCli()
strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), BITCOIN_CONF_FILENAME)); strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), BITCOIN_CONF_FILENAME));
strUsage += HelpMessageOpt("-datadir=<dir>", _("Specify data directory")); strUsage += HelpMessageOpt("-datadir=<dir>", _("Specify data directory"));
AppendParamsHelpMessages(strUsage); AppendParamsHelpMessages(strUsage);
strUsage += HelpMessageOpt("-named", strprintf(_("Pass named instead of positional arguments (default: %s)"), DEFAULT_NAMED));
strUsage += HelpMessageOpt("-rpcconnect=<ip>", strprintf(_("Send commands to node running on <ip> (default: %s)"), DEFAULT_RPCCONNECT)); strUsage += HelpMessageOpt("-rpcconnect=<ip>", strprintf(_("Send commands to node running on <ip> (default: %s)"), DEFAULT_RPCCONNECT));
strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Connect to JSON-RPC on <port> (default: %u or testnet: %u)"), BaseParams(CBaseChainParams::MAIN).RPCPort(), BaseParams(CBaseChainParams::TESTNET).RPCPort())); strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Connect to JSON-RPC on <port> (default: %u or testnet: %u)"), BaseParams(CBaseChainParams::MAIN).RPCPort(), BaseParams(CBaseChainParams::TESTNET).RPCPort()));
strUsage += HelpMessageOpt("-rpcwait", _("Wait for RPC server to start")); strUsage += HelpMessageOpt("-rpcwait", _("Wait for RPC server to start"));
@ -80,6 +82,7 @@ static int AppInitRPC(int argc, char* argv[])
if (!IsArgSet("-version")) { if (!IsArgSet("-version")) {
strUsage += "\n" + _("Usage:") + "\n" + strUsage += "\n" + _("Usage:") + "\n" +
" bitcoin-cli [options] <command> [params] " + strprintf(_("Send command to %s"), _(PACKAGE_NAME)) + "\n" + " bitcoin-cli [options] <command> [params] " + strprintf(_("Send command to %s"), _(PACKAGE_NAME)) + "\n" +
" bitcoin-cli [options] -named <command> [name=value] ... " + strprintf(_("Send command to %s (with named arguments)"), _(PACKAGE_NAME)) + "\n" +
" bitcoin-cli [options] help " + _("List commands") + "\n" + " bitcoin-cli [options] help " + _("List commands") + "\n" +
" bitcoin-cli [options] help <command> " + _("Get help for a command") + "\n"; " bitcoin-cli [options] help <command> " + _("Get help for a command") + "\n";
@ -278,7 +281,14 @@ int CommandLineRPC(int argc, char *argv[])
if (args.size() < 1) if (args.size() < 1)
throw std::runtime_error("too few parameters (need at least command)"); throw std::runtime_error("too few parameters (need at least command)");
std::string strMethod = args[0]; std::string strMethod = args[0];
UniValue params = RPCConvertValues(strMethod, std::vector<std::string>(args.begin()+1, args.end())); args.erase(args.begin()); // Remove trailing method name from arguments vector
UniValue params;
if(GetBoolArg("-named", DEFAULT_NAMED)) {
params = RPCConvertNamedValues(strMethod, args);
} else {
params = RPCConvertValues(strMethod, args);
}
// Execute and handle connection failures with -rpcwait // Execute and handle connection failures with -rpcwait
const bool fWait = GetBoolArg("-rpcwait", false); const bool fWait = GetBoolArg("-rpcwait", false);

102
src/rpc/blockchain.cpp

@ -236,8 +236,8 @@ UniValue waitforblock(const JSONRPCRequest& request)
"\nWaits for a specific new block and returns useful info about it.\n" "\nWaits for a specific new block and returns useful info about it.\n"
"\nReturns the current block on timeout or exit.\n" "\nReturns the current block on timeout or exit.\n"
"\nArguments:\n" "\nArguments:\n"
"1. blockhash to wait for (string)\n" "1. \"blockhash\" (required, string) Block hash to wait for.\n"
"2. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n" "2. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n"
"\nResult:\n" "\nResult:\n"
"{ (json object)\n" "{ (json object)\n"
" \"hash\" : { (string) The blockhash\n" " \"hash\" : { (string) The blockhash\n"
@ -274,12 +274,12 @@ UniValue waitforblockheight(const JSONRPCRequest& request)
{ {
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
throw runtime_error( throw runtime_error(
"waitforblockheight <blockheight> (timeout)\n" "waitforblockheight <height> (timeout)\n"
"\nWaits for (at least) block height and returns the height and hash\n" "\nWaits for (at least) block height and returns the height and hash\n"
"of the current tip.\n" "of the current tip.\n"
"\nReturns the current block on timeout or exit.\n" "\nReturns the current block on timeout or exit.\n"
"\nArguments:\n" "\nArguments:\n"
"1. block height to wait for (int)\n" "1. height (required, int) Block height to wait for (int)\n"
"2. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n" "2. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n"
"\nResult:\n" "\nResult:\n"
"{ (json object)\n" "{ (json object)\n"
@ -418,7 +418,7 @@ UniValue getrawmempool(const JSONRPCRequest& request)
"getrawmempool ( verbose )\n" "getrawmempool ( verbose )\n"
"\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n" "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
"\nArguments:\n" "\nArguments:\n"
"1. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n" "1. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
"\nResult: (for verbose = false):\n" "\nResult: (for verbose = false):\n"
"[ (json array of string)\n" "[ (json array of string)\n"
" \"transactionid\" (string) The transaction id\n" " \"transactionid\" (string) The transaction id\n"
@ -449,8 +449,8 @@ UniValue getmempoolancestors(const JSONRPCRequest& request)
"getmempoolancestors txid (verbose)\n" "getmempoolancestors txid (verbose)\n"
"\nIf txid is in the mempool, returns all in-mempool ancestors.\n" "\nIf txid is in the mempool, returns all in-mempool ancestors.\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"txid\" (string, required) The transaction id (must be in mempool)\n" "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
"2. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n" "2. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
"\nResult (for verbose=false):\n" "\nResult (for verbose=false):\n"
"[ (json array of strings)\n" "[ (json array of strings)\n"
" \"transactionid\" (string) The transaction id of an in-mempool ancestor transaction\n" " \"transactionid\" (string) The transaction id of an in-mempool ancestor transaction\n"
@ -513,8 +513,8 @@ UniValue getmempooldescendants(const JSONRPCRequest& request)
"getmempooldescendants txid (verbose)\n" "getmempooldescendants txid (verbose)\n"
"\nIf txid is in the mempool, returns all in-mempool descendants.\n" "\nIf txid is in the mempool, returns all in-mempool descendants.\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"txid\" (string, required) The transaction id (must be in mempool)\n" "1. \"txid\" (string, required) The transaction id (must be in mempool)\n"
"2. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n" "2. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n"
"\nResult (for verbose=false):\n" "\nResult (for verbose=false):\n"
"[ (json array of strings)\n" "[ (json array of strings)\n"
" \"transactionid\" (string) The transaction id of an in-mempool descendant transaction\n" " \"transactionid\" (string) The transaction id of an in-mempool descendant transaction\n"
@ -607,10 +607,10 @@ UniValue getblockhash(const JSONRPCRequest& request)
{ {
if (request.fHelp || request.params.size() != 1) if (request.fHelp || request.params.size() != 1)
throw runtime_error( throw runtime_error(
"getblockhash index\n" "getblockhash height\n"
"\nReturns hash of block in best-block-chain at index provided.\n" "\nReturns hash of block in best-block-chain at height provided.\n"
"\nArguments:\n" "\nArguments:\n"
"1. index (numeric, required) The block index\n" "1. height (numeric, required) The height index\n"
"\nResult:\n" "\nResult:\n"
"\"hash\" (string) The block hash\n" "\"hash\" (string) The block hash\n"
"\nExamples:\n" "\nExamples:\n"
@ -691,12 +691,12 @@ UniValue getblock(const JSONRPCRequest& request)
{ {
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
throw runtime_error( throw runtime_error(
"getblock \"hash\" ( verbose )\n" "getblock \"blockhash\" ( verbose )\n"
"\nIf verbose is false, returns a string that is serialized, hex-encoded data for block 'hash'.\n" "\nIf verbose is false, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
"If verbose is true, returns an Object with information about block <hash>.\n" "If verbose is true, returns an Object with information about block <hash>.\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"hash\" (string, required) The block hash\n" "1. \"blockhash\" (string, required) The block hash\n"
"2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n" "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
"\nResult (for verbose = true):\n" "\nResult (for verbose = true):\n"
"{\n" "{\n"
" \"hash\" : \"hash\", (string) the block hash (same as provided)\n" " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
@ -858,12 +858,12 @@ UniValue gettxout(const JSONRPCRequest& request)
{ {
if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
throw runtime_error( throw runtime_error(
"gettxout \"txid\" n ( includemempool )\n" "gettxout \"txid\" n ( include_mempool )\n"
"\nReturns details about an unspent transaction output.\n" "\nReturns details about an unspent transaction output.\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"txid\" (string, required) The transaction id\n" "1. \"txid\" (string, required) The transaction id\n"
"2. n (numeric, required) vout number\n" "2. n (numeric, required) vout number\n"
"3. includemempool (boolean, optional) Whether to include the mempool\n" "3. include_mempool (boolean, optional) Whether to include the mempool\n"
"\nResult:\n" "\nResult:\n"
"{\n" "{\n"
" \"bestblock\" : \"hash\", (string) the block hash\n" " \"bestblock\" : \"hash\", (string) the block hash\n"
@ -875,7 +875,7 @@ UniValue gettxout(const JSONRPCRequest& request)
" \"reqSigs\" : n, (numeric) Number of required signatures\n" " \"reqSigs\" : n, (numeric) Number of required signatures\n"
" \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n" " \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n"
" \"addresses\" : [ (array of string) array of bitcoin addresses\n" " \"addresses\" : [ (array of string) array of bitcoin addresses\n"
" \"bitcoinaddress\" (string) bitcoin address\n" " \"address\" (string) bitcoin address\n"
" ,...\n" " ,...\n"
" ]\n" " ]\n"
" },\n" " },\n"
@ -940,11 +940,11 @@ UniValue verifychain(const JSONRPCRequest& request)
int nCheckDepth = GetArg("-checkblocks", DEFAULT_CHECKBLOCKS); int nCheckDepth = GetArg("-checkblocks", DEFAULT_CHECKBLOCKS);
if (request.fHelp || request.params.size() > 2) if (request.fHelp || request.params.size() > 2)
throw runtime_error( throw runtime_error(
"verifychain ( checklevel numblocks )\n" "verifychain ( checklevel nblocks )\n"
"\nVerifies blockchain database.\n" "\nVerifies blockchain database.\n"
"\nArguments:\n" "\nArguments:\n"
"1. checklevel (numeric, optional, 0-4, default=" + strprintf("%d", nCheckLevel) + ") How thorough the block verification is.\n" "1. checklevel (numeric, optional, 0-4, default=" + strprintf("%d", nCheckLevel) + ") How thorough the block verification is.\n"
"2. numblocks (numeric, optional, default=" + strprintf("%d", nCheckDepth) + ", 0=all) The number of blocks to check.\n" "2. nblocks (numeric, optional, default=" + strprintf("%d", nCheckDepth) + ", 0=all) The number of blocks to check.\n"
"\nResult:\n" "\nResult:\n"
"true|false (boolean) Verified or not\n" "true|false (boolean) Verified or not\n"
"\nExamples:\n" "\nExamples:\n"
@ -1257,12 +1257,12 @@ UniValue preciousblock(const JSONRPCRequest& request)
{ {
if (request.fHelp || request.params.size() != 1) if (request.fHelp || request.params.size() != 1)
throw runtime_error( throw runtime_error(
"preciousblock \"hash\"\n" "preciousblock \"blockhash\"\n"
"\nTreats a block as if it were received before others with the same work.\n" "\nTreats a block as if it were received before others with the same work.\n"
"\nA later preciousblock call can override the effect of an earlier one.\n" "\nA later preciousblock call can override the effect of an earlier one.\n"
"\nThe effects of preciousblock are not retained across restarts.\n" "\nThe effects of preciousblock are not retained across restarts.\n"
"\nArguments:\n" "\nArguments:\n"
"1. hash (string, required) the hash of the block to mark as precious\n" "1. \"blockhash\" (string, required) the hash of the block to mark as precious\n"
"\nResult:\n" "\nResult:\n"
"\nExamples:\n" "\nExamples:\n"
+ HelpExampleCli("preciousblock", "\"blockhash\"") + HelpExampleCli("preciousblock", "\"blockhash\"")
@ -1295,10 +1295,10 @@ UniValue invalidateblock(const JSONRPCRequest& request)
{ {
if (request.fHelp || request.params.size() != 1) if (request.fHelp || request.params.size() != 1)
throw runtime_error( throw runtime_error(
"invalidateblock \"hash\"\n" "invalidateblock \"blockhash\"\n"
"\nPermanently marks a block as invalid, as if it violated a consensus rule.\n" "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n"
"\nArguments:\n" "\nArguments:\n"
"1. hash (string, required) the hash of the block to mark as invalid\n" "1. \"blockhash\" (string, required) the hash of the block to mark as invalid\n"
"\nResult:\n" "\nResult:\n"
"\nExamples:\n" "\nExamples:\n"
+ HelpExampleCli("invalidateblock", "\"blockhash\"") + HelpExampleCli("invalidateblock", "\"blockhash\"")
@ -1333,11 +1333,11 @@ UniValue reconsiderblock(const JSONRPCRequest& request)
{ {
if (request.fHelp || request.params.size() != 1) if (request.fHelp || request.params.size() != 1)
throw runtime_error( throw runtime_error(
"reconsiderblock \"hash\"\n" "reconsiderblock \"blockhash\"\n"
"\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n" "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n"
"This can be used to undo the effects of invalidateblock.\n" "This can be used to undo the effects of invalidateblock.\n"
"\nArguments:\n" "\nArguments:\n"
"1. hash (string, required) the hash of the block to reconsider\n" "1. \"blockhash\" (string, required) the hash of the block to reconsider\n"
"\nResult:\n" "\nResult:\n"
"\nExamples:\n" "\nExamples:\n"
+ HelpExampleCli("reconsiderblock", "\"blockhash\"") + HelpExampleCli("reconsiderblock", "\"blockhash\"")
@ -1367,33 +1367,33 @@ UniValue reconsiderblock(const JSONRPCRequest& request)
} }
static const CRPCCommand commands[] = static const CRPCCommand commands[] =
{ // category name actor (function) okSafeMode { // category name actor (function) okSafe argNames
// --------------------- ------------------------ ----------------------- ---------- // --------------------- ------------------------ ----------------------- ------ ----------
{ "blockchain", "getblockchaininfo", &getblockchaininfo, true }, { "blockchain", "getblockchaininfo", &getblockchaininfo, true, {} },
{ "blockchain", "getbestblockhash", &getbestblockhash, true }, { "blockchain", "getbestblockhash", &getbestblockhash, true, {} },
{ "blockchain", "getblockcount", &getblockcount, true }, { "blockchain", "getblockcount", &getblockcount, true, {} },
{ "blockchain", "getblock", &getblock, true }, { "blockchain", "getblock", &getblock, true, {"blockhash","verbose"} },
{ "blockchain", "getblockhash", &getblockhash, true }, { "blockchain", "getblockhash", &getblockhash, true, {"height"} },
{ "blockchain", "getblockheader", &getblockheader, true }, { "blockchain", "getblockheader", &getblockheader, true, {"blockhash","verbose"} },
{ "blockchain", "getchaintips", &getchaintips, true }, { "blockchain", "getchaintips", &getchaintips, true, {} },
{ "blockchain", "getdifficulty", &getdifficulty, true }, { "blockchain", "getdifficulty", &getdifficulty, true, {} },
{ "blockchain", "getmempoolancestors", &getmempoolancestors, true }, { "blockchain", "getmempoolancestors", &getmempoolancestors, true, {"txid","verbose"} },
{ "blockchain", "getmempooldescendants", &getmempooldescendants, true }, { "blockchain", "getmempooldescendants", &getmempooldescendants, true, {"txid","verbose"} },
{ "blockchain", "getmempoolentry", &getmempoolentry, true }, { "blockchain", "getmempoolentry", &getmempoolentry, true, {"txid"} },
{ "blockchain", "getmempoolinfo", &getmempoolinfo, true }, { "blockchain", "getmempoolinfo", &getmempoolinfo, true, {} },
{ "blockchain", "getrawmempool", &getrawmempool, true }, { "blockchain", "getrawmempool", &getrawmempool, true, {"verbose"} },
{ "blockchain", "gettxout", &gettxout, true }, { "blockchain", "gettxout", &gettxout, true, {"txid","n","include_mempool"} },
{ "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true }, { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, {} },
{ "blockchain", "verifychain", &verifychain, true }, { "blockchain", "verifychain", &verifychain, true, {"checklevel","nblocks"} },
{ "blockchain", "preciousblock", &preciousblock, true }, { "blockchain", "preciousblock", &preciousblock, true, {"blockhash"} },
/* Not shown in help */ /* Not shown in help */
{ "hidden", "invalidateblock", &invalidateblock, true }, { "hidden", "invalidateblock", &invalidateblock, true, {"blockhash"} },
{ "hidden", "reconsiderblock", &reconsiderblock, true }, { "hidden", "reconsiderblock", &reconsiderblock, true, {"blockhash"} },
{ "hidden", "waitfornewblock", &waitfornewblock, true }, { "hidden", "waitfornewblock", &waitfornewblock, true, {"timeout"} },
{ "hidden", "waitforblock", &waitforblock, true }, { "hidden", "waitforblock", &waitforblock, true, {"blockhash","timeout"} },
{ "hidden", "waitforblockheight", &waitforblockheight, true }, { "hidden", "waitforblockheight", &waitforblockheight, true, {"height","timeout"} },
}; };
void RegisterBlockchainRPCCommands(CRPCTable &t) void RegisterBlockchainRPCCommands(CRPCTable &t)

225
src/rpc/client.cpp

@ -20,104 +20,120 @@ class CRPCConvertParam
public: public:
std::string methodName; //!< method whose params want conversion std::string methodName; //!< method whose params want conversion
int paramIdx; //!< 0-based idx of param to convert int paramIdx; //!< 0-based idx of param to convert
std::string paramName; //!< parameter name
}; };
/**
* Specifiy a (method, idx, name) here if the argument is a non-string RPC
* argument and needs to be converted from JSON.
*
* @note Parameter indexes start from 0.
*/
static const CRPCConvertParam vRPCConvertParams[] = static const CRPCConvertParam vRPCConvertParams[] =
{ {
{ "stop", 0 }, { "setmocktime", 0, "timestamp" },
{ "setmocktime", 0 }, { "generate", 0, "nblocks" },
{ "generate", 0 }, { "generate", 1, "maxtries" },
{ "generate", 1 }, { "generatetoaddress", 0, "nblocks" },
{ "generatetoaddress", 0 }, { "generatetoaddress", 2, "maxtries" },
{ "generatetoaddress", 2 }, { "getnetworkhashps", 0, "nblocks" },
{ "getnetworkhashps", 0 }, { "getnetworkhashps", 1, "height" },
{ "getnetworkhashps", 1 }, { "sendtoaddress", 1, "amount" },
{ "sendtoaddress", 1 }, { "sendtoaddress", 4, "subtractfeefromamount" },
{ "sendtoaddress", 4 }, { "settxfee", 0, "amount" },
{ "settxfee", 0 }, { "getreceivedbyaddress", 1, "minconf" },
{ "getreceivedbyaddress", 1 }, { "getreceivedbyaccount", 1, "minconf" },
{ "getreceivedbyaccount", 1 }, { "listreceivedbyaddress", 0, "minconf" },
{ "listreceivedbyaddress", 0 }, { "listreceivedbyaddress", 1, "include_empty" },
{ "listreceivedbyaddress", 1 }, { "listreceivedbyaddress", 2, "include_watchonly" },
{ "listreceivedbyaddress", 2 }, { "listreceivedbyaccount", 0, "minconf" },
{ "listreceivedbyaccount", 0 }, { "listreceivedbyaccount", 1, "include_empty" },
{ "listreceivedbyaccount", 1 }, { "listreceivedbyaccount", 2, "include_watchonly" },
{ "listreceivedbyaccount", 2 }, { "getbalance", 1, "minconf" },
{ "getbalance", 1 }, { "getbalance", 2, "include_watchonly" },
{ "getbalance", 2 }, { "getblockhash", 0, "height" },
{ "getblockhash", 0 }, { "waitforblockheight", 0, "height" },
{ "waitforblockheight", 0 }, { "waitforblockheight", 1, "timeout" },
{ "waitforblockheight", 1 }, { "waitforblock", 1, "timeout" },
{ "waitforblock", 1 }, { "waitfornewblock", 0, "timeout" },
{ "waitforblock", 2 }, { "move", 2, "amount" },
{ "waitfornewblock", 0 }, { "move", 3, "minconf" },
{ "waitfornewblock", 1 }, { "sendfrom", 2, "amount" },
{ "move", 2 }, { "sendfrom", 3, "minconf" },
{ "move", 3 }, { "listtransactions", 1, "count" },
{ "sendfrom", 2 }, { "listtransactions", 2, "skip" },
{ "sendfrom", 3 }, { "listtransactions", 3, "include_watchonly" },
{ "listtransactions", 1 }, { "listaccounts", 0, "minconf" },
{ "listtransactions", 2 }, { "listaccounts", 1, "include_watchonly" },
{ "listtransactions", 3 }, { "walletpassphrase", 1, "timeout" },
{ "listaccounts", 0 }, { "getblocktemplate", 0, "template_request" },
{ "listaccounts", 1 }, { "listsinceblock", 1, "target_confirmations" },
{ "walletpassphrase", 1 }, { "listsinceblock", 2, "include_watchonly" },
{ "getblocktemplate", 0 }, { "sendmany", 1, "amounts" },
{ "listsinceblock", 1 }, { "sendmany", 2, "minconf" },
{ "listsinceblock", 2 }, { "sendmany", 4, "subtractfeefrom" },
{ "sendmany", 1 }, { "addmultisigaddress", 0, "nrequired" },
{ "sendmany", 2 }, { "addmultisigaddress", 1, "keys" },
{ "sendmany", 4 }, { "createmultisig", 0, "nrequired" },
{ "addmultisigaddress", 0 }, { "createmultisig", 1, "keys" },
{ "addmultisigaddress", 1 }, { "listunspent", 0, "minconf" },
{ "createmultisig", 0 }, { "listunspent", 1, "maxconf" },
{ "createmultisig", 1 }, { "listunspent", 2, "addresses" },
{ "listunspent", 0 }, { "getblock", 1, "verbose" },
{ "listunspent", 1 }, { "getblockheader", 1, "verbose" },
{ "listunspent", 2 }, { "gettransaction", 1, "include_watchonly" },
{ "getblock", 1 }, { "getrawtransaction", 1, "verbose" },
{ "getblockheader", 1 }, { "createrawtransaction", 0, "transactions" },
{ "gettransaction", 1 }, { "createrawtransaction", 1, "outputs" },
{ "getrawtransaction", 1 }, { "createrawtransaction", 2, "locktime" },
{ "createrawtransaction", 0 }, { "signrawtransaction", 1, "prevtxs" },
{ "createrawtransaction", 1 }, { "signrawtransaction", 2, "privkeys" },
{ "createrawtransaction", 2 }, { "sendrawtransaction", 1, "allowhighfees" },
{ "signrawtransaction", 1 }, { "fundrawtransaction", 1, "options" },
{ "signrawtransaction", 2 }, { "gettxout", 1, "n" },
{ "sendrawtransaction", 1 }, { "gettxout", 2, "include_mempool" },
{ "fundrawtransaction", 1 }, { "gettxoutproof", 0, "txids" },
{ "gettxout", 1 }, { "lockunspent", 0, "unlock" },
{ "gettxout", 2 }, { "lockunspent", 1, "transactions" },
{ "gettxoutproof", 0 }, { "importprivkey", 2, "rescan" },
{ "lockunspent", 0 }, { "importaddress", 2, "rescan" },
{ "lockunspent", 1 }, { "importaddress", 3, "p2sh" },
{ "importprivkey", 2 }, { "importpubkey", 2, "rescan" },
{ "importaddress", 2 }, { "importmulti", 0, "requests" },
{ "importaddress", 3 }, { "importmulti", 1, "options" },
{ "importpubkey", 2 }, { "verifychain", 0, "checklevel" },
{ "importmulti", 0 }, { "verifychain", 1, "nblocks" },
{ "importmulti", 1 }, { "keypoolrefill", 0, "newsize" },
{ "verifychain", 0 }, { "getrawmempool", 0, "verbose" },
{ "verifychain", 1 }, { "estimatefee", 0, "nblocks" },
{ "keypoolrefill", 0 }, { "estimatepriority", 0, "nblocks" },
{ "getrawmempool", 0 }, { "estimatesmartfee", 0, "nblocks" },
{ "estimatefee", 0 }, { "estimatesmartpriority", 0, "nblocks" },
{ "estimatepriority", 0 }, { "prioritisetransaction", 1, "priority_delta" },
{ "estimatesmartfee", 0 }, { "prioritisetransaction", 2, "fee_delta" },
{ "estimatesmartpriority", 0 }, { "setban", 2, "bantime" },
{ "prioritisetransaction", 1 }, { "setban", 3, "absolute" },
{ "prioritisetransaction", 2 }, { "setnetworkactive", 0, "state" },
{ "setban", 2 }, { "getmempoolancestors", 1, "verbose" },
{ "setban", 3 }, { "getmempooldescendants", 1, "verbose" },
{ "setnetworkactive", 0 }, // Echo with conversion (For testing only)
{ "getmempoolancestors", 1 }, { "echojson", 0, "arg0" },
{ "getmempooldescendants", 1 }, { "echojson", 1, "arg1" },
{ "echojson", 2, "arg2" },
{ "echojson", 3, "arg3" },
{ "echojson", 4, "arg4" },
{ "echojson", 5, "arg5" },
{ "echojson", 6, "arg6" },
{ "echojson", 7, "arg7" },
{ "echojson", 8, "arg8" },
{ "echojson", 9, "arg9" },
}; };
class CRPCConvertTable class CRPCConvertTable
{ {
private: private:
std::set<std::pair<std::string, int> > members; std::set<std::pair<std::string, int>> members;
std::set<std::pair<std::string, std::string>> membersByName;
public: public:
CRPCConvertTable(); CRPCConvertTable();
@ -125,6 +141,9 @@ public:
bool convert(const std::string& method, int idx) { bool convert(const std::string& method, int idx) {
return (members.count(std::make_pair(method, idx)) > 0); return (members.count(std::make_pair(method, idx)) > 0);
} }
bool convert(const std::string& method, const std::string& name) {
return (membersByName.count(std::make_pair(method, name)) > 0);
}
}; };
CRPCConvertTable::CRPCConvertTable() CRPCConvertTable::CRPCConvertTable()
@ -135,6 +154,8 @@ CRPCConvertTable::CRPCConvertTable()
for (unsigned int i = 0; i < n_elem; i++) { for (unsigned int i = 0; i < n_elem; i++) {
members.insert(std::make_pair(vRPCConvertParams[i].methodName, members.insert(std::make_pair(vRPCConvertParams[i].methodName,
vRPCConvertParams[i].paramIdx)); vRPCConvertParams[i].paramIdx));
membersByName.insert(std::make_pair(vRPCConvertParams[i].methodName,
vRPCConvertParams[i].paramName));
} }
} }
@ -152,7 +173,6 @@ UniValue ParseNonRFCJSONValue(const std::string& strVal)
return jVal[0]; return jVal[0];
} }
/** Convert strings to command-specific RPC representation */
UniValue RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams) UniValue RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams)
{ {
UniValue params(UniValue::VARR); UniValue params(UniValue::VARR);
@ -171,3 +191,28 @@ UniValue RPCConvertValues(const std::string &strMethod, const std::vector<std::s
return params; return params;
} }
UniValue RPCConvertNamedValues(const std::string &strMethod, const std::vector<std::string> &strParams)
{
UniValue params(UniValue::VOBJ);
for (const std::string &s: strParams) {
size_t pos = s.find("=");
if (pos == std::string::npos) {
throw(std::runtime_error("No '=' in named argument '"+s+"', this needs to be present for every argument (even if it is empty)"));
}
std::string name = s.substr(0, pos);
std::string value = s.substr(pos+1);
if (!rpcCvtTable.convert(strMethod, name)) {
// insert string value directly
params.pushKV(name, value);
} else {
// parse string as JSON, insert bool/number/object/etc. value
params.pushKV(name, ParseNonRFCJSONValue(value));
}
}
return params;
}

5
src/rpc/client.h

@ -8,7 +8,12 @@
#include <univalue.h> #include <univalue.h>
/** Convert positional arguments to command-specific RPC representation */
UniValue RPCConvertValues(const std::string& strMethod, const std::vector<std::string>& strParams); UniValue RPCConvertValues(const std::string& strMethod, const std::vector<std::string>& strParams);
/** Convert named arguments to command-specific RPC representation */
UniValue RPCConvertNamedValues(const std::string& strMethod, const std::vector<std::string>& strParams);
/** Non-RFC4627 JSON parser, accepts internal values (such as numbers, true, false, null) /** Non-RFC4627 JSON parser, accepts internal values (such as numbers, true, false, null)
* as well as objects and arrays. * as well as objects and arrays.
*/ */

62
src/rpc/mining.cpp

@ -78,13 +78,13 @@ UniValue getnetworkhashps(const JSONRPCRequest& request)
{ {
if (request.fHelp || request.params.size() > 2) if (request.fHelp || request.params.size() > 2)
throw runtime_error( throw runtime_error(
"getnetworkhashps ( blocks height )\n" "getnetworkhashps ( nblocks height )\n"
"\nReturns the estimated network hashes per second based on the last n blocks.\n" "\nReturns the estimated network hashes per second based on the last n blocks.\n"
"Pass in [blocks] to override # of blocks, -1 specifies since last difficulty change.\n" "Pass in [blocks] to override # of blocks, -1 specifies since last difficulty change.\n"
"Pass in [height] to estimate the network speed at the time when a certain block was found.\n" "Pass in [height] to estimate the network speed at the time when a certain block was found.\n"
"\nArguments:\n" "\nArguments:\n"
"1. blocks (numeric, optional, default=120) The number of blocks, or -1 for blocks since last difficulty change.\n" "1. nblocks (numeric, optional, default=120) The number of blocks, or -1 for blocks since last difficulty change.\n"
"2. height (numeric, optional, default=-1) To estimate at the time of the given height.\n" "2. height (numeric, optional, default=-1) To estimate at the time of the given height.\n"
"\nResult:\n" "\nResult:\n"
"x (numeric) Hashes per second estimated\n" "x (numeric) Hashes per second estimated\n"
"\nExamples:\n" "\nExamples:\n"
@ -150,10 +150,10 @@ UniValue generate(const JSONRPCRequest& request)
{ {
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
throw runtime_error( throw runtime_error(
"generate numblocks ( maxtries )\n" "generate nblocks ( maxtries )\n"
"\nMine up to numblocks blocks immediately (before the RPC call returns)\n" "\nMine up to nblocks blocks immediately (before the RPC call returns)\n"
"\nArguments:\n" "\nArguments:\n"
"1. numblocks (numeric, required) How many blocks are generated immediately.\n" "1. nblocks (numeric, required) How many blocks are generated immediately.\n"
"2. maxtries (numeric, optional) How many iterations to try (default = 1000000).\n" "2. maxtries (numeric, optional) How many iterations to try (default = 1000000).\n"
"\nResult:\n" "\nResult:\n"
"[ blockhashes ] (array) hashes of blocks generated\n" "[ blockhashes ] (array) hashes of blocks generated\n"
@ -186,11 +186,11 @@ UniValue generatetoaddress(const JSONRPCRequest& request)
{ {
if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
throw runtime_error( throw runtime_error(
"generatetoaddress numblocks address (maxtries)\n" "generatetoaddress nblocks address (maxtries)\n"
"\nMine blocks immediately to a specified address (before the RPC call returns)\n" "\nMine blocks immediately to a specified address (before the RPC call returns)\n"
"\nArguments:\n" "\nArguments:\n"
"1. numblocks (numeric, required) How many blocks are generated immediately.\n" "1. nblocks (numeric, required) How many blocks are generated immediately.\n"
"2. address (string, required) The address to send the newly generated bitcoin to.\n" "2. address (string, required) The address to send the newly generated bitcoin to.\n"
"3. maxtries (numeric, optional) How many iterations to try (default = 1000000).\n" "3. maxtries (numeric, optional) How many iterations to try (default = 1000000).\n"
"\nResult:\n" "\nResult:\n"
"[ blockhashes ] (array) hashes of blocks generated\n" "[ blockhashes ] (array) hashes of blocks generated\n"
@ -264,10 +264,10 @@ UniValue prioritisetransaction(const JSONRPCRequest& request)
"Accepts the transaction into mined blocks at a higher (or lower) priority\n" "Accepts the transaction into mined blocks at a higher (or lower) priority\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"txid\" (string, required) The transaction id.\n" "1. \"txid\" (string, required) The transaction id.\n"
"2. priority delta (numeric, required) The priority to add or subtract.\n" "2. priority_delta (numeric, required) The priority to add or subtract.\n"
" The transaction selection algorithm considers the tx as it would have a higher priority.\n" " The transaction selection algorithm considers the tx as it would have a higher priority.\n"
" (priority of a transaction is calculated: coinage * value_in_satoshis / txsize) \n" " (priority of a transaction is calculated: coinage * value_in_satoshis / txsize) \n"
"3. fee delta (numeric, required) The fee value (in satoshis) to add (or subtract, if negative).\n" "3. fee_delta (numeric, required) The fee value (in satoshis) to add (or subtract, if negative).\n"
" The fee is not actually paid, only the algorithm for selecting transactions into a block\n" " The fee is not actually paid, only the algorithm for selecting transactions into a block\n"
" considers the transaction as it would have paid a higher (or lower) fee.\n" " considers the transaction as it would have paid a higher (or lower) fee.\n"
"\nResult:\n" "\nResult:\n"
@ -329,7 +329,7 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
" https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki\n" " https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki\n"
"\nArguments:\n" "\nArguments:\n"
"1. TemplateRequest (json object, optional) A json object in the following spec\n" "1. template_request (json object, optional) A json object in the following spec\n"
" {\n" " {\n"
" \"mode\":\"template\" (string, optional) This must be set to \"template\", \"proposal\" (see BIP 23), or omitted\n" " \"mode\":\"template\" (string, optional) This must be set to \"template\", \"proposal\" (see BIP 23), or omitted\n"
" \"capabilities\":[ (array, optional) A list of strings\n" " \"capabilities\":[ (array, optional) A list of strings\n"
@ -717,9 +717,9 @@ UniValue submitblock(const JSONRPCRequest& request)
"The 'jsonparametersobject' parameter is currently ignored.\n" "The 'jsonparametersobject' parameter is currently ignored.\n"
"See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n" "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n"
"\nArguments:\n" "\nArguments\n"
"1. \"hexdata\" (string, required) the hex-encoded block data to submit\n" "1. \"hexdata\" (string, required) the hex-encoded block data to submit\n"
"2. \"jsonparametersobject\" (string, optional) object of optional parameters\n" "2. \"parameters\" (string, optional) object of optional parameters\n"
" {\n" " {\n"
" \"workid\" : \"id\" (string, optional) if the server provided a workid, it MUST be included with submissions\n" " \"workid\" : \"id\" (string, optional) if the server provided a workid, it MUST be included with submissions\n"
" }\n" " }\n"
@ -782,7 +782,7 @@ UniValue estimatefee(const JSONRPCRequest& request)
"confirmation within nblocks blocks. Uses virtual transaction size of transaction\n" "confirmation within nblocks blocks. Uses virtual transaction size of transaction\n"
"as defined in BIP 141 (witness data is discounted).\n" "as defined in BIP 141 (witness data is discounted).\n"
"\nArguments:\n" "\nArguments:\n"
"1. nblocks (numeric)\n" "1. nblocks (numeric, required)\n"
"\nResult:\n" "\nResult:\n"
"n (numeric) estimated fee-per-kilobyte\n" "n (numeric) estimated fee-per-kilobyte\n"
"\n" "\n"
@ -815,7 +815,7 @@ UniValue estimatepriority(const JSONRPCRequest& request)
"\nDEPRECATED. Estimates the approximate priority a zero-fee transaction needs to begin\n" "\nDEPRECATED. Estimates the approximate priority a zero-fee transaction needs to begin\n"
"confirmation within nblocks blocks.\n" "confirmation within nblocks blocks.\n"
"\nArguments:\n" "\nArguments:\n"
"1. nblocks (numeric)\n" "1. nblocks (numeric, required)\n"
"\nResult:\n" "\nResult:\n"
"n (numeric) estimated priority\n" "n (numeric) estimated priority\n"
"\n" "\n"
@ -881,7 +881,7 @@ UniValue estimatesmartpriority(const JSONRPCRequest& request)
"confirmation within nblocks blocks if possible and return the number of blocks\n" "confirmation within nblocks blocks if possible and return the number of blocks\n"
"for which the estimate is valid.\n" "for which the estimate is valid.\n"
"\nArguments:\n" "\nArguments:\n"
"1. nblocks (numeric)\n" "1. nblocks (numeric, required)\n"
"\nResult:\n" "\nResult:\n"
"{\n" "{\n"
" \"priority\" : x.x, (numeric) estimated priority\n" " \"priority\" : x.x, (numeric) estimated priority\n"
@ -910,19 +910,19 @@ UniValue estimatesmartpriority(const JSONRPCRequest& request)
static const CRPCCommand commands[] = static const CRPCCommand commands[] =
{ // category name actor (function) okSafeMode { // category name actor (function) okSafeMode
// --------------------- ------------------------ ----------------------- ---------- // --------------------- ------------------------ ----------------------- ----------
{ "mining", "getnetworkhashps", &getnetworkhashps, true }, { "mining", "getnetworkhashps", &getnetworkhashps, true, {"nblocks","height"} },
{ "mining", "getmininginfo", &getmininginfo, true }, { "mining", "getmininginfo", &getmininginfo, true, {} },
{ "mining", "prioritisetransaction", &prioritisetransaction, true }, { "mining", "prioritisetransaction", &prioritisetransaction, true, {"txid","priority_delta","fee_delta"} },
{ "mining", "getblocktemplate", &getblocktemplate, true }, { "mining", "getblocktemplate", &getblocktemplate, true, {"template_request"} },
{ "mining", "submitblock", &submitblock, true }, { "mining", "submitblock", &submitblock, true, {"hexdata","parameters"} },
{ "generating", "generate", &generate, true }, { "generating", "generate", &generate, true, {"nblocks","maxtries"} },
{ "generating", "generatetoaddress", &generatetoaddress, true }, { "generating", "generatetoaddress", &generatetoaddress, true, {"nblocks","address","maxtries"} },
{ "util", "estimatefee", &estimatefee, true }, { "util", "estimatefee", &estimatefee, true, {"nblocks"} },
{ "util", "estimatepriority", &estimatepriority, true }, { "util", "estimatepriority", &estimatepriority, true, {"nblocks"} },
{ "util", "estimatesmartfee", &estimatesmartfee, true }, { "util", "estimatesmartfee", &estimatesmartfee, true, {"nblocks"} },
{ "util", "estimatesmartpriority", &estimatesmartpriority, true }, { "util", "estimatesmartpriority", &estimatesmartpriority, true, {"nblocks"} },
}; };
void RegisterMiningRPCCommands(CRPCTable &t) void RegisterMiningRPCCommands(CRPCTable &t)

39
src/rpc/misc.cpp

@ -152,14 +152,14 @@ UniValue validateaddress(const JSONRPCRequest& request)
{ {
if (request.fHelp || request.params.size() != 1) if (request.fHelp || request.params.size() != 1)
throw runtime_error( throw runtime_error(
"validateaddress \"bitcoinaddress\"\n" "validateaddress \"address\"\n"
"\nReturn information about the given bitcoin address.\n" "\nReturn information about the given bitcoin address.\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"bitcoinaddress\" (string, required) The bitcoin address to validate\n" "1. \"address\" (string, required) The bitcoin address to validate\n"
"\nResult:\n" "\nResult:\n"
"{\n" "{\n"
" \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n" " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
" \"address\" : \"bitcoinaddress\", (string) The bitcoin address validated\n" " \"address\" : \"address\", (string) The bitcoin address validated\n"
" \"scriptPubKey\" : \"hex\", (string) The hex encoded scriptPubKey generated by the address\n" " \"scriptPubKey\" : \"hex\", (string) The hex encoded scriptPubKey generated by the address\n"
" \"ismine\" : true|false, (boolean) If the address is yours or not\n" " \"ismine\" : true|false, (boolean) If the address is yours or not\n"
" \"iswatchonly\" : true|false, (boolean) If the address is watchonly\n" " \"iswatchonly\" : true|false, (boolean) If the address is watchonly\n"
@ -325,10 +325,10 @@ UniValue verifymessage(const JSONRPCRequest& request)
{ {
if (request.fHelp || request.params.size() != 3) if (request.fHelp || request.params.size() != 3)
throw runtime_error( throw runtime_error(
"verifymessage \"bitcoinaddress\" \"signature\" \"message\"\n" "verifymessage \"address\" \"signature\" \"message\"\n"
"\nVerify a signed message\n" "\nVerify a signed message\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"bitcoinaddress\" (string, required) The bitcoin address to use for the signature.\n" "1. \"address\" (string, required) The bitcoin address to use for the signature.\n"
"2. \"signature\" (string, required) The signature provided by the signer in base 64 encoding (see signmessage).\n" "2. \"signature\" (string, required) The signature provided by the signer in base 64 encoding (see signmessage).\n"
"3. \"message\" (string, required) The message that was signed.\n" "3. \"message\" (string, required) The message that was signed.\n"
"\nResult:\n" "\nResult:\n"
@ -492,18 +492,33 @@ UniValue getmemoryinfo(const JSONRPCRequest& request)
return obj; return obj;
} }
UniValue echo(const JSONRPCRequest& request)
{
if (request.fHelp)
throw runtime_error(
"echo|echojson \"message\" ...\n"
"\nSimply echo back the input arguments. This command is for testing.\n"
"\nThe difference between echo and echojson is that echojson has argument conversion enabled in the client-side table in"
"bitcoin-cli and the GUI. There is no server-side difference."
);
return request.params;
}
static const CRPCCommand commands[] = static const CRPCCommand commands[] =
{ // category name actor (function) okSafeMode { // category name actor (function) okSafeMode
// --------------------- ------------------------ ----------------------- ---------- // --------------------- ------------------------ ----------------------- ----------
{ "control", "getinfo", &getinfo, true }, /* uses wallet if enabled */ { "control", "getinfo", &getinfo, true, {} }, /* uses wallet if enabled */
{ "control", "getmemoryinfo", &getmemoryinfo, true }, { "control", "getmemoryinfo", &getmemoryinfo, true, {} },
{ "util", "validateaddress", &validateaddress, true }, /* uses wallet if enabled */ { "util", "validateaddress", &validateaddress, true, {"address"} }, /* uses wallet if enabled */
{ "util", "createmultisig", &createmultisig, true }, { "util", "createmultisig", &createmultisig, true, {"nrequired","keys"} },
{ "util", "verifymessage", &verifymessage, true }, { "util", "verifymessage", &verifymessage, true, {"address","signature","message"} },
{ "util", "signmessagewithprivkey", &signmessagewithprivkey, true }, { "util", "signmessagewithprivkey", &signmessagewithprivkey, true, {"privkey","message"} },
/* Not shown in help */ /* Not shown in help */
{ "hidden", "setmocktime", &setmocktime, true }, { "hidden", "setmocktime", &setmocktime, true, {"timestamp"}},
{ "hidden", "echo", &echo, true, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}},
{ "hidden", "echojson", &echo, true, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}},
}; };
void RegisterMiscRPCCommands(CRPCTable &t) void RegisterMiscRPCCommands(CRPCTable &t)

32
src/rpc/net.cpp

@ -470,10 +470,10 @@ UniValue setban(const JSONRPCRequest& request)
if (request.fHelp || request.params.size() < 2 || if (request.fHelp || request.params.size() < 2 ||
(strCommand != "add" && strCommand != "remove")) (strCommand != "add" && strCommand != "remove"))
throw runtime_error( throw runtime_error(
"setban \"ip(/netmask)\" \"add|remove\" (bantime) (absolute)\n" "setban \"subnet\" \"add|remove\" (bantime) (absolute)\n"
"\nAttempts add or remove a IP/Subnet from the banned list.\n" "\nAttempts add or remove a IP/Subnet from the banned list.\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"ip(/netmask)\" (string, required) The IP/Subnet (see getpeerinfo for nodes ip) with a optional netmask (default is /32 = single ip)\n" "1. \"subnet\" (string, required) The IP/Subnet (see getpeerinfo for nodes ip) with a optional netmask (default is /32 = single ip)\n"
"2. \"command\" (string, required) 'add' to add a IP/Subnet to the list, 'remove' to remove a IP/Subnet from the list\n" "2. \"command\" (string, required) 'add' to add a IP/Subnet to the list, 'remove' to remove a IP/Subnet from the list\n"
"3. \"bantime\" (numeric, optional) time in seconds how long (or until when if [absolute] is set) the ip is banned (0 or empty means using the default time of 24h which can also be overwritten by the -bantime startup argument)\n" "3. \"bantime\" (numeric, optional) time in seconds how long (or until when if [absolute] is set) the ip is banned (0 or empty means using the default time of 24h which can also be overwritten by the -bantime startup argument)\n"
"4. \"absolute\" (boolean, optional) If set, the bantime must be a absolute timestamp in seconds since epoch (Jan 1 1970 GMT)\n" "4. \"absolute\" (boolean, optional) If set, the bantime must be a absolute timestamp in seconds since epoch (Jan 1 1970 GMT)\n"
@ -582,7 +582,9 @@ UniValue setnetworkactive(const JSONRPCRequest& request)
if (request.fHelp || request.params.size() != 1) { if (request.fHelp || request.params.size() != 1) {
throw runtime_error( throw runtime_error(
"setnetworkactive true|false\n" "setnetworkactive true|false\n"
"Disable/enable all p2p network activity." "\nDisable/enable all p2p network activity.\n"
"\nArguments:\n"
"1. \"state\" (boolean, required) true to enable networking, false to disable\n"
); );
} }
@ -598,18 +600,18 @@ UniValue setnetworkactive(const JSONRPCRequest& request)
static const CRPCCommand commands[] = static const CRPCCommand commands[] =
{ // category name actor (function) okSafeMode { // category name actor (function) okSafeMode
// --------------------- ------------------------ ----------------------- ---------- // --------------------- ------------------------ ----------------------- ----------
{ "network", "getconnectioncount", &getconnectioncount, true }, { "network", "getconnectioncount", &getconnectioncount, true, {} },
{ "network", "ping", &ping, true }, { "network", "ping", &ping, true, {} },
{ "network", "getpeerinfo", &getpeerinfo, true }, { "network", "getpeerinfo", &getpeerinfo, true, {} },
{ "network", "addnode", &addnode, true }, { "network", "addnode", &addnode, true, {"node","command"} },
{ "network", "disconnectnode", &disconnectnode, true }, { "network", "disconnectnode", &disconnectnode, true, {"node"} },
{ "network", "getaddednodeinfo", &getaddednodeinfo, true }, { "network", "getaddednodeinfo", &getaddednodeinfo, true, {"node"} },
{ "network", "getnettotals", &getnettotals, true }, { "network", "getnettotals", &getnettotals, true, {} },
{ "network", "getnetworkinfo", &getnetworkinfo, true }, { "network", "getnetworkinfo", &getnetworkinfo, true, {} },
{ "network", "setban", &setban, true }, { "network", "setban", &setban, true, {"subnet", "command", "bantime", "absolute"} },
{ "network", "listbanned", &listbanned, true }, { "network", "listbanned", &listbanned, true, {} },
{ "network", "clearbanned", &clearbanned, true }, { "network", "clearbanned", &clearbanned, true, {} },
{ "network", "setnetworkactive", &setnetworkactive, true, }, { "network", "setnetworkactive", &setnetworkactive, true, {"state"} },
}; };
void RegisterNetRPCCommands(CRPCTable &t) void RegisterNetRPCCommands(CRPCTable &t)

50
src/rpc/rawtransaction.cpp

@ -174,7 +174,7 @@ UniValue getrawtransaction(const JSONRPCRequest& request)
" \"reqSigs\" : n, (numeric) The required sigs\n" " \"reqSigs\" : n, (numeric) The required sigs\n"
" \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n" " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
" \"addresses\" : [ (json array of string)\n" " \"addresses\" : [ (json array of string)\n"
" \"bitcoinaddress\" (string) bitcoin address\n" " \"address\" (string) bitcoin address\n"
" ,...\n" " ,...\n"
" ]\n" " ]\n"
" }\n" " }\n"
@ -248,7 +248,7 @@ UniValue gettxoutproof(const JSONRPCRequest& request)
" \"txid\" (string) A transaction hash\n" " \"txid\" (string) A transaction hash\n"
" ,...\n" " ,...\n"
" ]\n" " ]\n"
"2. \"block hash\" (string, optional) If specified, looks for txid in the block with this hash\n" "2. \"blockhash\" (string, optional) If specified, looks for txid in the block with this hash\n"
"\nResult:\n" "\nResult:\n"
"\"data\" (string) A string that is a serialized, hex-encoded data for the proof.\n" "\"data\" (string) A string that is a serialized, hex-encoded data for the proof.\n"
); );
@ -358,24 +358,24 @@ UniValue createrawtransaction(const JSONRPCRequest& request)
"it is not stored in the wallet or transmitted to the network.\n" "it is not stored in the wallet or transmitted to the network.\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"transactions\" (string, required) A json array of json objects\n" "1. \"inputs\" (string, required) A json array of json objects\n"
" [\n" " [\n"
" {\n" " {\n"
" \"txid\":\"id\", (string, required) The transaction id\n" " \"txid\":\"id\", (string, required) The transaction id\n"
" \"vout\":n (numeric, required) The output number\n" " \"vout\":n, (numeric, required) The output number\n"
" \"sequence\":n (numeric, optional) The sequence number\n" " \"sequence\":n (numeric, optional) The sequence number\n"
" }\n" " } \n"
" ,...\n" " ,...\n"
" ]\n" " ]\n"
"2. \"outputs\" (string, required) a json object with outputs\n" "2. \"outputs\" (string, required) a json object with outputs\n"
" {\n" " {\n"
" \"address\": x.xxx (numeric or string, required) The key is the bitcoin address, the numeric value (can be string) is the " + CURRENCY_UNIT + " amount\n" " \"address\": x.xxx, (numeric or string, required) The key is the bitcoin address, the numeric value (can be string) is the " + CURRENCY_UNIT + " amount\n"
" \"data\": \"hex\", (string, required) The key is \"data\", the value is hex encoded data\n" " \"data\": \"hex\" (string, required) The key is \"data\", the value is hex encoded data\n"
" ...\n" " ,...\n"
" }\n" " }\n"
"3. locktime (numeric, optional, default=0) Raw locktime. Non-0 value also locktime-activates inputs\n" "3. locktime (numeric, optional, default=0) Raw locktime. Non-0 value also locktime-activates inputs\n"
"\nResult:\n" "\nResult:\n"
"\"transaction\" (string) hex string of the transaction\n" "\"transaction\" (string) hex string of the transaction\n"
"\nExamples:\n" "\nExamples:\n"
+ HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"address\\\":0.01}\"") + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"address\\\":0.01}\"")
@ -467,7 +467,7 @@ UniValue decoderawtransaction(const JSONRPCRequest& request)
"\nReturn a JSON object representing the serialized, hex-encoded transaction.\n" "\nReturn a JSON object representing the serialized, hex-encoded transaction.\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"hex\" (string, required) The transaction hex string\n" "1. \"hexstring\" (string, required) The transaction hex string\n"
"\nResult:\n" "\nResult:\n"
"{\n" "{\n"
@ -532,10 +532,10 @@ UniValue decodescript(const JSONRPCRequest& request)
{ {
if (request.fHelp || request.params.size() != 1) if (request.fHelp || request.params.size() != 1)
throw runtime_error( throw runtime_error(
"decodescript \"hex\"\n" "decodescript \"hexstring\"\n"
"\nDecode a hex-encoded script.\n" "\nDecode a hex-encoded script.\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"hex\" (string) the hex encoded script\n" "1. \"hexstring\" (string) the hex encoded script\n"
"\nResult:\n" "\nResult:\n"
"{\n" "{\n"
" \"asm\":\"asm\", (string) Script public key\n" " \"asm\":\"asm\", (string) Script public key\n"
@ -616,7 +616,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request)
" }\n" " }\n"
" ,...\n" " ,...\n"
" ]\n" " ]\n"
"3. \"privatekeys\" (string, optional) A json array of base58-encoded private keys for signing\n" "3. \"privkeys\" (string, optional) A json array of base58-encoded private keys for signing\n"
" [ (json array of strings, or 'null' if none provided)\n" " [ (json array of strings, or 'null' if none provided)\n"
" \"privatekey\" (string) private key in base58-encoding\n" " \"privatekey\" (string) private key in base58-encoding\n"
" ,...\n" " ,...\n"
@ -926,15 +926,15 @@ UniValue sendrawtransaction(const JSONRPCRequest& request)
static const CRPCCommand commands[] = static const CRPCCommand commands[] =
{ // category name actor (function) okSafeMode { // category name actor (function) okSafeMode
// --------------------- ------------------------ ----------------------- ---------- // --------------------- ------------------------ ----------------------- ----------
{ "rawtransactions", "getrawtransaction", &getrawtransaction, true }, { "rawtransactions", "getrawtransaction", &getrawtransaction, true, {"txid","verbose"} },
{ "rawtransactions", "createrawtransaction", &createrawtransaction, true }, { "rawtransactions", "createrawtransaction", &createrawtransaction, true, {"transactions","outputs","locktime"} },
{ "rawtransactions", "decoderawtransaction", &decoderawtransaction, true }, { "rawtransactions", "decoderawtransaction", &decoderawtransaction, true, {"hexstring"} },
{ "rawtransactions", "decodescript", &decodescript, true }, { "rawtransactions", "decodescript", &decodescript, true, {"hexstring"} },
{ "rawtransactions", "sendrawtransaction", &sendrawtransaction, false }, { "rawtransactions", "sendrawtransaction", &sendrawtransaction, false, {"hexstring","allowhighfees"} },
{ "rawtransactions", "signrawtransaction", &signrawtransaction, false }, /* uses wallet if enabled */ { "rawtransactions", "signrawtransaction", &signrawtransaction, false, {"hexstring","prevtxs","privkeys","sighashtype"} }, /* uses wallet if enabled */
{ "blockchain", "gettxoutproof", &gettxoutproof, true }, { "blockchain", "gettxoutproof", &gettxoutproof, true, {"txids", "blockhash"} },
{ "blockchain", "verifytxoutproof", &verifytxoutproof, true }, { "blockchain", "verifytxoutproof", &verifytxoutproof, true, {"proof"} },
}; };
void RegisterRawTransactionRPCCommands(CRPCTable &t) void RegisterRawTransactionRPCCommands(CRPCTable &t)

65
src/rpc/server.cpp

@ -26,6 +26,7 @@
#include <boost/algorithm/string/case_conv.hpp> // for to_upper() #include <boost/algorithm/string/case_conv.hpp> // for to_upper()
#include <memory> // for unique_ptr #include <memory> // for unique_ptr
#include <unordered_map>
using namespace RPCServer; using namespace RPCServer;
using namespace std; using namespace std;
@ -268,11 +269,11 @@ UniValue stop(const JSONRPCRequest& jsonRequest)
* Call Table * Call Table
*/ */
static const CRPCCommand vRPCCommands[] = static const CRPCCommand vRPCCommands[] =
{ // category name actor (function) okSafeMode { // category name actor (function) okSafe argNames
// --------------------- ------------------------ ----------------------- ---------- // --------------------- ------------------------ ----------------------- ------ ----------
/* Overall control/query calls */ /* Overall control/query calls */
{ "control", "help", &help, true }, { "control", "help", &help, true, {"command"} },
{ "control", "stop", &stop, true }, { "control", "stop", &stop, true, {} },
}; };
CRPCTable::CRPCTable() CRPCTable::CRPCTable()
@ -379,12 +380,12 @@ void JSONRPCRequest::parse(const UniValue& valRequest)
// Parse params // Parse params
UniValue valParams = find_value(request, "params"); UniValue valParams = find_value(request, "params");
if (valParams.isArray()) if (valParams.isArray() || valParams.isObject())
params = valParams.get_array(); params = valParams;
else if (valParams.isNull()) else if (valParams.isNull())
params = UniValue(UniValue::VARR); params = UniValue(UniValue::VARR);
else else
throw JSONRPCError(RPC_INVALID_REQUEST, "Params must be an array"); throw JSONRPCError(RPC_INVALID_REQUEST, "Params must be an array or object");
} }
static UniValue JSONRPCExecOne(const UniValue& req) static UniValue JSONRPCExecOne(const UniValue& req)
@ -420,6 +421,48 @@ std::string JSONRPCExecBatch(const UniValue& vReq)
return ret.write() + "\n"; return ret.write() + "\n";
} }
/**
* Process named arguments into a vector of positional arguments, based on the
* passed-in specification for the RPC call's arguments.
*/
static inline JSONRPCRequest transformNamedArguments(const JSONRPCRequest& in, const std::vector<std::string>& argNames)
{
JSONRPCRequest out = in;
out.params = UniValue(UniValue::VARR);
// Build a map of parameters, and remove ones that have been processed, so that we can throw a focused error if
// there is an unknown one.
const std::vector<std::string>& keys = in.params.getKeys();
const std::vector<UniValue>& values = in.params.getValues();
std::unordered_map<std::string, const UniValue*> argsIn;
for (size_t i=0; i<keys.size(); ++i) {
argsIn[keys[i]] = &values[i];
}
// Process expected parameters.
int hole = 0;
for (const std::string &argName: argNames) {
auto fr = argsIn.find(argName);
if (fr != argsIn.end()) {
for (int i = 0; i < hole; ++i) {
// Fill hole between specified parameters with JSON nulls,
// but not at the end (for backwards compatibility with calls
// that act based on number of specified parameters).
out.params.push_back(UniValue());
}
hole = 0;
out.params.push_back(*fr->second);
argsIn.erase(fr);
} else {
hole += 1;
}
}
// If there are still arguments in the argsIn map, this is an error.
if (!argsIn.empty()) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Unknown named parameter " + argsIn.begin()->first);
}
// Return request with named arguments transformed to positional arguments
return out;
}
UniValue CRPCTable::execute(const JSONRPCRequest &request) const UniValue CRPCTable::execute(const JSONRPCRequest &request) const
{ {
// Return immediately if in warmup // Return immediately if in warmup
@ -438,8 +481,12 @@ UniValue CRPCTable::execute(const JSONRPCRequest &request) const
try try
{ {
// Execute // Execute, convert arguments to array if necessary
return pcmd->actor(request); if (request.params.isObject()) {
return pcmd->actor(transformNamedArguments(request, pcmd->argNames));
} else {
return pcmd->actor(request);
}
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {

1
src/rpc/server.h

@ -136,6 +136,7 @@ public:
std::string name; std::string name;
rpcfn_type actor; rpcfn_type actor;
bool okSafeMode; bool okSafeMode;
std::vector<std::string> argNames;
}; };
/** /**

14
src/wallet/rpcdump.cpp

@ -82,7 +82,7 @@ UniValue importprivkey(const JSONRPCRequest& request)
if (request.fHelp || request.params.size() < 1 || request.params.size() > 3) if (request.fHelp || request.params.size() < 1 || request.params.size() > 3)
throw runtime_error( throw runtime_error(
"importprivkey \"bitcoinprivkey\" ( \"label\" rescan )\n" "importprivkey \"bitcoinprivkey\" ( \"label\" ) ( rescan )\n"
"\nAdds a private key (as returned by dumpprivkey) to your wallet.\n" "\nAdds a private key (as returned by dumpprivkey) to your wallet.\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"bitcoinprivkey\" (string, required) The private key (see dumpprivkey)\n" "1. \"bitcoinprivkey\" (string, required) The private key (see dumpprivkey)\n"
@ -520,11 +520,11 @@ UniValue dumpprivkey(const JSONRPCRequest& request)
if (request.fHelp || request.params.size() != 1) if (request.fHelp || request.params.size() != 1)
throw runtime_error( throw runtime_error(
"dumpprivkey \"bitcoinaddress\"\n" "dumpprivkey \"address\"\n"
"\nReveals the private key corresponding to 'bitcoinaddress'.\n" "\nReveals the private key corresponding to 'address'.\n"
"Then the importprivkey can be used with this output\n" "Then the importprivkey can be used with this output\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"bitcoinaddress\" (string, required) The bitcoin address for the private key\n" "1. \"address\" (string, required) The bitcoin address for the private key\n"
"\nResult:\n" "\nResult:\n"
"\"key\" (string) The private key\n" "\"key\" (string) The private key\n"
"\nExamples:\n" "\nExamples:\n"
@ -963,10 +963,10 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
// clang-format off // clang-format off
if (mainRequest.fHelp || mainRequest.params.size() < 1 || mainRequest.params.size() > 2) if (mainRequest.fHelp || mainRequest.params.size() < 1 || mainRequest.params.size() > 2)
throw runtime_error( throw runtime_error(
"importmulti '[<json import requests>]' '<json options>' \n\n" "importmulti \"requests\" \"options\"\n\n"
"Import addresses/scripts (with private or public keys, redeem script (P2SH)), rescanning all addresses in one-shot-only (rescan can be disabled via options).\n\n" "Import addresses/scripts (with private or public keys, redeem script (P2SH)), rescanning all addresses in one-shot-only (rescan can be disabled via options).\n\n"
"Arguments:\n" "Arguments:\n"
"1. request array (array, required) Data to be imported\n" "1. requests (array, required) Data to be imported\n"
" [ (array of json objects)\n" " [ (array of json objects)\n"
" {\n" " {\n"
" \"scriptPubKey\": \"<script>\" | { \"address\":\"<address>\" }, (string / json, required) Type of scriptPubKey (string for script, json for address)\n" " \"scriptPubKey\": \"<script>\" | { \"address\":\"<address>\" }, (string / json, required) Type of scriptPubKey (string for script, json for address)\n"
@ -980,7 +980,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
" }\n" " }\n"
" ,...\n" " ,...\n"
" ]\n" " ]\n"
"2. json options (json, optional)\n" "2. options (json, optional)\n"
" {\n" " {\n"
" \"rescan\": <false>, (boolean, optional, default: true) Stating if should rescan the blockchain after all imports\n" " \"rescan\": <false>, (boolean, optional, default: true) Stating if should rescan the blockchain after all imports\n"
" }\n" " }\n"

210
src/wallet/rpcwallet.cpp

@ -116,7 +116,7 @@ UniValue getnewaddress(const JSONRPCRequest& request)
"\nArguments:\n" "\nArguments:\n"
"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" "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"
"\nResult:\n" "\nResult:\n"
"\"bitcoinaddress\" (string) The new bitcoin address\n" "\"address\" (string) The new bitcoin address\n"
"\nExamples:\n" "\nExamples:\n"
+ HelpExampleCli("getnewaddress", "") + HelpExampleCli("getnewaddress", "")
+ HelpExampleRpc("getnewaddress", "") + HelpExampleRpc("getnewaddress", "")
@ -166,7 +166,7 @@ UniValue getaccountaddress(const JSONRPCRequest& request)
"\nArguments:\n" "\nArguments:\n"
"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" "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"
"\nResult:\n" "\nResult:\n"
"\"bitcoinaddress\" (string) The account bitcoin address\n" "\"address\" (string) The account bitcoin address\n"
"\nExamples:\n" "\nExamples:\n"
+ HelpExampleCli("getaccountaddress", "") + HelpExampleCli("getaccountaddress", "")
+ HelpExampleCli("getaccountaddress", "\"\"") + HelpExampleCli("getaccountaddress", "\"\"")
@ -228,10 +228,10 @@ UniValue setaccount(const JSONRPCRequest& request)
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
throw runtime_error( throw runtime_error(
"setaccount \"bitcoinaddress\" \"account\"\n" "setaccount \"address\" \"account\"\n"
"\nDEPRECATED. Sets the account associated with the given address.\n" "\nDEPRECATED. Sets the account associated with the given address.\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"bitcoinaddress\" (string, required) The bitcoin address to be associated with an account.\n" "1. \"address\" (string, required) The bitcoin address to be associated with an account.\n"
"2. \"account\" (string, required) The account to assign the address to.\n" "2. \"account\" (string, required) The account to assign the address to.\n"
"\nExamples:\n" "\nExamples:\n"
+ HelpExampleCli("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"tabby\"") + HelpExampleCli("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"tabby\"")
@ -274,10 +274,10 @@ UniValue getaccount(const JSONRPCRequest& request)
if (request.fHelp || request.params.size() != 1) if (request.fHelp || request.params.size() != 1)
throw runtime_error( throw runtime_error(
"getaccount \"bitcoinaddress\"\n" "getaccount \"address\"\n"
"\nDEPRECATED. Returns the account associated with the given address.\n" "\nDEPRECATED. Returns the account associated with the given address.\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"bitcoinaddress\" (string, required) The bitcoin address for account lookup.\n" "1. \"address\" (string, required) The bitcoin address for account lookup.\n"
"\nResult:\n" "\nResult:\n"
"\"accountname\" (string) the account address\n" "\"accountname\" (string) the account address\n"
"\nExamples:\n" "\nExamples:\n"
@ -309,10 +309,10 @@ UniValue getaddressesbyaccount(const JSONRPCRequest& request)
"getaddressesbyaccount \"account\"\n" "getaddressesbyaccount \"account\"\n"
"\nDEPRECATED. Returns the list of addresses for the given account.\n" "\nDEPRECATED. Returns the list of addresses for the given account.\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"account\" (string, required) The account name.\n" "1. \"account\" (string, required) The account name.\n"
"\nResult:\n" "\nResult:\n"
"[ (json array of string)\n" "[ (json array of string)\n"
" \"bitcoinaddress\" (string) a bitcoin address associated with the given account\n" " \"address\" (string) a bitcoin address associated with the given account\n"
" ,...\n" " ,...\n"
"]\n" "]\n"
"\nExamples:\n" "\nExamples:\n"
@ -380,21 +380,21 @@ UniValue sendtoaddress(const JSONRPCRequest& request)
if (request.fHelp || request.params.size() < 2 || request.params.size() > 5) if (request.fHelp || request.params.size() < 2 || request.params.size() > 5)
throw runtime_error( throw runtime_error(
"sendtoaddress \"bitcoinaddress\" amount ( \"comment\" \"comment-to\" subtractfeefromamount )\n" "sendtoaddress \"address\" amount ( \"comment\" \"comment_to\" subtractfeefromamount )\n"
"\nSend an amount to a given address.\n" "\nSend an amount to a given address.\n"
+ HelpRequiringPassphrase() + + HelpRequiringPassphrase() +
"\nArguments:\n" "\nArguments:\n"
"1. \"bitcoinaddress\" (string, required) The bitcoin address to send to.\n" "1. \"address\" (string, required) The bitcoin address to send to.\n"
"2. \"amount\" (numeric or string, required) The amount in " + CURRENCY_UNIT + " to send. eg 0.1\n" "2. \"amount\" (numeric or string, required) The amount in " + CURRENCY_UNIT + " to send. eg 0.1\n"
"3. \"comment\" (string, optional) A comment used to store what the transaction is for. \n" "3. \"comment\" (string, optional) A comment used to store what the transaction is for. \n"
" This is not part of the transaction, just kept in your wallet.\n" " This is not part of the transaction, just kept in your wallet.\n"
"4. \"comment-to\" (string, optional) A comment to store the name of the person or organization \n" "4. \"comment_to\" (string, optional) A comment to store the name of the person or organization \n"
" to which you're sending the transaction. This is not part of the \n" " to which you're sending the transaction. This is not part of the \n"
" transaction, just kept in your wallet.\n" " transaction, just kept in your wallet.\n"
"5. subtractfeefromamount (boolean, optional, default=false) The fee will be deducted from the amount being sent.\n" "5. subtractfeefromamount (boolean, optional, default=false) The fee will be deducted from the amount being sent.\n"
" The recipient will receive less bitcoins than you enter in the amount field.\n" " The recipient will receive less bitcoins than you enter in the amount field.\n"
"\nResult:\n" "\nResult:\n"
"\"transactionid\" (string) The transaction id.\n" "\"txid\" (string) The transaction id.\n"
"\nExamples:\n" "\nExamples:\n"
+ HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1") + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1")
+ HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"donation\" \"seans outpost\"") + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"donation\" \"seans outpost\"")
@ -446,7 +446,7 @@ UniValue listaddressgroupings(const JSONRPCRequest& request)
"[\n" "[\n"
" [\n" " [\n"
" [\n" " [\n"
" \"bitcoinaddress\", (string) The bitcoin address\n" " \"address\", (string) The bitcoin address\n"
" amount, (numeric) The amount in " + CURRENCY_UNIT + "\n" " amount, (numeric) The amount in " + CURRENCY_UNIT + "\n"
" \"account\" (string, optional) The account (DEPRECATED)\n" " \"account\" (string, optional) The account (DEPRECATED)\n"
" ]\n" " ]\n"
@ -489,11 +489,11 @@ UniValue signmessage(const JSONRPCRequest& request)
if (request.fHelp || request.params.size() != 2) if (request.fHelp || request.params.size() != 2)
throw runtime_error( throw runtime_error(
"signmessage \"bitcoinaddress\" \"message\"\n" "signmessage \"address\" \"message\"\n"
"\nSign a message with the private key of an address" "\nSign a message with the private key of an address"
+ HelpRequiringPassphrase() + "\n" + HelpRequiringPassphrase() + "\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"bitcoinaddress\" (string, required) The bitcoin address to use for the private key.\n" "1. \"address\" (string, required) The bitcoin address to use for the private key.\n"
"2. \"message\" (string, required) The message to create a signature of.\n" "2. \"message\" (string, required) The message to create a signature of.\n"
"\nResult:\n" "\nResult:\n"
"\"signature\" (string) The signature of the message encoded in base 64\n" "\"signature\" (string) The signature of the message encoded in base 64\n"
@ -545,10 +545,10 @@ UniValue getreceivedbyaddress(const JSONRPCRequest& request)
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
throw runtime_error( throw runtime_error(
"getreceivedbyaddress \"bitcoinaddress\" ( minconf )\n" "getreceivedbyaddress \"address\" ( minconf )\n"
"\nReturns the total amount received by the given bitcoinaddress in transactions with at least minconf confirmations.\n" "\nReturns the total amount received by the given address in transactions with at least minconf confirmations.\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"bitcoinaddress\" (string, required) The bitcoin address for transactions.\n" "1. \"address\" (string, required) The bitcoin address for transactions.\n"
"2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n" "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
"\nResult:\n" "\nResult:\n"
"amount (numeric) The total amount in " + CURRENCY_UNIT + " received at this address.\n" "amount (numeric) The total amount in " + CURRENCY_UNIT + " received at this address.\n"
@ -660,7 +660,7 @@ UniValue getbalance(const JSONRPCRequest& request)
if (request.fHelp || request.params.size() > 3) if (request.fHelp || request.params.size() > 3)
throw runtime_error( throw runtime_error(
"getbalance ( \"account\" minconf includeWatchonly )\n" "getbalance ( \"account\" minconf include_watchonly )\n"
"\nIf account is not specified, returns the server's total available balance.\n" "\nIf account is not specified, returns the server's total available balance.\n"
"If account is specified (DEPRECATED), returns the balance in the account.\n" "If account is specified (DEPRECATED), returns the balance in the account.\n"
"Note that the account \"\" is not the same as leaving the parameter out.\n" "Note that the account \"\" is not the same as leaving the parameter out.\n"
@ -668,7 +668,7 @@ UniValue getbalance(const JSONRPCRequest& request)
"\nArguments:\n" "\nArguments:\n"
"1. \"account\" (string, optional) DEPRECATED. The selected account, or \"*\" for entire wallet. It may be the default account using \"\".\n" "1. \"account\" (string, optional) DEPRECATED. The selected account, or \"*\" for entire wallet. It may be the default account using \"\".\n"
"2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n" "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
"3. includeWatchonly (bool, optional, default=false) Also include balance in watchonly addresses (see 'importaddress')\n" "3. include_watchonly (bool, optional, default=false) Also include balance in watchonly addresses (see 'importaddress')\n"
"\nResult:\n" "\nResult:\n"
"amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n" "amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n"
"\nExamples:\n" "\nExamples:\n"
@ -798,21 +798,21 @@ UniValue sendfrom(const JSONRPCRequest& request)
if (request.fHelp || request.params.size() < 3 || request.params.size() > 6) if (request.fHelp || request.params.size() < 3 || request.params.size() > 6)
throw runtime_error( throw runtime_error(
"sendfrom \"fromaccount\" \"tobitcoinaddress\" amount ( minconf \"comment\" \"comment-to\" )\n" "sendfrom \"fromaccount\" \"toaddress\" amount ( minconf \"comment\" \"comment_to\" )\n"
"\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a bitcoin address." "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a bitcoin address."
+ HelpRequiringPassphrase() + "\n" + HelpRequiringPassphrase() + "\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"fromaccount\" (string, required) The name of the account to send funds from. May be the default account using \"\".\n" "1. \"fromaccount\" (string, required) The name of the account to send funds from. May be the default account using \"\".\n"
"2. \"tobitcoinaddress\" (string, required) The bitcoin address to send funds to.\n" "2. \"toaddress\" (string, required) The bitcoin address to send funds to.\n"
"3. amount (numeric or string, required) The amount in " + CURRENCY_UNIT + " (transaction fee is added on top).\n" "3. amount (numeric or string, required) The amount in " + CURRENCY_UNIT + " (transaction fee is added on top).\n"
"4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n" "4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n"
"5. \"comment\" (string, optional) A comment used to store what the transaction is for. \n" "5. \"comment\" (string, optional) A comment used to store what the transaction is for. \n"
" This is not part of the transaction, just kept in your wallet.\n" " This is not part of the transaction, just kept in your wallet.\n"
"6. \"comment-to\" (string, optional) An optional comment to store the name of the person or organization \n" "6. \"comment_to\" (string, optional) An optional comment to store the name of the person or organization \n"
" to which you're sending the transaction. This is not part of the transaction, \n" " to which you're sending the transaction. This is not part of the transaction, \n"
" it is just kept in your wallet.\n" " it is just kept in your wallet.\n"
"\nResult:\n" "\nResult:\n"
"\"transactionid\" (string) The transaction id.\n" "\"txid\" (string) The transaction id.\n"
"\nExamples:\n" "\nExamples:\n"
"\nSend 0.01 " + CURRENCY_UNIT + " from the default account to the address, must have at least 1 confirmation\n" "\nSend 0.01 " + CURRENCY_UNIT + " from the default account to the address, must have at least 1 confirmation\n"
+ HelpExampleCli("sendfrom", "\"\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01") + + HelpExampleCli("sendfrom", "\"\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01") +
@ -874,16 +874,16 @@ UniValue sendmany(const JSONRPCRequest& request)
" }\n" " }\n"
"3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n" "3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n"
"4. \"comment\" (string, optional) A comment\n" "4. \"comment\" (string, optional) A comment\n"
"5. subtractfeefromamount (string, optional) A json array with addresses.\n" "5. subtractfeefrom (array, optional) A json array with addresses.\n"
" The fee will be equally deducted from the amount of each selected address.\n" " The fee will be equally deducted from the amount of each selected address.\n"
" Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n" " Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
" If no addresses are specified here, the sender pays the fee.\n" " If no addresses are specified here, the sender pays the fee.\n"
" [\n" " [\n"
" \"address\" (string) Subtract fee from this address\n" " \"address\" (string) Subtract fee from this address\n"
" ,...\n" " ,...\n"
" ]\n" " ]\n"
"\nResult:\n" "\nResult:\n"
"\"transactionid\" (string) The transaction id for the send. Only 1 transaction is created regardless of \n" "\"txid\" (string) The transaction id for the send. Only 1 transaction is created regardless of \n"
" the number of addresses.\n" " the number of addresses.\n"
"\nExamples:\n" "\nExamples:\n"
"\nSend two amounts to two different addresses:\n" "\nSend two amounts to two different addresses:\n"
@ -989,7 +989,7 @@ UniValue addmultisigaddress(const JSONRPCRequest& request)
"\nArguments:\n" "\nArguments:\n"
"1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n" "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
"2. \"keysobject\" (string, required) A json array of bitcoin addresses or hex-encoded public keys\n" "2. \"keys\" (string, required) A json array of bitcoin addresses or hex-encoded public keys\n"
" [\n" " [\n"
" \"address\" (string) bitcoin address or hex-encoded public key\n" " \"address\" (string) bitcoin address or hex-encoded public key\n"
" ...,\n" " ...,\n"
@ -997,7 +997,7 @@ UniValue addmultisigaddress(const JSONRPCRequest& request)
"3. \"account\" (string, optional) DEPRECATED. An account to assign the addresses to.\n" "3. \"account\" (string, optional) DEPRECATED. An account to assign the addresses to.\n"
"\nResult:\n" "\nResult:\n"
"\"bitcoinaddress\" (string) A bitcoin address associated with the keys.\n" "\"address\" (string) A bitcoin address associated with the keys.\n"
"\nExamples:\n" "\nExamples:\n"
"\nAdd a multisig address from 2 addresses\n" "\nAdd a multisig address from 2 addresses\n"
@ -1253,12 +1253,12 @@ UniValue listreceivedbyaddress(const JSONRPCRequest& request)
if (request.fHelp || request.params.size() > 3) if (request.fHelp || request.params.size() > 3)
throw runtime_error( throw runtime_error(
"listreceivedbyaddress ( minconf includeempty includeWatchonly)\n" "listreceivedbyaddress ( minconf include_empty include_watchonly)\n"
"\nList balances by receiving address.\n" "\nList balances by receiving address.\n"
"\nArguments:\n" "\nArguments:\n"
"1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n" "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
"2. includeempty (bool, optional, default=false) Whether to include addresses that haven't received any payments.\n" "2. include_empty (bool, optional, default=false) Whether to include addresses that haven't received any payments.\n"
"3. includeWatchonly (bool, optional, default=false) Whether to include watchonly addresses (see 'importaddress').\n" "3. include_watchonly (bool, optional, default=false) Whether to include watchonly addresses (see 'importaddress').\n"
"\nResult:\n" "\nResult:\n"
"[\n" "[\n"
@ -1291,12 +1291,12 @@ UniValue listreceivedbyaccount(const JSONRPCRequest& request)
if (request.fHelp || request.params.size() > 3) if (request.fHelp || request.params.size() > 3)
throw runtime_error( throw runtime_error(
"listreceivedbyaccount ( minconf includeempty includeWatchonly)\n" "listreceivedbyaccount ( minconf include_empty include_watchonly)\n"
"\nDEPRECATED. List balances by account.\n" "\nDEPRECATED. List balances by account.\n"
"\nArguments:\n" "\nArguments:\n"
"1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n" "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
"2. includeempty (bool, optional, default=false) Whether to include accounts that haven't received any payments.\n" "2. include_empty (bool, optional, default=false) Whether to include accounts that haven't received any payments.\n"
"3. includeWatchonly (bool, optional, default=false) Whether to include watchonly addresses (see 'importaddress').\n" "3. include_watchonly (bool, optional, default=false) Whether to include watchonly addresses (see 'importaddress').\n"
"\nResult:\n" "\nResult:\n"
"[\n" "[\n"
@ -1427,19 +1427,19 @@ UniValue listtransactions(const JSONRPCRequest& request)
if (request.fHelp || request.params.size() > 4) if (request.fHelp || request.params.size() > 4)
throw runtime_error( throw runtime_error(
"listtransactions ( \"account\" count from includeWatchonly)\n" "listtransactions ( \"account\" count skip include_watchonly)\n"
"\nReturns up to 'count' most recent transactions skipping the first 'from' transactions for account 'account'.\n" "\nReturns up to 'count' most recent transactions skipping the first 'from' transactions for account 'account'.\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"account\" (string, optional) DEPRECATED. The account name. Should be \"*\".\n" "1. \"account\" (string, optional) DEPRECATED. The account name. Should be \"*\".\n"
"2. count (numeric, optional, default=10) The number of transactions to return\n" "2. count (numeric, optional, default=10) The number of transactions to return\n"
"3. from (numeric, optional, default=0) The number of transactions to skip\n" "3. skip (numeric, optional, default=0) The number of transactions to skip\n"
"4. includeWatchonly (bool, optional, default=false) Include transactions to watchonly addresses (see 'importaddress')\n" "4. include_watchonly (bool, optional, default=false) Include transactions to watchonly addresses (see 'importaddress')\n"
"\nResult:\n" "\nResult:\n"
"[\n" "[\n"
" {\n" " {\n"
" \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. \n" " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. \n"
" It will be \"\" for the default account.\n" " It will be \"\" for the default account.\n"
" \"address\":\"bitcoinaddress\", (string) The bitcoin address of the transaction. Not present for \n" " \"address\":\"address\", (string) The bitcoin address of the transaction. Not present for \n"
" move transactions (category = move).\n" " move transactions (category = move).\n"
" \"category\":\"send|receive|move\", (string) The transaction category. 'move' is a local (off blockchain)\n" " \"category\":\"send|receive|move\", (string) The transaction category. 'move' is a local (off blockchain)\n"
" transaction between accounts, and not associated with an address,\n" " transaction between accounts, and not associated with an address,\n"
@ -1554,11 +1554,11 @@ UniValue listaccounts(const JSONRPCRequest& request)
if (request.fHelp || request.params.size() > 2) if (request.fHelp || request.params.size() > 2)
throw runtime_error( throw runtime_error(
"listaccounts ( minconf includeWatchonly)\n" "listaccounts ( minconf include_watchonly)\n"
"\nDEPRECATED. Returns Object that has account names as keys, account balances as values.\n" "\nDEPRECATED. Returns Object that has account names as keys, account balances as values.\n"
"\nArguments:\n" "\nArguments:\n"
"1. minconf (numeric, optional, default=1) Only include transactions with at least this many confirmations\n" "1. minconf (numeric, optional, default=1) Only include transactions with at least this many confirmations\n"
"2. includeWatchonly (bool, optional, default=false) Include balances in watchonly addresses (see 'importaddress')\n" "2. include_watchonly (bool, optional, default=false) Include balances in watchonly addresses (see 'importaddress')\n"
"\nResult:\n" "\nResult:\n"
"{ (json object where keys are account names, and values are numeric balances\n" "{ (json object where keys are account names, and values are numeric balances\n"
" \"account\": x.xxx, (numeric) The property name is the account name, and the value is the total balance for the account.\n" " \"account\": x.xxx, (numeric) The property name is the account name, and the value is the total balance for the account.\n"
@ -1633,17 +1633,17 @@ UniValue listsinceblock(const JSONRPCRequest& request)
if (request.fHelp) if (request.fHelp)
throw runtime_error( throw runtime_error(
"listsinceblock ( \"blockhash\" target-confirmations includeWatchonly)\n" "listsinceblock ( \"blockhash\" target_confirmations include_watchonly)\n"
"\nGet all transactions in blocks since block [blockhash], or all transactions if omitted\n" "\nGet all transactions in blocks since block [blockhash], or all transactions if omitted\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"blockhash\" (string, optional) The block hash to list transactions since\n" "1. \"blockhash\" (string, optional) The block hash to list transactions since\n"
"2. target-confirmations: (numeric, optional) The confirmations required, must be 1 or more\n" "2. target_confirmations: (numeric, optional) The confirmations required, must be 1 or more\n"
"3. includeWatchonly: (bool, optional, default=false) Include transactions to watchonly addresses (see 'importaddress')" "3. include_watchonly: (bool, optional, default=false) Include transactions to watchonly addresses (see 'importaddress')"
"\nResult:\n" "\nResult:\n"
"{\n" "{\n"
" \"transactions\": [\n" " \"transactions\": [\n"
" \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. Will be \"\" for the default account.\n" " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. Will be \"\" for the default account.\n"
" \"address\":\"bitcoinaddress\", (string) The bitcoin address of the transaction. Not present for move transactions (category = move).\n" " \"address\":\"address\", (string) The bitcoin address of the transaction. Not present for move transactions (category = move).\n"
" \"category\":\"send|receive\", (string) The transaction category. 'send' has negative amounts, 'receive' has positive amounts.\n" " \"category\":\"send|receive\", (string) The transaction category. 'send' has negative amounts, 'receive' has positive amounts.\n"
" \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the 'move' category for moves \n" " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the 'move' category for moves \n"
" outbound. It is positive for the 'receive' category, and for the 'move' category for inbound funds.\n" " outbound. It is positive for the 'receive' category, and for the 'move' category for inbound funds.\n"
@ -1726,11 +1726,11 @@ UniValue gettransaction(const JSONRPCRequest& request)
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
throw runtime_error( throw runtime_error(
"gettransaction \"txid\" ( includeWatchonly )\n" "gettransaction \"txid\" ( include_watchonly )\n"
"\nGet detailed information about in-wallet transaction <txid>\n" "\nGet detailed information about in-wallet transaction <txid>\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"txid\" (string, required) The transaction id\n" "1. \"txid\" (string, required) The transaction id\n"
"2. \"includeWatchonly\" (bool, optional, default=false) Whether to include watchonly addresses in balance calculation and details[]\n" "2. \"include_watchonly\" (bool, optional, default=false) Whether to include watchonly addresses in balance calculation and details[]\n"
"\nResult:\n" "\nResult:\n"
"{\n" "{\n"
" \"amount\" : x.xxx, (numeric) The transaction amount in " + CURRENCY_UNIT + "\n" " \"amount\" : x.xxx, (numeric) The transaction amount in " + CURRENCY_UNIT + "\n"
@ -1746,7 +1746,7 @@ UniValue gettransaction(const JSONRPCRequest& request)
" \"details\" : [\n" " \"details\" : [\n"
" {\n" " {\n"
" \"account\" : \"accountname\", (string) DEPRECATED. The account name involved in the transaction, can be \"\" for the default account.\n" " \"account\" : \"accountname\", (string) DEPRECATED. The account name involved in the transaction, can be \"\" for the default account.\n"
" \"address\" : \"bitcoinaddress\", (string) The bitcoin address involved in the transaction\n" " \"address\" : \"address\", (string) The bitcoin address involved in the transaction\n"
" \"category\" : \"send|receive\", (string) The category, either 'send' or 'receive'\n" " \"category\" : \"send|receive\", (string) The category, either 'send' or 'receive'\n"
" \"amount\" : x.xxx, (numeric) The amount in " + CURRENCY_UNIT + "\n" " \"amount\" : x.xxx, (numeric) The amount in " + CURRENCY_UNIT + "\n"
" \"label\" : \"label\", (string) A comment for the address/transaction, if any\n" " \"label\" : \"label\", (string) A comment for the address/transaction, if any\n"
@ -2071,7 +2071,7 @@ UniValue encryptwallet(const JSONRPCRequest& request)
"\nNow set the passphrase to use the wallet, such as for signing or sending bitcoin\n" "\nNow set the passphrase to use the wallet, such as for signing or sending bitcoin\n"
+ HelpExampleCli("walletpassphrase", "\"my pass phrase\"") + + HelpExampleCli("walletpassphrase", "\"my pass phrase\"") +
"\nNow we can so something like sign\n" "\nNow we can so something like sign\n"
+ HelpExampleCli("signmessage", "\"bitcoinaddress\" \"test message\"") + + HelpExampleCli("signmessage", "\"address\" \"test message\"") +
"\nNow lock the wallet again by removing the passphrase\n" "\nNow lock the wallet again by removing the passphrase\n"
+ HelpExampleCli("walletlock", "") + + HelpExampleCli("walletlock", "") +
"\nAs a json rpc call\n" "\nAs a json rpc call\n"
@ -2352,7 +2352,7 @@ UniValue listunspent(const JSONRPCRequest& request)
if (request.fHelp || request.params.size() > 3) if (request.fHelp || request.params.size() > 3)
throw runtime_error( throw runtime_error(
"listunspent ( minconf maxconf [\"address\",...] )\n" "listunspent ( minconf maxconf [\"addresses\",...] )\n"
"\nReturns array of unspent transaction outputs\n" "\nReturns array of unspent transaction outputs\n"
"with between minconf and maxconf (inclusive) confirmations.\n" "with between minconf and maxconf (inclusive) confirmations.\n"
"Optionally filter to only include txouts paid to specified addresses.\n" "Optionally filter to only include txouts paid to specified addresses.\n"
@ -2475,7 +2475,7 @@ UniValue fundrawtransaction(const JSONRPCRequest& request)
"Only pay-to-pubkey, multisig, and P2SH versions thereof are currently supported for watch-only\n" "Only pay-to-pubkey, multisig, and P2SH versions thereof are currently supported for watch-only\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"hexstring\" (string, required) The hex string of the raw transaction\n" "1. \"hexstring\" (string, required) The hex string of the raw transaction\n"
"2. options (object, optional)\n" "2. options (object, optional)\n"
" {\n" " {\n"
" \"changeAddress\" (string, optional, default pool address) The bitcoin address to receive the change\n" " \"changeAddress\" (string, optional, default pool address) The bitcoin address to receive the change\n"
" \"changePosition\" (numeric, optional, default random) The index of the change output\n" " \"changePosition\" (numeric, optional, default random) The index of the change output\n"
@ -2595,53 +2595,53 @@ extern UniValue importmulti(const JSONRPCRequest& request);
static const CRPCCommand commands[] = static const CRPCCommand commands[] =
{ // category name actor (function) okSafeMode { // category name actor (function) okSafeMode
// --------------------- ------------------------ ----------------------- ---------- // --------------------- ------------------------ ----------------------- ----------
{ "rawtransactions", "fundrawtransaction", &fundrawtransaction, false }, { "rawtransactions", "fundrawtransaction", &fundrawtransaction, false, {"hexstring","options"} },
{ "hidden", "resendwallettransactions", &resendwallettransactions, true }, { "hidden", "resendwallettransactions", &resendwallettransactions, true, {} },
{ "wallet", "abandontransaction", &abandontransaction, false }, { "wallet", "abandontransaction", &abandontransaction, false, {"txid"} },
{ "wallet", "addmultisigaddress", &addmultisigaddress, true }, { "wallet", "addmultisigaddress", &addmultisigaddress, true, {"nrequired","keys","account"} },
{ "wallet", "addwitnessaddress", &addwitnessaddress, true }, { "wallet", "addwitnessaddress", &addwitnessaddress, true, {"address"} },
{ "wallet", "backupwallet", &backupwallet, true }, { "wallet", "backupwallet", &backupwallet, true, {"destination"} },
{ "wallet", "dumpprivkey", &dumpprivkey, true }, { "wallet", "dumpprivkey", &dumpprivkey, true, {"address"} },
{ "wallet", "dumpwallet", &dumpwallet, true }, { "wallet", "dumpwallet", &dumpwallet, true, {"filename"} },
{ "wallet", "encryptwallet", &encryptwallet, true }, { "wallet", "encryptwallet", &encryptwallet, true, {"passphrase"} },
{ "wallet", "getaccountaddress", &getaccountaddress, true }, { "wallet", "getaccountaddress", &getaccountaddress, true, {"account"} },
{ "wallet", "getaccount", &getaccount, true }, { "wallet", "getaccount", &getaccount, true, {"address"} },
{ "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true }, { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true, {"account"} },
{ "wallet", "getbalance", &getbalance, false }, { "wallet", "getbalance", &getbalance, false, {"account","minconf","include_watchonly"} },
{ "wallet", "getnewaddress", &getnewaddress, true }, { "wallet", "getnewaddress", &getnewaddress, true, {"account"} },
{ "wallet", "getrawchangeaddress", &getrawchangeaddress, true }, { "wallet", "getrawchangeaddress", &getrawchangeaddress, true, {} },
{ "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false }, { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false, {"account","minconf"} },
{ "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false }, { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false, {"address","minconf"} },
{ "wallet", "gettransaction", &gettransaction, false }, { "wallet", "gettransaction", &gettransaction, false, {"txid","include_watchonly"} },
{ "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false }, { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false, {} },
{ "wallet", "getwalletinfo", &getwalletinfo, false }, { "wallet", "getwalletinfo", &getwalletinfo, false, {} },
{ "wallet", "importmulti", &importmulti, true }, { "wallet", "importmulti", &importmulti, true, {"requests","options"} },
{ "wallet", "importprivkey", &importprivkey, true }, { "wallet", "importprivkey", &importprivkey, true, {"privkey","label","rescan"} },
{ "wallet", "importwallet", &importwallet, true }, { "wallet", "importwallet", &importwallet, true, {"filename"} },
{ "wallet", "importaddress", &importaddress, true }, { "wallet", "importaddress", &importaddress, true, {"address","label","rescan","p2sh"} },
{ "wallet", "importprunedfunds", &importprunedfunds, true }, { "wallet", "importprunedfunds", &importprunedfunds, true, {"rawtransaction","txoutproof"} },
{ "wallet", "importpubkey", &importpubkey, true }, { "wallet", "importpubkey", &importpubkey, true, {"pubkey","label","rescan"} },
{ "wallet", "keypoolrefill", &keypoolrefill, true }, { "wallet", "keypoolrefill", &keypoolrefill, true, {"newsize"} },
{ "wallet", "listaccounts", &listaccounts, false }, { "wallet", "listaccounts", &listaccounts, false, {"minconf","include_watchonly"} },
{ "wallet", "listaddressgroupings", &listaddressgroupings, false }, { "wallet", "listaddressgroupings", &listaddressgroupings, false, {} },
{ "wallet", "listlockunspent", &listlockunspent, false }, { "wallet", "listlockunspent", &listlockunspent, false, {} },
{ "wallet", "listreceivedbyaccount", &listreceivedbyaccount, false }, { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, false, {"minconf","include_empty","include_watchonly"} },
{ "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false }, { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false, {"minconf","include_empty","include_watchonly"} },
{ "wallet", "listsinceblock", &listsinceblock, false }, { "wallet", "listsinceblock", &listsinceblock, false, {"blockhash","target_confirmations","include_watchonly"} },
{ "wallet", "listtransactions", &listtransactions, false }, { "wallet", "listtransactions", &listtransactions, false, {"account","count","skip","include_watchonly"} },
{ "wallet", "listunspent", &listunspent, false }, { "wallet", "listunspent", &listunspent, false, {"minconf","maxconf","addresses"} },
{ "wallet", "lockunspent", &lockunspent, true }, { "wallet", "lockunspent", &lockunspent, true, {"unlock","transactions"} },
{ "wallet", "move", &movecmd, false }, { "wallet", "move", &movecmd, false, {"fromaccount","toaccount","amount","minconf","comment"} },
{ "wallet", "sendfrom", &sendfrom, false }, { "wallet", "sendfrom", &sendfrom, false, {"fromaccount","toaddress","amount","minconf","comment","comment_to"} },
{ "wallet", "sendmany", &sendmany, false }, { "wallet", "sendmany", &sendmany, false, {"fromaccount","amounts","minconf","comment","subtractfeefrom"} },
{ "wallet", "sendtoaddress", &sendtoaddress, false }, { "wallet", "sendtoaddress", &sendtoaddress, false, {"address","amount","comment","comment_to","subtractfeefromamount"} },
{ "wallet", "setaccount", &setaccount, true }, { "wallet", "setaccount", &setaccount, true, {"address","account"} },
{ "wallet", "settxfee", &settxfee, true }, { "wallet", "settxfee", &settxfee, true, {"amount"} },
{ "wallet", "signmessage", &signmessage, true }, { "wallet", "signmessage", &signmessage, true, {"address","message"} },
{ "wallet", "walletlock", &walletlock, true }, { "wallet", "walletlock", &walletlock, true, {} },
{ "wallet", "walletpassphrasechange", &walletpassphrasechange, true }, { "wallet", "walletpassphrasechange", &walletpassphrasechange, true, {"oldpassphrase","newpassphrase"} },
{ "wallet", "walletpassphrase", &walletpassphrase, true }, { "wallet", "walletpassphrase", &walletpassphrase, true, {"passphrase","timeout"} },
{ "wallet", "removeprunedfunds", &removeprunedfunds, true }, { "wallet", "removeprunedfunds", &removeprunedfunds, true, {"txid"} },
}; };
void RegisterWalletRPCCommands(CRPCTable &t) void RegisterWalletRPCCommands(CRPCTable &t)

Loading…
Cancel
Save