]> Git Repo - VerusCoin.git/blame - src/rpcmisc.cpp
Copyright header updates s/2013/2014 on files whose last git commit was done in 2014.
[VerusCoin.git] / src / rpcmisc.cpp
CommitLineData
652e1569 1// Copyright (c) 2010 Satoshi Nakamoto
57702541 2// Copyright (c) 2009-2014 The Bitcoin developers
652e1569
WL
3// Distributed under the MIT/X11 software license, see the accompanying
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6#include "base58.h"
652e1569
WL
7#include "init.h"
8#include "main.h"
9#include "net.h"
10#include "netbase.h"
c037531d 11#include "rpcserver.h"
652e1569
WL
12#include "util.h"
13#ifdef ENABLE_WALLET
14#include "wallet.h"
15#include "walletdb.h"
16#endif
17
18#include <stdint.h>
19
20#include <boost/assign/list_of.hpp>
21#include "json/json_spirit_utils.h"
22#include "json/json_spirit_value.h"
23
24using namespace std;
25using namespace boost;
26using namespace boost::assign;
27using namespace json_spirit;
28
16bc9aaf
WL
29Value getinfo(const Array& params, bool fHelp)
30{
31 if (fHelp || params.size() != 0)
32 throw runtime_error(
33 "getinfo\n"
34 "Returns an object containing various state info.\n"
35 "\nResult:\n"
36 "{\n"
37 " \"version\": xxxxx, (numeric) the server version\n"
38 " \"protocolversion\": xxxxx, (numeric) the protocol version\n"
39 " \"walletversion\": xxxxx, (numeric) the wallet version\n"
40 " \"balance\": xxxxxxx, (numeric) the total bitcoin balance of the wallet\n"
41 " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
42 " \"timeoffset\": xxxxx, (numeric) the time offset\n"
43 " \"connections\": xxxxx, (numeric) the number of connections\n"
44 " \"proxy\": \"host:port\", (string, optional) the proxy used by the server\n"
45 " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
46 " \"testnet\": true|false, (boolean) if the server is using testnet or not\n"
47 " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n"
48 " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n"
49 " \"paytxfee\": x.xxxx, (numeric) the transaction fee set in btc\n"
50 " \"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"
51 " \"errors\": \"...\" (string) any error messages\n"
52 "}\n"
53 "\nExamples:\n"
54 + HelpExampleCli("getinfo", "")
55 + HelpExampleRpc("getinfo", "")
56 );
57
58 proxyType proxy;
59 GetProxy(NET_IPV4, proxy);
60
61 Object obj;
62 obj.push_back(Pair("version", (int)CLIENT_VERSION));
63 obj.push_back(Pair("protocolversion",(int)PROTOCOL_VERSION));
64#ifdef ENABLE_WALLET
65 if (pwalletMain) {
66 obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
67 obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
68 }
69#endif
70 obj.push_back(Pair("blocks", (int)chainActive.Height()));
71 obj.push_back(Pair("timeoffset", (boost::int64_t)GetTimeOffset()));
72 obj.push_back(Pair("connections", (int)vNodes.size()));
73 obj.push_back(Pair("proxy", (proxy.first.IsValid() ? proxy.first.ToStringIPPort() : string())));
74 obj.push_back(Pair("difficulty", (double)GetDifficulty()));
75 obj.push_back(Pair("testnet", TestNet()));
76#ifdef ENABLE_WALLET
77 if (pwalletMain) {
78 obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime()));
79 obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
80 }
16bc9aaf 81 obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee)));
16bc9aaf
WL
82 if (pwalletMain && pwalletMain->IsCrypted())
83 obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime));
84#endif
85 obj.push_back(Pair("errors", GetWarnings("statusbar")));
86 return obj;
87}
88
452955f5
WL
89#ifdef ENABLE_WALLET
90class DescribeAddressVisitor : public boost::static_visitor<Object>
91{
92public:
93 Object operator()(const CNoDestination &dest) const { return Object(); }
94
95 Object operator()(const CKeyID &keyID) const {
96 Object obj;
97 CPubKey vchPubKey;
98 pwalletMain->GetPubKey(keyID, vchPubKey);
99 obj.push_back(Pair("isscript", false));
100 obj.push_back(Pair("pubkey", HexStr(vchPubKey)));
101 obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed()));
102 return obj;
103 }
104
105 Object operator()(const CScriptID &scriptID) const {
106 Object obj;
107 obj.push_back(Pair("isscript", true));
108 CScript subscript;
109 pwalletMain->GetCScript(scriptID, subscript);
110 std::vector<CTxDestination> addresses;
111 txnouttype whichType;
112 int nRequired;
113 ExtractDestinations(subscript, whichType, addresses, nRequired);
114 obj.push_back(Pair("script", GetTxnOutputType(whichType)));
115 obj.push_back(Pair("hex", HexStr(subscript.begin(), subscript.end())));
116 Array a;
117 BOOST_FOREACH(const CTxDestination& addr, addresses)
118 a.push_back(CBitcoinAddress(addr).ToString());
119 obj.push_back(Pair("addresses", a));
120 if (whichType == TX_MULTISIG)
121 obj.push_back(Pair("sigsrequired", nRequired));
122 return obj;
123 }
124};
125#endif
126
127Value validateaddress(const Array& params, bool fHelp)
128{
129 if (fHelp || params.size() != 1)
130 throw runtime_error(
131 "validateaddress \"bitcoinaddress\"\n"
132 "\nReturn information about the given bitcoin address.\n"
133 "\nArguments:\n"
134 "1. \"bitcoinaddress\" (string, required) The bitcoin address to validate\n"
135 "\nResult:\n"
136 "{\n"
137 " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
138 " \"address\" : \"bitcoinaddress\", (string) The bitcoin address validated\n"
139 " \"ismine\" : true|false, (boolean) If the address is yours or not\n"
140 " \"isscript\" : true|false, (boolean) If the key is a script\n"
141 " \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n"
142 " \"iscompressed\" : true|false, (boolean) If the address is compressed\n"
143 " \"account\" : \"account\" (string) The account associated with the address, \"\" is the default account\n"
144 "}\n"
145 "\nExamples:\n"
146 + HelpExampleCli("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
147 + HelpExampleRpc("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
148 );
149
150 CBitcoinAddress address(params[0].get_str());
151 bool isValid = address.IsValid();
152
153 Object ret;
154 ret.push_back(Pair("isvalid", isValid));
155 if (isValid)
156 {
157 CTxDestination dest = address.Get();
158 string currentAddress = address.ToString();
159 ret.push_back(Pair("address", currentAddress));
160#ifdef ENABLE_WALLET
161 bool fMine = pwalletMain ? IsMine(*pwalletMain, dest) : false;
162 ret.push_back(Pair("ismine", fMine));
163 if (fMine) {
164 Object detail = boost::apply_visitor(DescribeAddressVisitor(), dest);
165 ret.insert(ret.end(), detail.begin(), detail.end());
166 }
167 if (pwalletMain && pwalletMain->mapAddressBook.count(dest))
168 ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name));
169#endif
170 }
171 return ret;
172}
173
723a03d2
WL
174//
175// Used by addmultisigaddress / createmultisig:
176//
177CScript _createmultisig(const Array& params)
178{
179 int nRequired = params[0].get_int();
180 const Array& keys = params[1].get_array();
181
182 // Gather public keys
183 if (nRequired < 1)
184 throw runtime_error("a multisignature address must require at least one key to redeem");
185 if ((int)keys.size() < nRequired)
186 throw runtime_error(
187 strprintf("not enough keys supplied "
188 "(got %"PRIszu" keys, but need at least %d to redeem)", keys.size(), nRequired));
189 std::vector<CPubKey> pubkeys;
190 pubkeys.resize(keys.size());
191 for (unsigned int i = 0; i < keys.size(); i++)
192 {
193 const std::string& ks = keys[i].get_str();
194#ifdef ENABLE_WALLET
195 // Case 1: Bitcoin address and we have full public key:
196 CBitcoinAddress address(ks);
197 if (pwalletMain && address.IsValid())
198 {
199 CKeyID keyID;
200 if (!address.GetKeyID(keyID))
201 throw runtime_error(
7d9d134b 202 strprintf("%s does not refer to a key",ks));
723a03d2
WL
203 CPubKey vchPubKey;
204 if (!pwalletMain->GetPubKey(keyID, vchPubKey))
205 throw runtime_error(
7d9d134b 206 strprintf("no full public key for address %s",ks));
723a03d2
WL
207 if (!vchPubKey.IsFullyValid())
208 throw runtime_error(" Invalid public key: "+ks);
209 pubkeys[i] = vchPubKey;
210 }
211
212 // Case 2: hex public key
213 else
214#endif
215 if (IsHex(ks))
216 {
217 CPubKey vchPubKey(ParseHex(ks));
218 if (!vchPubKey.IsFullyValid())
219 throw runtime_error(" Invalid public key: "+ks);
220 pubkeys[i] = vchPubKey;
221 }
222 else
223 {
224 throw runtime_error(" Invalid public key: "+ks);
225 }
226 }
227 CScript result;
228 result.SetMultisig(nRequired, pubkeys);
229 return result;
230}
231
232Value createmultisig(const Array& params, bool fHelp)
233{
234 if (fHelp || params.size() < 2 || params.size() > 2)
235 {
236 string msg = "createmultisig nrequired [\"key\",...]\n"
237 "\nCreates a multi-signature address with n signature of m keys required.\n"
238 "It returns a json object with the address and redeemScript.\n"
239
240 "\nArguments:\n"
241 "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
242 "2. \"keys\" (string, required) A json array of keys which are bitcoin addresses or hex-encoded public keys\n"
243 " [\n"
244 " \"key\" (string) bitcoin address or hex-encoded public key\n"
245 " ,...\n"
246 " ]\n"
247
248 "\nResult:\n"
249 "{\n"
250 " \"address\":\"multisigaddress\", (string) The value of the new multisig address.\n"
251 " \"redeemScript\":\"script\" (string) The string value of the hex-encoded redemption script.\n"
252 "}\n"
253
254 "\nExamples:\n"
255 "\nCreate a multisig address from 2 addresses\n"
256 + HelpExampleCli("createmultisig", "2 \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") +
257 "\nAs a json rpc call\n"
258 + HelpExampleRpc("icreatemultisig", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"")
259 ;
260 throw runtime_error(msg);
261 }
262
263 // Construct using pay-to-script-hash:
264 CScript inner = _createmultisig(params);
265 CScriptID innerID = inner.GetID();
266 CBitcoinAddress address(innerID);
267
268 Object result;
269 result.push_back(Pair("address", address.ToString()));
270 result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end())));
271
272 return result;
273}
274
c3a7f516
WL
275Value verifymessage(const Array& params, bool fHelp)
276{
277 if (fHelp || params.size() != 3)
278 throw runtime_error(
279 "verifymessage \"bitcoinaddress\" \"signature\" \"message\"\n"
280 "\nVerify a signed message\n"
281 "\nArguments:\n"
282 "1. \"bitcoinaddress\" (string, required) The bitcoin address to use for the signature.\n"
283 "2. \"signature\" (string, required) The signature provided by the signer in base 64 encoding (see signmessage).\n"
284 "3. \"message\" (string, required) The message that was signed.\n"
285 "\nResult:\n"
286 "true|false (boolean) If the signature is verified or not.\n"
287 "\nExamples:\n"
288 "\nUnlock the wallet for 30 seconds\n"
289 + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
290 "\nCreate the signature\n"
291 + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"my message\"") +
292 "\nVerify the signature\n"
293 + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") +
294 "\nAs json rpc\n"
295 + HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"signature\", \"my message\"")
296 );
297
298 string strAddress = params[0].get_str();
299 string strSign = params[1].get_str();
300 string strMessage = params[2].get_str();
301
302 CBitcoinAddress addr(strAddress);
303 if (!addr.IsValid())
304 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
305
306 CKeyID keyID;
307 if (!addr.GetKeyID(keyID))
308 throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
309
310 bool fInvalid = false;
311 vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);
312
313 if (fInvalid)
314 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding");
315
316 CHashWriter ss(SER_GETHASH, 0);
317 ss << strMessageMagic;
318 ss << strMessage;
319
320 CPubKey pubkey;
321 if (!pubkey.RecoverCompact(ss.GetHash(), vchSig))
322 return false;
323
324 return (pubkey.GetID() == keyID);
325}
This page took 0.068448 seconds and 4 git commands to generate.