]> Git Repo - VerusCoin.git/blame - src/rpcmisc.cpp
test
[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>
23#include "json/json_spirit_utils.h"
24#include "json/json_spirit_value.h"
25
652e1569 26using namespace json_spirit;
40a158e1 27using namespace std;
652e1569 28
f9de17ec
WL
29/**
30 * @note Do not add or change anything in the information returned by this
72fb3d29 31 * method. `getinfo` exists for backwards-compatibility only. It combines
f9de17ec
WL
32 * information from wildly different sources in the program, which is a mess,
33 * and is thus planned to be deprecated eventually.
34 *
35 * Based on the source of the information, new information should be added to:
36 * - `getblockchaininfo`,
37 * - `getnetworkinfo` or
38 * - `getwalletinfo`
39 *
40 * Or alternatively, create a specific query method for the information.
41 **/
16bc9aaf
WL
42Value getinfo(const Array& params, bool fHelp)
43{
1e81ccb7 44 extern uint256 NOTARIZED_HASH,NOTARIZED_DESTTXID;
21cc1d3e 45 extern int32_t NOTARIZED_HEIGHT;
16bc9aaf
WL
46 if (fHelp || params.size() != 0)
47 throw runtime_error(
48 "getinfo\n"
49 "Returns an object containing various state info.\n"
50 "\nResult:\n"
51 "{\n"
52 " \"version\": xxxxx, (numeric) the server version\n"
53 " \"protocolversion\": xxxxx, (numeric) the protocol version\n"
54 " \"walletversion\": xxxxx, (numeric) the wallet version\n"
55 " \"balance\": xxxxxxx, (numeric) the total bitcoin balance of the wallet\n"
56 " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
57 " \"timeoffset\": xxxxx, (numeric) the time offset\n"
58 " \"connections\": xxxxx, (numeric) the number of connections\n"
59 " \"proxy\": \"host:port\", (string, optional) the proxy used by the server\n"
60 " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
61 " \"testnet\": true|false, (boolean) if the server is using testnet or not\n"
62 " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n"
63 " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n"
16bc9aaf 64 " \"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
65 " \"paytxfee\": x.xxxx, (numeric) the transaction fee set in btc/kb\n"
66 " \"relayfee\": x.xxxx, (numeric) minimum relay fee for non-free transactions in btc/kb\n"
16bc9aaf
WL
67 " \"errors\": \"...\" (string) any error messages\n"
68 "}\n"
69 "\nExamples:\n"
70 + HelpExampleCli("getinfo", "")
71 + HelpExampleRpc("getinfo", "")
72 );
73
4401b2d7
EL
74#ifdef ENABLE_WALLET
75 LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
76#else
77 LOCK(cs_main);
78#endif
79
16bc9aaf
WL
80 proxyType proxy;
81 GetProxy(NET_IPV4, proxy);
82
83 Object obj;
faadbe17
PK
84 obj.push_back(Pair("version", CLIENT_VERSION));
85 obj.push_back(Pair("protocolversion", PROTOCOL_VERSION));
21cc1d3e 86 obj.push_back(Pair("notarized", NOTARIZED_HEIGHT));
87 obj.push_back(Pair("notarizedhash", NOTARIZED_HASH.ToString()));
1e81ccb7 88 obj.push_back(Pair("notarizedbtc", NOTARIZED_DESTTXID.ToString()));
16bc9aaf
WL
89#ifdef ENABLE_WALLET
90 if (pwalletMain) {
91 obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
92 obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
93 }
94#endif
95 obj.push_back(Pair("blocks", (int)chainActive.Height()));
d56e30ca 96 obj.push_back(Pair("timeoffset", GetTimeOffset()));
16bc9aaf 97 obj.push_back(Pair("connections", (int)vNodes.size()));
67a79493 98 obj.push_back(Pair("proxy", (proxy.IsValid() ? proxy.proxy.ToStringIPPort() : string())));
16bc9aaf 99 obj.push_back(Pair("difficulty", (double)GetDifficulty()));
cc972107 100 obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC()));
16bc9aaf
WL
101#ifdef ENABLE_WALLET
102 if (pwalletMain) {
d56e30ca 103 obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime()));
16bc9aaf
WL
104 obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
105 }
16bc9aaf 106 if (pwalletMain && pwalletMain->IsCrypted())
d56e30ca 107 obj.push_back(Pair("unlocked_until", nWalletUnlockTime));
c6cb21d1 108 obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())));
16bc9aaf 109#endif
13fc83c7 110 obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())));
16bc9aaf
WL
111 obj.push_back(Pair("errors", GetWarnings("statusbar")));
112 return obj;
113}
114
452955f5
WL
115#ifdef ENABLE_WALLET
116class DescribeAddressVisitor : public boost::static_visitor<Object>
117{
c8988460
PW
118private:
119 isminetype mine;
120
452955f5 121public:
c8988460
PW
122 DescribeAddressVisitor(isminetype mineIn) : mine(mineIn) {}
123
452955f5
WL
124 Object operator()(const CNoDestination &dest) const { return Object(); }
125
126 Object operator()(const CKeyID &keyID) const {
127 Object obj;
128 CPubKey vchPubKey;
452955f5 129 obj.push_back(Pair("isscript", false));
a3e192a3 130 if (mine == ISMINE_SPENDABLE) {
c8988460
PW
131 pwalletMain->GetPubKey(keyID, vchPubKey);
132 obj.push_back(Pair("pubkey", HexStr(vchPubKey)));
133 obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed()));
134 }
452955f5
WL
135 return obj;
136 }
137
138 Object operator()(const CScriptID &scriptID) const {
139 Object obj;
140 obj.push_back(Pair("isscript", true));
a3e192a3 141 if (mine != ISMINE_NO) {
c8988460
PW
142 CScript subscript;
143 pwalletMain->GetCScript(scriptID, subscript);
144 std::vector<CTxDestination> addresses;
145 txnouttype whichType;
146 int nRequired;
147 ExtractDestinations(subscript, whichType, addresses, nRequired);
148 obj.push_back(Pair("script", GetTxnOutputType(whichType)));
149 obj.push_back(Pair("hex", HexStr(subscript.begin(), subscript.end())));
150 Array a;
151 BOOST_FOREACH(const CTxDestination& addr, addresses)
152 a.push_back(CBitcoinAddress(addr).ToString());
153 obj.push_back(Pair("addresses", a));
154 if (whichType == TX_MULTISIG)
155 obj.push_back(Pair("sigsrequired", nRequired));
156 }
452955f5
WL
157 return obj;
158 }
159};
160#endif
161
162Value validateaddress(const Array& params, bool fHelp)
163{
164 if (fHelp || params.size() != 1)
165 throw runtime_error(
166 "validateaddress \"bitcoinaddress\"\n"
167 "\nReturn information about the given bitcoin address.\n"
168 "\nArguments:\n"
169 "1. \"bitcoinaddress\" (string, required) The bitcoin address to validate\n"
170 "\nResult:\n"
171 "{\n"
172 " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
173 " \"address\" : \"bitcoinaddress\", (string) The bitcoin address validated\n"
426a74ed 174 " \"scriptPubKey\" : \"hex\", (string) The hex encoded scriptPubKey generated by the address\n"
452955f5
WL
175 " \"ismine\" : true|false, (boolean) If the address is yours or not\n"
176 " \"isscript\" : true|false, (boolean) If the key is a script\n"
177 " \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n"
178 " \"iscompressed\" : true|false, (boolean) If the address is compressed\n"
7b782f5b 179 " \"account\" : \"account\" (string) DEPRECATED. The account associated with the address, \"\" is the default account\n"
452955f5
WL
180 "}\n"
181 "\nExamples:\n"
182 + HelpExampleCli("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
183 + HelpExampleRpc("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
184 );
185
4401b2d7
EL
186#ifdef ENABLE_WALLET
187 LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
188#else
189 LOCK(cs_main);
190#endif
191
452955f5
WL
192 CBitcoinAddress address(params[0].get_str());
193 bool isValid = address.IsValid();
194
195 Object ret;
196 ret.push_back(Pair("isvalid", isValid));
197 if (isValid)
198 {
199 CTxDestination dest = address.Get();
200 string currentAddress = address.ToString();
201 ret.push_back(Pair("address", currentAddress));
426a74ed
PT
202
203 CScript scriptPubKey = GetScriptForDestination(dest);
204 ret.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
205
452955f5 206#ifdef ENABLE_WALLET
a3e192a3
J
207 isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO;
208 ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false));
209 if (mine != ISMINE_NO) {
210 ret.push_back(Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true: false));
c8988460 211 Object detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest);
452955f5
WL
212 ret.insert(ret.end(), detail.begin(), detail.end());
213 }
214 if (pwalletMain && pwalletMain->mapAddressBook.count(dest))
215 ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name));
216#endif
217 }
218 return ret;
219}
220
72fb3d29
MF
221/**
222 * Used by addmultisigaddress / createmultisig:
223 */
787ee0c9 224CScript _createmultisig_redeemScript(const Array& params)
723a03d2
WL
225{
226 int nRequired = params[0].get_int();
227 const Array& keys = params[1].get_array();
228
229 // Gather public keys
230 if (nRequired < 1)
231 throw runtime_error("a multisignature address must require at least one key to redeem");
232 if ((int)keys.size() < nRequired)
233 throw runtime_error(
234 strprintf("not enough keys supplied "
783b182c 235 "(got %u keys, but need at least %d to redeem)", keys.size(), nRequired));
e5d9d77d 236 if (keys.size() > 16)
237 throw runtime_error("Number of addresses involved in the multisignature address creation > 16\nReduce the number");
723a03d2
WL
238 std::vector<CPubKey> pubkeys;
239 pubkeys.resize(keys.size());
240 for (unsigned int i = 0; i < keys.size(); i++)
241 {
242 const std::string& ks = keys[i].get_str();
243#ifdef ENABLE_WALLET
244 // Case 1: Bitcoin address and we have full public key:
245 CBitcoinAddress address(ks);
246 if (pwalletMain && address.IsValid())
247 {
248 CKeyID keyID;
249 if (!address.GetKeyID(keyID))
250 throw runtime_error(
7d9d134b 251 strprintf("%s does not refer to a key",ks));
723a03d2
WL
252 CPubKey vchPubKey;
253 if (!pwalletMain->GetPubKey(keyID, vchPubKey))
254 throw runtime_error(
7d9d134b 255 strprintf("no full public key for address %s",ks));
723a03d2
WL
256 if (!vchPubKey.IsFullyValid())
257 throw runtime_error(" Invalid public key: "+ks);
258 pubkeys[i] = vchPubKey;
259 }
260
261 // Case 2: hex public key
262 else
263#endif
264 if (IsHex(ks))
265 {
266 CPubKey vchPubKey(ParseHex(ks));
267 if (!vchPubKey.IsFullyValid())
268 throw runtime_error(" Invalid public key: "+ks);
269 pubkeys[i] = vchPubKey;
270 }
271 else
272 {
273 throw runtime_error(" Invalid public key: "+ks);
274 }
275 }
0be990ba 276 CScript result = GetScriptForMultisig(nRequired, pubkeys);
787ee0c9
PT
277
278 if (result.size() > MAX_SCRIPT_ELEMENT_SIZE)
279 throw runtime_error(
280 strprintf("redeemScript exceeds size limit: %d > %d", result.size(), MAX_SCRIPT_ELEMENT_SIZE));
281
723a03d2
WL
282 return result;
283}
284
285Value createmultisig(const Array& params, bool fHelp)
286{
287 if (fHelp || params.size() < 2 || params.size() > 2)
288 {
289 string msg = "createmultisig nrequired [\"key\",...]\n"
290 "\nCreates a multi-signature address with n signature of m keys required.\n"
291 "It returns a json object with the address and redeemScript.\n"
292
293 "\nArguments:\n"
294 "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
295 "2. \"keys\" (string, required) A json array of keys which are bitcoin addresses or hex-encoded public keys\n"
296 " [\n"
297 " \"key\" (string) bitcoin address or hex-encoded public key\n"
298 " ,...\n"
299 " ]\n"
300
301 "\nResult:\n"
302 "{\n"
303 " \"address\":\"multisigaddress\", (string) The value of the new multisig address.\n"
304 " \"redeemScript\":\"script\" (string) The string value of the hex-encoded redemption script.\n"
305 "}\n"
306
307 "\nExamples:\n"
308 "\nCreate a multisig address from 2 addresses\n"
309 + HelpExampleCli("createmultisig", "2 \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") +
310 "\nAs a json rpc call\n"
e3e3728f 311 + HelpExampleRpc("createmultisig", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"")
723a03d2
WL
312 ;
313 throw runtime_error(msg);
314 }
315
316 // Construct using pay-to-script-hash:
787ee0c9 317 CScript inner = _createmultisig_redeemScript(params);
066e2a14 318 CScriptID innerID(inner);
723a03d2
WL
319 CBitcoinAddress address(innerID);
320
321 Object result;
322 result.push_back(Pair("address", address.ToString()));
323 result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end())));
324
325 return result;
326}
327
c3a7f516
WL
328Value verifymessage(const Array& params, bool fHelp)
329{
330 if (fHelp || params.size() != 3)
331 throw runtime_error(
332 "verifymessage \"bitcoinaddress\" \"signature\" \"message\"\n"
333 "\nVerify a signed message\n"
334 "\nArguments:\n"
335 "1. \"bitcoinaddress\" (string, required) The bitcoin address to use for the signature.\n"
336 "2. \"signature\" (string, required) The signature provided by the signer in base 64 encoding (see signmessage).\n"
337 "3. \"message\" (string, required) The message that was signed.\n"
338 "\nResult:\n"
339 "true|false (boolean) If the signature is verified or not.\n"
340 "\nExamples:\n"
341 "\nUnlock the wallet for 30 seconds\n"
342 + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
343 "\nCreate the signature\n"
344 + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"my message\"") +
345 "\nVerify the signature\n"
346 + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") +
347 "\nAs json rpc\n"
348 + HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"signature\", \"my message\"")
349 );
350
4401b2d7
EL
351 LOCK(cs_main);
352
c3a7f516
WL
353 string strAddress = params[0].get_str();
354 string strSign = params[1].get_str();
355 string strMessage = params[2].get_str();
356
357 CBitcoinAddress addr(strAddress);
358 if (!addr.IsValid())
359 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
360
361 CKeyID keyID;
362 if (!addr.GetKeyID(keyID))
363 throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
364
365 bool fInvalid = false;
366 vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);
367
368 if (fInvalid)
369 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding");
370
371 CHashWriter ss(SER_GETHASH, 0);
372 ss << strMessageMagic;
373 ss << strMessage;
374
375 CPubKey pubkey;
376 if (!pubkey.RecoverCompact(ss.GetHash(), vchSig))
377 return false;
378
379 return (pubkey.GetID() == keyID);
380}
a8b2ce55
GA
381
382Value setmocktime(const Array& params, bool fHelp)
383{
384 if (fHelp || params.size() != 1)
385 throw runtime_error(
386 "setmocktime timestamp\n"
387 "\nSet the local time to given timestamp (-regtest only)\n"
388 "\nArguments:\n"
389 "1. timestamp (integer, required) Unix seconds-since-epoch timestamp\n"
390 " Pass 0 to go back to using the system time."
391 );
392
393 if (!Params().MineBlocksOnDemand())
394 throw runtime_error("setmocktime for regression testing (-regtest mode) only");
395
4401b2d7
EL
396 LOCK(cs_main);
397
a8b2ce55
GA
398 RPCTypeCheck(params, boost::assign::list_of(int_type));
399 SetMockTime(params[0].get_int64());
400
401 return Value::null;
402}
This page took 0.234463 seconds and 4 git commands to generate.