]> Git Repo - VerusCoin.git/blame - src/rpcmisc.cpp
Fix exception
[VerusCoin.git] / src / rpcmisc.cpp
CommitLineData
652e1569 1// Copyright (c) 2010 Satoshi Nakamoto
f914f1a7 2// Copyright (c) 2009-2014 The Bitcoin Core 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"
8b78a819 14#include "txmempool.h"
652e1569
WL
15#include "util.h"
16#ifdef ENABLE_WALLET
50c72f23
JS
17#include "wallet/wallet.h"
18#include "wallet/walletdb.h"
652e1569
WL
19#endif
20
21#include <stdint.h>
22
23#include <boost/assign/list_of.hpp>
a10a6e2a
JS
24
25#include <univalue.h>
652e1569 26
4e16a724
S
27#include "zcash/Address.hpp"
28
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 **/
945f015d 44
b487a8fe 45int32_t Jumblr_depositaddradd(char *depositaddr);
eeaaf554 46int32_t Jumblr_secretaddradd(char *secretaddr);
da16b12e 47uint64_t komodo_interestsum();
f595c2e0 48int32_t komodo_longestchain();
69d23911 49int32_t komodo_notarized_height(int32_t *prevhtp,uint256 *hashp,uint256 *txidp);
e34a9d43 50uint32_t komodo_chainactive_timestamp();
8683bd8d 51int32_t komodo_whoami(char *pubkeystr,int32_t height,uint32_t timestamp);
94d3d09d 52extern uint64_t KOMODO_INTERESTSUM,KOMODO_WALLETBALANCE;
6bb74a02 53extern int32_t KOMODO_LASTMINED,JUMBLR_PAUSE,KOMODO_LONGESTCHAIN;
9edf27ec 54extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
acbc7a94 55uint32_t komodo_segid32(char *coinaddr);
0cb025c1 56int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *kmdnotarized_heightp);
eeaaf554 57#define KOMODO_VERSION "0.1.1"
05c2ba63 58extern uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT;
dbc80050 59extern uint32_t ASSETCHAINS_CC;
60extern uint32_t ASSETCHAINS_MAGIC;
61extern uint64_t ASSETCHAINS_ENDSUBSIDY,ASSETCHAINS_REWARD,ASSETCHAINS_HALVING,ASSETCHAINS_DECAY,ASSETCHAINS_COMMISSION,ASSETCHAINS_STAKED,ASSETCHAINS_SUPPLY;
09e3cf94 62
d014114d 63UniValue getinfo(const UniValue& params, bool fHelp)
16bc9aaf 64{
69d23911 65 uint256 notarized_hash,notarized_desttxid; int32_t prevMoMheight,notarized_height,longestchain,kmdnotarized_height,txid_height;
16bc9aaf
WL
66 if (fHelp || params.size() != 0)
67 throw runtime_error(
68 "getinfo\n"
69 "Returns an object containing various state info.\n"
70 "\nResult:\n"
71 "{\n"
72 " \"version\": xxxxx, (numeric) the server version\n"
73 " \"protocolversion\": xxxxx, (numeric) the protocol version\n"
74 " \"walletversion\": xxxxx, (numeric) the wallet version\n"
a7322d77 75 " \"balance\": xxxxxxx, (numeric) the total Komodo balance of the wallet\n"
16bc9aaf
WL
76 " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
77 " \"timeoffset\": xxxxx, (numeric) the time offset\n"
78 " \"connections\": xxxxx, (numeric) the number of connections\n"
79 " \"proxy\": \"host:port\", (string, optional) the proxy used by the server\n"
80 " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
81 " \"testnet\": true|false, (boolean) if the server is using testnet or not\n"
82 " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n"
83 " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n"
16bc9aaf 84 " \"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"
091b2116
RN
85 " \"paytxfee\": x.xxxx, (numeric) the transaction fee set in " + CURRENCY_UNIT + "/kB\n"
86 " \"relayfee\": x.xxxx, (numeric) minimum relay fee for non-free transactions in " + CURRENCY_UNIT + "/kB\n"
16bc9aaf
WL
87 " \"errors\": \"...\" (string) any error messages\n"
88 "}\n"
89 "\nExamples:\n"
90 + HelpExampleCli("getinfo", "")
91 + HelpExampleRpc("getinfo", "")
92 );
247428bd 93//#ifdef ENABLE_WALLET
94// LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
95//#else
4add33cf 96 LOCK(cs_main);
247428bd 97//#endif
4401b2d7 98
16bc9aaf
WL
99 proxyType proxy;
100 GetProxy(NET_IPV4, proxy);
69d23911 101 notarized_height = komodo_notarized_height(&prevMoMheight,&notarized_hash,&notarized_desttxid);
6f1de985 102 //fprintf(stderr,"after notarized_height %u\n",(uint32_t)time(NULL));
16bc9aaf 103
38fc4b70 104 UniValue obj(UniValue::VOBJ);
faadbe17
PK
105 obj.push_back(Pair("version", CLIENT_VERSION));
106 obj.push_back(Pair("protocolversion", PROTOCOL_VERSION));
b000fa04 107 obj.push_back(Pair("KMDversion", KOMODO_VERSION));
c75c18fc 108 obj.push_back(Pair("notarized", notarized_height));
69d23911 109 obj.push_back(Pair("prevMoMheight", prevMoMheight));
c75c18fc 110 obj.push_back(Pair("notarizedhash", notarized_hash.ToString()));
111 obj.push_back(Pair("notarizedtxid", notarized_desttxid.ToString()));
6f1de985 112 txid_height = notarizedtxid_height(ASSETCHAINS_SYMBOL[0] != 0 ? (char *)"KMD" : (char *)"BTC",(char *)notarized_desttxid.ToString().c_str(),&kmdnotarized_height);
70d83934 113 if ( txid_height > 0 )
114 obj.push_back(Pair("notarizedtxid_height", txid_height));
6f1de985 115 else obj.push_back(Pair("notarizedtxid_height", "mempool"));
57dd4ada 116 if ( ASSETCHAINS_SYMBOL[0] != 0 )
117 obj.push_back(Pair("KMDnotarized_height", kmdnotarized_height));
118 obj.push_back(Pair("notarized_confirms", txid_height < kmdnotarized_height ? (kmdnotarized_height - txid_height + 1) : 0));
6f1de985 119 //fprintf(stderr,"after notarized_confirms %u\n",(uint32_t)time(NULL));
16bc9aaf
WL
120#ifdef ENABLE_WALLET
121 if (pwalletMain) {
122 obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
247428bd 123 obj.push_back(Pair("balance", ValueFromAmount(KOMODO_WALLETBALANCE))); //pwalletMain->GetBalance()
9e1bde7e 124 if ( ASSETCHAINS_SYMBOL[0] == 0 )
247428bd 125 obj.push_back(Pair("interest", ValueFromAmount(KOMODO_INTERESTSUM))); //komodo_interestsum()
16bc9aaf
WL
126 }
127#endif
6f1de985 128 //fprintf(stderr,"after wallet %u\n",(uint32_t)time(NULL));
16bc9aaf 129 obj.push_back(Pair("blocks", (int)chainActive.Height()));
daf214b1 130 if ( (longestchain= KOMODO_LONGESTCHAIN) != 0 && chainActive.Height() > longestchain )
a19b28ce 131 longestchain = chainActive.Height();
6f1de985 132 //fprintf(stderr,"after longestchain %u\n",(uint32_t)time(NULL));
a19b28ce 133 obj.push_back(Pair("longestchain", longestchain));
d56e30ca 134 obj.push_back(Pair("timeoffset", GetTimeOffset()));
98d166cf 135 if ( chainActive.Tip() != 0 )
49c9db6a 136 obj.push_back(Pair("tiptime", (int)chainActive.Tip()->nTime));
16bc9aaf 137 obj.push_back(Pair("connections", (int)vNodes.size()));
67a79493 138 obj.push_back(Pair("proxy", (proxy.IsValid() ? proxy.proxy.ToStringIPPort() : string())));
16bc9aaf 139 obj.push_back(Pair("difficulty", (double)GetDifficulty()));
cc972107 140 obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC()));
16bc9aaf
WL
141#ifdef ENABLE_WALLET
142 if (pwalletMain) {
d56e30ca 143 obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime()));
16bc9aaf
WL
144 obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
145 }
16bc9aaf 146 if (pwalletMain && pwalletMain->IsCrypted())
d56e30ca 147 obj.push_back(Pair("unlocked_until", nWalletUnlockTime));
c6cb21d1 148 obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())));
16bc9aaf 149#endif
13fc83c7 150 obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())));
16bc9aaf 151 obj.push_back(Pair("errors", GetWarnings("statusbar")));
58033467 152 {
153 char pubkeystr[65]; int32_t notaryid;
e34a9d43 154 if ( (notaryid= komodo_whoami(pubkeystr,(int32_t)chainActive.Tip()->nHeight,komodo_chainactive_timestamp())) >= 0 )
1e2a41f6 155 {
156 obj.push_back(Pair("notaryid", notaryid));
157 obj.push_back(Pair("pubkey", pubkeystr));
158 if ( KOMODO_LASTMINED != 0 )
159 obj.push_back(Pair("lastmined", KOMODO_LASTMINED));
160 }
58033467 161 }
dbc80050 162 if ( ASSETCHAINS_CC != 0 )
91e76e0c 163 obj.push_back(Pair("CCid", (int)ASSETCHAINS_CC));
9edf27ec 164 obj.push_back(Pair("name", ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL));
dbc80050 165 if ( ASSETCHAINS_SYMBOL[0] != 0 )
166 {
9edf27ec 167 //obj.push_back(Pair("name", ASSETCHAINS_SYMBOL));
05c2ba63 168 obj.push_back(Pair("p2pport", ASSETCHAINS_P2PPORT));
169 obj.push_back(Pair("rpcport", ASSETCHAINS_RPCPORT));
91e76e0c 170 obj.push_back(Pair("magic", (int)ASSETCHAINS_MAGIC));
dbc80050 171 if ( ASSETCHAINS_SUPPLY != 0 )
172 obj.push_back(Pair("premine", ASSETCHAINS_SUPPLY));
173 if ( ASSETCHAINS_REWARD != 0 )
174 obj.push_back(Pair("reward", ASSETCHAINS_REWARD));
175 if ( ASSETCHAINS_HALVING != 0 )
176 obj.push_back(Pair("halving", ASSETCHAINS_HALVING));
177 if ( ASSETCHAINS_DECAY != 0 )
178 obj.push_back(Pair("decay", ASSETCHAINS_DECAY));
179 if ( ASSETCHAINS_ENDSUBSIDY != 0 )
180 obj.push_back(Pair("endsubsidy", ASSETCHAINS_ENDSUBSIDY));
181 if ( ASSETCHAINS_COMMISSION != 0 )
182 obj.push_back(Pair("commission", ASSETCHAINS_COMMISSION));
183 if ( ASSETCHAINS_STAKED != 0 )
184 obj.push_back(Pair("staked", ASSETCHAINS_STAKED));
185 }
16bc9aaf
WL
186 return obj;
187}
188
452955f5 189#ifdef ENABLE_WALLET
d014114d 190class DescribeAddressVisitor : public boost::static_visitor<UniValue>
452955f5
WL
191{
192public:
d014114d 193 UniValue operator()(const CNoDestination &dest) const { return UniValue(UniValue::VOBJ); }
452955f5 194
851f58f9 195 UniValue operator()(const CKeyID &keyID) const {
38fc4b70 196 UniValue obj(UniValue::VOBJ);
452955f5 197 CPubKey vchPubKey;
452955f5 198 obj.push_back(Pair("isscript", false));
56215c77 199 if (pwalletMain && pwalletMain->GetPubKey(keyID, vchPubKey)) {
c8988460
PW
200 obj.push_back(Pair("pubkey", HexStr(vchPubKey)));
201 obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed()));
202 }
452955f5
WL
203 return obj;
204 }
205
851f58f9 206 UniValue operator()(const CScriptID &scriptID) const {
38fc4b70 207 UniValue obj(UniValue::VOBJ);
9c7167d1 208 CScript subscript;
452955f5 209 obj.push_back(Pair("isscript", true));
56215c77 210 if (pwalletMain && pwalletMain->GetCScript(scriptID, subscript)) {
c8988460
PW
211 std::vector<CTxDestination> addresses;
212 txnouttype whichType;
213 int nRequired;
214 ExtractDestinations(subscript, whichType, addresses, nRequired);
215 obj.push_back(Pair("script", GetTxnOutputType(whichType)));
216 obj.push_back(Pair("hex", HexStr(subscript.begin(), subscript.end())));
38fc4b70 217 UniValue a(UniValue::VARR);
c8988460
PW
218 BOOST_FOREACH(const CTxDestination& addr, addresses)
219 a.push_back(CBitcoinAddress(addr).ToString());
220 obj.push_back(Pair("addresses", a));
221 if (whichType == TX_MULTISIG)
222 obj.push_back(Pair("sigsrequired", nRequired));
223 }
452955f5
WL
224 return obj;
225 }
226};
227#endif
228
eeaaf554 229UniValue jumblr_deposit(const UniValue& params, bool fHelp)
230{
b487a8fe 231 int32_t retval; UniValue result(UniValue::VOBJ);
eeaaf554 232 if (fHelp || params.size() != 1)
233 throw runtime_error("jumblr_deposit \"depositaddress\"\n");
234 CBitcoinAddress address(params[0].get_str());
235 bool isValid = address.IsValid();
236 if ( isValid != 0 )
237 {
238 string addr = params[0].get_str();
b487a8fe 239 if ( (retval= Jumblr_depositaddradd((char *)addr.c_str())) >= 0 )
e21c70e9 240 {
190dbe6d 241 result.push_back(Pair("result", retval));
e21c70e9 242 JUMBLR_PAUSE = 0;
243 }
b487a8fe 244 else result.push_back(Pair("error", retval));
eeaaf554 245 } else result.push_back(Pair("error", "invalid address"));
246 return(result);
247}
248
249UniValue jumblr_secret(const UniValue& params, bool fHelp)
250{
251 int32_t retval; UniValue result(UniValue::VOBJ);
252 if (fHelp || params.size() != 1)
253 throw runtime_error("jumblr_secret \"secretaddress\"\n");
254 CBitcoinAddress address(params[0].get_str());
255 bool isValid = address.IsValid();
256 if ( isValid != 0 )
257 {
258 string addr = params[0].get_str();
bc035879 259 retval = Jumblr_secretaddradd((char *)addr.c_str());
eeaaf554 260 result.push_back(Pair("result", "success"));
261 result.push_back(Pair("num", retval));
e8fa58ec 262 JUMBLR_PAUSE = 0;
eeaaf554 263 } else result.push_back(Pair("error", "invalid address"));
264 return(result);
265}
266
eea03b7b 267UniValue jumblr_pause(const UniValue& params, bool fHelp)
268{
269 int32_t retval; UniValue result(UniValue::VOBJ);
270 if (fHelp )
271 throw runtime_error("jumblr_pause\n");
272 JUMBLR_PAUSE = 1;
273 result.push_back(Pair("result", "paused"));
274 return(result);
275}
276
277UniValue jumblr_resume(const UniValue& params, bool fHelp)
278{
279 int32_t retval; UniValue result(UniValue::VOBJ);
280 if (fHelp )
281 throw runtime_error("jumblr_resume\n");
282 JUMBLR_PAUSE = 0;
283 result.push_back(Pair("result", "resumed"));
284 return(result);
285}
286
d014114d 287UniValue validateaddress(const UniValue& params, bool fHelp)
452955f5
WL
288{
289 if (fHelp || params.size() != 1)
290 throw runtime_error(
a7322d77 291 "validateaddress \"komodoaddress\"\n"
292 "\nReturn information about the given Komodo address.\n"
452955f5 293 "\nArguments:\n"
a7322d77 294 "1. \"komodoaddress\" (string, required) The Komodo address to validate\n"
452955f5
WL
295 "\nResult:\n"
296 "{\n"
297 " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
a7322d77 298 " \"address\" : \"komodoaddress\", (string) The Komodo address validated\n"
426a74ed 299 " \"scriptPubKey\" : \"hex\", (string) The hex encoded scriptPubKey generated by the address\n"
452955f5
WL
300 " \"ismine\" : true|false, (boolean) If the address is yours or not\n"
301 " \"isscript\" : true|false, (boolean) If the key is a script\n"
302 " \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n"
303 " \"iscompressed\" : true|false, (boolean) If the address is compressed\n"
7b782f5b 304 " \"account\" : \"account\" (string) DEPRECATED. The account associated with the address, \"\" is the default account\n"
452955f5
WL
305 "}\n"
306 "\nExamples:\n"
a7322d77 307 + HelpExampleCli("validateaddress", "\"RTZMZHDFSTFQst8XmX2dR4DaH87cEUs3gC\"")
308 + HelpExampleRpc("validateaddress", "\"RTZMZHDFSTFQst8XmX2dR4DaH87cEUs3gC\"")
452955f5
WL
309 );
310
4401b2d7
EL
311#ifdef ENABLE_WALLET
312 LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
313#else
314 LOCK(cs_main);
315#endif
316
452955f5
WL
317 CBitcoinAddress address(params[0].get_str());
318 bool isValid = address.IsValid();
319
38fc4b70 320 UniValue ret(UniValue::VOBJ);
452955f5
WL
321 ret.push_back(Pair("isvalid", isValid));
322 if (isValid)
323 {
324 CTxDestination dest = address.Get();
325 string currentAddress = address.ToString();
326 ret.push_back(Pair("address", currentAddress));
426a74ed
PT
327
328 CScript scriptPubKey = GetScriptForDestination(dest);
329 ret.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
7cf23c98 330 ret.push_back(Pair("segid", (int32_t)komodo_segid32((char *)params[0].get_str().c_str()) & 0x3f));
452955f5 331#ifdef ENABLE_WALLET
a3e192a3
J
332 isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO;
333 ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false));
9c7167d1 334 ret.push_back(Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true: false));
335 UniValue detail = boost::apply_visitor(DescribeAddressVisitor(), dest);
336 ret.pushKVs(detail);
452955f5
WL
337 if (pwalletMain && pwalletMain->mapAddressBook.count(dest))
338 ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name));
339#endif
340 }
341 return ret;
342}
343
4e16a724 344
0d37ae3a 345UniValue z_validateaddress(const UniValue& params, bool fHelp)
4e16a724
S
346{
347 if (fHelp || params.size() != 1)
348 throw runtime_error(
349 "z_validateaddress \"zaddr\"\n"
350 "\nReturn information about the given z address.\n"
351 "\nArguments:\n"
352 "1. \"zaddr\" (string, required) The z address to validate\n"
353 "\nResult:\n"
354 "{\n"
355 " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
356 " \"address\" : \"zaddr\", (string) The z address validated\n"
357 " \"ismine\" : true|false, (boolean) If the address is yours or not\n"
358 " \"payingkey\" : \"hex\", (string) The hex value of the paying key, a_pk\n"
359 " \"transmissionkey\" : \"hex\", (string) The hex value of the transmission key, pk_enc\n"
360
361 "}\n"
362 "\nExamples:\n"
337a99a2
JG
363 + HelpExampleCli("z_validateaddress", "\"zcWsmqT4X2V4jgxbgiCzyrAfRT1vi1F4sn7M5Pkh66izzw8Uk7LBGAH3DtcSMJeUb2pi3W4SQF8LMKkU2cUuVP68yAGcomL\"")
364 + HelpExampleRpc("z_validateaddress", "\"zcWsmqT4X2V4jgxbgiCzyrAfRT1vi1F4sn7M5Pkh66izzw8Uk7LBGAH3DtcSMJeUb2pi3W4SQF8LMKkU2cUuVP68yAGcomL\"")
4e16a724
S
365 );
366
367
368#ifdef ENABLE_WALLET
369 LOCK2(cs_main, pwalletMain->cs_wallet);
370#else
371 LOCK(cs_main);
372#endif
373
374 bool isValid = false;
375 bool isMine = false;
376 std::string payingKey, transmissionKey;
377
378 string strAddress = params[0].get_str();
379 try {
380 CZCPaymentAddress address(strAddress);
381 libzcash::PaymentAddress addr = address.Get();
382
383#ifdef ENABLE_WALLET
384 isMine = pwalletMain->HaveSpendingKey(addr);
385#endif
386 payingKey = addr.a_pk.GetHex();
387 transmissionKey = addr.pk_enc.GetHex();
388 isValid = true;
389 } catch (std::runtime_error e) {
390 // address is invalid, nop here as isValid is false.
391 }
392
0d37ae3a 393 UniValue ret(UniValue::VOBJ);
4e16a724
S
394 ret.push_back(Pair("isvalid", isValid));
395 if (isValid)
396 {
397 ret.push_back(Pair("address", strAddress));
398 ret.push_back(Pair("payingkey", payingKey));
399 ret.push_back(Pair("transmissionkey", transmissionKey));
400#ifdef ENABLE_WALLET
401 ret.push_back(Pair("ismine", isMine));
402#endif
403 }
404 return ret;
405}
406
407
72fb3d29
MF
408/**
409 * Used by addmultisigaddress / createmultisig:
410 */
d014114d 411CScript _createmultisig_redeemScript(const UniValue& params)
723a03d2
WL
412{
413 int nRequired = params[0].get_int();
d014114d 414 const UniValue& keys = params[1].get_array();
723a03d2
WL
415
416 // Gather public keys
417 if (nRequired < 1)
418 throw runtime_error("a multisignature address must require at least one key to redeem");
419 if ((int)keys.size() < nRequired)
420 throw runtime_error(
421 strprintf("not enough keys supplied "
783b182c 422 "(got %u keys, but need at least %d to redeem)", keys.size(), nRequired));
e5d9d77d 423 if (keys.size() > 16)
424 throw runtime_error("Number of addresses involved in the multisignature address creation > 16\nReduce the number");
723a03d2
WL
425 std::vector<CPubKey> pubkeys;
426 pubkeys.resize(keys.size());
427 for (unsigned int i = 0; i < keys.size(); i++)
428 {
429 const std::string& ks = keys[i].get_str();
430#ifdef ENABLE_WALLET
431 // Case 1: Bitcoin address and we have full public key:
432 CBitcoinAddress address(ks);
433 if (pwalletMain && address.IsValid())
434 {
435 CKeyID keyID;
436 if (!address.GetKeyID(keyID))
437 throw runtime_error(
7d9d134b 438 strprintf("%s does not refer to a key",ks));
723a03d2
WL
439 CPubKey vchPubKey;
440 if (!pwalletMain->GetPubKey(keyID, vchPubKey))
441 throw runtime_error(
7d9d134b 442 strprintf("no full public key for address %s",ks));
723a03d2
WL
443 if (!vchPubKey.IsFullyValid())
444 throw runtime_error(" Invalid public key: "+ks);
445 pubkeys[i] = vchPubKey;
446 }
447
448 // Case 2: hex public key
449 else
450#endif
451 if (IsHex(ks))
452 {
453 CPubKey vchPubKey(ParseHex(ks));
454 if (!vchPubKey.IsFullyValid())
455 throw runtime_error(" Invalid public key: "+ks);
456 pubkeys[i] = vchPubKey;
457 }
458 else
459 {
460 throw runtime_error(" Invalid public key: "+ks);
461 }
462 }
0be990ba 463 CScript result = GetScriptForMultisig(nRequired, pubkeys);
787ee0c9
PT
464
465 if (result.size() > MAX_SCRIPT_ELEMENT_SIZE)
466 throw runtime_error(
467 strprintf("redeemScript exceeds size limit: %d > %d", result.size(), MAX_SCRIPT_ELEMENT_SIZE));
468
723a03d2
WL
469 return result;
470}
471
d014114d 472UniValue createmultisig(const UniValue& params, bool fHelp)
723a03d2
WL
473{
474 if (fHelp || params.size() < 2 || params.size() > 2)
475 {
476 string msg = "createmultisig nrequired [\"key\",...]\n"
477 "\nCreates a multi-signature address with n signature of m keys required.\n"
478 "It returns a json object with the address and redeemScript.\n"
479
480 "\nArguments:\n"
481 "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
a7322d77 482 "2. \"keys\" (string, required) A json array of keys which are Komodo addresses or hex-encoded public keys\n"
723a03d2 483 " [\n"
a7322d77 484 " \"key\" (string) Komodo address or hex-encoded public key\n"
723a03d2
WL
485 " ,...\n"
486 " ]\n"
487
488 "\nResult:\n"
489 "{\n"
490 " \"address\":\"multisigaddress\", (string) The value of the new multisig address.\n"
491 " \"redeemScript\":\"script\" (string) The string value of the hex-encoded redemption script.\n"
492 "}\n"
493
494 "\nExamples:\n"
495 "\nCreate a multisig address from 2 addresses\n"
a7322d77 496 + HelpExampleCli("createmultisig", "2 \"[\\\"RTZMZHDFSTFQst8XmX2dR4DaH87cEUs3gC\\\",\\\"RNKiEBduBru6Siv1cZRVhp4fkZNyPska6z\\\"]\"") +
723a03d2 497 "\nAs a json rpc call\n"
a7322d77 498 + HelpExampleRpc("createmultisig", "2, \"[\\\"RTZMZHDFSTFQst8XmX2dR4DaH87cEUs3gC\\\",\\\"RNKiEBduBru6Siv1cZRVhp4fkZNyPska6z\\\"]\"")
723a03d2
WL
499 ;
500 throw runtime_error(msg);
501 }
502
503 // Construct using pay-to-script-hash:
787ee0c9 504 CScript inner = _createmultisig_redeemScript(params);
066e2a14 505 CScriptID innerID(inner);
723a03d2
WL
506 CBitcoinAddress address(innerID);
507
b47f3aea 508 UniValue result(UniValue::VOBJ);
723a03d2
WL
509 result.push_back(Pair("address", address.ToString()));
510 result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end())));
511
512 return result;
513}
514
d014114d 515UniValue verifymessage(const UniValue& params, bool fHelp)
c3a7f516
WL
516{
517 if (fHelp || params.size() != 3)
518 throw runtime_error(
a7322d77 519 "verifymessage \"komodoaddress\" \"signature\" \"message\"\n"
c3a7f516
WL
520 "\nVerify a signed message\n"
521 "\nArguments:\n"
a7322d77 522 "1. \"komodoaddress\" (string, required) The Komodo address to use for the signature.\n"
c3a7f516
WL
523 "2. \"signature\" (string, required) The signature provided by the signer in base 64 encoding (see signmessage).\n"
524 "3. \"message\" (string, required) The message that was signed.\n"
525 "\nResult:\n"
526 "true|false (boolean) If the signature is verified or not.\n"
527 "\nExamples:\n"
528 "\nUnlock the wallet for 30 seconds\n"
529 + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
530 "\nCreate the signature\n"
a7322d77 531 + HelpExampleCli("signmessage", "\"RNKiEBduBru6Siv1cZRVhp4fkZNyPska6z\" \"my message\"") +
c3a7f516 532 "\nVerify the signature\n"
a7322d77 533 + HelpExampleCli("verifymessage", "\"RNKiEBduBru6Siv1cZRVhp4fkZNyPska6z\" \"signature\" \"my message\"") +
c3a7f516 534 "\nAs json rpc\n"
a7322d77 535 + HelpExampleRpc("verifymessage", "\"RNKiEBduBru6Siv1cZRVhp4fkZNyPska6z\", \"signature\", \"my message\"")
c3a7f516
WL
536 );
537
4401b2d7
EL
538 LOCK(cs_main);
539
c3a7f516
WL
540 string strAddress = params[0].get_str();
541 string strSign = params[1].get_str();
542 string strMessage = params[2].get_str();
543
544 CBitcoinAddress addr(strAddress);
545 if (!addr.IsValid())
546 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
547
548 CKeyID keyID;
549 if (!addr.GetKeyID(keyID))
550 throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
551
552 bool fInvalid = false;
553 vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);
554
555 if (fInvalid)
556 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding");
557
558 CHashWriter ss(SER_GETHASH, 0);
559 ss << strMessageMagic;
560 ss << strMessage;
561
562 CPubKey pubkey;
563 if (!pubkey.RecoverCompact(ss.GetHash(), vchSig))
564 return false;
565
566 return (pubkey.GetID() == keyID);
567}
a8b2ce55 568
d014114d 569UniValue setmocktime(const UniValue& params, bool fHelp)
a8b2ce55
GA
570{
571 if (fHelp || params.size() != 1)
572 throw runtime_error(
573 "setmocktime timestamp\n"
574 "\nSet the local time to given timestamp (-regtest only)\n"
575 "\nArguments:\n"
576 "1. timestamp (integer, required) Unix seconds-since-epoch timestamp\n"
577 " Pass 0 to go back to using the system time."
578 );
579
580 if (!Params().MineBlocksOnDemand())
581 throw runtime_error("setmocktime for regression testing (-regtest mode) only");
582
abb0e8cc
GA
583 // cs_vNodes is locked and node send/receive times are updated
584 // atomically with the time change to prevent peers from being
585 // disconnected because we think we haven't communicated with them
586 // in a long time.
587 LOCK2(cs_main, cs_vNodes);
4401b2d7 588
9756b7bd 589 RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM));
a8b2ce55
GA
590 SetMockTime(params[0].get_int64());
591
abb0e8cc
GA
592 uint64_t t = GetTime();
593 BOOST_FOREACH(CNode* pnode, vNodes) {
594 pnode->nLastSend = pnode->nLastRecv = t;
595 }
596
9756b7bd 597 return NullUniValue;
a8b2ce55 598}
8b78a819
T
599
600bool getAddressFromIndex(const int &type, const uint160 &hash, std::string &address)
601{
602 if (type == 2) {
603 address = CBitcoinAddress(CScriptID(hash)).ToString();
604 } else if (type == 1) {
605 address = CBitcoinAddress(CKeyID(hash)).ToString();
fa7bf712 606 }
fa7bf712 607 else {
8b78a819
T
608 return false;
609 }
610 return true;
611}
612
613bool getAddressesFromParams(const UniValue& params, std::vector<std::pair<uint160, int> > &addresses)
614{
615 if (params[0].isStr()) {
616 CBitcoinAddress address(params[0].get_str());
617 uint160 hashBytes;
618 int type = 0;
619 if (!address.GetIndexKey(hashBytes, type)) {
620 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
621 }
622 addresses.push_back(std::make_pair(hashBytes, type));
623 } else if (params[0].isObject()) {
624
625 UniValue addressValues = find_value(params[0].get_obj(), "addresses");
626 if (!addressValues.isArray()) {
627 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Addresses is expected to be an array");
628 }
629
630 std::vector<UniValue> values = addressValues.getValues();
631
632 for (std::vector<UniValue>::iterator it = values.begin(); it != values.end(); ++it) {
633
634 CBitcoinAddress address(it->get_str());
635 uint160 hashBytes;
636 int type = 0;
637 if (!address.GetIndexKey(hashBytes, type)) {
67d4c3be 638 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid addresses");
8b78a819
T
639 }
640 addresses.push_back(std::make_pair(hashBytes, type));
641 }
642 } else {
67d4c3be 643 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid addresse");
8b78a819
T
644 }
645
646 return true;
647}
648
649bool heightSort(std::pair<CAddressUnspentKey, CAddressUnspentValue> a,
650 std::pair<CAddressUnspentKey, CAddressUnspentValue> b) {
651 return a.second.blockHeight < b.second.blockHeight;
652}
653
654bool timestampSort(std::pair<CMempoolAddressDeltaKey, CMempoolAddressDelta> a,
655 std::pair<CMempoolAddressDeltaKey, CMempoolAddressDelta> b) {
656 return a.second.time < b.second.time;
657}
658
659UniValue getaddressmempool(const UniValue& params, bool fHelp)
660{
661 if (fHelp || params.size() != 1)
662 throw runtime_error(
663 "getaddressmempool\n"
664 "\nReturns all mempool deltas for an address (requires addressindex to be enabled).\n"
665 "\nArguments:\n"
666 "{\n"
667 " \"addresses\"\n"
668 " [\n"
669 " \"address\" (string) The base58check encoded address\n"
670 " ,...\n"
671 " ]\n"
672 "}\n"
673 "\nResult:\n"
674 "[\n"
675 " {\n"
676 " \"address\" (string) The base58check encoded address\n"
677 " \"txid\" (string) The related txid\n"
678 " \"index\" (number) The related input or output index\n"
679 " \"satoshis\" (number) The difference of satoshis\n"
680 " \"timestamp\" (number) The time the transaction entered the mempool (seconds)\n"
681 " \"prevtxid\" (string) The previous txid (if spending)\n"
682 " \"prevout\" (string) The previous transaction output index (if spending)\n"
683 " }\n"
684 "]\n"
685 "\nExamples:\n"
67d4c3be 686 + HelpExampleCli("getaddressmempool", "'{\"addresses\": [\"RY5LccmGiX9bUHYGtSWQouNy1yFhc5rM87\"]}'")
687 + HelpExampleRpc("getaddressmempool", "{\"addresses\": [\"RY5LccmGiX9bUHYGtSWQouNy1yFhc5rM87\"]}")
8b78a819
T
688 );
689
690 std::vector<std::pair<uint160, int> > addresses;
691
692 if (!getAddressesFromParams(params, addresses)) {
693 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
694 }
695
696 std::vector<std::pair<CMempoolAddressDeltaKey, CMempoolAddressDelta> > indexes;
697
698 if (!mempool.getAddressIndex(addresses, indexes)) {
699 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address");
700 }
701
702 std::sort(indexes.begin(), indexes.end(), timestampSort);
703
704 UniValue result(UniValue::VARR);
705
706 for (std::vector<std::pair<CMempoolAddressDeltaKey, CMempoolAddressDelta> >::iterator it = indexes.begin();
707 it != indexes.end(); it++) {
708
709 std::string address;
710 if (!getAddressFromIndex(it->first.type, it->first.addressBytes, address)) {
711 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unknown address type");
712 }
713
714 UniValue delta(UniValue::VOBJ);
715 delta.push_back(Pair("address", address));
716 delta.push_back(Pair("txid", it->first.txhash.GetHex()));
717 delta.push_back(Pair("index", (int)it->first.index));
718 delta.push_back(Pair("satoshis", it->second.amount));
719 delta.push_back(Pair("timestamp", it->second.time));
720 if (it->second.amount < 0) {
721 delta.push_back(Pair("prevtxid", it->second.prevhash.GetHex()));
722 delta.push_back(Pair("prevout", (int)it->second.prevout));
723 }
724 result.push_back(delta);
725 }
726
727 return result;
728}
729
730UniValue getaddressutxos(const UniValue& params, bool fHelp)
731{
732 if (fHelp || params.size() != 1)
733 throw runtime_error(
734 "getaddressutxos\n"
735 "\nReturns all unspent outputs for an address (requires addressindex to be enabled).\n"
736 "\nArguments:\n"
737 "{\n"
738 " \"addresses\"\n"
739 " [\n"
740 " \"address\" (string) The base58check encoded address\n"
741 " ,...\n"
742 " ],\n"
743 " \"chainInfo\" (boolean) Include chain info with results\n"
744 "}\n"
745 "\nResult\n"
746 "[\n"
747 " {\n"
748 " \"address\" (string) The address base58check encoded\n"
749 " \"txid\" (string) The output txid\n"
750 " \"height\" (number) The block height\n"
751 " \"outputIndex\" (number) The output index\n"
752 " \"script\" (strin) The script hex encoded\n"
753 " \"satoshis\" (number) The number of satoshis of the output\n"
754 " }\n"
755 "]\n"
756 "\nExamples:\n"
67d4c3be 757 + HelpExampleCli("getaddressutxos", "'{\"addresses\": [\"RY5LccmGiX9bUHYGtSWQouNy1yFhc5rM87\"]}'")
758 + HelpExampleRpc("getaddressutxos", "{\"addresses\": [\"RY5LccmGiX9bUHYGtSWQouNy1yFhc5rM87\"]}")
8b78a819
T
759 );
760
761 bool includeChainInfo = false;
762 if (params[0].isObject()) {
763 UniValue chainInfo = find_value(params[0].get_obj(), "chainInfo");
764 if (chainInfo.isBool()) {
765 includeChainInfo = chainInfo.get_bool();
766 }
767 }
768
769 std::vector<std::pair<uint160, int> > addresses;
770
771 if (!getAddressesFromParams(params, addresses)) {
772 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
773 }
774
775 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
776
777 for (std::vector<std::pair<uint160, int> >::iterator it = addresses.begin(); it != addresses.end(); it++) {
778 if (!GetAddressUnspent((*it).first, (*it).second, unspentOutputs)) {
779 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address");
780 }
781 }
782
783 std::sort(unspentOutputs.begin(), unspentOutputs.end(), heightSort);
784
785 UniValue utxos(UniValue::VARR);
786
787 for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) {
788 UniValue output(UniValue::VOBJ);
789 std::string address;
790 if (!getAddressFromIndex(it->first.type, it->first.hashBytes, address)) {
791 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unknown address type");
792 }
793
794 output.push_back(Pair("address", address));
795 output.push_back(Pair("txid", it->first.txhash.GetHex()));
796 output.push_back(Pair("outputIndex", (int)it->first.index));
797 output.push_back(Pair("script", HexStr(it->second.script.begin(), it->second.script.end())));
798 output.push_back(Pair("satoshis", it->second.satoshis));
799 output.push_back(Pair("height", it->second.blockHeight));
800 utxos.push_back(output);
801 }
802
803 if (includeChainInfo) {
804 UniValue result(UniValue::VOBJ);
805 result.push_back(Pair("utxos", utxos));
806
807 LOCK(cs_main);
808 result.push_back(Pair("hash", chainActive.Tip()->GetBlockHash().GetHex()));
809 result.push_back(Pair("height", (int)chainActive.Height()));
810 return result;
811 } else {
812 return utxos;
813 }
814}
815
816UniValue getaddressdeltas(const UniValue& params, bool fHelp)
817{
818 if (fHelp || params.size() != 1 || !params[0].isObject())
819 throw runtime_error(
820 "getaddressdeltas\n"
821 "\nReturns all changes for an address (requires addressindex to be enabled).\n"
822 "\nArguments:\n"
823 "{\n"
824 " \"addresses\"\n"
825 " [\n"
826 " \"address\" (string) The base58check encoded address\n"
827 " ,...\n"
828 " ]\n"
829 " \"start\" (number) The start block height\n"
830 " \"end\" (number) The end block height\n"
831 " \"chainInfo\" (boolean) Include chain info in results, only applies if start and end specified\n"
832 "}\n"
833 "\nResult:\n"
834 "[\n"
835 " {\n"
836 " \"satoshis\" (number) The difference of satoshis\n"
837 " \"txid\" (string) The related txid\n"
838 " \"index\" (number) The related input or output index\n"
839 " \"height\" (number) The block height\n"
840 " \"address\" (string) The base58check encoded address\n"
841 " }\n"
842 "]\n"
843 "\nExamples:\n"
67d4c3be 844 + HelpExampleCli("getaddressdeltas", "'{\"addresses\": [\"RY5LccmGiX9bUHYGtSWQouNy1yFhc5rM87\"]}'")
845 + HelpExampleRpc("getaddressdeltas", "{\"addresses\": [\"RY5LccmGiX9bUHYGtSWQouNy1yFhc5rM87\"]}")
8b78a819
T
846 );
847
848
849 UniValue startValue = find_value(params[0].get_obj(), "start");
850 UniValue endValue = find_value(params[0].get_obj(), "end");
851
852 UniValue chainInfo = find_value(params[0].get_obj(), "chainInfo");
853 bool includeChainInfo = false;
854 if (chainInfo.isBool()) {
855 includeChainInfo = chainInfo.get_bool();
856 }
857
858 int start = 0;
859 int end = 0;
860
861 if (startValue.isNum() && endValue.isNum()) {
862 start = startValue.get_int();
863 end = endValue.get_int();
864 if (start <= 0 || end <= 0) {
865 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Start and end is expected to be greater than zero");
866 }
867 if (end < start) {
868 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "End value is expected to be greater than start");
869 }
870 }
871
872 std::vector<std::pair<uint160, int> > addresses;
873
874 if (!getAddressesFromParams(params, addresses)) {
875 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
876 }
877
878 std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
879
880 for (std::vector<std::pair<uint160, int> >::iterator it = addresses.begin(); it != addresses.end(); it++) {
881 if (start > 0 && end > 0) {
882 if (!GetAddressIndex((*it).first, (*it).second, addressIndex, start, end)) {
883 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address");
884 }
885 } else {
886 if (!GetAddressIndex((*it).first, (*it).second, addressIndex)) {
887 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address");
888 }
889 }
890 }
891
892 UniValue deltas(UniValue::VARR);
893
894 for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) {
895 std::string address;
896 if (!getAddressFromIndex(it->first.type, it->first.hashBytes, address)) {
897 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unknown address type");
898 }
899
900 UniValue delta(UniValue::VOBJ);
901 delta.push_back(Pair("satoshis", it->second));
902 delta.push_back(Pair("txid", it->first.txhash.GetHex()));
903 delta.push_back(Pair("index", (int)it->first.index));
904 delta.push_back(Pair("blockindex", (int)it->first.txindex));
905 delta.push_back(Pair("height", it->first.blockHeight));
906 delta.push_back(Pair("address", address));
907 deltas.push_back(delta);
908 }
909
910 UniValue result(UniValue::VOBJ);
911
912 if (includeChainInfo && start > 0 && end > 0) {
913 LOCK(cs_main);
914
915 if (start > chainActive.Height() || end > chainActive.Height()) {
916 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Start or end is outside chain range");
917 }
918
919 CBlockIndex* startIndex = chainActive[start];
920 CBlockIndex* endIndex = chainActive[end];
921
922 UniValue startInfo(UniValue::VOBJ);
923 UniValue endInfo(UniValue::VOBJ);
924
925 startInfo.push_back(Pair("hash", startIndex->GetBlockHash().GetHex()));
926 startInfo.push_back(Pair("height", start));
927
928 endInfo.push_back(Pair("hash", endIndex->GetBlockHash().GetHex()));
929 endInfo.push_back(Pair("height", end));
930
931 result.push_back(Pair("deltas", deltas));
932 result.push_back(Pair("start", startInfo));
933 result.push_back(Pair("end", endInfo));
934
935 return result;
936 } else {
937 return deltas;
938 }
939}
940
941UniValue getaddressbalance(const UniValue& params, bool fHelp)
942{
943 if (fHelp || params.size() != 1)
944 throw runtime_error(
945 "getaddressbalance\n"
946 "\nReturns the balance for an address(es) (requires addressindex to be enabled).\n"
947 "\nArguments:\n"
948 "{\n"
949 " \"addresses\"\n"
950 " [\n"
951 " \"address\" (string) The base58check encoded address\n"
952 " ,...\n"
953 " ]\n"
954 "}\n"
955 "\nResult:\n"
956 "{\n"
957 " \"balance\" (string) The current balance in satoshis\n"
958 " \"received\" (string) The total number of satoshis received (including change)\n"
959 "}\n"
960 "\nExamples:\n"
67d4c3be 961 + HelpExampleCli("getaddressbalance", "'{\"addresses\": [\"RY5LccmGiX9bUHYGtSWQouNy1yFhc5rM87\"]}'")
962 + HelpExampleRpc("getaddressbalance", "{\"addresses\": [\"RY5LccmGiX9bUHYGtSWQouNy1yFhc5rM87\"]}")
8b78a819
T
963 );
964
965 std::vector<std::pair<uint160, int> > addresses;
966
967 if (!getAddressesFromParams(params, addresses)) {
968 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
969 }
970
971 std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
972
973 for (std::vector<std::pair<uint160, int> >::iterator it = addresses.begin(); it != addresses.end(); it++) {
974 if (!GetAddressIndex((*it).first, (*it).second, addressIndex)) {
975 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address");
976 }
977 }
978
979 CAmount balance = 0;
980 CAmount received = 0;
981
982 for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) {
983 if (it->second > 0) {
984 received += it->second;
985 }
986 balance += it->second;
987 }
988
989 UniValue result(UniValue::VOBJ);
990 result.push_back(Pair("balance", balance));
991 result.push_back(Pair("received", received));
992
993 return result;
994
995}
996
329d80d2 997int32_t komodo_snapshot();
998
22007819 999UniValue getsnapshot(const UniValue& params, bool fHelp)
1000{
67d2e41b 1001 UniValue result(UniValue::VOBJ); int64_t total;
22007819 1002 if ( fHelp || params.size() > 0 )
1003 {
1004 throw runtime_error(
1005 "getsnapshot\n"
1006 );
1007 }
67d2e41b 1008 if ( (total= komodo_snapshot()) >= 0 )
1009 result.push_back(Pair("total", (double)total/COIN));
329d80d2 1010 else result.push_back(Pair("error", "no addressindex"));
22007819 1011 return(result);
1012}
1013
8b78a819
T
1014UniValue getaddresstxids(const UniValue& params, bool fHelp)
1015{
1016 if (fHelp || params.size() != 1)
1017 throw runtime_error(
1018 "getaddresstxids\n"
1019 "\nReturns the txids for an address(es) (requires addressindex to be enabled).\n"
1020 "\nArguments:\n"
1021 "{\n"
1022 " \"addresses\"\n"
1023 " [\n"
1024 " \"address\" (string) The base58check encoded address\n"
1025 " ,...\n"
1026 " ]\n"
1027 " \"start\" (number) The start block height\n"
1028 " \"end\" (number) The end block height\n"
1029 "}\n"
1030 "\nResult:\n"
1031 "[\n"
1032 " \"transactionid\" (string) The transaction id\n"
1033 " ,...\n"
1034 "]\n"
1035 "\nExamples:\n"
67d4c3be 1036 + HelpExampleCli("getaddresstxids", "'{\"addresses\": [\"RY5LccmGiX9bUHYGtSWQouNy1yFhc5rM87\"]}'")
1037 + HelpExampleRpc("getaddresstxids", "{\"addresses\": [\"RY5LccmGiX9bUHYGtSWQouNy1yFhc5rM87\"]}")
8b78a819
T
1038 );
1039
1040 std::vector<std::pair<uint160, int> > addresses;
1041
1042 if (!getAddressesFromParams(params, addresses)) {
1043 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
1044 }
1045
1046 int start = 0;
1047 int end = 0;
1048 if (params[0].isObject()) {
1049 UniValue startValue = find_value(params[0].get_obj(), "start");
1050 UniValue endValue = find_value(params[0].get_obj(), "end");
1051 if (startValue.isNum() && endValue.isNum()) {
1052 start = startValue.get_int();
1053 end = endValue.get_int();
1054 }
1055 }
1056
1057 std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
1058
1059 for (std::vector<std::pair<uint160, int> >::iterator it = addresses.begin(); it != addresses.end(); it++) {
1060 if (start > 0 && end > 0) {
1061 if (!GetAddressIndex((*it).first, (*it).second, addressIndex, start, end)) {
1062 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address");
1063 }
1064 } else {
1065 if (!GetAddressIndex((*it).first, (*it).second, addressIndex)) {
1066 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address");
1067 }
1068 }
1069 }
1070
1071 std::set<std::pair<int, std::string> > txids;
1072 UniValue result(UniValue::VARR);
1073
1074 for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) {
1075 int height = it->first.blockHeight;
1076 std::string txid = it->first.txhash.GetHex();
1077
1078 if (addresses.size() > 1) {
1079 txids.insert(std::make_pair(height, txid));
1080 } else {
1081 if (txids.insert(std::make_pair(height, txid)).second) {
1082 result.push_back(txid);
1083 }
1084 }
1085 }
1086
1087 if (addresses.size() > 1) {
1088 for (std::set<std::pair<int, std::string> >::const_iterator it=txids.begin(); it!=txids.end(); it++) {
1089 result.push_back(it->second);
1090 }
1091 }
1092
1093 return result;
1094
1095}
1096
1097UniValue getspentinfo(const UniValue& params, bool fHelp)
1098{
1099
1100 if (fHelp || params.size() != 1 || !params[0].isObject())
1101 throw runtime_error(
1102 "getspentinfo\n"
1103 "\nReturns the txid and index where an output is spent.\n"
1104 "\nArguments:\n"
1105 "{\n"
1106 " \"txid\" (string) The hex string of the txid\n"
1107 " \"index\" (number) The start block height\n"
1108 "}\n"
1109 "\nResult:\n"
1110 "{\n"
1111 " \"txid\" (string) The transaction id\n"
1112 " \"index\" (number) The spending input index\n"
1113 " ,...\n"
1114 "}\n"
1115 "\nExamples:\n"
1116 + HelpExampleCli("getspentinfo", "'{\"txid\": \"0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9\", \"index\": 0}'")
1117 + HelpExampleRpc("getspentinfo", "{\"txid\": \"0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9\", \"index\": 0}")
1118 );
1119
1120 UniValue txidValue = find_value(params[0].get_obj(), "txid");
1121 UniValue indexValue = find_value(params[0].get_obj(), "index");
1122
1123 if (!txidValue.isStr() || !indexValue.isNum()) {
1124 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid txid or index");
1125 }
1126
1127 uint256 txid = ParseHashV(txidValue, "txid");
1128 int outputIndex = indexValue.get_int();
1129
1130 CSpentIndexKey key(txid, outputIndex);
1131 CSpentIndexValue value;
1132
1133 if (!GetSpentIndex(key, value)) {
1134 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unable to get spent info");
1135 }
1136
1137 UniValue obj(UniValue::VOBJ);
1138 obj.push_back(Pair("txid", value.txid.GetHex()));
1139 obj.push_back(Pair("index", (int)value.inputIndex));
1140 obj.push_back(Pair("height", value.blockHeight));
1141
1142 return obj;
e8fa58ec 1143}
This page took 0.49179 seconds and 4 git commands to generate.