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