]> Git Repo - VerusCoin.git/blame - src/rpcmisc.cpp
Auto merge of #2138 - daira:2137.compactsize-portability.0, r=arcalinea
[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 113{
c8988460
PW
114private:
115 isminetype mine;
116
452955f5 117public:
c8988460
PW
118 DescribeAddressVisitor(isminetype mineIn) : mine(mineIn) {}
119
d014114d 120 UniValue operator()(const CNoDestination &dest) const { return UniValue(UniValue::VOBJ); }
452955f5 121
851f58f9 122 UniValue operator()(const CKeyID &keyID) const {
38fc4b70 123 UniValue obj(UniValue::VOBJ);
452955f5 124 CPubKey vchPubKey;
452955f5 125 obj.push_back(Pair("isscript", false));
a3e192a3 126 if (mine == ISMINE_SPENDABLE) {
c8988460
PW
127 pwalletMain->GetPubKey(keyID, vchPubKey);
128 obj.push_back(Pair("pubkey", HexStr(vchPubKey)));
129 obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed()));
130 }
452955f5
WL
131 return obj;
132 }
133
851f58f9 134 UniValue operator()(const CScriptID &scriptID) const {
38fc4b70 135 UniValue obj(UniValue::VOBJ);
452955f5 136 obj.push_back(Pair("isscript", true));
a3e192a3 137 if (mine != ISMINE_NO) {
c8988460
PW
138 CScript subscript;
139 pwalletMain->GetCScript(scriptID, subscript);
140 std::vector<CTxDestination> addresses;
141 txnouttype whichType;
142 int nRequired;
143 ExtractDestinations(subscript, whichType, addresses, nRequired);
144 obj.push_back(Pair("script", GetTxnOutputType(whichType)));
145 obj.push_back(Pair("hex", HexStr(subscript.begin(), subscript.end())));
38fc4b70 146 UniValue a(UniValue::VARR);
c8988460
PW
147 BOOST_FOREACH(const CTxDestination& addr, addresses)
148 a.push_back(CBitcoinAddress(addr).ToString());
149 obj.push_back(Pair("addresses", a));
150 if (whichType == TX_MULTISIG)
151 obj.push_back(Pair("sigsrequired", nRequired));
152 }
452955f5
WL
153 return obj;
154 }
155};
156#endif
157
d014114d 158UniValue validateaddress(const UniValue& params, bool fHelp)
452955f5
WL
159{
160 if (fHelp || params.size() != 1)
161 throw runtime_error(
162 "validateaddress \"bitcoinaddress\"\n"
163 "\nReturn information about the given bitcoin address.\n"
164 "\nArguments:\n"
165 "1. \"bitcoinaddress\" (string, required) The bitcoin address to validate\n"
166 "\nResult:\n"
167 "{\n"
168 " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
169 " \"address\" : \"bitcoinaddress\", (string) The bitcoin address validated\n"
426a74ed 170 " \"scriptPubKey\" : \"hex\", (string) The hex encoded scriptPubKey generated by the address\n"
452955f5
WL
171 " \"ismine\" : true|false, (boolean) If the address is yours or not\n"
172 " \"isscript\" : true|false, (boolean) If the key is a script\n"
173 " \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n"
174 " \"iscompressed\" : true|false, (boolean) If the address is compressed\n"
7b782f5b 175 " \"account\" : \"account\" (string) DEPRECATED. The account associated with the address, \"\" is the default account\n"
452955f5
WL
176 "}\n"
177 "\nExamples:\n"
178 + HelpExampleCli("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
179 + HelpExampleRpc("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
180 );
181
4401b2d7
EL
182#ifdef ENABLE_WALLET
183 LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
184#else
185 LOCK(cs_main);
186#endif
187
452955f5
WL
188 CBitcoinAddress address(params[0].get_str());
189 bool isValid = address.IsValid();
190
38fc4b70 191 UniValue ret(UniValue::VOBJ);
452955f5
WL
192 ret.push_back(Pair("isvalid", isValid));
193 if (isValid)
194 {
195 CTxDestination dest = address.Get();
196 string currentAddress = address.ToString();
197 ret.push_back(Pair("address", currentAddress));
426a74ed
PT
198
199 CScript scriptPubKey = GetScriptForDestination(dest);
200 ret.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
201
452955f5 202#ifdef ENABLE_WALLET
a3e192a3
J
203 isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO;
204 ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false));
205 if (mine != ISMINE_NO) {
206 ret.push_back(Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true: false));
851f58f9 207 UniValue detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest);
ed21d5bd 208 ret.pushKVs(detail);
452955f5
WL
209 }
210 if (pwalletMain && pwalletMain->mapAddressBook.count(dest))
211 ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name));
212#endif
213 }
214 return ret;
215}
216
4e16a724 217
0d37ae3a 218UniValue z_validateaddress(const UniValue& params, bool fHelp)
4e16a724
S
219{
220 if (fHelp || params.size() != 1)
221 throw runtime_error(
222 "z_validateaddress \"zaddr\"\n"
223 "\nReturn information about the given z address.\n"
224 "\nArguments:\n"
225 "1. \"zaddr\" (string, required) The z address to validate\n"
226 "\nResult:\n"
227 "{\n"
228 " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
229 " \"address\" : \"zaddr\", (string) The z address validated\n"
230 " \"ismine\" : true|false, (boolean) If the address is yours or not\n"
231 " \"payingkey\" : \"hex\", (string) The hex value of the paying key, a_pk\n"
232 " \"transmissionkey\" : \"hex\", (string) The hex value of the transmission key, pk_enc\n"
233
234 "}\n"
235 "\nExamples:\n"
236 + HelpExampleCli("validateaddress", "\"zcWsmqT4X2V4jgxbgiCzyrAfRT1vi1F4sn7M5Pkh66izzw8Uk7LBGAH3DtcSMJeUb2pi3W4SQF8LMKkU2cUuVP68yAGcomL\"")
237 );
238
239
240#ifdef ENABLE_WALLET
241 LOCK2(cs_main, pwalletMain->cs_wallet);
242#else
243 LOCK(cs_main);
244#endif
245
246 bool isValid = false;
247 bool isMine = false;
248 std::string payingKey, transmissionKey;
249
250 string strAddress = params[0].get_str();
251 try {
252 CZCPaymentAddress address(strAddress);
253 libzcash::PaymentAddress addr = address.Get();
254
255#ifdef ENABLE_WALLET
256 isMine = pwalletMain->HaveSpendingKey(addr);
257#endif
258 payingKey = addr.a_pk.GetHex();
259 transmissionKey = addr.pk_enc.GetHex();
260 isValid = true;
261 } catch (std::runtime_error e) {
262 // address is invalid, nop here as isValid is false.
263 }
264
0d37ae3a 265 UniValue ret(UniValue::VOBJ);
4e16a724
S
266 ret.push_back(Pair("isvalid", isValid));
267 if (isValid)
268 {
269 ret.push_back(Pair("address", strAddress));
270 ret.push_back(Pair("payingkey", payingKey));
271 ret.push_back(Pair("transmissionkey", transmissionKey));
272#ifdef ENABLE_WALLET
273 ret.push_back(Pair("ismine", isMine));
274#endif
275 }
276 return ret;
277}
278
279
72fb3d29
MF
280/**
281 * Used by addmultisigaddress / createmultisig:
282 */
d014114d 283CScript _createmultisig_redeemScript(const UniValue& params)
723a03d2
WL
284{
285 int nRequired = params[0].get_int();
d014114d 286 const UniValue& keys = params[1].get_array();
723a03d2
WL
287
288 // Gather public keys
289 if (nRequired < 1)
290 throw runtime_error("a multisignature address must require at least one key to redeem");
291 if ((int)keys.size() < nRequired)
292 throw runtime_error(
293 strprintf("not enough keys supplied "
783b182c 294 "(got %u keys, but need at least %d to redeem)", keys.size(), nRequired));
e5d9d77d 295 if (keys.size() > 16)
296 throw runtime_error("Number of addresses involved in the multisignature address creation > 16\nReduce the number");
723a03d2
WL
297 std::vector<CPubKey> pubkeys;
298 pubkeys.resize(keys.size());
299 for (unsigned int i = 0; i < keys.size(); i++)
300 {
301 const std::string& ks = keys[i].get_str();
302#ifdef ENABLE_WALLET
303 // Case 1: Bitcoin address and we have full public key:
304 CBitcoinAddress address(ks);
305 if (pwalletMain && address.IsValid())
306 {
307 CKeyID keyID;
308 if (!address.GetKeyID(keyID))
309 throw runtime_error(
7d9d134b 310 strprintf("%s does not refer to a key",ks));
723a03d2
WL
311 CPubKey vchPubKey;
312 if (!pwalletMain->GetPubKey(keyID, vchPubKey))
313 throw runtime_error(
7d9d134b 314 strprintf("no full public key for address %s",ks));
723a03d2
WL
315 if (!vchPubKey.IsFullyValid())
316 throw runtime_error(" Invalid public key: "+ks);
317 pubkeys[i] = vchPubKey;
318 }
319
320 // Case 2: hex public key
321 else
322#endif
323 if (IsHex(ks))
324 {
325 CPubKey vchPubKey(ParseHex(ks));
326 if (!vchPubKey.IsFullyValid())
327 throw runtime_error(" Invalid public key: "+ks);
328 pubkeys[i] = vchPubKey;
329 }
330 else
331 {
332 throw runtime_error(" Invalid public key: "+ks);
333 }
334 }
0be990ba 335 CScript result = GetScriptForMultisig(nRequired, pubkeys);
787ee0c9
PT
336
337 if (result.size() > MAX_SCRIPT_ELEMENT_SIZE)
338 throw runtime_error(
339 strprintf("redeemScript exceeds size limit: %d > %d", result.size(), MAX_SCRIPT_ELEMENT_SIZE));
340
723a03d2
WL
341 return result;
342}
343
d014114d 344UniValue createmultisig(const UniValue& params, bool fHelp)
723a03d2
WL
345{
346 if (fHelp || params.size() < 2 || params.size() > 2)
347 {
348 string msg = "createmultisig nrequired [\"key\",...]\n"
349 "\nCreates a multi-signature address with n signature of m keys required.\n"
350 "It returns a json object with the address and redeemScript.\n"
351
352 "\nArguments:\n"
353 "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
354 "2. \"keys\" (string, required) A json array of keys which are bitcoin addresses or hex-encoded public keys\n"
355 " [\n"
356 " \"key\" (string) bitcoin address or hex-encoded public key\n"
357 " ,...\n"
358 " ]\n"
359
360 "\nResult:\n"
361 "{\n"
362 " \"address\":\"multisigaddress\", (string) The value of the new multisig address.\n"
363 " \"redeemScript\":\"script\" (string) The string value of the hex-encoded redemption script.\n"
364 "}\n"
365
366 "\nExamples:\n"
367 "\nCreate a multisig address from 2 addresses\n"
368 + HelpExampleCli("createmultisig", "2 \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") +
369 "\nAs a json rpc call\n"
e3e3728f 370 + HelpExampleRpc("createmultisig", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"")
723a03d2
WL
371 ;
372 throw runtime_error(msg);
373 }
374
375 // Construct using pay-to-script-hash:
787ee0c9 376 CScript inner = _createmultisig_redeemScript(params);
066e2a14 377 CScriptID innerID(inner);
723a03d2
WL
378 CBitcoinAddress address(innerID);
379
b47f3aea 380 UniValue result(UniValue::VOBJ);
723a03d2
WL
381 result.push_back(Pair("address", address.ToString()));
382 result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end())));
383
384 return result;
385}
386
d014114d 387UniValue verifymessage(const UniValue& params, bool fHelp)
c3a7f516
WL
388{
389 if (fHelp || params.size() != 3)
390 throw runtime_error(
391 "verifymessage \"bitcoinaddress\" \"signature\" \"message\"\n"
392 "\nVerify a signed message\n"
393 "\nArguments:\n"
394 "1. \"bitcoinaddress\" (string, required) The bitcoin address to use for the signature.\n"
395 "2. \"signature\" (string, required) The signature provided by the signer in base 64 encoding (see signmessage).\n"
396 "3. \"message\" (string, required) The message that was signed.\n"
397 "\nResult:\n"
398 "true|false (boolean) If the signature is verified or not.\n"
399 "\nExamples:\n"
400 "\nUnlock the wallet for 30 seconds\n"
401 + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
402 "\nCreate the signature\n"
403 + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"my message\"") +
404 "\nVerify the signature\n"
405 + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") +
406 "\nAs json rpc\n"
407 + HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"signature\", \"my message\"")
408 );
409
4401b2d7
EL
410 LOCK(cs_main);
411
c3a7f516
WL
412 string strAddress = params[0].get_str();
413 string strSign = params[1].get_str();
414 string strMessage = params[2].get_str();
415
416 CBitcoinAddress addr(strAddress);
417 if (!addr.IsValid())
418 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
419
420 CKeyID keyID;
421 if (!addr.GetKeyID(keyID))
422 throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
423
424 bool fInvalid = false;
425 vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);
426
427 if (fInvalid)
428 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding");
429
430 CHashWriter ss(SER_GETHASH, 0);
431 ss << strMessageMagic;
432 ss << strMessage;
433
434 CPubKey pubkey;
435 if (!pubkey.RecoverCompact(ss.GetHash(), vchSig))
436 return false;
437
438 return (pubkey.GetID() == keyID);
439}
a8b2ce55 440
d014114d 441UniValue setmocktime(const UniValue& params, bool fHelp)
a8b2ce55
GA
442{
443 if (fHelp || params.size() != 1)
444 throw runtime_error(
445 "setmocktime timestamp\n"
446 "\nSet the local time to given timestamp (-regtest only)\n"
447 "\nArguments:\n"
448 "1. timestamp (integer, required) Unix seconds-since-epoch timestamp\n"
449 " Pass 0 to go back to using the system time."
450 );
451
452 if (!Params().MineBlocksOnDemand())
453 throw runtime_error("setmocktime for regression testing (-regtest mode) only");
454
4401b2d7
EL
455 LOCK(cs_main);
456
9756b7bd 457 RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM));
a8b2ce55
GA
458 SetMockTime(params[0].get_int64());
459
9756b7bd 460 return NullUniValue;
a8b2ce55 461}
This page took 0.220472 seconds and 4 git commands to generate.