~ubuntu-branches/debian/stretch/bitcoin/stretch

« back to all changes in this revision

Viewing changes to src/rpc/misc.cpp

  • Committer: Package Import Robot
  • Author(s): Anthony Towns
  • Date: 2016-10-21 17:13:13 UTC
  • mfrom: (1.3.2)
  • Revision ID: package-import@ubuntu.com-20161021171313-7eu2ltpbk0xag3q1
Tags: 0.13.0-0.1
* Non-maintainer upload.
* New upstream release.
* Allow compilation with gcc/g++ 6. (Closes: Bug#835963)
* Additional fixes for openssl 1.1 compatibility. (See Bug#828248)
* Check if -latomic is needed (it is on mips*).
* Remove reproducible build patch, since leveldb build system is
  no longer used in 0.13. (See Bug#791834)
* Update description since the blockchain is much more than "several GB"
  now. (Closes: Bug#835809)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (c) 2010 Satoshi Nakamoto
 
2
// Copyright (c) 2009-2015 The Bitcoin Core developers
 
3
// Distributed under the MIT software license, see the accompanying
 
4
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
5
 
 
6
#include "base58.h"
 
7
#include "clientversion.h"
 
8
#include "init.h"
 
9
#include "main.h"
 
10
#include "net.h"
 
11
#include "netbase.h"
 
12
#include "rpc/server.h"
 
13
#include "timedata.h"
 
14
#include "util.h"
 
15
#include "utilstrencodings.h"
 
16
#ifdef ENABLE_WALLET
 
17
#include "wallet/wallet.h"
 
18
#include "wallet/walletdb.h"
 
19
#endif
 
20
 
 
21
#include <stdint.h>
 
22
 
 
23
#include <boost/assign/list_of.hpp>
 
24
 
 
25
#include <univalue.h>
 
26
 
 
27
using namespace std;
 
28
 
 
29
/**
 
30
 * @note Do not add or change anything in the information returned by this
 
31
 * method. `getinfo` exists for backwards-compatibility only. It combines
 
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
 **/
 
42
UniValue getinfo(const UniValue& 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"
 
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"
 
63
            "  \"paytxfee\": x.xxxx,         (numeric) the transaction fee set in " + CURRENCY_UNIT + "/kB\n"
 
64
            "  \"relayfee\": x.xxxx,         (numeric) minimum relay fee for non-free transactions in " + CURRENCY_UNIT + "/kB\n"
 
65
            "  \"errors\": \"...\"           (string) any error messages\n"
 
66
            "}\n"
 
67
            "\nExamples:\n"
 
68
            + HelpExampleCli("getinfo", "")
 
69
            + HelpExampleRpc("getinfo", "")
 
70
        );
 
71
 
 
72
#ifdef ENABLE_WALLET
 
73
    LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
 
74
#else
 
75
    LOCK(cs_main);
 
76
#endif
 
77
 
 
78
    proxyType proxy;
 
79
    GetProxy(NET_IPV4, proxy);
 
80
 
 
81
    UniValue obj(UniValue::VOBJ);
 
82
    obj.push_back(Pair("version", CLIENT_VERSION));
 
83
    obj.push_back(Pair("protocolversion", PROTOCOL_VERSION));
 
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()));
 
91
    obj.push_back(Pair("timeoffset",    GetTimeOffset()));
 
92
    obj.push_back(Pair("connections",   (int)vNodes.size()));
 
93
    obj.push_back(Pair("proxy",         (proxy.IsValid() ? proxy.proxy.ToStringIPPort() : string())));
 
94
    obj.push_back(Pair("difficulty",    (double)GetDifficulty()));
 
95
    obj.push_back(Pair("testnet",       Params().TestnetToBeDeprecatedFieldRPC()));
 
96
#ifdef ENABLE_WALLET
 
97
    if (pwalletMain) {
 
98
        obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime()));
 
99
        obj.push_back(Pair("keypoolsize",   (int)pwalletMain->GetKeyPoolSize()));
 
100
    }
 
101
    if (pwalletMain && pwalletMain->IsCrypted())
 
102
        obj.push_back(Pair("unlocked_until", nWalletUnlockTime));
 
103
    obj.push_back(Pair("paytxfee",      ValueFromAmount(payTxFee.GetFeePerK())));
 
104
#endif
 
105
    obj.push_back(Pair("relayfee",      ValueFromAmount(::minRelayTxFee.GetFeePerK())));
 
106
    obj.push_back(Pair("errors",        GetWarnings("statusbar")));
 
107
    return obj;
 
108
}
 
109
 
 
110
#ifdef ENABLE_WALLET
 
111
class DescribeAddressVisitor : public boost::static_visitor<UniValue>
 
112
{
 
113
public:
 
114
    UniValue operator()(const CNoDestination &dest) const { return UniValue(UniValue::VOBJ); }
 
115
 
 
116
    UniValue operator()(const CKeyID &keyID) const {
 
117
        UniValue obj(UniValue::VOBJ);
 
118
        CPubKey vchPubKey;
 
119
        obj.push_back(Pair("isscript", false));
 
120
        if (pwalletMain && pwalletMain->GetPubKey(keyID, vchPubKey)) {
 
121
            obj.push_back(Pair("pubkey", HexStr(vchPubKey)));
 
122
            obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed()));
 
123
        }
 
124
        return obj;
 
125
    }
 
126
 
 
127
    UniValue operator()(const CScriptID &scriptID) const {
 
128
        UniValue obj(UniValue::VOBJ);
 
129
        CScript subscript;
 
130
        obj.push_back(Pair("isscript", true));
 
131
        if (pwalletMain && pwalletMain->GetCScript(scriptID, subscript)) {
 
132
            std::vector<CTxDestination> addresses;
 
133
            txnouttype whichType;
 
134
            int nRequired;
 
135
            ExtractDestinations(subscript, whichType, addresses, nRequired);
 
136
            obj.push_back(Pair("script", GetTxnOutputType(whichType)));
 
137
            obj.push_back(Pair("hex", HexStr(subscript.begin(), subscript.end())));
 
138
            UniValue a(UniValue::VARR);
 
139
            BOOST_FOREACH(const CTxDestination& addr, addresses)
 
140
                a.push_back(CBitcoinAddress(addr).ToString());
 
141
            obj.push_back(Pair("addresses", a));
 
142
            if (whichType == TX_MULTISIG)
 
143
                obj.push_back(Pair("sigsrequired", nRequired));
 
144
        }
 
145
        return obj;
 
146
    }
 
147
};
 
148
#endif
 
149
 
 
150
UniValue validateaddress(const UniValue& params, bool fHelp)
 
151
{
 
152
    if (fHelp || params.size() != 1)
 
153
        throw runtime_error(
 
154
            "validateaddress \"bitcoinaddress\"\n"
 
155
            "\nReturn information about the given bitcoin address.\n"
 
156
            "\nArguments:\n"
 
157
            "1. \"bitcoinaddress\"     (string, required) The bitcoin address to validate\n"
 
158
            "\nResult:\n"
 
159
            "{\n"
 
160
            "  \"isvalid\" : true|false,       (boolean) If the address is valid or not. If not, this is the only property returned.\n"
 
161
            "  \"address\" : \"bitcoinaddress\", (string) The bitcoin address validated\n"
 
162
            "  \"scriptPubKey\" : \"hex\",       (string) The hex encoded scriptPubKey generated by the address\n"
 
163
            "  \"ismine\" : true|false,        (boolean) If the address is yours or not\n"
 
164
            "  \"iswatchonly\" : true|false,   (boolean) If the address is watchonly\n"
 
165
            "  \"isscript\" : true|false,      (boolean) If the key is a script\n"
 
166
            "  \"pubkey\" : \"publickeyhex\",    (string) The hex value of the raw public key\n"
 
167
            "  \"iscompressed\" : true|false,  (boolean) If the address is compressed\n"
 
168
            "  \"account\" : \"account\"         (string) DEPRECATED. The account associated with the address, \"\" is the default account\n"
 
169
            "  \"hdkeypath\" : \"keypath\"       (string, optional) The HD keypath if the key is HD and available\n"
 
170
            "  \"hdmasterkeyid\" : \"<hash160>\" (string, optional) The Hash160 of the HD master pubkey\n"
 
171
            "}\n"
 
172
            "\nExamples:\n"
 
173
            + HelpExampleCli("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
 
174
            + HelpExampleRpc("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
 
175
        );
 
176
 
 
177
#ifdef ENABLE_WALLET
 
178
    LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
 
179
#else
 
180
    LOCK(cs_main);
 
181
#endif
 
182
 
 
183
    CBitcoinAddress address(params[0].get_str());
 
184
    bool isValid = address.IsValid();
 
185
 
 
186
    UniValue ret(UniValue::VOBJ);
 
187
    ret.push_back(Pair("isvalid", isValid));
 
188
    if (isValid)
 
189
    {
 
190
        CTxDestination dest = address.Get();
 
191
        string currentAddress = address.ToString();
 
192
        ret.push_back(Pair("address", currentAddress));
 
193
 
 
194
        CScript scriptPubKey = GetScriptForDestination(dest);
 
195
        ret.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
 
196
 
 
197
#ifdef ENABLE_WALLET
 
198
        isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO;
 
199
        ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false));
 
200
        ret.push_back(Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true: false));
 
201
        UniValue detail = boost::apply_visitor(DescribeAddressVisitor(), dest);
 
202
        ret.pushKVs(detail);
 
203
        if (pwalletMain && pwalletMain->mapAddressBook.count(dest))
 
204
            ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name));
 
205
        CKeyID keyID;
 
206
        if (pwalletMain && address.GetKeyID(keyID) && pwalletMain->mapKeyMetadata.count(keyID) && !pwalletMain->mapKeyMetadata[keyID].hdKeypath.empty())
 
207
        {
 
208
            ret.push_back(Pair("hdkeypath", pwalletMain->mapKeyMetadata[keyID].hdKeypath));
 
209
            ret.push_back(Pair("hdmasterkeyid", pwalletMain->mapKeyMetadata[keyID].hdMasterKeyID.GetHex()));
 
210
        }
 
211
#endif
 
212
    }
 
213
    return ret;
 
214
}
 
215
 
 
216
/**
 
217
 * Used by addmultisigaddress / createmultisig:
 
218
 */
 
219
CScript _createmultisig_redeemScript(const UniValue& params)
 
220
{
 
221
    int nRequired = params[0].get_int();
 
222
    const UniValue& 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 "
 
230
                      "(got %u keys, but need at least %d to redeem)", keys.size(), nRequired));
 
231
    if (keys.size() > 16)
 
232
        throw runtime_error("Number of addresses involved in the multisignature address creation > 16\nReduce the number");
 
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(
 
246
                    strprintf("%s does not refer to a key",ks));
 
247
            CPubKey vchPubKey;
 
248
            if (!pwalletMain->GetPubKey(keyID, vchPubKey))
 
249
                throw runtime_error(
 
250
                    strprintf("no full public key for address %s",ks));
 
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
    }
 
271
    CScript result = GetScriptForMultisig(nRequired, pubkeys);
 
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
 
 
277
    return result;
 
278
}
 
279
 
 
280
UniValue createmultisig(const UniValue& 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"
 
306
            + HelpExampleRpc("createmultisig", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"")
 
307
        ;
 
308
        throw runtime_error(msg);
 
309
    }
 
310
 
 
311
    // Construct using pay-to-script-hash:
 
312
    CScript inner = _createmultisig_redeemScript(params);
 
313
    CScriptID innerID(inner);
 
314
    CBitcoinAddress address(innerID);
 
315
 
 
316
    UniValue result(UniValue::VOBJ);
 
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
 
 
323
UniValue createwitnessaddress(const UniValue& params, bool fHelp)
 
324
{
 
325
    if (fHelp || params.size() < 1 || params.size() > 1)
 
326
    {
 
327
        string msg = "createwitnessaddress \"script\"\n"
 
328
            "\nCreates a witness address for a particular script.\n"
 
329
            "It returns a json object with the address and witness script.\n"
 
330
 
 
331
            "\nArguments:\n"
 
332
            "1. \"script\"       (string, required) A hex encoded script\n"
 
333
 
 
334
            "\nResult:\n"
 
335
            "{\n"
 
336
            "  \"address\":\"multisigaddress\",  (string) The value of the new address (P2SH of witness script).\n"
 
337
            "  \"witnessScript\":\"script\"      (string) The string value of the hex-encoded witness script.\n"
 
338
            "}\n"
 
339
        ;
 
340
        throw runtime_error(msg);
 
341
    }
 
342
 
 
343
    if (!IsHex(params[0].get_str())) {
 
344
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Script must be hex-encoded");
 
345
    }
 
346
 
 
347
    std::vector<unsigned char> code = ParseHex(params[0].get_str());
 
348
    CScript script(code.begin(), code.end());
 
349
    CScript witscript = GetScriptForWitness(script);
 
350
    CScriptID witscriptid(witscript);
 
351
    CBitcoinAddress address(witscriptid);
 
352
 
 
353
    UniValue result(UniValue::VOBJ);
 
354
    result.push_back(Pair("address", address.ToString()));
 
355
    result.push_back(Pair("witnessScript", HexStr(witscript.begin(), witscript.end())));
 
356
 
 
357
    return result;
 
358
}
 
359
 
 
360
UniValue verifymessage(const UniValue& params, bool fHelp)
 
361
{
 
362
    if (fHelp || params.size() != 3)
 
363
        throw runtime_error(
 
364
            "verifymessage \"bitcoinaddress\" \"signature\" \"message\"\n"
 
365
            "\nVerify a signed message\n"
 
366
            "\nArguments:\n"
 
367
            "1. \"bitcoinaddress\"  (string, required) The bitcoin address to use for the signature.\n"
 
368
            "2. \"signature\"       (string, required) The signature provided by the signer in base 64 encoding (see signmessage).\n"
 
369
            "3. \"message\"         (string, required) The message that was signed.\n"
 
370
            "\nResult:\n"
 
371
            "true|false   (boolean) If the signature is verified or not.\n"
 
372
            "\nExamples:\n"
 
373
            "\nUnlock the wallet for 30 seconds\n"
 
374
            + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
 
375
            "\nCreate the signature\n"
 
376
            + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"my message\"") +
 
377
            "\nVerify the signature\n"
 
378
            + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") +
 
379
            "\nAs json rpc\n"
 
380
            + HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"signature\", \"my message\"")
 
381
        );
 
382
 
 
383
    LOCK(cs_main);
 
384
 
 
385
    string strAddress  = params[0].get_str();
 
386
    string strSign     = params[1].get_str();
 
387
    string strMessage  = params[2].get_str();
 
388
 
 
389
    CBitcoinAddress addr(strAddress);
 
390
    if (!addr.IsValid())
 
391
        throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
 
392
 
 
393
    CKeyID keyID;
 
394
    if (!addr.GetKeyID(keyID))
 
395
        throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
 
396
 
 
397
    bool fInvalid = false;
 
398
    vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);
 
399
 
 
400
    if (fInvalid)
 
401
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding");
 
402
 
 
403
    CHashWriter ss(SER_GETHASH, 0);
 
404
    ss << strMessageMagic;
 
405
    ss << strMessage;
 
406
 
 
407
    CPubKey pubkey;
 
408
    if (!pubkey.RecoverCompact(ss.GetHash(), vchSig))
 
409
        return false;
 
410
 
 
411
    return (pubkey.GetID() == keyID);
 
412
}
 
413
 
 
414
UniValue signmessagewithprivkey(const UniValue& params, bool fHelp)
 
415
{
 
416
    if (fHelp || params.size() != 2)
 
417
        throw runtime_error(
 
418
            "signmessagewithprivkey \"privkey\" \"message\"\n"
 
419
            "\nSign a message with the private key of an address\n"
 
420
            "\nArguments:\n"
 
421
            "1. \"privkey\"         (string, required) The private key to sign the message with.\n"
 
422
            "2. \"message\"         (string, required) The message to create a signature of.\n"
 
423
            "\nResult:\n"
 
424
            "\"signature\"          (string) The signature of the message encoded in base 64\n"
 
425
            "\nExamples:\n"
 
426
            "\nCreate the signature\n"
 
427
            + HelpExampleCli("signmessagewithprivkey", "\"privkey\" \"my message\"") +
 
428
            "\nVerify the signature\n"
 
429
            + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") +
 
430
            "\nAs json rpc\n"
 
431
            + HelpExampleRpc("signmessagewithprivkey", "\"privkey\", \"my message\"")
 
432
        );
 
433
 
 
434
    string strPrivkey = params[0].get_str();
 
435
    string strMessage = params[1].get_str();
 
436
 
 
437
    CBitcoinSecret vchSecret;
 
438
    bool fGood = vchSecret.SetString(strPrivkey);
 
439
    if (!fGood)
 
440
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
 
441
    CKey key = vchSecret.GetKey();
 
442
    if (!key.IsValid())
 
443
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");
 
444
 
 
445
    CHashWriter ss(SER_GETHASH, 0);
 
446
    ss << strMessageMagic;
 
447
    ss << strMessage;
 
448
 
 
449
    vector<unsigned char> vchSig;
 
450
    if (!key.SignCompact(ss.GetHash(), vchSig))
 
451
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed");
 
452
 
 
453
    return EncodeBase64(&vchSig[0], vchSig.size());
 
454
}
 
455
 
 
456
UniValue setmocktime(const UniValue& params, bool fHelp)
 
457
{
 
458
    if (fHelp || params.size() != 1)
 
459
        throw runtime_error(
 
460
            "setmocktime timestamp\n"
 
461
            "\nSet the local time to given timestamp (-regtest only)\n"
 
462
            "\nArguments:\n"
 
463
            "1. timestamp  (integer, required) Unix seconds-since-epoch timestamp\n"
 
464
            "   Pass 0 to go back to using the system time."
 
465
        );
 
466
 
 
467
    if (!Params().MineBlocksOnDemand())
 
468
        throw runtime_error("setmocktime for regression testing (-regtest mode) only");
 
469
 
 
470
    // cs_vNodes is locked and node send/receive times are updated
 
471
    // atomically with the time change to prevent peers from being
 
472
    // disconnected because we think we haven't communicated with them
 
473
    // in a long time.
 
474
    LOCK2(cs_main, cs_vNodes);
 
475
 
 
476
    RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM));
 
477
    SetMockTime(params[0].get_int64());
 
478
 
 
479
    uint64_t t = GetTime();
 
480
    BOOST_FOREACH(CNode* pnode, vNodes) {
 
481
        pnode->nLastSend = pnode->nLastRecv = t;
 
482
    }
 
483
 
 
484
    return NullUniValue;
 
485
}
 
486
 
 
487
static const CRPCCommand commands[] =
 
488
{ //  category              name                      actor (function)         okSafeMode
 
489
  //  --------------------- ------------------------  -----------------------  ----------
 
490
    { "control",            "getinfo",                &getinfo,                true  }, /* uses wallet if enabled */
 
491
    { "util",               "validateaddress",        &validateaddress,        true  }, /* uses wallet if enabled */
 
492
    { "util",               "createmultisig",         &createmultisig,         true  },
 
493
    { "util",               "createwitnessaddress",   &createwitnessaddress,   true  },
 
494
    { "util",               "verifymessage",          &verifymessage,          true  },
 
495
    { "util",               "signmessagewithprivkey", &signmessagewithprivkey, true  },
 
496
 
 
497
    /* Not shown in help */
 
498
    { "hidden",             "setmocktime",            &setmocktime,            true  },
 
499
};
 
500
 
 
501
void RegisterMiscRPCCommands(CRPCTable &tableRPC)
 
502
{
 
503
    for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
 
504
        tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
 
505
}