Auto merge of #2052 - str4d:2032-z_importkey-partial-rescan, r=bitcartel
[VerusCoin.git] / src / rpcmisc.cpp
CommitLineData
652e1569 1// Copyright (c) 2010 Satoshi Nakamoto
f914f1a7 2// Copyright (c) 2009-2014 The Bitcoin Core developers
72fb3d29 3// Distributed under the MIT software license, see the accompanying
652e1569
WL
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6#include "base58.h"
71697f97 7#include "clientversion.h"
652e1569
WL
8#include "init.h"
9#include "main.h"
10#include "net.h"
11#include "netbase.h"
c037531d 12#include "rpcserver.h"
14f888ca 13#include "timedata.h"
652e1569
WL
14#include "util.h"
15#ifdef ENABLE_WALLET
50c72f23
JS
16#include "wallet/wallet.h"
17#include "wallet/walletdb.h"
652e1569
WL
18#endif
19
20#include <stdint.h>
21
22#include <boost/assign/list_of.hpp>
a10a6e2a
JS
23
24#include <univalue.h>
652e1569 25
4e16a724
S
26#include "zcash/Address.hpp"
27
40a158e1 28using namespace std;
652e1569 29
f9de17ec
WL
30/**
31 * @note Do not add or change anything in the information returned by this
72fb3d29 32 * method. `getinfo` exists for backwards-compatibility only. It combines
f9de17ec
WL
33 * information from wildly different sources in the program, which is a mess,
34 * and is thus planned to be deprecated eventually.
35 *
36 * Based on the source of the information, new information should be added to:
37 * - `getblockchaininfo`,
38 * - `getnetworkinfo` or
39 * - `getwalletinfo`
40 *
41 * Or alternatively, create a specific query method for the information.
42 **/
d014114d 43UniValue getinfo(const UniValue& params, bool fHelp)
16bc9aaf
WL
44{
45 if (fHelp || params.size() != 0)
46 throw runtime_error(
47 "getinfo\n"
48 "Returns an object containing various state info.\n"
49 "\nResult:\n"
50 "{\n"
51 " \"version\": xxxxx, (numeric) the server version\n"
52 " \"protocolversion\": xxxxx, (numeric) the protocol version\n"
53 " \"walletversion\": xxxxx, (numeric) the wallet version\n"
54 " \"balance\": xxxxxxx, (numeric) the total bitcoin balance of the wallet\n"
55 " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
56 " \"timeoffset\": xxxxx, (numeric) the time offset\n"
57 " \"connections\": xxxxx, (numeric) the number of connections\n"
58 " \"proxy\": \"host:port\", (string, optional) the proxy used by the server\n"
59 " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
60 " \"testnet\": true|false, (boolean) if the server is using testnet or not\n"
61 " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n"
62 " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n"
16bc9aaf 63 " \"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"
1294cdc4
GM
64 " \"paytxfee\": x.xxxx, (numeric) the transaction fee set in btc/kb\n"
65 " \"relayfee\": x.xxxx, (numeric) minimum relay fee for non-free transactions in btc/kb\n"
16bc9aaf
WL
66 " \"errors\": \"...\" (string) any error messages\n"
67 "}\n"
68 "\nExamples:\n"
69 + HelpExampleCli("getinfo", "")
70 + HelpExampleRpc("getinfo", "")
71 );
72
4401b2d7
EL
73#ifdef ENABLE_WALLET
74 LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
75#else
76 LOCK(cs_main);
77#endif
78
16bc9aaf
WL
79 proxyType proxy;
80 GetProxy(NET_IPV4, proxy);
81
38fc4b70 82 UniValue obj(UniValue::VOBJ);
faadbe17
PK
83 obj.push_back(Pair("version", CLIENT_VERSION));
84 obj.push_back(Pair("protocolversion", PROTOCOL_VERSION));
16bc9aaf
WL
85#ifdef ENABLE_WALLET
86 if (pwalletMain) {
87 obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
88 obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
89 }
90#endif
91 obj.push_back(Pair("blocks", (int)chainActive.Height()));
d56e30ca 92 obj.push_back(Pair("timeoffset", GetTimeOffset()));
16bc9aaf 93 obj.push_back(Pair("connections", (int)vNodes.size()));
67a79493 94 obj.push_back(Pair("proxy", (proxy.IsValid() ? proxy.proxy.ToStringIPPort() : string())));
16bc9aaf 95 obj.push_back(Pair("difficulty", (double)GetDifficulty()));
cc972107 96 obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC()));
16bc9aaf
WL
97#ifdef ENABLE_WALLET
98 if (pwalletMain) {
d56e30ca 99 obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime()));
16bc9aaf
WL
100 obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
101 }
16bc9aaf 102 if (pwalletMain && pwalletMain->IsCrypted())
d56e30ca 103 obj.push_back(Pair("unlocked_until", nWalletUnlockTime));
c6cb21d1 104 obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())));
16bc9aaf 105#endif
13fc83c7 106 obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())));
16bc9aaf
WL
107 obj.push_back(Pair("errors", GetWarnings("statusbar")));
108 return obj;
109}
110
452955f5 111#ifdef ENABLE_WALLET
d014114d 112class DescribeAddressVisitor : public boost::static_visitor<UniValue>
452955f5
WL
113{
114public:
d014114d 115 UniValue operator()(const CNoDestination &dest) const { return UniValue(UniValue::VOBJ); }
452955f5 116
851f58f9 117 UniValue operator()(const CKeyID &keyID) const {
38fc4b70 118 UniValue obj(UniValue::VOBJ);
452955f5 119 CPubKey vchPubKey;
452955f5 120 obj.push_back(Pair("isscript", false));
56215c77 121 if (pwalletMain && pwalletMain->GetPubKey(keyID, vchPubKey)) {
c8988460
PW
122 obj.push_back(Pair("pubkey", HexStr(vchPubKey)));
123 obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed()));
124 }
452955f5
WL
125 return obj;
126 }
127
851f58f9 128 UniValue operator()(const CScriptID &scriptID) const {
38fc4b70 129 UniValue obj(UniValue::VOBJ);
9c7167d1 130 CScript subscript;
452955f5 131 obj.push_back(Pair("isscript", true));
56215c77 132 if (pwalletMain && pwalletMain->GetCScript(scriptID, subscript)) {
c8988460
PW
133 std::vector<CTxDestination> addresses;
134 txnouttype whichType;
135 int nRequired;
136 ExtractDestinations(subscript, whichType, addresses, nRequired);
137 obj.push_back(Pair("script", GetTxnOutputType(whichType)));
138 obj.push_back(Pair("hex", HexStr(subscript.begin(), subscript.end())));
38fc4b70 139 UniValue a(UniValue::VARR);
c8988460
PW
140 BOOST_FOREACH(const CTxDestination& addr, addresses)
141 a.push_back(CBitcoinAddress(addr).ToString());
142 obj.push_back(Pair("addresses", a));
143 if (whichType == TX_MULTISIG)
144 obj.push_back(Pair("sigsrequired", nRequired));
145 }
452955f5
WL
146 return obj;
147 }
148};
149#endif
150
d014114d 151UniValue validateaddress(const UniValue& params, bool fHelp)
452955f5
WL
152{
153 if (fHelp || params.size() != 1)
154 throw runtime_error(
155 "validateaddress \"bitcoinaddress\"\n"
156 "\nReturn information about the given bitcoin address.\n"
157 "\nArguments:\n"
158 "1. \"bitcoinaddress\" (string, required) The bitcoin address to validate\n"
159 "\nResult:\n"
160 "{\n"
161 " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
162 " \"address\" : \"bitcoinaddress\", (string) The bitcoin address validated\n"
426a74ed 163 " \"scriptPubKey\" : \"hex\", (string) The hex encoded scriptPubKey generated by the address\n"
452955f5
WL
164 " \"ismine\" : true|false, (boolean) If the address is yours or not\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"
7b782f5b 168 " \"account\" : \"account\" (string) DEPRECATED. The account associated with the address, \"\" is the default account\n"
452955f5
WL
169 "}\n"
170 "\nExamples:\n"
171 + HelpExampleCli("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
172 + HelpExampleRpc("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
173 );
174
4401b2d7
EL
175#ifdef ENABLE_WALLET
176 LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
177#else
178 LOCK(cs_main);
179#endif
180
452955f5
WL
181 CBitcoinAddress address(params[0].get_str());
182 bool isValid = address.IsValid();
183
38fc4b70 184 UniValue ret(UniValue::VOBJ);
452955f5
WL
185 ret.push_back(Pair("isvalid", isValid));
186 if (isValid)
187 {
188 CTxDestination dest = address.Get();
189 string currentAddress = address.ToString();
190 ret.push_back(Pair("address", currentAddress));
426a74ed
PT
191
192 CScript scriptPubKey = GetScriptForDestination(dest);
193 ret.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
194
452955f5 195#ifdef ENABLE_WALLET
a3e192a3
J
196 isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO;
197 ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false));
9c7167d1 198 ret.push_back(Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true: false));
199 UniValue detail = boost::apply_visitor(DescribeAddressVisitor(), dest);
200 ret.pushKVs(detail);
452955f5
WL
201 if (pwalletMain && pwalletMain->mapAddressBook.count(dest))
202 ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name));
203#endif
204 }
205 return ret;
206}
207
4e16a724 208
0d37ae3a 209UniValue z_validateaddress(const UniValue& params, bool fHelp)
4e16a724
S
210{
211 if (fHelp || params.size() != 1)
212 throw runtime_error(
213 "z_validateaddress \"zaddr\"\n"
214 "\nReturn information about the given z address.\n"
215 "\nArguments:\n"
216 "1. \"zaddr\" (string, required) The z address to validate\n"
217 "\nResult:\n"
218 "{\n"
219 " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
220 " \"address\" : \"zaddr\", (string) The z address validated\n"
221 " \"ismine\" : true|false, (boolean) If the address is yours or not\n"
222 " \"payingkey\" : \"hex\", (string) The hex value of the paying key, a_pk\n"
223 " \"transmissionkey\" : \"hex\", (string) The hex value of the transmission key, pk_enc\n"
224
225 "}\n"
226 "\nExamples:\n"
227 + HelpExampleCli("validateaddress", "\"zcWsmqT4X2V4jgxbgiCzyrAfRT1vi1F4sn7M5Pkh66izzw8Uk7LBGAH3DtcSMJeUb2pi3W4SQF8LMKkU2cUuVP68yAGcomL\"")
228 );
229
230
231#ifdef ENABLE_WALLET
232 LOCK2(cs_main, pwalletMain->cs_wallet);
233#else
234 LOCK(cs_main);
235#endif
236
237 bool isValid = false;
238 bool isMine = false;
239 std::string payingKey, transmissionKey;
240
241 string strAddress = params[0].get_str();
242 try {
243 CZCPaymentAddress address(strAddress);
244 libzcash::PaymentAddress addr = address.Get();
245
246#ifdef ENABLE_WALLET
247 isMine = pwalletMain->HaveSpendingKey(addr);
248#endif
249 payingKey = addr.a_pk.GetHex();
250 transmissionKey = addr.pk_enc.GetHex();
251 isValid = true;
252 } catch (std::runtime_error e) {
253 // address is invalid, nop here as isValid is false.
254 }
255
0d37ae3a 256 UniValue ret(UniValue::VOBJ);
4e16a724
S
257 ret.push_back(Pair("isvalid", isValid));
258 if (isValid)
259 {
260 ret.push_back(Pair("address", strAddress));
261 ret.push_back(Pair("payingkey", payingKey));
262 ret.push_back(Pair("transmissionkey", transmissionKey));
263#ifdef ENABLE_WALLET
264 ret.push_back(Pair("ismine", isMine));
265#endif
266 }
267 return ret;
268}
269
270
72fb3d29
MF
271/**
272 * Used by addmultisigaddress / createmultisig:
273 */
d014114d 274CScript _createmultisig_redeemScript(const UniValue& params)
723a03d2
WL
275{
276 int nRequired = params[0].get_int();
d014114d 277 const UniValue& keys = params[1].get_array();
723a03d2
WL
278
279 // Gather public keys
280 if (nRequired < 1)
281 throw runtime_error("a multisignature address must require at least one key to redeem");
282 if ((int)keys.size() < nRequired)
283 throw runtime_error(
284 strprintf("not enough keys supplied "
783b182c 285 "(got %u keys, but need at least %d to redeem)", keys.size(), nRequired));
e5d9d77d 286 if (keys.size() > 16)
287 throw runtime_error("Number of addresses involved in the multisignature address creation > 16\nReduce the number");
723a03d2
WL
288 std::vector<CPubKey> pubkeys;
289 pubkeys.resize(keys.size());
290 for (unsigned int i = 0; i < keys.size(); i++)
291 {
292 const std::string& ks = keys[i].get_str();
293#ifdef ENABLE_WALLET
294 // Case 1: Bitcoin address and we have full public key:
295 CBitcoinAddress address(ks);
296 if (pwalletMain && address.IsValid())
297 {
298 CKeyID keyID;
299 if (!address.GetKeyID(keyID))
300 throw runtime_error(
7d9d134b 301 strprintf("%s does not refer to a key",ks));
723a03d2
WL
302 CPubKey vchPubKey;
303 if (!pwalletMain->GetPubKey(keyID, vchPubKey))
304 throw runtime_error(
7d9d134b 305 strprintf("no full public key for address %s",ks));
723a03d2
WL
306 if (!vchPubKey.IsFullyValid())
307 throw runtime_error(" Invalid public key: "+ks);
308 pubkeys[i] = vchPubKey;
309 }
310
311 // Case 2: hex public key
312 else
313#endif
314 if (IsHex(ks))
315 {
316 CPubKey vchPubKey(ParseHex(ks));
317 if (!vchPubKey.IsFullyValid())
318 throw runtime_error(" Invalid public key: "+ks);
319 pubkeys[i] = vchPubKey;
320 }
321 else
322 {
323 throw runtime_error(" Invalid public key: "+ks);
324 }
325 }
0be990ba 326 CScript result = GetScriptForMultisig(nRequired, pubkeys);
787ee0c9
PT
327
328 if (result.size() > MAX_SCRIPT_ELEMENT_SIZE)
329 throw runtime_error(
330 strprintf("redeemScript exceeds size limit: %d > %d", result.size(), MAX_SCRIPT_ELEMENT_SIZE));
331
723a03d2
WL
332 return result;
333}
334
d014114d 335UniValue createmultisig(const UniValue& params, bool fHelp)
723a03d2
WL
336{
337 if (fHelp || params.size() < 2 || params.size() > 2)
338 {
339 string msg = "createmultisig nrequired [\"key\",...]\n"
340 "\nCreates a multi-signature address with n signature of m keys required.\n"
341 "It returns a json object with the address and redeemScript.\n"
342
343 "\nArguments:\n"
344 "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
345 "2. \"keys\" (string, required) A json array of keys which are bitcoin addresses or hex-encoded public keys\n"
346 " [\n"
347 " \"key\" (string) bitcoin address or hex-encoded public key\n"
348 " ,...\n"
349 " ]\n"
350
351 "\nResult:\n"
352 "{\n"
353 " \"address\":\"multisigaddress\", (string) The value of the new multisig address.\n"
354 " \"redeemScript\":\"script\" (string) The string value of the hex-encoded redemption script.\n"
355 "}\n"
356
357 "\nExamples:\n"
358 "\nCreate a multisig address from 2 addresses\n"
359 + HelpExampleCli("createmultisig", "2 \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") +
360 "\nAs a json rpc call\n"
e3e3728f 361 + HelpExampleRpc("createmultisig", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"")
723a03d2
WL
362 ;
363 throw runtime_error(msg);
364 }
365
366 // Construct using pay-to-script-hash:
787ee0c9 367 CScript inner = _createmultisig_redeemScript(params);
066e2a14 368 CScriptID innerID(inner);
723a03d2
WL
369 CBitcoinAddress address(innerID);
370
b47f3aea 371 UniValue result(UniValue::VOBJ);
723a03d2
WL
372 result.push_back(Pair("address", address.ToString()));
373 result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end())));
374
375 return result;
376}
377
d014114d 378UniValue verifymessage(const UniValue& params, bool fHelp)
c3a7f516
WL
379{
380 if (fHelp || params.size() != 3)
381 throw runtime_error(
382 "verifymessage \"bitcoinaddress\" \"signature\" \"message\"\n"
383 "\nVerify a signed message\n"
384 "\nArguments:\n"
385 "1. \"bitcoinaddress\" (string, required) The bitcoin address to use for the signature.\n"
386 "2. \"signature\" (string, required) The signature provided by the signer in base 64 encoding (see signmessage).\n"
387 "3. \"message\" (string, required) The message that was signed.\n"
388 "\nResult:\n"
389 "true|false (boolean) If the signature is verified or not.\n"
390 "\nExamples:\n"
391 "\nUnlock the wallet for 30 seconds\n"
392 + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
393 "\nCreate the signature\n"
394 + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"my message\"") +
395 "\nVerify the signature\n"
396 + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") +
397 "\nAs json rpc\n"
398 + HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"signature\", \"my message\"")
399 );
400
4401b2d7
EL
401 LOCK(cs_main);
402
c3a7f516
WL
403 string strAddress = params[0].get_str();
404 string strSign = params[1].get_str();
405 string strMessage = params[2].get_str();
406
407 CBitcoinAddress addr(strAddress);
408 if (!addr.IsValid())
409 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
410
411 CKeyID keyID;
412 if (!addr.GetKeyID(keyID))
413 throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
414
415 bool fInvalid = false;
416 vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);
417
418 if (fInvalid)
419 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding");
420
421 CHashWriter ss(SER_GETHASH, 0);
422 ss << strMessageMagic;
423 ss << strMessage;
424
425 CPubKey pubkey;
426 if (!pubkey.RecoverCompact(ss.GetHash(), vchSig))
427 return false;
428
429 return (pubkey.GetID() == keyID);
430}
a8b2ce55 431
d014114d 432UniValue setmocktime(const UniValue& params, bool fHelp)
a8b2ce55
GA
433{
434 if (fHelp || params.size() != 1)
435 throw runtime_error(
436 "setmocktime timestamp\n"
437 "\nSet the local time to given timestamp (-regtest only)\n"
438 "\nArguments:\n"
439 "1. timestamp (integer, required) Unix seconds-since-epoch timestamp\n"
440 " Pass 0 to go back to using the system time."
441 );
442
443 if (!Params().MineBlocksOnDemand())
444 throw runtime_error("setmocktime for regression testing (-regtest mode) only");
445
abb0e8cc
GA
446 // cs_vNodes is locked and node send/receive times are updated
447 // atomically with the time change to prevent peers from being
448 // disconnected because we think we haven't communicated with them
449 // in a long time.
450 LOCK2(cs_main, cs_vNodes);
4401b2d7 451
9756b7bd 452 RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM));
a8b2ce55
GA
453 SetMockTime(params[0].get_int64());
454
abb0e8cc
GA
455 uint64_t t = GetTime();
456 BOOST_FOREACH(CNode* pnode, vNodes) {
457 pnode->nLastSend = pnode->nLastRecv = t;
458 }
459
9756b7bd 460 return NullUniValue;
a8b2ce55 461}
This page took 0.254857 seconds and 4 git commands to generate.