Master Core  v0.0.9 - 2abfd2849db8ba7a83957c64eb976b406713c123
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
rpcmisc.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin developers
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"
7 #include "init.h"
8 #include "main.h"
9 #include "net.h"
10 #include "netbase.h"
11 #include "rpcserver.h"
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 
24 using namespace std;
25 using namespace boost;
26 using namespace boost::assign;
27 using namespace json_spirit;
28 
29 Value 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  " \"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"
50  " \"paytxfee\": x.xxxx, (numeric) the transaction fee set in btc/kb\n"
51  " \"relayfee\": x.xxxx, (numeric) minimum relay fee for non-free transactions in btc/kb\n"
52  " \"errors\": \"...\" (string) any error messages\n"
53  "}\n"
54  "\nExamples:\n"
55  + HelpExampleCli("getinfo", "")
56  + HelpExampleRpc("getinfo", "")
57  );
58 
59  proxyType proxy;
60  GetProxy(NET_IPV4, proxy);
61 
62  Object obj;
63  obj.push_back(Pair("version", (int)CLIENT_VERSION));
64  obj.push_back(Pair("protocolversion",(int)PROTOCOL_VERSION));
65 #ifdef ENABLE_WALLET
66  if (pwalletMain) {
67  obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
68  obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
69  }
70 #endif
71  obj.push_back(Pair("blocks", (int)chainActive.Height()));
72  obj.push_back(Pair("timeoffset", GetTimeOffset()));
73  obj.push_back(Pair("connections", (int)vNodes.size()));
74  obj.push_back(Pair("proxy", (proxy.first.IsValid() ? proxy.first.ToStringIPPort() : string())));
75  obj.push_back(Pair("difficulty", (double)GetDifficulty()));
76  obj.push_back(Pair("testnet", TestNet()));
77 #ifdef ENABLE_WALLET
78  if (pwalletMain) {
79  obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime()));
80  obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
81  }
83  obj.push_back(Pair("unlocked_until", nWalletUnlockTime));
84  obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee)));
85 #endif
86  obj.push_back(Pair("relayfee", ValueFromAmount(CTransaction::nMinRelayTxFee)));
87  obj.push_back(Pair("errors", GetWarnings("statusbar")));
88  return obj;
89 }
90 
91 #ifdef ENABLE_WALLET
92 class DescribeAddressVisitor : public boost::static_visitor<Object>
93 {
94 public:
95  Object operator()(const CNoDestination &dest) const { return Object(); }
96 
97  Object operator()(const CKeyID &keyID) const {
98  Object obj;
99  CPubKey vchPubKey;
100  pwalletMain->GetPubKey(keyID, vchPubKey);
101  obj.push_back(Pair("isscript", false));
102  obj.push_back(Pair("pubkey", HexStr(vchPubKey)));
103  obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed()));
104  return obj;
105  }
106 
107  Object operator()(const CScriptID &scriptID) const {
108  Object obj;
109  obj.push_back(Pair("isscript", true));
110  CScript subscript;
111  pwalletMain->GetCScript(scriptID, subscript);
112  std::vector<CTxDestination> addresses;
113  txnouttype whichType;
114  int nRequired;
115  ExtractDestinations(subscript, whichType, addresses, nRequired);
116  obj.push_back(Pair("script", GetTxnOutputType(whichType)));
117  obj.push_back(Pair("hex", HexStr(subscript.begin(), subscript.end())));
118  Array a;
119  BOOST_FOREACH(const CTxDestination& addr, addresses)
120  a.push_back(CBitcoinAddress(addr).ToString());
121  obj.push_back(Pair("addresses", a));
122  if (whichType == TX_MULTISIG)
123  obj.push_back(Pair("sigsrequired", nRequired));
124  return obj;
125  }
126 };
127 #endif
128 
129 Value validateaddress(const Array& params, bool fHelp)
130 {
131  if (fHelp || params.size() != 1)
132  throw runtime_error(
133  "validateaddress \"bitcoinaddress\"\n"
134  "\nReturn information about the given bitcoin address.\n"
135  "\nArguments:\n"
136  "1. \"bitcoinaddress\" (string, required) The bitcoin address to validate\n"
137  "\nResult:\n"
138  "{\n"
139  " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
140  " \"address\" : \"bitcoinaddress\", (string) The bitcoin address validated\n"
141  " \"ismine\" : true|false, (boolean) If the address is yours or not\n"
142  " \"isscript\" : true|false, (boolean) If the key is a script\n"
143  " \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n"
144  " \"iscompressed\" : true|false, (boolean) If the address is compressed\n"
145  " \"account\" : \"account\" (string) The account associated with the address, \"\" is the default account\n"
146  "}\n"
147  "\nExamples:\n"
148  + HelpExampleCli("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
149  + HelpExampleRpc("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
150  );
151 
152  CBitcoinAddress address(params[0].get_str());
153  bool isValid = address.IsValid();
154 
155  Object ret;
156  ret.push_back(Pair("isvalid", isValid));
157  if (isValid)
158  {
159  CTxDestination dest = address.Get();
160  string currentAddress = address.ToString();
161  ret.push_back(Pair("address", currentAddress));
162 #ifdef ENABLE_WALLET
163  bool fMine = pwalletMain ? IsMine(*pwalletMain, dest) : false;
164  ret.push_back(Pair("ismine", fMine));
165  if (fMine) {
166  Object detail = boost::apply_visitor(DescribeAddressVisitor(), dest);
167  ret.insert(ret.end(), detail.begin(), detail.end());
168  }
169  if (pwalletMain && pwalletMain->mapAddressBook.count(dest))
170  ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name));
171 #endif
172  }
173  return ret;
174 }
175 
176 //
177 // Used by addmultisigaddress / createmultisig:
178 //
180 {
181  int nRequired = params[0].get_int();
182  const Array& keys = params[1].get_array();
183 
184  // Gather public keys
185  if (nRequired < 1)
186  throw runtime_error("a multisignature address must require at least one key to redeem");
187  if ((int)keys.size() < nRequired)
188  throw runtime_error(
189  strprintf("not enough keys supplied "
190  "(got %u keys, but need at least %d to redeem)", keys.size(), nRequired));
191  std::vector<CPubKey> pubkeys;
192  pubkeys.resize(keys.size());
193  for (unsigned int i = 0; i < keys.size(); i++)
194  {
195  const std::string& ks = keys[i].get_str();
196 #ifdef ENABLE_WALLET
197  // Case 1: Bitcoin address and we have full public key:
198  CBitcoinAddress address(ks);
199  if (pwalletMain && address.IsValid())
200  {
201  CKeyID keyID;
202  if (!address.GetKeyID(keyID))
203  throw runtime_error(
204  strprintf("%s does not refer to a key",ks));
205  CPubKey vchPubKey;
206  if (!pwalletMain->GetPubKey(keyID, vchPubKey))
207  throw runtime_error(
208  strprintf("no full public key for address %s",ks));
209  if (!vchPubKey.IsFullyValid())
210  throw runtime_error(" Invalid public key: "+ks);
211  pubkeys[i] = vchPubKey;
212  }
213 
214  // Case 2: hex public key
215  else
216 #endif
217  if (IsHex(ks))
218  {
219  CPubKey vchPubKey(ParseHex(ks));
220  if (!vchPubKey.IsFullyValid())
221  throw runtime_error(" Invalid public key: "+ks);
222  pubkeys[i] = vchPubKey;
223  }
224  else
225  {
226  throw runtime_error(" Invalid public key: "+ks);
227  }
228  }
229  CScript result;
230  result.SetMultisig(nRequired, pubkeys);
231 
232  if (result.size() > MAX_SCRIPT_ELEMENT_SIZE)
233  throw runtime_error(
234  strprintf("redeemScript exceeds size limit: %d > %d", result.size(), MAX_SCRIPT_ELEMENT_SIZE));
235 
236  return result;
237 }
238 
239 Value createmultisig(const Array& params, bool fHelp)
240 {
241  if (fHelp || params.size() < 2 || params.size() > 2)
242  {
243  string msg = "createmultisig nrequired [\"key\",...]\n"
244  "\nCreates a multi-signature address with n signature of m keys required.\n"
245  "It returns a json object with the address and redeemScript.\n"
246 
247  "\nArguments:\n"
248  "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
249  "2. \"keys\" (string, required) A json array of keys which are bitcoin addresses or hex-encoded public keys\n"
250  " [\n"
251  " \"key\" (string) bitcoin address or hex-encoded public key\n"
252  " ,...\n"
253  " ]\n"
254 
255  "\nResult:\n"
256  "{\n"
257  " \"address\":\"multisigaddress\", (string) The value of the new multisig address.\n"
258  " \"redeemScript\":\"script\" (string) The string value of the hex-encoded redemption script.\n"
259  "}\n"
260 
261  "\nExamples:\n"
262  "\nCreate a multisig address from 2 addresses\n"
263  + HelpExampleCli("createmultisig", "2 \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") +
264  "\nAs a json rpc call\n"
265  + HelpExampleRpc("createmultisig", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"")
266  ;
267  throw runtime_error(msg);
268  }
269 
270  // Construct using pay-to-script-hash:
271  CScript inner = _createmultisig_redeemScript(params);
272  CScriptID innerID = inner.GetID();
273  CBitcoinAddress address(innerID);
274 
275  Object result;
276  result.push_back(Pair("address", address.ToString()));
277  result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end())));
278 
279  return result;
280 }
281 
282 Value verifymessage(const Array& params, bool fHelp)
283 {
284  if (fHelp || params.size() != 3)
285  throw runtime_error(
286  "verifymessage \"bitcoinaddress\" \"signature\" \"message\"\n"
287  "\nVerify a signed message\n"
288  "\nArguments:\n"
289  "1. \"bitcoinaddress\" (string, required) The bitcoin address to use for the signature.\n"
290  "2. \"signature\" (string, required) The signature provided by the signer in base 64 encoding (see signmessage).\n"
291  "3. \"message\" (string, required) The message that was signed.\n"
292  "\nResult:\n"
293  "true|false (boolean) If the signature is verified or not.\n"
294  "\nExamples:\n"
295  "\nUnlock the wallet for 30 seconds\n"
296  + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
297  "\nCreate the signature\n"
298  + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"my message\"") +
299  "\nVerify the signature\n"
300  + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") +
301  "\nAs json rpc\n"
302  + HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"signature\", \"my message\"")
303  );
304 
305  string strAddress = params[0].get_str();
306  string strSign = params[1].get_str();
307  string strMessage = params[2].get_str();
308 
309  CBitcoinAddress addr(strAddress);
310  if (!addr.IsValid())
311  throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
312 
313  CKeyID keyID;
314  if (!addr.GetKeyID(keyID))
315  throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
316 
317  bool fInvalid = false;
318  vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);
319 
320  if (fInvalid)
321  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding");
322 
323  CHashWriter ss(SER_GETHASH, 0);
324  ss << strMessageMagic;
325  ss << strMessage;
326 
327  CPubKey pubkey;
328  if (!pubkey.RecoverCompact(ss.GetHash(), vchSig))
329  return false;
330 
331  return (pubkey.GetID() == keyID);
332 }
CScript _createmultisig_redeemScript(const Array &params)
Definition: rpcmisc.cpp:179
int64_t nWalletUnlockTime
Definition: rpcwallet.cpp:26
bool IsValid() const
Definition: base58.cpp:215
bool IsCrypted() const
Definition: crypter.h:137
Definition: init.h:13
std::map< CTxDestination, CAddressBookData > mapAddressBook
Definition: wallet.h:173
Value getinfo(const Array &params, bool fHelp)
Definition: rpcmisc.cpp:29
std::string HelpExampleRpc(string methodname, string args)
Definition: rpcserver.cpp:923
bool TestNet()
Definition: chainparams.h:100
static const int CLIENT_VERSION
Definition: version.h:15
string GetWarnings(string strFor)
Format a string that describes several potential problems detected by the core.
Definition: main.cpp:3204
#define strprintf
Definition: util.h:116
STL namespace.
const char * GetTxnOutputType(txnouttype t)
Definition: script.cpp:65
unsigned int GetKeyPoolSize()
Definition: wallet.h:363
bool IsHex(const string &str)
Definition: util.cpp:409
Object JSONRPCError(int code, const string &message)
base58-encoded Bitcoin addresses.
Definition: base58.h:101
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
Definition: script.h:24
CTxDestination Get() const
Definition: base58.cpp:222
bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const
Definition: crypter.cpp:235
const string strMessageMagic
Definition: main.cpp:82
CChain chainActive
The currently-connected chain of blocks.
Definition: main.cpp:48
vector< CNode * > vNodes
Definition: net.cpp:63
bool GetKeyID(CKeyID &keyID) const
Definition: base58.cpp:235
int64_t GetBalance() const
Definition: wallet.cpp:980
int Height() const
Return the maximal height in the chain.
Definition: main.h:1043
Value ValueFromAmount(int64_t amount)
Definition: rpcserver.cpp:94
int64_t nTransactionFee
Definition: wallet.cpp:19
int64_t GetOldestKeyPoolTime()
Definition: wallet.cpp:1745
txnouttype
Definition: script.h:195
bool RecoverCompact(const uint256 &hash, const std::vector< unsigned char > &vchSig)
Definition: key.cpp:448
int GetVersion()
Definition: wallet.h:378
An encapsulated public key.
Definition: key.h:42
std::string ToString() const
Definition: base58.cpp:174
Value createmultisig(const Array &params, bool fHelp)
Definition: rpcmisc.cpp:239
bool IsCompressed() const
Definition: key.h:151
uint256 GetHash()
Definition: hash.h:52
bool ExtractDestinations(const CScript &scriptPubKey, txnouttype &typeRet, vector< CTxDestination > &addressRet, int &nRequiredRet)
Definition: script.cpp:1519
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:401
static const int PROTOCOL_VERSION
Definition: version.h:29
double GetDifficulty(const CBlockIndex *blockindex)
void SetMultisig(int nRequired, const std::vector< CPubKey > &keys)
Definition: script.cpp:1930
bool IsMine(const CKeyStore &keystore, const CTxDestination &dest)
Definition: script.cpp:1448
int64_t GetTimeOffset()
Definition: util.cpp:1230
A reference to a CKey: the Hash160 of its serialized public key.
Definition: key.h:26
bool IsFullyValid() const
Definition: key.cpp:473
CScriptID GetID() const
Definition: script.h:708
virtual bool GetCScript(const CScriptID &hash, CScript &redeemScriptOut) const
Definition: keystore.cpp:50
std::pair< CService, int > proxyType
Definition: netbase.h:136
static int64_t nMinRelayTxFee
Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) ...
Definition: core.h:187
Value verifymessage(const Array &params, bool fHelp)
Definition: rpcmisc.cpp:282
A reference to a CScript: the Hash160 of its serialization (see script.h)
Definition: key.h:34
bool GetProxy(enum Network net, proxyType &proxyInfoOut)
Definition: netbase.cpp:430
std::string HelpExampleCli(string methodname, string args)
Definition: rpcserver.cpp:919
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
Definition: script.h:218
vector< unsigned char > DecodeBase64(const char *p, bool *pfInvalid)
Definition: util.cpp:598
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
Definition: util.h:263
CKeyID GetID() const
Definition: key.h:131
vector< unsigned char > ParseHex(const char *psz)
Definition: util.cpp:419
Value validateaddress(const Array &params, bool fHelp)
Definition: rpcmisc.cpp:129
CWallet * pwalletMain