Anoncoin  0.9.4
P2P Digital Currency
rpcmisc.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin developers
3 // Copyright (c) 2013-2014 The Anoncoin Core developers
4 // Distributed under the MIT/X11 software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 
7 // Many builder specific things set in the config file, ENABLE_WALLET is a good example. Don't forget to include it this way in your source files.
8 #if defined(HAVE_CONFIG_H)
10 #endif
11 
12 #include "base58.h"
13 #include "init.h"
14 #include "main.h"
15 #include "net.h"
16 #include "netbase.h"
17 #include "rpcserver.h"
18 #include "util.h"
19 #ifdef ENABLE_WALLET
20 #include "wallet.h"
21 #include "walletdb.h"
22 #endif
23 
24 #include <stdint.h>
25 
26 #include <boost/assign/list_of.hpp>
27 #include "json/json_spirit_utils.h"
28 #include "json/json_spirit_value.h"
29 
30 using namespace std;
31 using namespace boost;
32 using namespace boost::assign;
33 using namespace json_spirit;
34 
35 Value getinfo(const Array& params, bool fHelp)
36 {
37  if (fHelp || params.size() != 0)
38  throw runtime_error(
39  "getinfo\n"
40  "Returns an object containing various state info.\n"
41  "\nResult:\n"
42  "{\n"
43  " \"version\": xxxxx, (numeric) the server version\n"
44  " \"protocolversion\": xxxxx, (numeric) the protocol version\n"
45  " \"walletversion\": xxxxx, (numeric) the wallet version\n"
46  " \"balance\": xxxxxxx, (numeric) the total anoncoin balance of the wallet\n"
47  " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
48  " \"timeoffset\": xxxxx, (numeric) the time offset\n"
49  " \"connections\": xxxxx, (numeric) the number of connections\n"
50  " \"proxy\": \"host:port\", (string, optional) the proxy used by the server\n"
51  " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
52  " \"testnet\": true|false, (boolean) if the server is using testnet or not\n"
53  " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n"
54  " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n"
55  " \"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"
56  " \"paytxfee\": x.xxxx, (numeric) the transaction fee set in btc/kb\n"
57  " \"relayfee\": x.xxxx, (numeric) minimum relay fee for non-free transactions in btc/kb\n"
58  " \"errors\": \"...\" (string) any error messages\n"
59  "}\n"
60  "\nExamples:\n"
61  + HelpExampleCli("getinfo", "")
62  + HelpExampleRpc("getinfo", "")
63  );
64 
65  proxyType proxy;
66  GetProxy(NET_IPV4, proxy);
67 
68  Object obj;
69  obj.push_back(Pair("version", (int)CLIENT_VERSION));
70  obj.push_back(Pair("protocolversion",(int)PROTOCOL_VERSION));
71 #ifdef ENABLE_WALLET
72  if (pwalletMain) {
73  obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
74  obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
75  }
76 #endif
77  obj.push_back(Pair("blocks", (int)chainActive.Height()));
78  obj.push_back(Pair("timeoffset", GetTimeOffset()));
79  obj.push_back(Pair("connections", (int)vNodes.size()));
80  obj.push_back(Pair("proxy", (proxy.IsValid() ? proxy.ToStringIPPort() : string())));
81  obj.push_back(Pair("difficulty", (double)GetDifficulty()));
82  obj.push_back(Pair("testnet", TestNet()));
83 #ifdef ENABLE_WALLET
84  if (pwalletMain) {
85  obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime()));
86  obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
87  }
89  obj.push_back(Pair("unlocked_until", nWalletUnlockTime));
90  obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee)));
91 #endif
92  obj.push_back(Pair("relayfee", ValueFromAmount(CTransaction::nMinRelayTxFee)));
93  obj.push_back(Pair("errors", GetWarnings("statusbar")));
94  return obj;
95 }
96 
97 #ifdef ENABLE_WALLET
98 class DescribeAddressVisitor : public boost::static_visitor<Object>
99 {
100 private:
101  isminetype mine;
102 
103 public:
104  DescribeAddressVisitor(isminetype mineIn) : mine(mineIn) {}
105 
106  Object operator()(const CNoDestination &dest) const { return Object(); }
107 
108  Object operator()(const CKeyID &keyID) const {
109  Object obj;
110  CPubKey vchPubKey;
111  obj.push_back(Pair("isscript", false));
112  if (mine == ISMINE_SPENDABLE) {
113  pwalletMain->GetPubKey(keyID, vchPubKey);
114  obj.push_back(Pair("pubkey", HexStr(vchPubKey)));
115  obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed()));
116  }
117  return obj;
118  }
119 
120  Object operator()(const CScriptID &scriptID) const {
121  Object obj;
122  obj.push_back(Pair("isscript", true));
123  if (mine != ISMINE_NO) {
124  CScript subscript;
125  pwalletMain->GetCScript(scriptID, subscript);
126  std::vector<CTxDestination> addresses;
127  txnouttype whichType;
128  int nRequired;
129  ExtractDestinations(subscript, whichType, addresses, nRequired);
130  obj.push_back(Pair("script", GetTxnOutputType(whichType)));
131  obj.push_back(Pair("hex", HexStr(subscript.begin(), subscript.end())));
132  Array a;
133  BOOST_FOREACH(const CTxDestination& addr, addresses)
134  a.push_back(CAnoncoinAddress(addr).ToString());
135  obj.push_back(Pair("addresses", a));
136  if (whichType == TX_MULTISIG)
137  obj.push_back(Pair("sigsrequired", nRequired));
138  }
139  return obj;
140  }
141 };
142 #endif
143 
144 Value validateaddress(const Array& params, bool fHelp)
145 {
146  if (fHelp || params.size() != 1)
147  throw runtime_error(
148  "validateaddress \"anoncoinaddress\"\n"
149  "\nReturn information about the given anoncoin address.\n"
150  "\nArguments:\n"
151  "1. \"anoncoinaddress\" (string, required) The anoncoin address to validate\n"
152  "\nResult:\n"
153  "{\n"
154  " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
155  " \"address\" : \"anoncoinaddress\", (string) The anoncoin address validated\n"
156  " \"ismine\" : true|false, (boolean) If the address is yours or not\n"
157  " \"isscript\" : true|false, (boolean) If the key is a script\n"
158  " \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n"
159  " \"iscompressed\" : true|false, (boolean) If the address is compressed\n"
160  " \"account\" : \"account\" (string) The account associated with the address, \"\" is the default account\n"
161  "}\n"
162  "\nExamples:\n"
163  + HelpExampleCli("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
164  + HelpExampleRpc("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
165  );
166 
167  CAnoncoinAddress address(params[0].get_str());
168  bool isValid = address.IsValid();
169 
170  Object ret;
171  ret.push_back(Pair("isvalid", isValid));
172  if (isValid)
173  {
174  CTxDestination dest = address.Get();
175  string currentAddress = address.ToString();
176  ret.push_back(Pair("address", currentAddress));
177 #ifdef ENABLE_WALLET
179  ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false));
180  if (mine != ISMINE_NO) {
181  ret.push_back(Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true: false));
182  Object detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest);
183  ret.insert(ret.end(), detail.begin(), detail.end());
184  }
185  if (pwalletMain && pwalletMain->mapAddressBook.count(dest))
186  ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name));
187 #endif
188  }
189  return ret;
190 }
191 
192 //
193 // Used by addmultisigaddress / createmultisig:
194 //
196 {
197  int nRequired = params[0].get_int();
198  const Array& keys = params[1].get_array();
199 
200  // Gather public keys
201  if (nRequired < 1)
202  throw runtime_error("a multisignature address must require at least one key to redeem");
203  if ((int)keys.size() < nRequired)
204  throw runtime_error(
205  strprintf("not enough keys supplied "
206  "(got %u keys, but need at least %d to redeem)", keys.size(), nRequired));
207  std::vector<CPubKey> pubkeys;
208  pubkeys.resize(keys.size());
209  for (unsigned int i = 0; i < keys.size(); i++)
210  {
211  const std::string& ks = keys[i].get_str();
212 #ifdef ENABLE_WALLET
213  // Case 1: Anoncoin address and we have full public key:
214  CAnoncoinAddress address(ks);
215  if (pwalletMain && address.IsValid())
216  {
217  CKeyID keyID;
218  if (!address.GetKeyID(keyID))
219  throw runtime_error(
220  strprintf("%s does not refer to a key",ks));
221  CPubKey vchPubKey;
222  if (!pwalletMain->GetPubKey(keyID, vchPubKey))
223  throw runtime_error(
224  strprintf("no full public key for address %s",ks));
225  if (!vchPubKey.IsFullyValid())
226  throw runtime_error(" Invalid public key: "+ks);
227  pubkeys[i] = vchPubKey;
228  }
229 
230  // Case 2: hex public key
231  else
232 #endif
233  if (IsHex(ks))
234  {
235  CPubKey vchPubKey(ParseHex(ks));
236  if (!vchPubKey.IsFullyValid())
237  throw runtime_error(" Invalid public key: "+ks);
238  pubkeys[i] = vchPubKey;
239  }
240  else
241  {
242  throw runtime_error(" Invalid public key: "+ks);
243  }
244  }
245  CScript result;
246  result.SetMultisig(nRequired, pubkeys);
247 
248  if (result.size() > MAX_SCRIPT_ELEMENT_SIZE)
249  throw runtime_error(
250  strprintf("redeemScript exceeds size limit: %d > %d", result.size(), MAX_SCRIPT_ELEMENT_SIZE));
251 
252  return result;
253 }
254 
255 Value createmultisig(const Array& params, bool fHelp)
256 {
257  if (fHelp || params.size() < 2 || params.size() > 2)
258  {
259  string msg = "createmultisig nrequired [\"key\",...]\n"
260  "\nCreates a multi-signature address with n signature of m keys required.\n"
261  "It returns a json object with the address and redeemScript.\n"
262 
263  "\nArguments:\n"
264  "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
265  "2. \"keys\" (string, required) A json array of keys which are anoncoin addresses or hex-encoded public keys\n"
266  " [\n"
267  " \"key\" (string) anoncoin address or hex-encoded public key\n"
268  " ,...\n"
269  " ]\n"
270 
271  "\nResult:\n"
272  "{\n"
273  " \"address\":\"multisigaddress\", (string) The value of the new multisig address.\n"
274  " \"redeemScript\":\"script\" (string) The string value of the hex-encoded redemption script.\n"
275  "}\n"
276 
277  "\nExamples:\n"
278  "\nCreate a multisig address from 2 addresses\n"
279  + HelpExampleCli("createmultisig", "2 \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") +
280  "\nAs a json rpc call\n"
281  + HelpExampleRpc("createmultisig", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"")
282  ;
283  throw runtime_error(msg);
284  }
285 
286  // Construct using pay-to-script-hash:
287  CScript inner = _createmultisig_redeemScript(params);
288  CScriptID innerID = inner.GetID();
289  CAnoncoinAddress address(innerID);
290 
291  Object result;
292  result.push_back(Pair("address", address.ToString()));
293  result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end())));
294 
295  return result;
296 }
297 
298 Value verifymessage(const Array& params, bool fHelp)
299 {
300  if (fHelp || params.size() != 3)
301  throw runtime_error(
302  "verifymessage \"anoncoinaddress\" \"signature\" \"message\"\n"
303  "\nVerify a signed message\n"
304  "\nArguments:\n"
305  "1. \"anoncoinaddress\" (string, required) The anoncoin address to use for the signature.\n"
306  "2. \"signature\" (string, required) The signature provided by the signer in base 64 encoding (see signmessage).\n"
307  "3. \"message\" (string, required) The message that was signed.\n"
308  "\nResult:\n"
309  "true|false (boolean) If the signature is verified or not.\n"
310  "\nExamples:\n"
311  "\nUnlock the wallet for 30 seconds\n"
312  + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
313  "\nCreate the signature\n"
314  + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"my message\"") +
315  "\nVerify the signature\n"
316  + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") +
317  "\nAs json rpc\n"
318  + HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"signature\", \"my message\"")
319  );
320 
321  string strAddress = params[0].get_str();
322  string strSign = params[1].get_str();
323  string strMessage = params[2].get_str();
324 
325  CAnoncoinAddress addr(strAddress);
326  if (!addr.IsValid())
327  throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
328 
329  CKeyID keyID;
330  if (!addr.GetKeyID(keyID))
331  throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
332 
333  bool fInvalid = false;
334  vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);
335 
336  if (fInvalid)
337  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding");
338 
339  CHashWriter ss(SER_GETHASH, 0);
340  ss << strMessageMagic;
341  ss << strMessage;
342 
343  CPubKey pubkey;
344  if (!pubkey.RecoverCompact(ss.GetHash(), vchSig))
345  return false;
346 
347  return (pubkey.GetID() == keyID);
348 }
CScript _createmultisig_redeemScript(const Array &params)
Definition: rpcmisc.cpp:195
int64_t nWalletUnlockTime
Definition: rpcwallet.cpp:27
bool IsCrypted() const
Definition: crypter.h:138
Definition: init.h:14
std::map< CTxDestination, CAddressBookData > mapAddressBook
Definition: wallet.h:174
#define strprintf
Definition: tinyformat.h:1011
isminetype IsMine(const CKeyStore &keystore, const CTxDestination &dest)
Definition: script.cpp:1450
Value getinfo(const Array &params, bool fHelp)
Definition: rpcmisc.cpp:35
std::string ToStringIPPort() const
Definition: netbase.cpp:1314
std::string HelpExampleRpc(string methodname, string args)
Definition: rpcserver.cpp:903
bool TestNet()
Definition: chainparams.h:127
CTxDestination Get() const
Definition: base58.cpp:223
string GetWarnings(string strFor)
Definition: main.cpp:3093
bool GetKeyID(CKeyID &keyID) const
Definition: base58.cpp:236
const char * GetTxnOutputType(txnouttype t)
Definition: script.cpp:66
unsigned int GetKeyPoolSize()
Definition: wallet.h:373
bool IsHex(const string &str)
Definition: util.cpp:409
Object JSONRPCError(int code, const string &message)
bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const
Definition: crypter.cpp:236
const string strMessageMagic
Definition: main.cpp:77
CChain chainActive
The currently-connected chain of blocks.
Definition: main.cpp:43
bool IsValid() const
Definition: base58.cpp:216
vector< CNode * > vNodes
Definition: net.cpp:74
isminetype
IsMine() return codes.
Definition: script.h:197
int64_t GetBalance() const
Definition: wallet.cpp:1019
int Height() const
Return the maximal height in the chain.
Definition: main.h:1055
Value ValueFromAmount(int64_t amount)
Definition: rpcserver.cpp:100
int64_t nTransactionFee
Definition: wallet.cpp:20
bool IsValid() const
Definition: netbase.cpp:816
int64_t GetOldestKeyPoolTime()
Definition: wallet.cpp:1835
txnouttype
Definition: script.h:207
bool RecoverCompact(const uint256 &hash, const std::vector< unsigned char > &vchSig)
Definition: key.cpp:457
int GetVersion()
Definition: wallet.h:388
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netbase.h:109
An encapsulated public key.
Definition: key.h:43
base58-encoded Anoncoin addresses.
Definition: base58.h:102
std::string ToString() const
Definition: base58.cpp:175
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
Definition: keystore.h:17
Value createmultisig(const Array &params, bool fHelp)
Definition: rpcmisc.cpp:255
bool IsCompressed() const
Definition: key.h:152
uint256 GetHash()
Definition: hash.h:53
bool ExtractDestinations(const CScript &scriptPubKey, txnouttype &typeRet, vector< CTxDestination > &addressRet, int &nRequiredRet)
Definition: script.cpp:1539
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:413
double GetDifficulty(const CBlockIndex *blockindex)
void SetMultisig(int nRequired, const std::vector< CPubKey > &keys)
Definition: script.cpp:1950
int64_t GetTimeOffset()
Definition: util.cpp:1235
A reference to a CKey: the Hash160 of its serialized public key.
Definition: key.h:27
bool IsFullyValid() const
Definition: key.cpp:482
CScriptID GetID() const
Definition: script.h:720
virtual bool GetCScript(const CScriptID &hash, CScript &redeemScriptOut) const
Definition: keystore.cpp:51
static int64_t nMinRelayTxFee
Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) ...
Definition: core.h:183
Value verifymessage(const Array &params, bool fHelp)
Definition: rpcmisc.cpp:298
A reference to a CScript: the Hash160 of its serialization (see script.h)
Definition: key.h:35
bool GetProxy(enum Network net, proxyType &proxyInfoOut)
Definition: netbase.cpp:476
std::string HelpExampleCli(string methodname, string args)
Definition: rpcserver.cpp:899
vector< unsigned char > DecodeBase64(const char *p, bool *pfInvalid)
Definition: util.cpp:599
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
Definition: util.h:256
CKeyID GetID() const
Definition: key.h:132
vector< unsigned char > ParseHex(const char *psz)
Definition: util.cpp:419
Value validateaddress(const Array &params, bool fHelp)
Definition: rpcmisc.cpp:144
CWallet * pwalletMain