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