1
// Copyright (c) 2010 Satoshi Nakamoto
2
// Copyright (c) 2009-2015 The Bitcoin Core developers
3
// Distributed under the MIT software license, see the accompanying
4
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
7
#include "clientversion.h"
12
#include "rpcserver.h"
15
#include "utilstrencodings.h"
17
#include "wallet/wallet.h"
18
#include "wallet/walletdb.h"
23
#include <boost/assign/list_of.hpp>
30
* @note Do not add or change anything in the information returned by this
31
* method. `getinfo` exists for backwards-compatibility only. It combines
32
* information from wildly different sources in the program, which is a mess,
33
* and is thus planned to be deprecated eventually.
35
* Based on the source of the information, new information should be added to:
36
* - `getblockchaininfo`,
37
* - `getnetworkinfo` or
40
* Or alternatively, create a specific query method for the information.
42
UniValue getinfo(const UniValue& params, bool fHelp)
44
if (fHelp || params.size() != 0)
47
"Returns an object containing various state info.\n"
50
" \"version\": xxxxx, (numeric) the server version\n"
51
" \"protocolversion\": xxxxx, (numeric) the protocol version\n"
52
" \"walletversion\": xxxxx, (numeric) the wallet version\n"
53
" \"balance\": xxxxxxx, (numeric) the total bitcoin balance of the wallet\n"
54
" \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
55
" \"timeoffset\": xxxxx, (numeric) the time offset\n"
56
" \"connections\": xxxxx, (numeric) the number of connections\n"
57
" \"proxy\": \"host:port\", (string, optional) the proxy used by the server\n"
58
" \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
59
" \"testnet\": true|false, (boolean) if the server is using testnet or not\n"
60
" \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n"
61
" \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n"
62
" \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n"
63
" \"paytxfee\": x.xxxx, (numeric) the transaction fee set in " + CURRENCY_UNIT + "/kB\n"
64
" \"relayfee\": x.xxxx, (numeric) minimum relay fee for non-free transactions in " + CURRENCY_UNIT + "/kB\n"
65
" \"errors\": \"...\" (string) any error messages\n"
68
+ HelpExampleCli("getinfo", "")
69
+ HelpExampleRpc("getinfo", "")
73
LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
79
GetProxy(NET_IPV4, proxy);
81
UniValue obj(UniValue::VOBJ);
82
obj.push_back(Pair("version", CLIENT_VERSION));
83
obj.push_back(Pair("protocolversion", PROTOCOL_VERSION));
86
obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
87
obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
90
obj.push_back(Pair("blocks", (int)chainActive.Height()));
91
obj.push_back(Pair("timeoffset", GetTimeOffset()));
92
obj.push_back(Pair("connections", (int)vNodes.size()));
93
obj.push_back(Pair("proxy", (proxy.IsValid() ? proxy.proxy.ToStringIPPort() : string())));
94
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
95
obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC()));
98
obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime()));
99
obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
101
if (pwalletMain && pwalletMain->IsCrypted())
102
obj.push_back(Pair("unlocked_until", nWalletUnlockTime));
103
obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())));
105
obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())));
106
obj.push_back(Pair("errors", GetWarnings("statusbar")));
111
class DescribeAddressVisitor : public boost::static_visitor<UniValue>
114
UniValue operator()(const CNoDestination &dest) const { return UniValue(UniValue::VOBJ); }
116
UniValue operator()(const CKeyID &keyID) const {
117
UniValue obj(UniValue::VOBJ);
119
obj.push_back(Pair("isscript", false));
120
if (pwalletMain && pwalletMain->GetPubKey(keyID, vchPubKey)) {
121
obj.push_back(Pair("pubkey", HexStr(vchPubKey)));
122
obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed()));
127
UniValue operator()(const CScriptID &scriptID) const {
128
UniValue obj(UniValue::VOBJ);
130
obj.push_back(Pair("isscript", true));
131
if (pwalletMain && pwalletMain->GetCScript(scriptID, subscript)) {
132
std::vector<CTxDestination> addresses;
133
txnouttype whichType;
135
ExtractDestinations(subscript, whichType, addresses, nRequired);
136
obj.push_back(Pair("script", GetTxnOutputType(whichType)));
137
obj.push_back(Pair("hex", HexStr(subscript.begin(), subscript.end())));
138
UniValue a(UniValue::VARR);
139
BOOST_FOREACH(const CTxDestination& addr, addresses)
140
a.push_back(CBitcoinAddress(addr).ToString());
141
obj.push_back(Pair("addresses", a));
142
if (whichType == TX_MULTISIG)
143
obj.push_back(Pair("sigsrequired", nRequired));
150
UniValue validateaddress(const UniValue& params, bool fHelp)
152
if (fHelp || params.size() != 1)
154
"validateaddress \"bitcoinaddress\"\n"
155
"\nReturn information about the given bitcoin address.\n"
157
"1. \"bitcoinaddress\" (string, required) The bitcoin address to validate\n"
160
" \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
161
" \"address\" : \"bitcoinaddress\", (string) The bitcoin address validated\n"
162
" \"scriptPubKey\" : \"hex\", (string) The hex encoded scriptPubKey generated by the address\n"
163
" \"ismine\" : true|false, (boolean) If the address is yours or not\n"
164
" \"iswatchonly\" : true|false, (boolean) If the address is watchonly\n"
165
" \"isscript\" : true|false, (boolean) If the key is a script\n"
166
" \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n"
167
" \"iscompressed\" : true|false, (boolean) If the address is compressed\n"
168
" \"account\" : \"account\" (string) DEPRECATED. The account associated with the address, \"\" is the default account\n"
171
+ HelpExampleCli("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
172
+ HelpExampleRpc("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
176
LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
181
CBitcoinAddress address(params[0].get_str());
182
bool isValid = address.IsValid();
184
UniValue ret(UniValue::VOBJ);
185
ret.push_back(Pair("isvalid", isValid));
188
CTxDestination dest = address.Get();
189
string currentAddress = address.ToString();
190
ret.push_back(Pair("address", currentAddress));
192
CScript scriptPubKey = GetScriptForDestination(dest);
193
ret.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
196
isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO;
197
ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false));
198
ret.push_back(Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true: false));
199
UniValue detail = boost::apply_visitor(DescribeAddressVisitor(), dest);
201
if (pwalletMain && pwalletMain->mapAddressBook.count(dest))
202
ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name));
209
* Used by addmultisigaddress / createmultisig:
211
CScript _createmultisig_redeemScript(const UniValue& params)
213
int nRequired = params[0].get_int();
214
const UniValue& keys = params[1].get_array();
216
// Gather public keys
218
throw runtime_error("a multisignature address must require at least one key to redeem");
219
if ((int)keys.size() < nRequired)
221
strprintf("not enough keys supplied "
222
"(got %u keys, but need at least %d to redeem)", keys.size(), nRequired));
223
if (keys.size() > 16)
224
throw runtime_error("Number of addresses involved in the multisignature address creation > 16\nReduce the number");
225
std::vector<CPubKey> pubkeys;
226
pubkeys.resize(keys.size());
227
for (unsigned int i = 0; i < keys.size(); i++)
229
const std::string& ks = keys[i].get_str();
231
// Case 1: Bitcoin address and we have full public key:
232
CBitcoinAddress address(ks);
233
if (pwalletMain && address.IsValid())
236
if (!address.GetKeyID(keyID))
238
strprintf("%s does not refer to a key",ks));
240
if (!pwalletMain->GetPubKey(keyID, vchPubKey))
242
strprintf("no full public key for address %s",ks));
243
if (!vchPubKey.IsFullyValid())
244
throw runtime_error(" Invalid public key: "+ks);
245
pubkeys[i] = vchPubKey;
248
// Case 2: hex public key
253
CPubKey vchPubKey(ParseHex(ks));
254
if (!vchPubKey.IsFullyValid())
255
throw runtime_error(" Invalid public key: "+ks);
256
pubkeys[i] = vchPubKey;
260
throw runtime_error(" Invalid public key: "+ks);
263
CScript result = GetScriptForMultisig(nRequired, pubkeys);
265
if (result.size() > MAX_SCRIPT_ELEMENT_SIZE)
267
strprintf("redeemScript exceeds size limit: %d > %d", result.size(), MAX_SCRIPT_ELEMENT_SIZE));
272
UniValue createmultisig(const UniValue& params, bool fHelp)
274
if (fHelp || params.size() < 2 || params.size() > 2)
276
string msg = "createmultisig nrequired [\"key\",...]\n"
277
"\nCreates a multi-signature address with n signature of m keys required.\n"
278
"It returns a json object with the address and redeemScript.\n"
281
"1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
282
"2. \"keys\" (string, required) A json array of keys which are bitcoin addresses or hex-encoded public keys\n"
284
" \"key\" (string) bitcoin address or hex-encoded public key\n"
290
" \"address\":\"multisigaddress\", (string) The value of the new multisig address.\n"
291
" \"redeemScript\":\"script\" (string) The string value of the hex-encoded redemption script.\n"
295
"\nCreate a multisig address from 2 addresses\n"
296
+ HelpExampleCli("createmultisig", "2 \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") +
297
"\nAs a json rpc call\n"
298
+ HelpExampleRpc("createmultisig", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"")
300
throw runtime_error(msg);
303
// Construct using pay-to-script-hash:
304
CScript inner = _createmultisig_redeemScript(params);
305
CScriptID innerID(inner);
306
CBitcoinAddress address(innerID);
308
UniValue result(UniValue::VOBJ);
309
result.push_back(Pair("address", address.ToString()));
310
result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end())));
315
UniValue verifymessage(const UniValue& params, bool fHelp)
317
if (fHelp || params.size() != 3)
319
"verifymessage \"bitcoinaddress\" \"signature\" \"message\"\n"
320
"\nVerify a signed message\n"
322
"1. \"bitcoinaddress\" (string, required) The bitcoin address to use for the signature.\n"
323
"2. \"signature\" (string, required) The signature provided by the signer in base 64 encoding (see signmessage).\n"
324
"3. \"message\" (string, required) The message that was signed.\n"
326
"true|false (boolean) If the signature is verified or not.\n"
328
"\nUnlock the wallet for 30 seconds\n"
329
+ HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
330
"\nCreate the signature\n"
331
+ HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"my message\"") +
332
"\nVerify the signature\n"
333
+ HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") +
335
+ HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"signature\", \"my message\"")
340
string strAddress = params[0].get_str();
341
string strSign = params[1].get_str();
342
string strMessage = params[2].get_str();
344
CBitcoinAddress addr(strAddress);
346
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
349
if (!addr.GetKeyID(keyID))
350
throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
352
bool fInvalid = false;
353
vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);
356
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding");
358
CHashWriter ss(SER_GETHASH, 0);
359
ss << strMessageMagic;
363
if (!pubkey.RecoverCompact(ss.GetHash(), vchSig))
366
return (pubkey.GetID() == keyID);
369
UniValue setmocktime(const UniValue& params, bool fHelp)
371
if (fHelp || params.size() != 1)
373
"setmocktime timestamp\n"
374
"\nSet the local time to given timestamp (-regtest only)\n"
376
"1. timestamp (integer, required) Unix seconds-since-epoch timestamp\n"
377
" Pass 0 to go back to using the system time."
380
if (!Params().MineBlocksOnDemand())
381
throw runtime_error("setmocktime for regression testing (-regtest mode) only");
383
// cs_vNodes is locked and node send/receive times are updated
384
// atomically with the time change to prevent peers from being
385
// disconnected because we think we haven't communicated with them
387
LOCK2(cs_main, cs_vNodes);
389
RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM));
390
SetMockTime(params[0].get_int64());
392
uint64_t t = GetTime();
393
BOOST_FOREACH(CNode* pnode, vNodes) {
394
pnode->nLastSend = pnode->nLastRecv = t;