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