15 #include <boost/algorithm/string.hpp>
16 #include <boost/asio.hpp>
17 #include <boost/asio/ssl.hpp>
18 #include <boost/bind.hpp>
19 #include <boost/filesystem.hpp>
20 #include <boost/foreach.hpp>
21 #include <boost/iostreams/concepts.hpp>
22 #include <boost/iostreams/stream.hpp>
23 #include <boost/shared_ptr.hpp>
24 #include "json/json_spirit_writer_template.h"
27 using namespace boost;
31 Object
CallRPC(
const string& strMethod,
const Array& params)
35 _(
"You must set rpcpassword=<password> in the configuration file:\n%s\n"
36 "If the file does not exist, create it with owner-readable-only file permissions."),
41 asio::io_service io_service;
42 ssl::context context(io_service, ssl::context::sslv23);
43 context.set_options(ssl::context::no_sslv2);
44 asio::ssl::stream<asio::ip::tcp::socket> sslStream(io_service, context);
46 iostreams::stream< SSLIOStreamDevice<asio::ip::tcp> > stream(d);
51 if (fConnected)
break;
55 throw runtime_error(
"couldn't connect to server");
60 map<string, string> mapRequestHeaders;
61 mapRequestHeaders[
"Authorization"] = string(
"Basic ") + strUserPass64;
65 string strPost =
HTTPPost(strRequest, mapRequestHeaders);
66 stream << strPost << std::flush;
73 map<string, string> mapHeaders;
78 throw runtime_error(
"incorrect rpcuser or rpcpassword (authorization failed)");
80 throw runtime_error(
strprintf(
"server returned HTTP error %d", nStatus));
81 else if (strReply.empty())
82 throw runtime_error(
"no response from server");
86 if (!read_string(strReply, valReply))
87 throw runtime_error(
"couldn't parse reply from server");
88 const Object& reply = valReply.get_obj();
90 throw runtime_error(
"expected reply to have result, error and id properties");
98 if (fAllowNull && value.type() == null_type)
100 if (value.type() == str_type)
104 string strJSON = value.get_str();
105 if (!read_string(strJSON, value2))
106 throw runtime_error(
string(
"Error parsing JSON:")+strJSON);
107 ConvertTo<T>(value2, fAllowNull);
112 value = value.get_value<T>();
117 Array
RPCConvertValues(
const std::string &strMethod,
const std::vector<std::string> &strParams)
120 BOOST_FOREACH(
const std::string ¶m, strParams)
121 params.push_back(param);
123 int n = params.size();
128 if (strMethod ==
"stop" && n > 0) ConvertTo<bool>(params[0]);
129 if (strMethod ==
"getaddednodeinfo" && n > 0) ConvertTo<bool>(params[0]);
130 if (strMethod ==
"setgenerate" && n > 0) ConvertTo<bool>(params[0]);
131 if (strMethod ==
"setgenerate" && n > 1) ConvertTo<int64_t>(params[1]);
132 if (strMethod ==
"getnetworkhashps" && n > 0) ConvertTo<int64_t>(params[0]);
133 if (strMethod ==
"getnetworkhashps" && n > 1) ConvertTo<int64_t>(params[1]);
134 if (strMethod ==
"sendtoaddress" && n > 1) ConvertTo<double>(params[1]);
135 if (strMethod ==
"settxfee" && n > 0) ConvertTo<double>(params[0]);
136 if (strMethod ==
"getreceivedbyaddress" && n > 1) ConvertTo<int64_t>(params[1]);
137 if (strMethod ==
"getreceivedbyaccount" && n > 1) ConvertTo<int64_t>(params[1]);
138 if (strMethod ==
"listreceivedbyaddress" && n > 0) ConvertTo<int64_t>(params[0]);
139 if (strMethod ==
"listreceivedbyaddress" && n > 1) ConvertTo<bool>(params[1]);
140 if (strMethod ==
"listreceivedbyaccount" && n > 0) ConvertTo<int64_t>(params[0]);
141 if (strMethod ==
"listreceivedbyaccount" && n > 1) ConvertTo<bool>(params[1]);
142 if (strMethod ==
"getbalance" && n > 1) ConvertTo<int64_t>(params[1]);
143 if (strMethod ==
"getblockhash" && n > 0) ConvertTo<int64_t>(params[0]);
144 if (strMethod ==
"move" && n > 2) ConvertTo<double>(params[2]);
145 if (strMethod ==
"move" && n > 3) ConvertTo<int64_t>(params[3]);
146 if (strMethod ==
"sendfrom" && n > 2) ConvertTo<double>(params[2]);
147 if (strMethod ==
"sendfrom" && n > 3) ConvertTo<int64_t>(params[3]);
148 if (strMethod ==
"listtransactions" && n > 1) ConvertTo<int64_t>(params[1]);
149 if (strMethod ==
"listtransactions" && n > 2) ConvertTo<int64_t>(params[2]);
150 if (strMethod ==
"listaccounts" && n > 0) ConvertTo<int64_t>(params[0]);
151 if (strMethod ==
"walletpassphrase" && n > 1) ConvertTo<int64_t>(params[1]);
152 if (strMethod ==
"getblocktemplate" && n > 0) ConvertTo<Object>(params[0]);
153 if (strMethod ==
"listsinceblock" && n > 1) ConvertTo<int64_t>(params[1]);
154 if (strMethod ==
"sendmany" && n > 1) ConvertTo<Object>(params[1]);
155 if (strMethod ==
"sendmany" && n > 2) ConvertTo<int64_t>(params[2]);
156 if (strMethod ==
"addmultisigaddress" && n > 0) ConvertTo<int64_t>(params[0]);
157 if (strMethod ==
"addmultisigaddress" && n > 1) ConvertTo<Array>(params[1]);
158 if (strMethod ==
"createmultisig" && n > 0) ConvertTo<int64_t>(params[0]);
159 if (strMethod ==
"createmultisig" && n > 1) ConvertTo<Array>(params[1]);
160 if (strMethod ==
"listunspent" && n > 0) ConvertTo<int64_t>(params[0]);
161 if (strMethod ==
"listunspent" && n > 1) ConvertTo<int64_t>(params[1]);
162 if (strMethod ==
"listunspent" && n > 2) ConvertTo<Array>(params[2]);
163 if (strMethod ==
"getblock" && n > 1) ConvertTo<bool>(params[1]);
164 if (strMethod ==
"getrawtransaction" && n > 1) ConvertTo<int64_t>(params[1]);
165 if (strMethod ==
"createrawtransaction" && n > 0) ConvertTo<Array>(params[0]);
166 if (strMethod ==
"createrawtransaction" && n > 1) ConvertTo<Object>(params[1]);
167 if (strMethod ==
"signrawtransaction" && n > 1) ConvertTo<Array>(params[1],
true);
168 if (strMethod ==
"signrawtransaction" && n > 2) ConvertTo<Array>(params[2],
true);
169 if (strMethod ==
"sendrawtransaction" && n > 1) ConvertTo<bool>(params[1],
true);
170 if (strMethod ==
"gettxout" && n > 1) ConvertTo<int64_t>(params[1]);
171 if (strMethod ==
"gettxout" && n > 2) ConvertTo<bool>(params[2]);
172 if (strMethod ==
"lockunspent" && n > 0) ConvertTo<bool>(params[0]);
173 if (strMethod ==
"lockunspent" && n > 1) ConvertTo<Array>(params[1]);
174 if (strMethod ==
"importprivkey" && n > 2) ConvertTo<bool>(params[2]);
175 if (strMethod ==
"verifychain" && n > 0) ConvertTo<int64_t>(params[0]);
176 if (strMethod ==
"verifychain" && n > 1) ConvertTo<int64_t>(params[1]);
177 if (strMethod ==
"keypoolrefill" && n > 0) ConvertTo<int64_t>(params[0]);
178 if (strMethod ==
"getrawmempool" && n > 0) ConvertTo<bool>(params[0]);
181 if (strMethod ==
"getcrowdsale_MP" && n > 0) ConvertTo<int64_t>(params[0]);
182 if (strMethod ==
"getcrowdsale_MP" && n > 1) ConvertTo<bool>(params[1]);
183 if (strMethod ==
"getgrants_MP" && n > 0) ConvertTo<int64_t>(params[0]);
184 if (strMethod ==
"send_MP" && n > 2) ConvertTo<int64_t>(params[2]);
185 if (strMethod ==
"getbalance_MP" && n > 1) ConvertTo<int64_t>(params[1]);
186 if (strMethod ==
"sendtoowners_MP" && n > 1) ConvertTo<int64_t>(params[1]);
187 if (strMethod ==
"getproperty_MP" && n > 0) ConvertTo<int64_t>(params[0]);
188 if (strMethod ==
"listtransactions_MP" && n > 1) ConvertTo<int64_t>(params[1]);
189 if (strMethod ==
"listtransactions_MP" && n > 2) ConvertTo<int64_t>(params[2]);
190 if (strMethod ==
"listtransactions_MP" && n > 3) ConvertTo<int64_t>(params[3]);
191 if (strMethod ==
"listtransactions_MP" && n > 4) ConvertTo<int64_t>(params[4]);
192 if (strMethod ==
"getallbalancesforid_MP" && n > 0) ConvertTo<int64_t>(params[0]);
193 if (strMethod ==
"listblocktransactions_MP" && n > 0) ConvertTo<int64_t>(params[0]);
195 if (strMethod ==
"trade_MP" && n > 2) ConvertTo<int64_t>(params[2]);
196 if (strMethod ==
"trade_MP" && n > 4) ConvertTo<int64_t>(params[4]);
197 if (strMethod ==
"trade_MP" && n > 5) ConvertTo<int64_t>(params[5]);
198 if (strMethod ==
"getorderbook_MP" && n > 0) ConvertTo<int64_t>(params[0]);
199 if (strMethod ==
"getorderbook_MP" && n > 1) ConvertTo<int64_t>(params[1]);
200 if (strMethod ==
"gettradessince_MP" && n > 0) ConvertTo<int64_t>(params[0]);
201 if (strMethod ==
"gettradessince_MP" && n > 1) ConvertTo<int64_t>(params[1]);
202 if (strMethod ==
"gettradessince_MP" && n > 2) ConvertTo<int64_t>(params[2]);
203 if (strMethod ==
"gettradehistory_MP" && n > 1) ConvertTo<int64_t>(params[1]);
204 if (strMethod ==
"gettradehistory_MP" && n > 2) ConvertTo<int64_t>(params[2]);
225 throw runtime_error(
"too few parameters");
226 string strMethod = argv[1];
229 std::vector<std::string> strParams(&argv[2], &argv[argc]);
233 Object reply =
CallRPC(strMethod, params);
236 const Value& result = find_value(reply,
"result");
237 const Value&
error = find_value(reply,
"error");
239 if (error.type() != null_type)
242 strPrint =
"error: " + write_string(error,
false);
243 int code = find_value(error.get_obj(),
"code").get_int();
249 if (result.type() == null_type)
251 else if (result.type() == str_type)
252 strPrint = result.get_str();
254 strPrint = write_string(result,
true);
257 catch (boost::thread_interrupted) {
260 catch (std::exception& e) {
261 strPrint = string(
"error: ") + e.what();
271 fprintf((nRet == 0 ? stdout : stderr),
"%s\n", strPrint.c_str());
281 strUsage +=
_(
"Options:") +
"\n";
282 strUsage +=
" -? " +
_(
"This help message") +
"\n";
283 strUsage +=
" -conf=<file> " +
_(
"Specify configuration file (default: bitcoin.conf)") +
"\n";
284 strUsage +=
" -datadir=<dir> " +
_(
"Specify data directory") +
"\n";
285 strUsage +=
" -testnet " +
_(
"Use the test network") +
"\n";
286 strUsage +=
" -regtest " +
_(
"Enter regression test mode, which uses a special chain in which blocks can be "
287 "solved instantly. This is intended for regression testing tools and app development.") +
"\n";
289 strUsage +=
_(
"RPC client options:") +
"\n";
292 strUsage +=
" -rpcconnect=<ip> " +
_(
"Send commands to node running on <ip> (default: 127.0.0.1)") +
"\n";
293 strUsage +=
" -rpcport=<port> " +
_(
"Connect to JSON-RPC on <port> (default: 8332 or testnet: 18332)") +
"\n";
294 strUsage +=
" -rpcwait " +
_(
"Wait for RPC server to start") +
"\n";
298 strUsage +=
" -rpcuser=<user> " +
_(
"Username for JSON-RPC connections") +
"\n";
299 strUsage +=
" -rpcpassword=<pw> " +
_(
"Password for JSON-RPC connections") +
"\n";
301 strUsage +=
"\n" +
_(
"SSL options: (see the Bitcoin Wiki for SSL setup instructions)") +
"\n";
302 strUsage +=
" -rpcssl " +
_(
"Use OpenSSL (https) for JSON-RPC connections") +
"\n";
int ReadHTTPStatus(std::basic_istream< char > &stream, int &proto)
std::string HelpMessageCli(bool mainProgram)
Show help message for bitcoin-cli.
void MilliSleep(int64_t n)
void ConvertTo(Value &value, bool fAllowNull=false)
Object CallRPC(const string &strMethod, const Array ¶ms)
string EncodeBase64(const unsigned char *pch, size_t len)
bool GetBoolArg(const std::string &strArg, bool fDefault)
Return boolean argument or default value.
int ReadHTTPMessage(std::basic_istream< char > &stream, map< string, string > &mapHeadersRet, string &strMessageRet, int nProto)
std::string itostr(int n)
static bool error(const char *format)
void PrintExceptionContinue(std::exception *pex, const char *pszThread)
int CommandLineRPC(int argc, char *argv[])
bool IsSwitchChar(char c)
const CChainParams & Params()
Return the currently selected parameters.
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a boost::optional result...
string HTTPPost(const string &strMsg, const map< string, string > &mapRequestHeaders)
std::string GetArg(const std::string &strArg, const std::string &strDefault)
Return string argument or default value.
string JSONRPCRequest(const string &strMethod, const Array ¶ms, const Value &id)
bool connect(const std::string &server, const std::string &port)
Array RPCConvertValues(const std::string &strMethod, const std::vector< std::string > &strParams)
map< string, string > mapArgs
boost::filesystem::path GetConfigFile()