]> Git Repo - VerusCoin.git/blob - src/wallet/rpcwallet.cpp
Auto merge of #3376 - LarryRuane:2728-help-message-experimental, r=bitcartel
[VerusCoin.git] / src / wallet / rpcwallet.cpp
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6 #include "amount.h"
7 #include "consensus/upgrades.h"
8 #include "core_io.h"
9 #include "init.h"
10 #include "key_io.h"
11 #include "main.h"
12 #include "net.h"
13 #include "netbase.h"
14 #include "rpcserver.h"
15 #include "timedata.h"
16 #include "util.h"
17 #include "utilmoneystr.h"
18 #include "wallet.h"
19 #include "walletdb.h"
20 #include "primitives/transaction.h"
21 #include "zcbenchmarks.h"
22 #include "script/interpreter.h"
23
24 #include "utiltime.h"
25 #include "asyncrpcoperation.h"
26 #include "asyncrpcqueue.h"
27 #include "wallet/asyncrpcoperation_mergetoaddress.h"
28 #include "wallet/asyncrpcoperation_sendmany.h"
29 #include "wallet/asyncrpcoperation_shieldcoinbase.h"
30
31 #include "sodium.h"
32
33 #include <stdint.h>
34
35 #include <boost/assign/list_of.hpp>
36
37 #include <univalue.h>
38
39 #include <numeric>
40
41 using namespace std;
42
43 using namespace libzcash;
44
45 extern UniValue TxJoinSplitToJSON(const CTransaction& tx);
46
47 int64_t nWalletUnlockTime;
48 static CCriticalSection cs_nWalletUnlockTime;
49
50 // Private method:
51 UniValue z_getoperationstatus_IMPL(const UniValue&, bool);
52
53 std::string HelpRequiringPassphrase()
54 {
55     return pwalletMain && pwalletMain->IsCrypted()
56         ? "\nRequires wallet passphrase to be set with walletpassphrase call."
57         : "";
58 }
59
60 bool EnsureWalletIsAvailable(bool avoidException)
61 {
62     if (!pwalletMain)
63     {
64         if (!avoidException)
65             throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
66         else
67             return false;
68     }
69     return true;
70 }
71
72 void EnsureWalletIsUnlocked()
73 {
74     if (pwalletMain->IsLocked())
75         throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first.");
76 }
77
78 void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry)
79 {
80     int confirms = wtx.GetDepthInMainChain();
81     entry.push_back(Pair("confirmations", confirms));
82     if (wtx.IsCoinBase())
83         entry.push_back(Pair("generated", true));
84     if (confirms > 0)
85     {
86         entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex()));
87         entry.push_back(Pair("blockindex", wtx.nIndex));
88         entry.push_back(Pair("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime()));
89         entry.push_back(Pair("expiryheight", (int64_t)wtx.nExpiryHeight));
90     }
91     uint256 hash = wtx.GetHash();
92     entry.push_back(Pair("txid", hash.GetHex()));
93     UniValue conflicts(UniValue::VARR);
94     BOOST_FOREACH(const uint256& conflict, wtx.GetConflicts())
95         conflicts.push_back(conflict.GetHex());
96     entry.push_back(Pair("walletconflicts", conflicts));
97     entry.push_back(Pair("time", wtx.GetTxTime()));
98     entry.push_back(Pair("timereceived", (int64_t)wtx.nTimeReceived));
99     BOOST_FOREACH(const PAIRTYPE(string,string)& item, wtx.mapValue)
100         entry.push_back(Pair(item.first, item.second));
101
102     entry.push_back(Pair("vjoinsplit", TxJoinSplitToJSON(wtx)));
103 }
104
105 string AccountFromValue(const UniValue& value)
106 {
107     string strAccount = value.get_str();
108     if (strAccount != "")
109         throw JSONRPCError(RPC_WALLET_ACCOUNTS_UNSUPPORTED, "Accounts are unsupported");
110     return strAccount;
111 }
112
113 UniValue getnewaddress(const UniValue& params, bool fHelp)
114 {
115     if (!EnsureWalletIsAvailable(fHelp))
116         return NullUniValue;
117
118     if (fHelp || params.size() > 1)
119         throw runtime_error(
120             "getnewaddress ( \"account\" )\n"
121             "\nReturns a new Zcash address for receiving payments.\n"
122             "\nArguments:\n"
123             "1. \"account\"        (string, optional) DEPRECATED. If provided, it MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
124             "\nResult:\n"
125             "\"zcashaddress\"    (string) The new Zcash address\n"
126             "\nExamples:\n"
127             + HelpExampleCli("getnewaddress", "")
128             + HelpExampleRpc("getnewaddress", "")
129         );
130
131     LOCK2(cs_main, pwalletMain->cs_wallet);
132
133     // Parse the account first so we don't generate a key if there's an error
134     string strAccount;
135     if (params.size() > 0)
136         strAccount = AccountFromValue(params[0]);
137
138     if (!pwalletMain->IsLocked())
139         pwalletMain->TopUpKeyPool();
140
141     // Generate a new key that is added to wallet
142     CPubKey newKey;
143     if (!pwalletMain->GetKeyFromPool(newKey))
144         throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
145     CKeyID keyID = newKey.GetID();
146
147     pwalletMain->SetAddressBook(keyID, strAccount, "receive");
148
149     return EncodeDestination(keyID);
150 }
151
152
153 CTxDestination GetAccountAddress(std::string strAccount, bool bForceNew=false)
154 {
155     CWalletDB walletdb(pwalletMain->strWalletFile);
156
157     CAccount account;
158     walletdb.ReadAccount(strAccount, account);
159
160     bool bKeyUsed = false;
161
162     // Check if the current key has been used
163     if (account.vchPubKey.IsValid())
164     {
165         CScript scriptPubKey = GetScriptForDestination(account.vchPubKey.GetID());
166         for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin();
167              it != pwalletMain->mapWallet.end() && account.vchPubKey.IsValid();
168              ++it)
169         {
170             const CWalletTx& wtx = (*it).second;
171             BOOST_FOREACH(const CTxOut& txout, wtx.vout)
172                 if (txout.scriptPubKey == scriptPubKey)
173                     bKeyUsed = true;
174         }
175     }
176
177     // Generate a new key
178     if (!account.vchPubKey.IsValid() || bForceNew || bKeyUsed)
179     {
180         if (!pwalletMain->GetKeyFromPool(account.vchPubKey))
181             throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
182
183         pwalletMain->SetAddressBook(account.vchPubKey.GetID(), strAccount, "receive");
184         walletdb.WriteAccount(strAccount, account);
185     }
186
187     return account.vchPubKey.GetID();
188 }
189
190 UniValue getaccountaddress(const UniValue& params, bool fHelp)
191 {
192     if (!EnsureWalletIsAvailable(fHelp))
193         return NullUniValue;
194
195     if (fHelp || params.size() != 1)
196         throw runtime_error(
197             "getaccountaddress \"account\"\n"
198             "\nDEPRECATED. Returns the current Zcash address for receiving payments to this account.\n"
199             "\nArguments:\n"
200             "1. \"account\"       (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
201             "\nResult:\n"
202             "\"zcashaddress\"   (string) The account Zcash address\n"
203             "\nExamples:\n"
204             + HelpExampleCli("getaccountaddress", "")
205             + HelpExampleCli("getaccountaddress", "\"\"")
206             + HelpExampleCli("getaccountaddress", "\"myaccount\"")
207             + HelpExampleRpc("getaccountaddress", "\"myaccount\"")
208         );
209
210     LOCK2(cs_main, pwalletMain->cs_wallet);
211
212     // Parse the account first so we don't generate a key if there's an error
213     string strAccount = AccountFromValue(params[0]);
214
215     UniValue ret(UniValue::VSTR);
216
217     ret = EncodeDestination(GetAccountAddress(strAccount));
218     return ret;
219 }
220
221
222 UniValue getrawchangeaddress(const UniValue& params, bool fHelp)
223 {
224     if (!EnsureWalletIsAvailable(fHelp))
225         return NullUniValue;
226
227     if (fHelp || params.size() > 1)
228         throw runtime_error(
229             "getrawchangeaddress\n"
230             "\nReturns a new Zcash address, for receiving change.\n"
231             "This is for use with raw transactions, NOT normal use.\n"
232             "\nResult:\n"
233             "\"address\"    (string) The address\n"
234             "\nExamples:\n"
235             + HelpExampleCli("getrawchangeaddress", "")
236             + HelpExampleRpc("getrawchangeaddress", "")
237        );
238
239     LOCK2(cs_main, pwalletMain->cs_wallet);
240
241     if (!pwalletMain->IsLocked())
242         pwalletMain->TopUpKeyPool();
243
244     CReserveKey reservekey(pwalletMain);
245     CPubKey vchPubKey;
246     if (!reservekey.GetReservedKey(vchPubKey))
247         throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
248
249     reservekey.KeepKey();
250
251     CKeyID keyID = vchPubKey.GetID();
252
253     return EncodeDestination(keyID);
254 }
255
256
257 UniValue setaccount(const UniValue& params, bool fHelp)
258 {
259     if (!EnsureWalletIsAvailable(fHelp))
260         return NullUniValue;
261
262     if (fHelp || params.size() < 1 || params.size() > 2)
263         throw runtime_error(
264             "setaccount \"zcashaddress\" \"account\"\n"
265             "\nDEPRECATED. Sets the account associated with the given address.\n"
266             "\nArguments:\n"
267             "1. \"zcashaddress\"  (string, required) The Zcash address to be associated with an account.\n"
268             "2. \"account\"         (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
269             "\nExamples:\n"
270             + HelpExampleCli("setaccount", "\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\" \"tabby\"")
271             + HelpExampleRpc("setaccount", "\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\", \"tabby\"")
272         );
273
274     LOCK2(cs_main, pwalletMain->cs_wallet);
275
276     CTxDestination dest = DecodeDestination(params[0].get_str());
277     if (!IsValidDestination(dest)) {
278         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Zcash address");
279     }
280
281     string strAccount;
282     if (params.size() > 1)
283         strAccount = AccountFromValue(params[1]);
284
285     // Only add the account if the address is yours.
286     if (IsMine(*pwalletMain, dest)) {
287         // Detect when changing the account of an address that is the 'unused current key' of another account:
288         if (pwalletMain->mapAddressBook.count(dest)) {
289             std::string strOldAccount = pwalletMain->mapAddressBook[dest].name;
290             if (dest == GetAccountAddress(strOldAccount)) {
291                 GetAccountAddress(strOldAccount, true);
292             }
293         }
294         pwalletMain->SetAddressBook(dest, strAccount, "receive");
295     }
296     else
297         throw JSONRPCError(RPC_MISC_ERROR, "setaccount can only be used with own address");
298
299     return NullUniValue;
300 }
301
302
303 UniValue getaccount(const UniValue& params, bool fHelp)
304 {
305     if (!EnsureWalletIsAvailable(fHelp))
306         return NullUniValue;
307
308     if (fHelp || params.size() != 1)
309         throw runtime_error(
310             "getaccount \"zcashaddress\"\n"
311             "\nDEPRECATED. Returns the account associated with the given address.\n"
312             "\nArguments:\n"
313             "1. \"zcashaddress\"  (string, required) The Zcash address for account lookup.\n"
314             "\nResult:\n"
315             "\"accountname\"        (string) the account address\n"
316             "\nExamples:\n"
317             + HelpExampleCli("getaccount", "\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\"")
318             + HelpExampleRpc("getaccount", "\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\"")
319         );
320
321     LOCK2(cs_main, pwalletMain->cs_wallet);
322
323     CTxDestination dest = DecodeDestination(params[0].get_str());
324     if (!IsValidDestination(dest)) {
325         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Zcash address");
326     }
327
328     std::string strAccount;
329     std::map<CTxDestination, CAddressBookData>::iterator mi = pwalletMain->mapAddressBook.find(dest);
330     if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.name.empty()) {
331         strAccount = (*mi).second.name;
332     }
333     return strAccount;
334 }
335
336
337 UniValue getaddressesbyaccount(const UniValue& params, bool fHelp)
338 {
339     if (!EnsureWalletIsAvailable(fHelp))
340         return NullUniValue;
341
342     if (fHelp || params.size() != 1)
343         throw runtime_error(
344             "getaddressesbyaccount \"account\"\n"
345             "\nDEPRECATED. Returns the list of addresses for the given account.\n"
346             "\nArguments:\n"
347             "1. \"account\"  (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
348             "\nResult:\n"
349             "[                     (json array of string)\n"
350             "  \"zcashaddress\"  (string) a Zcash address associated with the given account\n"
351             "  ,...\n"
352             "]\n"
353             "\nExamples:\n"
354             + HelpExampleCli("getaddressesbyaccount", "\"tabby\"")
355             + HelpExampleRpc("getaddressesbyaccount", "\"tabby\"")
356         );
357
358     LOCK2(cs_main, pwalletMain->cs_wallet);
359
360     string strAccount = AccountFromValue(params[0]);
361
362     // Find all addresses that have the given account
363     UniValue ret(UniValue::VARR);
364     for (const std::pair<CTxDestination, CAddressBookData>& item : pwalletMain->mapAddressBook) {
365         const CTxDestination& dest = item.first;
366         const std::string& strName = item.second.name;
367         if (strName == strAccount) {
368             ret.push_back(EncodeDestination(dest));
369         }
370     }
371     return ret;
372 }
373
374 static void SendMoney(const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew)
375 {
376     CAmount curBalance = pwalletMain->GetBalance();
377
378     // Check amount
379     if (nValue <= 0)
380         throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount");
381
382     if (nValue > curBalance)
383         throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds");
384
385     // Parse Zcash address
386     CScript scriptPubKey = GetScriptForDestination(address);
387
388     // Create and send the transaction
389     CReserveKey reservekey(pwalletMain);
390     CAmount nFeeRequired;
391     std::string strError;
392     vector<CRecipient> vecSend;
393     int nChangePosRet = -1;
394     CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount};
395     vecSend.push_back(recipient);
396     if (!pwalletMain->CreateTransaction(vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError)) {
397         if (!fSubtractFeeFromAmount && nValue + nFeeRequired > pwalletMain->GetBalance())
398             strError = strprintf("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!", FormatMoney(nFeeRequired));
399         throw JSONRPCError(RPC_WALLET_ERROR, strError);
400     }
401     if (!pwalletMain->CommitTransaction(wtxNew, reservekey))
402         throw JSONRPCError(RPC_WALLET_ERROR, "Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.");
403 }
404
405 UniValue sendtoaddress(const UniValue& params, bool fHelp)
406 {
407     if (!EnsureWalletIsAvailable(fHelp))
408         return NullUniValue;
409
410     if (fHelp || params.size() < 2 || params.size() > 5)
411         throw runtime_error(
412             "sendtoaddress \"zcashaddress\" amount ( \"comment\" \"comment-to\" subtractfeefromamount )\n"
413             "\nSend an amount to a given address. The amount is a real and is rounded to the nearest 0.00000001\n"
414             + HelpRequiringPassphrase() +
415             "\nArguments:\n"
416             "1. \"zcashaddress\"  (string, required) The Zcash address to send to.\n"
417             "2. \"amount\"      (numeric, required) The amount in " + CURRENCY_UNIT + " to send. eg 0.1\n"
418             "3. \"comment\"     (string, optional) A comment used to store what the transaction is for. \n"
419             "                             This is not part of the transaction, just kept in your wallet.\n"
420             "4. \"comment-to\"  (string, optional) A comment to store the name of the person or organization \n"
421             "                             to which you're sending the transaction. This is not part of the \n"
422             "                             transaction, just kept in your wallet.\n"
423             "5. subtractfeefromamount  (boolean, optional, default=false) The fee will be deducted from the amount being sent.\n"
424             "                             The recipient will receive less Zcash than you enter in the amount field.\n"
425             "\nResult:\n"
426             "\"transactionid\"  (string) The transaction id.\n"
427             "\nExamples:\n"
428             + HelpExampleCli("sendtoaddress", "\"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1")
429             + HelpExampleCli("sendtoaddress", "\"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"donation\" \"seans outpost\"")
430             + HelpExampleCli("sendtoaddress", "\"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"\" \"\" true")
431             + HelpExampleRpc("sendtoaddress", "\"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.1, \"donation\", \"seans outpost\"")
432         );
433
434     LOCK2(cs_main, pwalletMain->cs_wallet);
435
436     CTxDestination dest = DecodeDestination(params[0].get_str());
437     if (!IsValidDestination(dest)) {
438         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Zcash address");
439     }
440
441     // Amount
442     CAmount nAmount = AmountFromValue(params[1]);
443     if (nAmount <= 0)
444         throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
445
446     // Wallet comments
447     CWalletTx wtx;
448     if (params.size() > 2 && !params[2].isNull() && !params[2].get_str().empty())
449         wtx.mapValue["comment"] = params[2].get_str();
450     if (params.size() > 3 && !params[3].isNull() && !params[3].get_str().empty())
451         wtx.mapValue["to"]      = params[3].get_str();
452
453     bool fSubtractFeeFromAmount = false;
454     if (params.size() > 4)
455         fSubtractFeeFromAmount = params[4].get_bool();
456
457     EnsureWalletIsUnlocked();
458
459     SendMoney(dest, nAmount, fSubtractFeeFromAmount, wtx);
460
461     return wtx.GetHash().GetHex();
462 }
463
464 UniValue listaddressgroupings(const UniValue& params, bool fHelp)
465 {
466     if (!EnsureWalletIsAvailable(fHelp))
467         return NullUniValue;
468
469     if (fHelp)
470         throw runtime_error(
471             "listaddressgroupings\n"
472             "\nLists groups of addresses which have had their common ownership\n"
473             "made public by common use as inputs or as the resulting change\n"
474             "in past transactions\n"
475             "\nResult:\n"
476             "[\n"
477             "  [\n"
478             "    [\n"
479             "      \"zcashaddress\",     (string) The zcash address\n"
480             "      amount,                 (numeric) The amount in " + CURRENCY_UNIT + "\n"
481             "      \"account\"             (string, optional) The account (DEPRECATED)\n"
482             "    ]\n"
483             "    ,...\n"
484             "  ]\n"
485             "  ,...\n"
486             "]\n"
487             "\nExamples:\n"
488             + HelpExampleCli("listaddressgroupings", "")
489             + HelpExampleRpc("listaddressgroupings", "")
490         );
491
492     LOCK2(cs_main, pwalletMain->cs_wallet);
493
494     UniValue jsonGroupings(UniValue::VARR);
495     std::map<CTxDestination, CAmount> balances = pwalletMain->GetAddressBalances();
496     for (const std::set<CTxDestination>& grouping : pwalletMain->GetAddressGroupings()) {
497         UniValue jsonGrouping(UniValue::VARR);
498         for (const CTxDestination& address : grouping)
499         {
500             UniValue addressInfo(UniValue::VARR);
501             addressInfo.push_back(EncodeDestination(address));
502             addressInfo.push_back(ValueFromAmount(balances[address]));
503             {
504                 if (pwalletMain->mapAddressBook.find(address) != pwalletMain->mapAddressBook.end()) {
505                     addressInfo.push_back(pwalletMain->mapAddressBook.find(address)->second.name);
506                 }
507             }
508             jsonGrouping.push_back(addressInfo);
509         }
510         jsonGroupings.push_back(jsonGrouping);
511     }
512     return jsonGroupings;
513 }
514
515 UniValue signmessage(const UniValue& params, bool fHelp)
516 {
517     if (!EnsureWalletIsAvailable(fHelp))
518         return NullUniValue;
519
520     if (fHelp || params.size() != 2)
521         throw runtime_error(
522             "signmessage \"t-addr\" \"message\"\n"
523             "\nSign a message with the private key of a t-addr"
524             + HelpRequiringPassphrase() + "\n"
525             "\nArguments:\n"
526             "1. \"t-addr\"  (string, required) The transparent address to use for the private key.\n"
527             "2. \"message\"         (string, required) The message to create a signature of.\n"
528             "\nResult:\n"
529             "\"signature\"          (string) The signature of the message encoded in base 64\n"
530             "\nExamples:\n"
531             "\nUnlock the wallet for 30 seconds\n"
532             + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
533             "\nCreate the signature\n"
534             + HelpExampleCli("signmessage", "\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\" \"my message\"") +
535             "\nVerify the signature\n"
536             + HelpExampleCli("verifymessage", "\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\" \"signature\" \"my message\"") +
537             "\nAs json rpc\n"
538             + HelpExampleRpc("signmessage", "\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\", \"my message\"")
539         );
540
541     LOCK2(cs_main, pwalletMain->cs_wallet);
542
543     EnsureWalletIsUnlocked();
544
545     string strAddress = params[0].get_str();
546     string strMessage = params[1].get_str();
547
548     CTxDestination dest = DecodeDestination(strAddress);
549     if (!IsValidDestination(dest)) {
550         throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
551     }
552
553     const CKeyID *keyID = boost::get<CKeyID>(&dest);
554     if (!keyID) {
555         throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
556     }
557
558     CKey key;
559     if (!pwalletMain->GetKey(*keyID, key)) {
560         throw JSONRPCError(RPC_WALLET_ERROR, "Private key not available");
561     }
562
563     CHashWriter ss(SER_GETHASH, 0);
564     ss << strMessageMagic;
565     ss << strMessage;
566
567     vector<unsigned char> vchSig;
568     if (!key.SignCompact(ss.GetHash(), vchSig))
569         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed");
570
571     return EncodeBase64(&vchSig[0], vchSig.size());
572 }
573
574 UniValue getreceivedbyaddress(const UniValue& params, bool fHelp)
575 {
576     if (!EnsureWalletIsAvailable(fHelp))
577         return NullUniValue;
578
579     if (fHelp || params.size() < 1 || params.size() > 2)
580         throw runtime_error(
581             "getreceivedbyaddress \"zcashaddress\" ( minconf )\n"
582             "\nReturns the total amount received by the given Zcash address in transactions with at least minconf confirmations.\n"
583             "\nArguments:\n"
584             "1. \"zcashaddress\"  (string, required) The Zcash address for transactions.\n"
585             "2. minconf             (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
586             "\nResult:\n"
587             "amount   (numeric) The total amount in " + CURRENCY_UNIT + " received at this address.\n"
588             "\nExamples:\n"
589             "\nThe amount from transactions with at least 1 confirmation\n"
590             + HelpExampleCli("getreceivedbyaddress", "\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\"") +
591             "\nThe amount including unconfirmed transactions, zero confirmations\n"
592             + HelpExampleCli("getreceivedbyaddress", "\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\" 0") +
593             "\nThe amount with at least 6 confirmations, very safe\n"
594             + HelpExampleCli("getreceivedbyaddress", "\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\" 6") +
595             "\nAs a json rpc call\n"
596             + HelpExampleRpc("getreceivedbyaddress", "\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\", 6")
597        );
598
599     LOCK2(cs_main, pwalletMain->cs_wallet);
600
601     // Bitcoin address
602     CTxDestination dest = DecodeDestination(params[0].get_str());
603     if (!IsValidDestination(dest)) {
604         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Zcash address");
605     }
606     CScript scriptPubKey = GetScriptForDestination(dest);
607     if (!IsMine(*pwalletMain, scriptPubKey)) {
608         return ValueFromAmount(0);
609     }
610
611     // Minimum confirmations
612     int nMinDepth = 1;
613     if (params.size() > 1)
614         nMinDepth = params[1].get_int();
615
616     // Tally
617     CAmount nAmount = 0;
618     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
619     {
620         const CWalletTx& wtx = (*it).second;
621         if (wtx.IsCoinBase() || !CheckFinalTx(wtx))
622             continue;
623
624         BOOST_FOREACH(const CTxOut& txout, wtx.vout)
625             if (txout.scriptPubKey == scriptPubKey)
626                 if (wtx.GetDepthInMainChain() >= nMinDepth)
627                     nAmount += txout.nValue;
628     }
629
630     return  ValueFromAmount(nAmount);
631 }
632
633
634 UniValue getreceivedbyaccount(const UniValue& params, bool fHelp)
635 {
636     if (!EnsureWalletIsAvailable(fHelp))
637         return NullUniValue;
638
639     if (fHelp || params.size() < 1 || params.size() > 2)
640         throw runtime_error(
641             "getreceivedbyaccount \"account\" ( minconf )\n"
642             "\nDEPRECATED. Returns the total amount received by addresses with <account> in transactions with at least [minconf] confirmations.\n"
643             "\nArguments:\n"
644             "1. \"account\"      (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
645             "2. minconf          (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
646             "\nResult:\n"
647             "amount              (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n"
648             "\nExamples:\n"
649             "\nAmount received by the default account with at least 1 confirmation\n"
650             + HelpExampleCli("getreceivedbyaccount", "\"\"") +
651             "\nAmount received at the tabby account including unconfirmed amounts with zero confirmations\n"
652             + HelpExampleCli("getreceivedbyaccount", "\"tabby\" 0") +
653             "\nThe amount with at least 6 confirmation, very safe\n"
654             + HelpExampleCli("getreceivedbyaccount", "\"tabby\" 6") +
655             "\nAs a json rpc call\n"
656             + HelpExampleRpc("getreceivedbyaccount", "\"tabby\", 6")
657         );
658
659     LOCK2(cs_main, pwalletMain->cs_wallet);
660
661     // Minimum confirmations
662     int nMinDepth = 1;
663     if (params.size() > 1)
664         nMinDepth = params[1].get_int();
665
666     // Get the set of pub keys assigned to account
667     string strAccount = AccountFromValue(params[0]);
668     set<CTxDestination> setAddress = pwalletMain->GetAccountAddresses(strAccount);
669
670     // Tally
671     CAmount nAmount = 0;
672     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
673     {
674         const CWalletTx& wtx = (*it).second;
675         if (wtx.IsCoinBase() || !CheckFinalTx(wtx))
676             continue;
677
678         BOOST_FOREACH(const CTxOut& txout, wtx.vout)
679         {
680             CTxDestination address;
681             if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*pwalletMain, address) && setAddress.count(address))
682                 if (wtx.GetDepthInMainChain() >= nMinDepth)
683                     nAmount += txout.nValue;
684         }
685     }
686
687     return ValueFromAmount(nAmount);
688 }
689
690
691 CAmount GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth, const isminefilter& filter)
692 {
693     CAmount nBalance = 0;
694
695     // Tally wallet transactions
696     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
697     {
698         const CWalletTx& wtx = (*it).second;
699         if (!CheckFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0 || wtx.GetDepthInMainChain() < 0)
700             continue;
701
702         CAmount nReceived, nSent, nFee;
703         wtx.GetAccountAmounts(strAccount, nReceived, nSent, nFee, filter);
704
705         if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth)
706             nBalance += nReceived;
707         nBalance -= nSent + nFee;
708     }
709
710     // Tally internal accounting entries
711     nBalance += walletdb.GetAccountCreditDebit(strAccount);
712
713     return nBalance;
714 }
715
716 CAmount GetAccountBalance(const string& strAccount, int nMinDepth, const isminefilter& filter)
717 {
718     CWalletDB walletdb(pwalletMain->strWalletFile);
719     return GetAccountBalance(walletdb, strAccount, nMinDepth, filter);
720 }
721
722
723 UniValue getbalance(const UniValue& params, bool fHelp)
724 {
725     if (!EnsureWalletIsAvailable(fHelp))
726         return NullUniValue;
727
728     if (fHelp || params.size() > 3)
729         throw runtime_error(
730             "getbalance ( \"account\" minconf includeWatchonly )\n"
731             "\nReturns the server's total available balance.\n"
732             "\nArguments:\n"
733             "1. \"account\"      (string, optional) DEPRECATED. If provided, it MUST be set to the empty string \"\" or to the string \"*\", either of which will give the total available balance. Passing any other string will result in an error.\n"
734             "2. minconf          (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
735             "3. includeWatchonly (bool, optional, default=false) Also include balance in watchonly addresses (see 'importaddress')\n"
736             "\nResult:\n"
737             "amount              (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n"
738             "\nExamples:\n"
739             "\nThe total amount in the wallet\n"
740             + HelpExampleCli("getbalance", "") +
741             "\nThe total amount in the wallet at least 5 blocks confirmed\n"
742             + HelpExampleCli("getbalance", "\"*\" 6") +
743             "\nAs a json rpc call\n"
744             + HelpExampleRpc("getbalance", "\"*\", 6")
745         );
746
747     LOCK2(cs_main, pwalletMain->cs_wallet);
748
749     if (params.size() == 0)
750         return  ValueFromAmount(pwalletMain->GetBalance());
751
752     int nMinDepth = 1;
753     if (params.size() > 1)
754         nMinDepth = params[1].get_int();
755     isminefilter filter = ISMINE_SPENDABLE;
756     if(params.size() > 2)
757         if(params[2].get_bool())
758             filter = filter | ISMINE_WATCH_ONLY;
759
760     if (params[0].get_str() == "*") {
761         // Calculate total balance a different way from GetBalance()
762         // (GetBalance() sums up all unspent TxOuts)
763         // getbalance and "getbalance * 1 true" should return the same number
764         CAmount nBalance = 0;
765         for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
766         {
767             const CWalletTx& wtx = (*it).second;
768             if (!CheckFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0 || wtx.GetDepthInMainChain() < 0)
769                 continue;
770
771             CAmount allFee;
772             string strSentAccount;
773             list<COutputEntry> listReceived;
774             list<COutputEntry> listSent;
775             wtx.GetAmounts(listReceived, listSent, allFee, strSentAccount, filter);
776             if (wtx.GetDepthInMainChain() >= nMinDepth)
777             {
778                 BOOST_FOREACH(const COutputEntry& r, listReceived)
779                     nBalance += r.amount;
780             }
781             BOOST_FOREACH(const COutputEntry& s, listSent)
782                 nBalance -= s.amount;
783             nBalance -= allFee;
784         }
785         return  ValueFromAmount(nBalance);
786     }
787
788     string strAccount = AccountFromValue(params[0]);
789
790     CAmount nBalance = GetAccountBalance(strAccount, nMinDepth, filter);
791
792     return ValueFromAmount(nBalance);
793 }
794
795 UniValue getunconfirmedbalance(const UniValue &params, bool fHelp)
796 {
797     if (!EnsureWalletIsAvailable(fHelp))
798         return NullUniValue;
799
800     if (fHelp || params.size() > 0)
801         throw runtime_error(
802                 "getunconfirmedbalance\n"
803                 "Returns the server's total unconfirmed balance\n");
804
805     LOCK2(cs_main, pwalletMain->cs_wallet);
806
807     return ValueFromAmount(pwalletMain->GetUnconfirmedBalance());
808 }
809
810
811 UniValue movecmd(const UniValue& params, bool fHelp)
812 {
813     if (!EnsureWalletIsAvailable(fHelp))
814         return NullUniValue;
815
816     if (fHelp || params.size() < 3 || params.size() > 5)
817         throw runtime_error(
818             "move \"fromaccount\" \"toaccount\" amount ( minconf \"comment\" )\n"
819             "\nDEPRECATED. Move a specified amount from one account in your wallet to another.\n"
820             "\nArguments:\n"
821             "1. \"fromaccount\"   (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
822             "2. \"toaccount\"     (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
823             "3. amount            (numeric) Quantity of " + CURRENCY_UNIT + " to move between accounts.\n"
824             "4. minconf           (numeric, optional, default=1) Only use funds with at least this many confirmations.\n"
825             "5. \"comment\"       (string, optional) An optional comment, stored in the wallet only.\n"
826             "\nResult:\n"
827             "true|false           (boolean) true if successful.\n"
828             "\nExamples:\n"
829             "\nMove 0.01 " + CURRENCY_UNIT + " from the default account to the account named tabby\n"
830             + HelpExampleCli("move", "\"\" \"tabby\" 0.01") +
831             "\nMove 0.01 " + CURRENCY_UNIT + " timotei to akiko with a comment and funds have 6 confirmations\n"
832             + HelpExampleCli("move", "\"timotei\" \"akiko\" 0.01 6 \"happy birthday!\"") +
833             "\nAs a json rpc call\n"
834             + HelpExampleRpc("move", "\"timotei\", \"akiko\", 0.01, 6, \"happy birthday!\"")
835         );
836
837     LOCK2(cs_main, pwalletMain->cs_wallet);
838
839     string strFrom = AccountFromValue(params[0]);
840     string strTo = AccountFromValue(params[1]);
841     CAmount nAmount = AmountFromValue(params[2]);
842     if (nAmount <= 0)
843         throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
844     if (params.size() > 3)
845         // unused parameter, used to be nMinDepth, keep type-checking it though
846         (void)params[3].get_int();
847     string strComment;
848     if (params.size() > 4)
849         strComment = params[4].get_str();
850
851     CWalletDB walletdb(pwalletMain->strWalletFile);
852     if (!walletdb.TxnBegin())
853         throw JSONRPCError(RPC_DATABASE_ERROR, "database error");
854
855     int64_t nNow = GetAdjustedTime();
856
857     // Debit
858     CAccountingEntry debit;
859     debit.nOrderPos = pwalletMain->IncOrderPosNext(&walletdb);
860     debit.strAccount = strFrom;
861     debit.nCreditDebit = -nAmount;
862     debit.nTime = nNow;
863     debit.strOtherAccount = strTo;
864     debit.strComment = strComment;
865     walletdb.WriteAccountingEntry(debit);
866
867     // Credit
868     CAccountingEntry credit;
869     credit.nOrderPos = pwalletMain->IncOrderPosNext(&walletdb);
870     credit.strAccount = strTo;
871     credit.nCreditDebit = nAmount;
872     credit.nTime = nNow;
873     credit.strOtherAccount = strFrom;
874     credit.strComment = strComment;
875     walletdb.WriteAccountingEntry(credit);
876
877     if (!walletdb.TxnCommit())
878         throw JSONRPCError(RPC_DATABASE_ERROR, "database error");
879
880     return true;
881 }
882
883
884 UniValue sendfrom(const UniValue& params, bool fHelp)
885 {
886     if (!EnsureWalletIsAvailable(fHelp))
887         return NullUniValue;
888
889     if (fHelp || params.size() < 3 || params.size() > 6)
890         throw runtime_error(
891             "sendfrom \"fromaccount\" \"tozcashaddress\" amount ( minconf \"comment\" \"comment-to\" )\n"
892             "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a Zcash address.\n"
893             "The amount is a real and is rounded to the nearest 0.00000001."
894             + HelpRequiringPassphrase() + "\n"
895             "\nArguments:\n"
896             "1. \"fromaccount\"       (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
897             "2. \"tozcashaddress\"  (string, required) The Zcash address to send funds to.\n"
898             "3. amount                (numeric, required) The amount in " + CURRENCY_UNIT + " (transaction fee is added on top).\n"
899             "4. minconf               (numeric, optional, default=1) Only use funds with at least this many confirmations.\n"
900             "5. \"comment\"           (string, optional) A comment used to store what the transaction is for. \n"
901             "                                     This is not part of the transaction, just kept in your wallet.\n"
902             "6. \"comment-to\"        (string, optional) An optional comment to store the name of the person or organization \n"
903             "                                     to which you're sending the transaction. This is not part of the transaction, \n"
904             "                                     it is just kept in your wallet.\n"
905             "\nResult:\n"
906             "\"transactionid\"        (string) The transaction id.\n"
907             "\nExamples:\n"
908             "\nSend 0.01 " + CURRENCY_UNIT + " from the default account to the address, must have at least 1 confirmation\n"
909             + HelpExampleCli("sendfrom", "\"\" \"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01") +
910             "\nSend 0.01 from the tabby account to the given address, funds must have at least 6 confirmations\n"
911             + HelpExampleCli("sendfrom", "\"tabby\" \"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01 6 \"donation\" \"seans outpost\"") +
912             "\nAs a json rpc call\n"
913             + HelpExampleRpc("sendfrom", "\"tabby\", \"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.01, 6, \"donation\", \"seans outpost\"")
914         );
915
916     LOCK2(cs_main, pwalletMain->cs_wallet);
917
918     std::string strAccount = AccountFromValue(params[0]);
919     CTxDestination dest = DecodeDestination(params[1].get_str());
920     if (!IsValidDestination(dest)) {
921         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Zcash address");
922     }
923     CAmount nAmount = AmountFromValue(params[2]);
924     if (nAmount <= 0)
925         throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
926     int nMinDepth = 1;
927     if (params.size() > 3)
928         nMinDepth = params[3].get_int();
929
930     CWalletTx wtx;
931     wtx.strFromAccount = strAccount;
932     if (params.size() > 4 && !params[4].isNull() && !params[4].get_str().empty())
933         wtx.mapValue["comment"] = params[4].get_str();
934     if (params.size() > 5 && !params[5].isNull() && !params[5].get_str().empty())
935         wtx.mapValue["to"]      = params[5].get_str();
936
937     EnsureWalletIsUnlocked();
938
939     // Check funds
940     CAmount nBalance = GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE);
941     if (nAmount > nBalance)
942         throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
943
944     SendMoney(dest, nAmount, false, wtx);
945
946     return wtx.GetHash().GetHex();
947 }
948
949
950 UniValue sendmany(const UniValue& params, bool fHelp)
951 {
952     if (!EnsureWalletIsAvailable(fHelp))
953         return NullUniValue;
954
955     if (fHelp || params.size() < 2 || params.size() > 5)
956         throw runtime_error(
957             "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" [\"address\",...] )\n"
958             "\nSend multiple times. Amounts are double-precision floating point numbers."
959             + HelpRequiringPassphrase() + "\n"
960             "\nArguments:\n"
961             "1. \"fromaccount\"         (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
962             "2. \"amounts\"             (string, required) A json object with addresses and amounts\n"
963             "    {\n"
964             "      \"address\":amount   (numeric) The Zcash address is the key, the numeric amount in " + CURRENCY_UNIT + " is the value\n"
965             "      ,...\n"
966             "    }\n"
967             "3. minconf                 (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n"
968             "4. \"comment\"             (string, optional) A comment\n"
969             "5. subtractfeefromamount   (string, optional) A json array with addresses.\n"
970             "                           The fee will be equally deducted from the amount of each selected address.\n"
971             "                           Those recipients will receive less Zcash than you enter in their corresponding amount field.\n"
972             "                           If no addresses are specified here, the sender pays the fee.\n"
973             "    [\n"
974             "      \"address\"            (string) Subtract fee from this address\n"
975             "      ,...\n"
976             "    ]\n"
977             "\nResult:\n"
978             "\"transactionid\"          (string) The transaction id for the send. Only 1 transaction is created regardless of \n"
979             "                                    the number of addresses.\n"
980             "\nExamples:\n"
981             "\nSend two amounts to two different addresses:\n"
982             + HelpExampleCli("sendmany", "\"\" \"{\\\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\\\":0.01,\\\"t1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") +
983             "\nSend two amounts to two different addresses setting the confirmation and comment:\n"
984             + HelpExampleCli("sendmany", "\"\" \"{\\\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\\\":0.01,\\\"t1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 6 \"testing\"") +
985             "\nSend two amounts to two different addresses, subtract fee from amount:\n"
986             + HelpExampleCli("sendmany", "\"\" \"{\\\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\\\":0.01,\\\"t1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 1 \"\" \"[\\\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\\\",\\\"t1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\"]\"") +
987             "\nAs a json rpc call\n"
988             + HelpExampleRpc("sendmany", "\"\", \"{\\\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\\\":0.01,\\\"t1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"")
989         );
990
991     LOCK2(cs_main, pwalletMain->cs_wallet);
992
993     string strAccount = AccountFromValue(params[0]);
994     UniValue sendTo = params[1].get_obj();
995     int nMinDepth = 1;
996     if (params.size() > 2)
997         nMinDepth = params[2].get_int();
998
999     CWalletTx wtx;
1000     wtx.strFromAccount = strAccount;
1001     if (params.size() > 3 && !params[3].isNull() && !params[3].get_str().empty())
1002         wtx.mapValue["comment"] = params[3].get_str();
1003
1004     UniValue subtractFeeFromAmount(UniValue::VARR);
1005     if (params.size() > 4)
1006         subtractFeeFromAmount = params[4].get_array();
1007
1008     std::set<CTxDestination> destinations;
1009     std::vector<CRecipient> vecSend;
1010
1011     CAmount totalAmount = 0;
1012     std::vector<std::string> keys = sendTo.getKeys();
1013     for (const std::string& name_ : keys) {
1014         CTxDestination dest = DecodeDestination(name_);
1015         if (!IsValidDestination(dest)) {
1016             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Zcash address: ") + name_);
1017         }
1018
1019         if (destinations.count(dest)) {
1020             throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + name_);
1021         }
1022         destinations.insert(dest);
1023
1024         CScript scriptPubKey = GetScriptForDestination(dest);
1025         CAmount nAmount = AmountFromValue(sendTo[name_]);
1026         if (nAmount <= 0)
1027             throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
1028         totalAmount += nAmount;
1029
1030         bool fSubtractFeeFromAmount = false;
1031         for (size_t idx = 0; idx < subtractFeeFromAmount.size(); idx++) {
1032             const UniValue& addr = subtractFeeFromAmount[idx];
1033             if (addr.get_str() == name_)
1034                 fSubtractFeeFromAmount = true;
1035         }
1036
1037         CRecipient recipient = {scriptPubKey, nAmount, fSubtractFeeFromAmount};
1038         vecSend.push_back(recipient);
1039     }
1040
1041     EnsureWalletIsUnlocked();
1042
1043     // Check funds
1044     CAmount nBalance = GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE);
1045     if (totalAmount > nBalance)
1046         throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
1047
1048     // Send
1049     CReserveKey keyChange(pwalletMain);
1050     CAmount nFeeRequired = 0;
1051     int nChangePosRet = -1;
1052     string strFailReason;
1053     bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, nChangePosRet, strFailReason);
1054     if (!fCreated)
1055         throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
1056     if (!pwalletMain->CommitTransaction(wtx, keyChange))
1057         throw JSONRPCError(RPC_WALLET_ERROR, "Transaction commit failed");
1058
1059     return wtx.GetHash().GetHex();
1060 }
1061
1062 // Defined in rpcmisc.cpp
1063 extern CScript _createmultisig_redeemScript(const UniValue& params);
1064
1065 UniValue addmultisigaddress(const UniValue& params, bool fHelp)
1066 {
1067     if (!EnsureWalletIsAvailable(fHelp))
1068         return NullUniValue;
1069
1070     if (fHelp || params.size() < 2 || params.size() > 3)
1071     {
1072         string msg = "addmultisigaddress nrequired [\"key\",...] ( \"account\" )\n"
1073             "\nAdd a nrequired-to-sign multisignature address to the wallet.\n"
1074             "Each key is a Zcash address or hex-encoded public key.\n"
1075             "If 'account' is specified (DEPRECATED), assign address to that account.\n"
1076
1077             "\nArguments:\n"
1078             "1. nrequired        (numeric, required) The number of required signatures out of the n keys or addresses.\n"
1079             "2. \"keysobject\"   (string, required) A json array of Zcash addresses or hex-encoded public keys\n"
1080             "     [\n"
1081             "       \"address\"  (string) Zcash address or hex-encoded public key\n"
1082             "       ...,\n"
1083             "     ]\n"
1084             "3. \"account\"      (string, optional) DEPRECATED. If provided, MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n"
1085
1086             "\nResult:\n"
1087             "\"zcashaddress\"  (string) A Zcash address associated with the keys.\n"
1088
1089             "\nExamples:\n"
1090             "\nAdd a multisig address from 2 addresses\n"
1091             + HelpExampleCli("addmultisigaddress", "2 \"[\\\"t16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"t171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") +
1092             "\nAs json rpc call\n"
1093             + HelpExampleRpc("addmultisigaddress", "2, \"[\\\"t16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"t171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"")
1094         ;
1095         throw runtime_error(msg);
1096     }
1097
1098     LOCK2(cs_main, pwalletMain->cs_wallet);
1099
1100     string strAccount;
1101     if (params.size() > 2)
1102         strAccount = AccountFromValue(params[2]);
1103
1104     // Construct using pay-to-script-hash:
1105     CScript inner = _createmultisig_redeemScript(params);
1106     CScriptID innerID(inner);
1107     pwalletMain->AddCScript(inner);
1108
1109     pwalletMain->SetAddressBook(innerID, strAccount, "send");
1110     return EncodeDestination(innerID);
1111 }
1112
1113
1114 struct tallyitem
1115 {
1116     CAmount nAmount;
1117     int nConf;
1118     vector<uint256> txids;
1119     bool fIsWatchonly;
1120     tallyitem()
1121     {
1122         nAmount = 0;
1123         nConf = std::numeric_limits<int>::max();
1124         fIsWatchonly = false;
1125     }
1126 };
1127
1128 UniValue ListReceived(const UniValue& params, bool fByAccounts)
1129 {
1130     // Minimum confirmations
1131     int nMinDepth = 1;
1132     if (params.size() > 0)
1133         nMinDepth = params[0].get_int();
1134
1135     // Whether to include empty accounts
1136     bool fIncludeEmpty = false;
1137     if (params.size() > 1)
1138         fIncludeEmpty = params[1].get_bool();
1139
1140     isminefilter filter = ISMINE_SPENDABLE;
1141     if(params.size() > 2)
1142         if(params[2].get_bool())
1143             filter = filter | ISMINE_WATCH_ONLY;
1144
1145     // Tally
1146     std::map<CTxDestination, tallyitem> mapTally;
1147     for (const std::pair<uint256, CWalletTx>& pairWtx : pwalletMain->mapWallet) {
1148         const CWalletTx& wtx = pairWtx.second;
1149
1150         if (wtx.IsCoinBase() || !CheckFinalTx(wtx))
1151             continue;
1152
1153         int nDepth = wtx.GetDepthInMainChain();
1154         if (nDepth < nMinDepth)
1155             continue;
1156
1157         BOOST_FOREACH(const CTxOut& txout, wtx.vout)
1158         {
1159             CTxDestination address;
1160             if (!ExtractDestination(txout.scriptPubKey, address))
1161                 continue;
1162
1163             isminefilter mine = IsMine(*pwalletMain, address);
1164             if(!(mine & filter))
1165                 continue;
1166
1167             tallyitem& item = mapTally[address];
1168             item.nAmount += txout.nValue;
1169             item.nConf = min(item.nConf, nDepth);
1170             item.txids.push_back(wtx.GetHash());
1171             if (mine & ISMINE_WATCH_ONLY)
1172                 item.fIsWatchonly = true;
1173         }
1174     }
1175
1176     // Reply
1177     UniValue ret(UniValue::VARR);
1178     std::map<std::string, tallyitem> mapAccountTally;
1179     for (const std::pair<CTxDestination, CAddressBookData>& item : pwalletMain->mapAddressBook) {
1180         const CTxDestination& dest = item.first;
1181         const std::string& strAccount = item.second.name;
1182         std::map<CTxDestination, tallyitem>::iterator it = mapTally.find(dest);
1183         if (it == mapTally.end() && !fIncludeEmpty)
1184             continue;
1185
1186         CAmount nAmount = 0;
1187         int nConf = std::numeric_limits<int>::max();
1188         bool fIsWatchonly = false;
1189         if (it != mapTally.end())
1190         {
1191             nAmount = (*it).second.nAmount;
1192             nConf = (*it).second.nConf;
1193             fIsWatchonly = (*it).second.fIsWatchonly;
1194         }
1195
1196         if (fByAccounts)
1197         {
1198             tallyitem& item = mapAccountTally[strAccount];
1199             item.nAmount += nAmount;
1200             item.nConf = min(item.nConf, nConf);
1201             item.fIsWatchonly = fIsWatchonly;
1202         }
1203         else
1204         {
1205             UniValue obj(UniValue::VOBJ);
1206             if(fIsWatchonly)
1207                 obj.push_back(Pair("involvesWatchonly", true));
1208             obj.push_back(Pair("address",       EncodeDestination(dest)));
1209             obj.push_back(Pair("account",       strAccount));
1210             obj.push_back(Pair("amount",        ValueFromAmount(nAmount)));
1211             obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
1212             UniValue transactions(UniValue::VARR);
1213             if (it != mapTally.end())
1214             {
1215                 BOOST_FOREACH(const uint256& item, (*it).second.txids)
1216                 {
1217                     transactions.push_back(item.GetHex());
1218                 }
1219             }
1220             obj.push_back(Pair("txids", transactions));
1221             ret.push_back(obj);
1222         }
1223     }
1224
1225     if (fByAccounts)
1226     {
1227         for (map<string, tallyitem>::iterator it = mapAccountTally.begin(); it != mapAccountTally.end(); ++it)
1228         {
1229             CAmount nAmount = (*it).second.nAmount;
1230             int nConf = (*it).second.nConf;
1231             UniValue obj(UniValue::VOBJ);
1232             if((*it).second.fIsWatchonly)
1233                 obj.push_back(Pair("involvesWatchonly", true));
1234             obj.push_back(Pair("account",       (*it).first));
1235             obj.push_back(Pair("amount",        ValueFromAmount(nAmount)));
1236             obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
1237             ret.push_back(obj);
1238         }
1239     }
1240
1241     return ret;
1242 }
1243
1244 UniValue listreceivedbyaddress(const UniValue& params, bool fHelp)
1245 {
1246     if (!EnsureWalletIsAvailable(fHelp))
1247         return NullUniValue;
1248
1249     if (fHelp || params.size() > 3)
1250         throw runtime_error(
1251             "listreceivedbyaddress ( minconf includeempty includeWatchonly)\n"
1252             "\nList balances by receiving address.\n"
1253             "\nArguments:\n"
1254             "1. minconf       (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
1255             "2. includeempty  (numeric, optional, default=false) Whether to include addresses that haven't received any payments.\n"
1256             "3. includeWatchonly (bool, optional, default=false) Whether to include watchonly addresses (see 'importaddress').\n"
1257
1258             "\nResult:\n"
1259             "[\n"
1260             "  {\n"
1261             "    \"involvesWatchonly\" : true,        (bool) Only returned if imported addresses were involved in transaction\n"
1262             "    \"address\" : \"receivingaddress\",  (string) The receiving address\n"
1263             "    \"account\" : \"accountname\",       (string) DEPRECATED. The account of the receiving address. The default account is \"\".\n"
1264             "    \"amount\" : x.xxx,                  (numeric) The total amount in " + CURRENCY_UNIT + " received by the address\n"
1265             "    \"confirmations\" : n                (numeric) The number of confirmations of the most recent transaction included\n"
1266             "  }\n"
1267             "  ,...\n"
1268             "]\n"
1269
1270             "\nExamples:\n"
1271             + HelpExampleCli("listreceivedbyaddress", "")
1272             + HelpExampleCli("listreceivedbyaddress", "6 true")
1273             + HelpExampleRpc("listreceivedbyaddress", "6, true, true")
1274         );
1275
1276     LOCK2(cs_main, pwalletMain->cs_wallet);
1277
1278     return ListReceived(params, false);
1279 }
1280
1281 UniValue listreceivedbyaccount(const UniValue& params, bool fHelp)
1282 {
1283     if (!EnsureWalletIsAvailable(fHelp))
1284         return NullUniValue;
1285
1286     if (fHelp || params.size() > 3)
1287         throw runtime_error(
1288             "listreceivedbyaccount ( minconf includeempty includeWatchonly)\n"
1289             "\nDEPRECATED. List balances by account.\n"
1290             "\nArguments:\n"
1291             "1. minconf      (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
1292             "2. includeempty (boolean, optional, default=false) Whether to include accounts that haven't received any payments.\n"
1293             "3. includeWatchonly (bool, optional, default=false) Whether to include watchonly addresses (see 'importaddress').\n"
1294
1295             "\nResult:\n"
1296             "[\n"
1297             "  {\n"
1298             "    \"involvesWatchonly\" : true,   (bool) Only returned if imported addresses were involved in transaction\n"
1299             "    \"account\" : \"accountname\",  (string) The account name of the receiving account\n"
1300             "    \"amount\" : x.xxx,             (numeric) The total amount received by addresses with this account\n"
1301             "    \"confirmations\" : n           (numeric) The number of confirmations of the most recent transaction included\n"
1302             "  }\n"
1303             "  ,...\n"
1304             "]\n"
1305
1306             "\nExamples:\n"
1307             + HelpExampleCli("listreceivedbyaccount", "")
1308             + HelpExampleCli("listreceivedbyaccount", "6 true")
1309             + HelpExampleRpc("listreceivedbyaccount", "6, true, true")
1310         );
1311
1312     LOCK2(cs_main, pwalletMain->cs_wallet);
1313
1314     return ListReceived(params, true);
1315 }
1316
1317 static void MaybePushAddress(UniValue & entry, const CTxDestination &dest)
1318 {
1319     if (IsValidDestination(dest)) {
1320         entry.push_back(Pair("address", EncodeDestination(dest)));
1321     }
1322 }
1323
1324 void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter)
1325 {
1326     CAmount nFee;
1327     string strSentAccount;
1328     list<COutputEntry> listReceived;
1329     list<COutputEntry> listSent;
1330
1331     wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount, filter);
1332
1333     bool fAllAccounts = (strAccount == string("*"));
1334     bool involvesWatchonly = wtx.IsFromMe(ISMINE_WATCH_ONLY);
1335
1336     // Sent
1337     if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount))
1338     {
1339         BOOST_FOREACH(const COutputEntry& s, listSent)
1340         {
1341             UniValue entry(UniValue::VOBJ);
1342             if(involvesWatchonly || (::IsMine(*pwalletMain, s.destination) & ISMINE_WATCH_ONLY))
1343                 entry.push_back(Pair("involvesWatchonly", true));
1344             entry.push_back(Pair("account", strSentAccount));
1345             MaybePushAddress(entry, s.destination);
1346             entry.push_back(Pair("category", "send"));
1347             entry.push_back(Pair("amount", ValueFromAmount(-s.amount)));
1348             entry.push_back(Pair("vout", s.vout));
1349             entry.push_back(Pair("fee", ValueFromAmount(-nFee)));
1350             if (fLong)
1351                 WalletTxToJSON(wtx, entry);
1352             entry.push_back(Pair("size", static_cast<uint64_t>(GetSerializeSize(static_cast<CTransaction>(wtx), SER_NETWORK, PROTOCOL_VERSION))));
1353             ret.push_back(entry);
1354         }
1355     }
1356
1357     // Received
1358     if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth)
1359     {
1360         BOOST_FOREACH(const COutputEntry& r, listReceived)
1361         {
1362             string account;
1363             if (pwalletMain->mapAddressBook.count(r.destination))
1364                 account = pwalletMain->mapAddressBook[r.destination].name;
1365             if (fAllAccounts || (account == strAccount))
1366             {
1367                 UniValue entry(UniValue::VOBJ);
1368                 if(involvesWatchonly || (::IsMine(*pwalletMain, r.destination) & ISMINE_WATCH_ONLY))
1369                     entry.push_back(Pair("involvesWatchonly", true));
1370                 entry.push_back(Pair("account", account));
1371                 MaybePushAddress(entry, r.destination);
1372                 if (wtx.IsCoinBase())
1373                 {
1374                     if (wtx.GetDepthInMainChain() < 1)
1375                         entry.push_back(Pair("category", "orphan"));
1376                     else if (wtx.GetBlocksToMaturity() > 0)
1377                         entry.push_back(Pair("category", "immature"));
1378                     else
1379                         entry.push_back(Pair("category", "generate"));
1380                 }
1381                 else
1382                 {
1383                     entry.push_back(Pair("category", "receive"));
1384                 }
1385                 entry.push_back(Pair("amount", ValueFromAmount(r.amount)));
1386                 entry.push_back(Pair("vout", r.vout));
1387                 if (fLong)
1388                     WalletTxToJSON(wtx, entry);
1389                 entry.push_back(Pair("size", static_cast<uint64_t>(GetSerializeSize(static_cast<CTransaction>(wtx), SER_NETWORK, PROTOCOL_VERSION))));
1390                 ret.push_back(entry);
1391             }
1392         }
1393     }
1394 }
1395
1396 void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, UniValue& ret)
1397 {
1398     bool fAllAccounts = (strAccount == string("*"));
1399
1400     if (fAllAccounts || acentry.strAccount == strAccount)
1401     {
1402         UniValue entry(UniValue::VOBJ);
1403         entry.push_back(Pair("account", acentry.strAccount));
1404         entry.push_back(Pair("category", "move"));
1405         entry.push_back(Pair("time", acentry.nTime));
1406         entry.push_back(Pair("amount", ValueFromAmount(acentry.nCreditDebit)));
1407         entry.push_back(Pair("otheraccount", acentry.strOtherAccount));
1408         entry.push_back(Pair("comment", acentry.strComment));
1409         ret.push_back(entry);
1410     }
1411 }
1412
1413 UniValue listtransactions(const UniValue& params, bool fHelp)
1414 {
1415     if (!EnsureWalletIsAvailable(fHelp))
1416         return NullUniValue;
1417
1418     if (fHelp || params.size() > 4)
1419         throw runtime_error(
1420             "listtransactions ( \"account\" count from includeWatchonly)\n"
1421             "\nReturns up to 'count' most recent transactions skipping the first 'from' transactions for account 'account'.\n"
1422             "\nArguments:\n"
1423             "1. \"account\"    (string, optional) DEPRECATED. The account name. Should be \"*\".\n"
1424             "2. count          (numeric, optional, default=10) The number of transactions to return\n"
1425             "3. from           (numeric, optional, default=0) The number of transactions to skip\n"
1426             "4. includeWatchonly (bool, optional, default=false) Include transactions to watchonly addresses (see 'importaddress')\n"
1427             "\nResult:\n"
1428             "[\n"
1429             "  {\n"
1430             "    \"account\":\"accountname\",       (string) DEPRECATED. The account name associated with the transaction. \n"
1431             "                                                It will be \"\" for the default account.\n"
1432             "    \"address\":\"zcashaddress\",    (string) The Zcash address of the transaction. Not present for \n"
1433             "                                                move transactions (category = move).\n"
1434             "    \"category\":\"send|receive|move\", (string) The transaction category. 'move' is a local (off blockchain)\n"
1435             "                                                transaction between accounts, and not associated with an address,\n"
1436             "                                                transaction id or block. 'send' and 'receive' transactions are \n"
1437             "                                                associated with an address, transaction id and block details\n"
1438             "    \"amount\": x.xxx,          (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the\n"
1439             "                                         'move' category for moves outbound. It is positive for the 'receive' category,\n"
1440             "                                         and for the 'move' category for inbound funds.\n"
1441             "    \"vout\" : n,               (numeric) the vout value\n"
1442             "    \"fee\": x.xxx,             (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n"
1443             "                                         'send' category of transactions.\n"
1444             "    \"confirmations\": n,       (numeric) The number of confirmations for the transaction. Available for 'send' and \n"
1445             "                                         'receive' category of transactions.\n"
1446             "    \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive'\n"
1447             "                                          category of transactions.\n"
1448             "    \"blockindex\": n,          (numeric) The block index containing the transaction. Available for 'send' and 'receive'\n"
1449             "                                          category of transactions.\n"
1450             "    \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
1451             "    \"time\": xxx,              (numeric) The transaction time in seconds since epoch (midnight Jan 1 1970 GMT).\n"
1452             "    \"timereceived\": xxx,      (numeric) The time received in seconds since epoch (midnight Jan 1 1970 GMT). Available \n"
1453             "                                          for 'send' and 'receive' category of transactions.\n"
1454             "    \"comment\": \"...\",       (string) If a comment is associated with the transaction.\n"
1455             "    \"otheraccount\": \"accountname\",  (string) For the 'move' category of transactions, the account the funds came \n"
1456             "                                          from (for receiving funds, positive amounts), or went to (for sending funds,\n"
1457             "                                          negative amounts).\n"
1458             "    \"size\": n,                (numeric) Transaction size in bytes\n"
1459             "  }\n"
1460             "]\n"
1461
1462             "\nExamples:\n"
1463             "\nList the most recent 10 transactions in the systems\n"
1464             + HelpExampleCli("listtransactions", "") +
1465             "\nList transactions 100 to 120\n"
1466             + HelpExampleCli("listtransactions", "\"*\" 20 100") +
1467             "\nAs a json rpc call\n"
1468             + HelpExampleRpc("listtransactions", "\"*\", 20, 100")
1469         );
1470
1471     LOCK2(cs_main, pwalletMain->cs_wallet);
1472
1473     string strAccount = "*";
1474     if (params.size() > 0)
1475         strAccount = params[0].get_str();
1476     int nCount = 10;
1477     if (params.size() > 1)
1478         nCount = params[1].get_int();
1479     int nFrom = 0;
1480     if (params.size() > 2)
1481         nFrom = params[2].get_int();
1482     isminefilter filter = ISMINE_SPENDABLE;
1483     if(params.size() > 3)
1484         if(params[3].get_bool())
1485             filter = filter | ISMINE_WATCH_ONLY;
1486
1487     if (nCount < 0)
1488         throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count");
1489     if (nFrom < 0)
1490         throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from");
1491
1492     UniValue ret(UniValue::VARR);
1493
1494     std::list<CAccountingEntry> acentries;
1495     CWallet::TxItems txOrdered = pwalletMain->OrderedTxItems(acentries, strAccount);
1496
1497     // iterate backwards until we have nCount items to return:
1498     for (CWallet::TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
1499     {
1500         CWalletTx *const pwtx = (*it).second.first;
1501         if (pwtx != 0)
1502             ListTransactions(*pwtx, strAccount, 0, true, ret, filter);
1503         CAccountingEntry *const pacentry = (*it).second.second;
1504         if (pacentry != 0)
1505             AcentryToJSON(*pacentry, strAccount, ret);
1506
1507         if ((int)ret.size() >= (nCount+nFrom)) break;
1508     }
1509     // ret is newest to oldest
1510
1511     if (nFrom > (int)ret.size())
1512         nFrom = ret.size();
1513     if ((nFrom + nCount) > (int)ret.size())
1514         nCount = ret.size() - nFrom;
1515
1516     vector<UniValue> arrTmp = ret.getValues();
1517
1518     vector<UniValue>::iterator first = arrTmp.begin();
1519     std::advance(first, nFrom);
1520     vector<UniValue>::iterator last = arrTmp.begin();
1521     std::advance(last, nFrom+nCount);
1522
1523     if (last != arrTmp.end()) arrTmp.erase(last, arrTmp.end());
1524     if (first != arrTmp.begin()) arrTmp.erase(arrTmp.begin(), first);
1525
1526     std::reverse(arrTmp.begin(), arrTmp.end()); // Return oldest to newest
1527
1528     ret.clear();
1529     ret.setArray();
1530     ret.push_backV(arrTmp);
1531
1532     return ret;
1533 }
1534
1535 UniValue listaccounts(const UniValue& params, bool fHelp)
1536 {
1537     if (!EnsureWalletIsAvailable(fHelp))
1538         return NullUniValue;
1539
1540     if (fHelp || params.size() > 2)
1541         throw runtime_error(
1542             "listaccounts ( minconf includeWatchonly)\n"
1543             "\nDEPRECATED. Returns Object that has account names as keys, account balances as values.\n"
1544             "\nArguments:\n"
1545             "1. minconf          (numeric, optional, default=1) Only include transactions with at least this many confirmations\n"
1546             "2. includeWatchonly (bool, optional, default=false) Include balances in watchonly addresses (see 'importaddress')\n"
1547             "\nResult:\n"
1548             "{                      (json object where keys are account names, and values are numeric balances\n"
1549             "  \"account\": x.xxx,  (numeric) The property name is the account name, and the value is the total balance for the account.\n"
1550             "  ...\n"
1551             "}\n"
1552             "\nExamples:\n"
1553             "\nList account balances where there at least 1 confirmation\n"
1554             + HelpExampleCli("listaccounts", "") +
1555             "\nList account balances including zero confirmation transactions\n"
1556             + HelpExampleCli("listaccounts", "0") +
1557             "\nList account balances for 6 or more confirmations\n"
1558             + HelpExampleCli("listaccounts", "6") +
1559             "\nAs json rpc call\n"
1560             + HelpExampleRpc("listaccounts", "6")
1561         );
1562
1563     LOCK2(cs_main, pwalletMain->cs_wallet);
1564
1565     int nMinDepth = 1;
1566     if (params.size() > 0)
1567         nMinDepth = params[0].get_int();
1568     isminefilter includeWatchonly = ISMINE_SPENDABLE;
1569     if(params.size() > 1)
1570         if(params[1].get_bool())
1571             includeWatchonly = includeWatchonly | ISMINE_WATCH_ONLY;
1572
1573     map<string, CAmount> mapAccountBalances;
1574     BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& entry, pwalletMain->mapAddressBook) {
1575         if (IsMine(*pwalletMain, entry.first) & includeWatchonly) // This address belongs to me
1576             mapAccountBalances[entry.second.name] = 0;
1577     }
1578
1579     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
1580     {
1581         const CWalletTx& wtx = (*it).second;
1582         CAmount nFee;
1583         string strSentAccount;
1584         list<COutputEntry> listReceived;
1585         list<COutputEntry> listSent;
1586         int nDepth = wtx.GetDepthInMainChain();
1587         if (wtx.GetBlocksToMaturity() > 0 || nDepth < 0)
1588             continue;
1589         wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount, includeWatchonly);
1590         mapAccountBalances[strSentAccount] -= nFee;
1591         BOOST_FOREACH(const COutputEntry& s, listSent)
1592             mapAccountBalances[strSentAccount] -= s.amount;
1593         if (nDepth >= nMinDepth)
1594         {
1595             BOOST_FOREACH(const COutputEntry& r, listReceived)
1596                 if (pwalletMain->mapAddressBook.count(r.destination))
1597                     mapAccountBalances[pwalletMain->mapAddressBook[r.destination].name] += r.amount;
1598                 else
1599                     mapAccountBalances[""] += r.amount;
1600         }
1601     }
1602
1603     list<CAccountingEntry> acentries;
1604     CWalletDB(pwalletMain->strWalletFile).ListAccountCreditDebit("*", acentries);
1605     BOOST_FOREACH(const CAccountingEntry& entry, acentries)
1606         mapAccountBalances[entry.strAccount] += entry.nCreditDebit;
1607
1608     UniValue ret(UniValue::VOBJ);
1609     BOOST_FOREACH(const PAIRTYPE(string, CAmount)& accountBalance, mapAccountBalances) {
1610         ret.push_back(Pair(accountBalance.first, ValueFromAmount(accountBalance.second)));
1611     }
1612     return ret;
1613 }
1614
1615 UniValue listsinceblock(const UniValue& params, bool fHelp)
1616 {
1617     if (!EnsureWalletIsAvailable(fHelp))
1618         return NullUniValue;
1619
1620     if (fHelp)
1621         throw runtime_error(
1622             "listsinceblock ( \"blockhash\" target-confirmations includeWatchonly)\n"
1623             "\nGet all transactions in blocks since block [blockhash], or all transactions if omitted\n"
1624             "\nArguments:\n"
1625             "1. \"blockhash\"   (string, optional) The block hash to list transactions since\n"
1626             "2. target-confirmations:    (numeric, optional) The confirmations required, must be 1 or more\n"
1627             "3. includeWatchonly:        (bool, optional, default=false) Include transactions to watchonly addresses (see 'importaddress')"
1628             "\nResult:\n"
1629             "{\n"
1630             "  \"transactions\": [\n"
1631             "    \"account\":\"accountname\",       (string) DEPRECATED. The account name associated with the transaction. Will be \"\" for the default account.\n"
1632             "    \"address\":\"zcashaddress\",    (string) The Zcash address of the transaction. Not present for move transactions (category = move).\n"
1633             "    \"category\":\"send|receive\",     (string) The transaction category. 'send' has negative amounts, 'receive' has positive amounts.\n"
1634             "    \"amount\": x.xxx,          (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the 'move' category for moves \n"
1635             "                                          outbound. It is positive for the 'receive' category, and for the 'move' category for inbound funds.\n"
1636             "    \"vout\" : n,               (numeric) the vout value\n"
1637             "    \"fee\": x.xxx,             (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the 'send' category of transactions.\n"
1638             "    \"confirmations\": n,       (numeric) The number of confirmations for the transaction. Available for 'send' and 'receive' category of transactions.\n"
1639             "    \"blockhash\": \"hashvalue\",     (string) The block hash containing the transaction. Available for 'send' and 'receive' category of transactions.\n"
1640             "    \"blockindex\": n,          (numeric) The block index containing the transaction. Available for 'send' and 'receive' category of transactions.\n"
1641             "    \"blocktime\": xxx,         (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n"
1642             "    \"txid\": \"transactionid\",  (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
1643             "    \"time\": xxx,              (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT).\n"
1644             "    \"timereceived\": xxx,      (numeric) The time received in seconds since epoch (Jan 1 1970 GMT). Available for 'send' and 'receive' category of transactions.\n"
1645             "    \"comment\": \"...\",       (string) If a comment is associated with the transaction.\n"
1646             "    \"to\": \"...\",            (string) If a comment to is associated with the transaction.\n"
1647              "  ],\n"
1648             "  \"lastblock\": \"lastblockhash\"     (string) The hash of the last block\n"
1649             "}\n"
1650             "\nExamples:\n"
1651             + HelpExampleCli("listsinceblock", "")
1652             + HelpExampleCli("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\" 6")
1653             + HelpExampleRpc("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\", 6")
1654         );
1655
1656     LOCK2(cs_main, pwalletMain->cs_wallet);
1657
1658     CBlockIndex *pindex = NULL;
1659     int target_confirms = 1;
1660     isminefilter filter = ISMINE_SPENDABLE;
1661
1662     if (params.size() > 0)
1663     {
1664         uint256 blockId;
1665
1666         blockId.SetHex(params[0].get_str());
1667         BlockMap::iterator it = mapBlockIndex.find(blockId);
1668         if (it != mapBlockIndex.end())
1669             pindex = it->second;
1670     }
1671
1672     if (params.size() > 1)
1673     {
1674         target_confirms = params[1].get_int();
1675
1676         if (target_confirms < 1)
1677             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter");
1678     }
1679
1680     if(params.size() > 2)
1681         if(params[2].get_bool())
1682             filter = filter | ISMINE_WATCH_ONLY;
1683
1684     int depth = pindex ? (1 + chainActive.Height() - pindex->nHeight) : -1;
1685
1686     UniValue transactions(UniValue::VARR);
1687
1688     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); it++)
1689     {
1690         CWalletTx tx = (*it).second;
1691
1692         if (depth == -1 || tx.GetDepthInMainChain() < depth)
1693             ListTransactions(tx, "*", 0, true, transactions, filter);
1694     }
1695
1696     CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms];
1697     uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : uint256();
1698
1699     UniValue ret(UniValue::VOBJ);
1700     ret.push_back(Pair("transactions", transactions));
1701     ret.push_back(Pair("lastblock", lastblock.GetHex()));
1702
1703     return ret;
1704 }
1705
1706 UniValue gettransaction(const UniValue& params, bool fHelp)
1707 {
1708     if (!EnsureWalletIsAvailable(fHelp))
1709         return NullUniValue;
1710
1711     if (fHelp || params.size() < 1 || params.size() > 2)
1712         throw runtime_error(
1713             "gettransaction \"txid\" ( includeWatchonly )\n"
1714             "\nGet detailed information about in-wallet transaction <txid>\n"
1715             "\nArguments:\n"
1716             "1. \"txid\"    (string, required) The transaction id\n"
1717             "2. \"includeWatchonly\"    (bool, optional, default=false) Whether to include watchonly addresses in balance calculation and details[]\n"
1718             "\nResult:\n"
1719             "{\n"
1720             "  \"amount\" : x.xxx,        (numeric) The transaction amount in " + CURRENCY_UNIT + "\n"
1721             "  \"confirmations\" : n,     (numeric) The number of confirmations\n"
1722             "  \"blockhash\" : \"hash\",  (string) The block hash\n"
1723             "  \"blockindex\" : xx,       (numeric) The block index\n"
1724             "  \"blocktime\" : ttt,       (numeric) The time in seconds since epoch (1 Jan 1970 GMT)\n"
1725             "  \"txid\" : \"transactionid\",   (string) The transaction id.\n"
1726             "  \"time\" : ttt,            (numeric) The transaction time in seconds since epoch (1 Jan 1970 GMT)\n"
1727             "  \"timereceived\" : ttt,    (numeric) The time received in seconds since epoch (1 Jan 1970 GMT)\n"
1728             "  \"details\" : [\n"
1729             "    {\n"
1730             "      \"account\" : \"accountname\",  (string) DEPRECATED. The account name involved in the transaction, can be \"\" for the default account.\n"
1731             "      \"address\" : \"zcashaddress\",   (string) The Zcash address involved in the transaction\n"
1732             "      \"category\" : \"send|receive\",    (string) The category, either 'send' or 'receive'\n"
1733             "      \"amount\" : x.xxx                  (numeric) The amount in " + CURRENCY_UNIT + "\n"
1734             "      \"vout\" : n,                       (numeric) the vout value\n"
1735             "    }\n"
1736             "    ,...\n"
1737             "  ],\n"
1738             "  \"vjoinsplit\" : [\n"
1739             "    {\n"
1740             "      \"anchor\" : \"treestateref\",          (string) Merkle root of note commitment tree\n"
1741             "      \"nullifiers\" : [ string, ... ]      (string) Nullifiers of input notes\n"
1742             "      \"commitments\" : [ string, ... ]     (string) Note commitments for note outputs\n"
1743             "      \"macs\" : [ string, ... ]            (string) Message authentication tags\n"
1744             "      \"vpub_old\" : x.xxx                  (numeric) The amount removed from the transparent value pool\n"
1745             "      \"vpub_new\" : x.xxx,                 (numeric) The amount added to the transparent value pool\n"
1746             "    }\n"
1747             "    ,...\n"
1748             "  ],\n"
1749             "  \"hex\" : \"data\"         (string) Raw data for transaction\n"
1750             "}\n"
1751
1752             "\nExamples:\n"
1753             + HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
1754             + HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\" true")
1755             + HelpExampleRpc("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
1756         );
1757
1758     LOCK2(cs_main, pwalletMain->cs_wallet);
1759
1760     uint256 hash;
1761     hash.SetHex(params[0].get_str());
1762
1763     isminefilter filter = ISMINE_SPENDABLE;
1764     if(params.size() > 1)
1765         if(params[1].get_bool())
1766             filter = filter | ISMINE_WATCH_ONLY;
1767
1768     UniValue entry(UniValue::VOBJ);
1769     if (!pwalletMain->mapWallet.count(hash))
1770         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
1771     const CWalletTx& wtx = pwalletMain->mapWallet[hash];
1772
1773     CAmount nCredit = wtx.GetCredit(filter);
1774     CAmount nDebit = wtx.GetDebit(filter);
1775     CAmount nNet = nCredit - nDebit;
1776     CAmount nFee = (wtx.IsFromMe(filter) ? wtx.GetValueOut() - nDebit : 0);
1777
1778     entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
1779     if (wtx.IsFromMe(filter))
1780         entry.push_back(Pair("fee", ValueFromAmount(nFee)));
1781
1782     WalletTxToJSON(wtx, entry);
1783
1784     UniValue details(UniValue::VARR);
1785     ListTransactions(wtx, "*", 0, false, details, filter);
1786     entry.push_back(Pair("details", details));
1787
1788     string strHex = EncodeHexTx(static_cast<CTransaction>(wtx));
1789     entry.push_back(Pair("hex", strHex));
1790
1791     return entry;
1792 }
1793
1794
1795 UniValue backupwallet(const UniValue& params, bool fHelp)
1796 {
1797     if (!EnsureWalletIsAvailable(fHelp))
1798         return NullUniValue;
1799
1800     if (fHelp || params.size() != 1)
1801         throw runtime_error(
1802             "backupwallet \"destination\"\n"
1803             "\nSafely copies wallet.dat to destination filename\n"
1804             "\nArguments:\n"
1805             "1. \"destination\"   (string, required) The destination filename, saved in the directory set by -exportdir option.\n"
1806             "\nResult:\n"
1807             "\"path\"             (string) The full path of the destination file\n"
1808             "\nExamples:\n"
1809             + HelpExampleCli("backupwallet", "\"backupdata\"")
1810             + HelpExampleRpc("backupwallet", "\"backupdata\"")
1811         );
1812
1813     LOCK2(cs_main, pwalletMain->cs_wallet);
1814
1815     boost::filesystem::path exportdir;
1816     try {
1817         exportdir = GetExportDir();
1818     } catch (const std::runtime_error& e) {
1819         throw JSONRPCError(RPC_INTERNAL_ERROR, e.what());
1820     }
1821     if (exportdir.empty()) {
1822         throw JSONRPCError(RPC_WALLET_ERROR, "Cannot backup wallet until the -exportdir option has been set");
1823     }
1824     std::string unclean = params[0].get_str();
1825     std::string clean = SanitizeFilename(unclean);
1826     if (clean.compare(unclean) != 0) {
1827         throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Filename is invalid as only alphanumeric characters are allowed.  Try '%s' instead.", clean));
1828     }
1829     boost::filesystem::path exportfilepath = exportdir / clean;
1830
1831     if (!BackupWallet(*pwalletMain, exportfilepath.string()))
1832         throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!");
1833
1834     return exportfilepath.string();
1835 }
1836
1837
1838 UniValue keypoolrefill(const UniValue& params, bool fHelp)
1839 {
1840     if (!EnsureWalletIsAvailable(fHelp))
1841         return NullUniValue;
1842
1843     if (fHelp || params.size() > 1)
1844         throw runtime_error(
1845             "keypoolrefill ( newsize )\n"
1846             "\nFills the keypool."
1847             + HelpRequiringPassphrase() + "\n"
1848             "\nArguments\n"
1849             "1. newsize     (numeric, optional, default=100) The new keypool size\n"
1850             "\nExamples:\n"
1851             + HelpExampleCli("keypoolrefill", "")
1852             + HelpExampleRpc("keypoolrefill", "")
1853         );
1854
1855     LOCK2(cs_main, pwalletMain->cs_wallet);
1856
1857     // 0 is interpreted by TopUpKeyPool() as the default keypool size given by -keypool
1858     unsigned int kpSize = 0;
1859     if (params.size() > 0) {
1860         if (params[0].get_int() < 0)
1861             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected valid size.");
1862         kpSize = (unsigned int)params[0].get_int();
1863     }
1864
1865     EnsureWalletIsUnlocked();
1866     pwalletMain->TopUpKeyPool(kpSize);
1867
1868     if (pwalletMain->GetKeyPoolSize() < kpSize)
1869         throw JSONRPCError(RPC_WALLET_ERROR, "Error refreshing keypool.");
1870
1871     return NullUniValue;
1872 }
1873
1874
1875 static void LockWallet(CWallet* pWallet)
1876 {
1877     LOCK(cs_nWalletUnlockTime);
1878     nWalletUnlockTime = 0;
1879     pWallet->Lock();
1880 }
1881
1882 UniValue walletpassphrase(const UniValue& params, bool fHelp)
1883 {
1884     if (!EnsureWalletIsAvailable(fHelp))
1885         return NullUniValue;
1886
1887     if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2))
1888         throw runtime_error(
1889             "walletpassphrase \"passphrase\" timeout\n"
1890             "\nStores the wallet decryption key in memory for 'timeout' seconds.\n"
1891             "This is needed prior to performing transactions related to private keys such as sending Zcash\n"
1892             "\nArguments:\n"
1893             "1. \"passphrase\"     (string, required) The wallet passphrase\n"
1894             "2. timeout            (numeric, required) The time to keep the decryption key in seconds.\n"
1895             "\nNote:\n"
1896             "Issuing the walletpassphrase command while the wallet is already unlocked will set a new unlock\n"
1897             "time that overrides the old one.\n"
1898             "\nExamples:\n"
1899             "\nunlock the wallet for 60 seconds\n"
1900             + HelpExampleCli("walletpassphrase", "\"my pass phrase\" 60") +
1901             "\nLock the wallet again (before 60 seconds)\n"
1902             + HelpExampleCli("walletlock", "") +
1903             "\nAs json rpc call\n"
1904             + HelpExampleRpc("walletpassphrase", "\"my pass phrase\", 60")
1905         );
1906
1907     LOCK2(cs_main, pwalletMain->cs_wallet);
1908
1909     if (fHelp)
1910         return true;
1911     if (!pwalletMain->IsCrypted())
1912         throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrase was called.");
1913
1914     // Note that the walletpassphrase is stored in params[0] which is not mlock()ed
1915     SecureString strWalletPass;
1916     strWalletPass.reserve(100);
1917     // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
1918     // Alternately, find a way to make params[0] mlock()'d to begin with.
1919     strWalletPass = params[0].get_str().c_str();
1920
1921     if (strWalletPass.length() > 0)
1922     {
1923         if (!pwalletMain->Unlock(strWalletPass))
1924             throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect.");
1925     }
1926     else
1927         throw runtime_error(
1928             "walletpassphrase <passphrase> <timeout>\n"
1929             "Stores the wallet decryption key in memory for <timeout> seconds.");
1930
1931     // No need to check return values, because the wallet was unlocked above
1932     pwalletMain->UpdateNullifierNoteMap();
1933     pwalletMain->TopUpKeyPool();
1934
1935     int64_t nSleepTime = params[1].get_int64();
1936     LOCK(cs_nWalletUnlockTime);
1937     nWalletUnlockTime = GetTime() + nSleepTime;
1938     RPCRunLater("lockwallet", boost::bind(LockWallet, pwalletMain), nSleepTime);
1939
1940     return NullUniValue;
1941 }
1942
1943
1944 UniValue walletpassphrasechange(const UniValue& params, bool fHelp)
1945 {
1946     if (!EnsureWalletIsAvailable(fHelp))
1947         return NullUniValue;
1948
1949     if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2))
1950         throw runtime_error(
1951             "walletpassphrasechange \"oldpassphrase\" \"newpassphrase\"\n"
1952             "\nChanges the wallet passphrase from 'oldpassphrase' to 'newpassphrase'.\n"
1953             "\nArguments:\n"
1954             "1. \"oldpassphrase\"      (string) The current passphrase\n"
1955             "2. \"newpassphrase\"      (string) The new passphrase\n"
1956             "\nExamples:\n"
1957             + HelpExampleCli("walletpassphrasechange", "\"old one\" \"new one\"")
1958             + HelpExampleRpc("walletpassphrasechange", "\"old one\", \"new one\"")
1959         );
1960
1961     LOCK2(cs_main, pwalletMain->cs_wallet);
1962
1963     if (fHelp)
1964         return true;
1965     if (!pwalletMain->IsCrypted())
1966         throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrasechange was called.");
1967
1968     // TODO: get rid of these .c_str() calls by implementing SecureString::operator=(std::string)
1969     // Alternately, find a way to make params[0] mlock()'d to begin with.
1970     SecureString strOldWalletPass;
1971     strOldWalletPass.reserve(100);
1972     strOldWalletPass = params[0].get_str().c_str();
1973
1974     SecureString strNewWalletPass;
1975     strNewWalletPass.reserve(100);
1976     strNewWalletPass = params[1].get_str().c_str();
1977
1978     if (strOldWalletPass.length() < 1 || strNewWalletPass.length() < 1)
1979         throw runtime_error(
1980             "walletpassphrasechange <oldpassphrase> <newpassphrase>\n"
1981             "Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>.");
1982
1983     if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass))
1984         throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect.");
1985
1986     return NullUniValue;
1987 }
1988
1989
1990 UniValue walletlock(const UniValue& params, bool fHelp)
1991 {
1992     if (!EnsureWalletIsAvailable(fHelp))
1993         return NullUniValue;
1994
1995     if (pwalletMain->IsCrypted() && (fHelp || params.size() != 0))
1996         throw runtime_error(
1997             "walletlock\n"
1998             "\nRemoves the wallet encryption key from memory, locking the wallet.\n"
1999             "After calling this method, you will need to call walletpassphrase again\n"
2000             "before being able to call any methods which require the wallet to be unlocked.\n"
2001             "\nExamples:\n"
2002             "\nSet the passphrase for 2 minutes to perform a transaction\n"
2003             + HelpExampleCli("walletpassphrase", "\"my pass phrase\" 120") +
2004             "\nPerform a send (requires passphrase set)\n"
2005             + HelpExampleCli("sendtoaddress", "\"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 1.0") +
2006             "\nClear the passphrase since we are done before 2 minutes is up\n"
2007             + HelpExampleCli("walletlock", "") +
2008             "\nAs json rpc call\n"
2009             + HelpExampleRpc("walletlock", "")
2010         );
2011
2012     LOCK2(cs_main, pwalletMain->cs_wallet);
2013
2014     if (fHelp)
2015         return true;
2016     if (!pwalletMain->IsCrypted())
2017         throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletlock was called.");
2018
2019     {
2020         LOCK(cs_nWalletUnlockTime);
2021         pwalletMain->Lock();
2022         nWalletUnlockTime = 0;
2023     }
2024
2025     return NullUniValue;
2026 }
2027
2028
2029 UniValue encryptwallet(const UniValue& params, bool fHelp)
2030 {
2031     if (!EnsureWalletIsAvailable(fHelp))
2032         return NullUniValue;
2033
2034     string enableArg = "developerencryptwallet";
2035     auto fEnableWalletEncryption = fExperimentalMode && GetBoolArg("-" + enableArg, false);
2036
2037     std::string strWalletEncryptionDisabledMsg = "";
2038     if (!fEnableWalletEncryption) {
2039         strWalletEncryptionDisabledMsg = experimentalDisabledHelpMsg("encryptwallet", enableArg);
2040     }
2041
2042     if (!pwalletMain->IsCrypted() && (fHelp || params.size() != 1))
2043         throw runtime_error(
2044             "encryptwallet \"passphrase\"\n"
2045             + strWalletEncryptionDisabledMsg +
2046             "\nEncrypts the wallet with 'passphrase'. This is for first time encryption.\n"
2047             "After this, any calls that interact with private keys such as sending or signing \n"
2048             "will require the passphrase to be set prior the making these calls.\n"
2049             "Use the walletpassphrase call for this, and then walletlock call.\n"
2050             "If the wallet is already encrypted, use the walletpassphrasechange call.\n"
2051             "Note that this will shutdown the server.\n"
2052             "\nArguments:\n"
2053             "1. \"passphrase\"    (string) The pass phrase to encrypt the wallet with. It must be at least 1 character, but should be long.\n"
2054             "\nExamples:\n"
2055             "\nEncrypt you wallet\n"
2056             + HelpExampleCli("encryptwallet", "\"my pass phrase\"") +
2057             "\nNow set the passphrase to use the wallet, such as for signing or sending Zcash\n"
2058             + HelpExampleCli("walletpassphrase", "\"my pass phrase\"") +
2059             "\nNow we can so something like sign\n"
2060             + HelpExampleCli("signmessage", "\"zcashaddress\" \"test message\"") +
2061             "\nNow lock the wallet again by removing the passphrase\n"
2062             + HelpExampleCli("walletlock", "") +
2063             "\nAs a json rpc call\n"
2064             + HelpExampleRpc("encryptwallet", "\"my pass phrase\"")
2065         );
2066
2067     LOCK2(cs_main, pwalletMain->cs_wallet);
2068
2069     if (fHelp)
2070         return true;
2071     if (!fEnableWalletEncryption) {
2072         throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Error: wallet encryption is disabled.");
2073     }
2074     if (pwalletMain->IsCrypted())
2075         throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an encrypted wallet, but encryptwallet was called.");
2076
2077     // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
2078     // Alternately, find a way to make params[0] mlock()'d to begin with.
2079     SecureString strWalletPass;
2080     strWalletPass.reserve(100);
2081     strWalletPass = params[0].get_str().c_str();
2082
2083     if (strWalletPass.length() < 1)
2084         throw runtime_error(
2085             "encryptwallet <passphrase>\n"
2086             "Encrypts the wallet with <passphrase>.");
2087
2088     if (!pwalletMain->EncryptWallet(strWalletPass))
2089         throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Error: Failed to encrypt the wallet.");
2090
2091     // BDB seems to have a bad habit of writing old data into
2092     // slack space in .dat files; that is bad if the old data is
2093     // unencrypted private keys. So:
2094     StartShutdown();
2095     return "wallet encrypted; Zcash server stopping, restart to run with encrypted wallet. The keypool has been flushed, you need to make a new backup.";
2096 }
2097
2098 UniValue lockunspent(const UniValue& params, bool fHelp)
2099 {
2100     if (!EnsureWalletIsAvailable(fHelp))
2101         return NullUniValue;
2102
2103     if (fHelp || params.size() < 1 || params.size() > 2)
2104         throw runtime_error(
2105             "lockunspent unlock [{\"txid\":\"txid\",\"vout\":n},...]\n"
2106             "\nUpdates list of temporarily unspendable outputs.\n"
2107             "Temporarily lock (unlock=false) or unlock (unlock=true) specified transaction outputs.\n"
2108             "A locked transaction output will not be chosen by automatic coin selection, when spending Zcash.\n"
2109             "Locks are stored in memory only. Nodes start with zero locked outputs, and the locked output list\n"
2110             "is always cleared (by virtue of process exit) when a node stops or fails.\n"
2111             "Also see the listunspent call\n"
2112             "\nArguments:\n"
2113             "1. unlock            (boolean, required) Whether to unlock (true) or lock (false) the specified transactions\n"
2114             "2. \"transactions\"  (string, required) A json array of objects. Each object the txid (string) vout (numeric)\n"
2115             "     [           (json array of json objects)\n"
2116             "       {\n"
2117             "         \"txid\":\"id\",    (string) The transaction id\n"
2118             "         \"vout\": n         (numeric) The output number\n"
2119             "       }\n"
2120             "       ,...\n"
2121             "     ]\n"
2122
2123             "\nResult:\n"
2124             "true|false    (boolean) Whether the command was successful or not\n"
2125
2126             "\nExamples:\n"
2127             "\nList the unspent transactions\n"
2128             + HelpExampleCli("listunspent", "") +
2129             "\nLock an unspent transaction\n"
2130             + HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2131             "\nList the locked transactions\n"
2132             + HelpExampleCli("listlockunspent", "") +
2133             "\nUnlock the transaction again\n"
2134             + HelpExampleCli("lockunspent", "true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2135             "\nAs a json rpc call\n"
2136             + HelpExampleRpc("lockunspent", "false, \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"")
2137         );
2138
2139     LOCK2(cs_main, pwalletMain->cs_wallet);
2140
2141     if (params.size() == 1)
2142         RPCTypeCheck(params, boost::assign::list_of(UniValue::VBOOL));
2143     else
2144         RPCTypeCheck(params, boost::assign::list_of(UniValue::VBOOL)(UniValue::VARR));
2145
2146     bool fUnlock = params[0].get_bool();
2147
2148     if (params.size() == 1) {
2149         if (fUnlock)
2150             pwalletMain->UnlockAllCoins();
2151         return true;
2152     }
2153
2154     UniValue outputs = params[1].get_array();
2155     for (size_t idx = 0; idx < outputs.size(); idx++) {
2156         const UniValue& output = outputs[idx];
2157         if (!output.isObject())
2158             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected object");
2159         const UniValue& o = output.get_obj();
2160
2161         RPCTypeCheckObj(o, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM));
2162
2163         string txid = find_value(o, "txid").get_str();
2164         if (!IsHex(txid))
2165             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected hex txid");
2166
2167         int nOutput = find_value(o, "vout").get_int();
2168         if (nOutput < 0)
2169             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
2170
2171         COutPoint outpt(uint256S(txid), nOutput);
2172
2173         if (fUnlock)
2174             pwalletMain->UnlockCoin(outpt);
2175         else
2176             pwalletMain->LockCoin(outpt);
2177     }
2178
2179     return true;
2180 }
2181
2182 UniValue listlockunspent(const UniValue& params, bool fHelp)
2183 {
2184     if (!EnsureWalletIsAvailable(fHelp))
2185         return NullUniValue;
2186
2187     if (fHelp || params.size() > 0)
2188         throw runtime_error(
2189             "listlockunspent\n"
2190             "\nReturns list of temporarily unspendable outputs.\n"
2191             "See the lockunspent call to lock and unlock transactions for spending.\n"
2192             "\nResult:\n"
2193             "[\n"
2194             "  {\n"
2195             "    \"txid\" : \"transactionid\",     (string) The transaction id locked\n"
2196             "    \"vout\" : n                      (numeric) The vout value\n"
2197             "  }\n"
2198             "  ,...\n"
2199             "]\n"
2200             "\nExamples:\n"
2201             "\nList the unspent transactions\n"
2202             + HelpExampleCli("listunspent", "") +
2203             "\nLock an unspent transaction\n"
2204             + HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2205             "\nList the locked transactions\n"
2206             + HelpExampleCli("listlockunspent", "") +
2207             "\nUnlock the transaction again\n"
2208             + HelpExampleCli("lockunspent", "true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2209             "\nAs a json rpc call\n"
2210             + HelpExampleRpc("listlockunspent", "")
2211         );
2212
2213     LOCK2(cs_main, pwalletMain->cs_wallet);
2214
2215     vector<COutPoint> vOutpts;
2216     pwalletMain->ListLockedCoins(vOutpts);
2217
2218     UniValue ret(UniValue::VARR);
2219
2220     BOOST_FOREACH(COutPoint &outpt, vOutpts) {
2221         UniValue o(UniValue::VOBJ);
2222
2223         o.push_back(Pair("txid", outpt.hash.GetHex()));
2224         o.push_back(Pair("vout", (int)outpt.n));
2225         ret.push_back(o);
2226     }
2227
2228     return ret;
2229 }
2230
2231 UniValue settxfee(const UniValue& params, bool fHelp)
2232 {
2233     if (!EnsureWalletIsAvailable(fHelp))
2234         return NullUniValue;
2235
2236     if (fHelp || params.size() < 1 || params.size() > 1)
2237         throw runtime_error(
2238             "settxfee amount\n"
2239             "\nSet the transaction fee per kB.\n"
2240             "\nArguments:\n"
2241             "1. amount         (numeric, required) The transaction fee in " + CURRENCY_UNIT + "/kB rounded to the nearest 0.00000001\n"
2242             "\nResult\n"
2243             "true|false        (boolean) Returns true if successful\n"
2244             "\nExamples:\n"
2245             + HelpExampleCli("settxfee", "0.00001")
2246             + HelpExampleRpc("settxfee", "0.00001")
2247         );
2248
2249     LOCK2(cs_main, pwalletMain->cs_wallet);
2250
2251     // Amount
2252     CAmount nAmount = AmountFromValue(params[0]);
2253
2254     payTxFee = CFeeRate(nAmount, 1000);
2255     return true;
2256 }
2257
2258 UniValue getwalletinfo(const UniValue& params, bool fHelp)
2259 {
2260     if (!EnsureWalletIsAvailable(fHelp))
2261         return NullUniValue;
2262
2263     if (fHelp || params.size() != 0)
2264         throw runtime_error(
2265             "getwalletinfo\n"
2266             "Returns an object containing various wallet state info.\n"
2267             "\nResult:\n"
2268             "{\n"
2269             "  \"walletversion\": xxxxx,     (numeric) the wallet version\n"
2270             "  \"balance\": xxxxxxx,         (numeric) the total confirmed balance of the wallet in " + CURRENCY_UNIT + "\n"
2271             "  \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed balance of the wallet in " + CURRENCY_UNIT + "\n"
2272             "  \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet in " + CURRENCY_UNIT + "\n"
2273             "  \"txcount\": xxxxxxx,         (numeric) the total number of transactions in the wallet\n"
2274             "  \"keypoololdest\": xxxxxx,    (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n"
2275             "  \"keypoolsize\": xxxx,        (numeric) how many new keys are pre-generated\n"
2276             "  \"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"
2277             "  \"paytxfee\": x.xxxx,         (numeric) the transaction fee configuration, set in " + CURRENCY_UNIT + "/kB\n"
2278             "}\n"
2279             "\nExamples:\n"
2280             + HelpExampleCli("getwalletinfo", "")
2281             + HelpExampleRpc("getwalletinfo", "")
2282         );
2283
2284     LOCK2(cs_main, pwalletMain->cs_wallet);
2285
2286     UniValue obj(UniValue::VOBJ);
2287     obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
2288     obj.push_back(Pair("balance",       ValueFromAmount(pwalletMain->GetBalance())));
2289     obj.push_back(Pair("unconfirmed_balance", ValueFromAmount(pwalletMain->GetUnconfirmedBalance())));
2290     obj.push_back(Pair("immature_balance",    ValueFromAmount(pwalletMain->GetImmatureBalance())));
2291     obj.push_back(Pair("txcount",       (int)pwalletMain->mapWallet.size()));
2292     obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime()));
2293     obj.push_back(Pair("keypoolsize",   (int)pwalletMain->GetKeyPoolSize()));
2294     if (pwalletMain->IsCrypted())
2295         obj.push_back(Pair("unlocked_until", nWalletUnlockTime));
2296     obj.push_back(Pair("paytxfee",      ValueFromAmount(payTxFee.GetFeePerK())));
2297     return obj;
2298 }
2299
2300 UniValue resendwallettransactions(const UniValue& params, bool fHelp)
2301 {
2302     if (!EnsureWalletIsAvailable(fHelp))
2303         return NullUniValue;
2304
2305     if (fHelp || params.size() != 0)
2306         throw runtime_error(
2307             "resendwallettransactions\n"
2308             "Immediately re-broadcast unconfirmed wallet transactions to all peers.\n"
2309             "Intended only for testing; the wallet code periodically re-broadcasts\n"
2310             "automatically.\n"
2311             "Returns array of transaction ids that were re-broadcast.\n"
2312             );
2313
2314     LOCK2(cs_main, pwalletMain->cs_wallet);
2315
2316     std::vector<uint256> txids = pwalletMain->ResendWalletTransactionsBefore(GetTime());
2317     UniValue result(UniValue::VARR);
2318     BOOST_FOREACH(const uint256& txid, txids)
2319     {
2320         result.push_back(txid.ToString());
2321     }
2322     return result;
2323 }
2324
2325 UniValue listunspent(const UniValue& params, bool fHelp)
2326 {
2327     if (!EnsureWalletIsAvailable(fHelp))
2328         return NullUniValue;
2329
2330     if (fHelp || params.size() > 3)
2331         throw runtime_error(
2332             "listunspent ( minconf maxconf  [\"address\",...] )\n"
2333             "\nReturns array of unspent transaction outputs\n"
2334             "with between minconf and maxconf (inclusive) confirmations.\n"
2335             "Optionally filter to only include txouts paid to specified addresses.\n"
2336             "Results are an array of Objects, each of which has:\n"
2337             "{txid, vout, scriptPubKey, amount, confirmations}\n"
2338             "\nArguments:\n"
2339             "1. minconf          (numeric, optional, default=1) The minimum confirmations to filter\n"
2340             "2. maxconf          (numeric, optional, default=9999999) The maximum confirmations to filter\n"
2341             "3. \"addresses\"    (string) A json array of Zcash addresses to filter\n"
2342             "    [\n"
2343             "      \"address\"   (string) Zcash address\n"
2344             "      ,...\n"
2345             "    ]\n"
2346             "\nResult\n"
2347             "[                   (array of json object)\n"
2348             "  {\n"
2349             "    \"txid\" : \"txid\",          (string) the transaction id \n"
2350             "    \"vout\" : n,               (numeric) the vout value\n"
2351             "    \"generated\" : true|false  (boolean) true if txout is a coinbase transaction output\n"
2352             "    \"address\" : \"address\",    (string) the Zcash address\n"
2353             "    \"account\" : \"account\",    (string) DEPRECATED. The associated account, or \"\" for the default account\n"
2354             "    \"scriptPubKey\" : \"key\",   (string) the script key\n"
2355             "    \"amount\" : x.xxx,         (numeric) the transaction amount in " + CURRENCY_UNIT + "\n"
2356             "    \"confirmations\" : n,      (numeric) The number of confirmations\n"
2357             "    \"redeemScript\" : n        (string) The redeemScript if scriptPubKey is P2SH\n"
2358             "    \"spendable\" : xxx         (bool) Whether we have the private keys to spend this output\n"
2359             "  }\n"
2360             "  ,...\n"
2361             "]\n"
2362
2363             "\nExamples\n"
2364             + HelpExampleCli("listunspent", "")
2365             + HelpExampleCli("listunspent", "6 9999999 \"[\\\"t1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"t1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"")
2366             + HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"t1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"t1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"")
2367         );
2368
2369     RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)(UniValue::VNUM)(UniValue::VARR));
2370
2371     int nMinDepth = 1;
2372     if (params.size() > 0)
2373         nMinDepth = params[0].get_int();
2374
2375     int nMaxDepth = 9999999;
2376     if (params.size() > 1)
2377         nMaxDepth = params[1].get_int();
2378
2379     std::set<CTxDestination> destinations;
2380     if (params.size() > 2) {
2381         UniValue inputs = params[2].get_array();
2382         for (size_t idx = 0; idx < inputs.size(); idx++) {
2383             const UniValue& input = inputs[idx];
2384             CTxDestination dest = DecodeDestination(input.get_str());
2385             if (!IsValidDestination(dest)) {
2386                 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Zcash address: ") + input.get_str());
2387             }
2388             if (!destinations.insert(dest).second) {
2389                 throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + input.get_str());
2390             }
2391         }
2392     }
2393
2394     UniValue results(UniValue::VARR);
2395     vector<COutput> vecOutputs;
2396     assert(pwalletMain != NULL);
2397     LOCK2(cs_main, pwalletMain->cs_wallet);
2398     pwalletMain->AvailableCoins(vecOutputs, false, NULL, true);
2399     BOOST_FOREACH(const COutput& out, vecOutputs) {
2400         if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth)
2401             continue;
2402
2403         CTxDestination address;
2404         const CScript& scriptPubKey = out.tx->vout[out.i].scriptPubKey;
2405         bool fValidAddress = ExtractDestination(scriptPubKey, address);
2406
2407         if (destinations.size() && (!fValidAddress || !destinations.count(address)))
2408             continue;
2409
2410         UniValue entry(UniValue::VOBJ);
2411         entry.push_back(Pair("txid", out.tx->GetHash().GetHex()));
2412         entry.push_back(Pair("vout", out.i));
2413         entry.push_back(Pair("generated", out.tx->IsCoinBase()));
2414
2415         if (fValidAddress) {
2416             entry.push_back(Pair("address", EncodeDestination(address)));
2417
2418             if (pwalletMain->mapAddressBook.count(address))
2419                 entry.push_back(Pair("account", pwalletMain->mapAddressBook[address].name));
2420
2421             if (scriptPubKey.IsPayToScriptHash()) {
2422                 const CScriptID& hash = boost::get<CScriptID>(address);
2423                 CScript redeemScript;
2424                 if (pwalletMain->GetCScript(hash, redeemScript))
2425                     entry.push_back(Pair("redeemScript", HexStr(redeemScript.begin(), redeemScript.end())));
2426             }
2427         }
2428
2429         entry.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
2430         entry.push_back(Pair("amount", ValueFromAmount(out.tx->vout[out.i].nValue)));
2431         entry.push_back(Pair("confirmations", out.nDepth));
2432         entry.push_back(Pair("spendable", out.fSpendable));
2433         results.push_back(entry);
2434     }
2435
2436     return results;
2437 }
2438
2439
2440 UniValue z_listunspent(const UniValue& params, bool fHelp)
2441 {
2442     if (!EnsureWalletIsAvailable(fHelp))
2443         return NullUniValue;
2444
2445     if (fHelp || params.size() > 4)
2446         throw runtime_error(
2447             "z_listunspent ( minconf maxconf includeWatchonly [\"zaddr\",...] )\n"
2448             "\nReturns array of unspent shielded notes with between minconf and maxconf (inclusive) confirmations.\n"
2449             "Optionally filter to only include notes sent to specified addresses.\n"
2450             "When minconf is 0, unspent notes with zero confirmations are returned, even though they are not immediately spendable.\n"
2451             "Results are an array of Objects, each of which has:\n"
2452             "{txid, jsindex, jsoutindex, confirmations, address, amount, memo}\n"
2453             "\nArguments:\n"
2454             "1. minconf          (numeric, optional, default=1) The minimum confirmations to filter\n"
2455             "2. maxconf          (numeric, optional, default=9999999) The maximum confirmations to filter\n"
2456             "3. includeWatchonly (bool, optional, default=false) Also include watchonly addresses (see 'z_importviewingkey')\n"
2457             "4. \"addresses\"      (string) A json array of zaddrs to filter on.  Duplicate addresses not allowed.\n"
2458             "    [\n"
2459             "      \"address\"     (string) zaddr\n"
2460             "      ,...\n"
2461             "    ]\n"
2462             "\nResult\n"
2463             "[                             (array of json object)\n"
2464             "  {\n"
2465             "    \"txid\" : \"txid\",          (string) the transaction id \n"
2466             "    \"jsindex\" : n             (numeric) the joinsplit index\n"
2467             "    \"jsoutindex\" : n          (numeric) the output index of the joinsplit\n"
2468             "    \"confirmations\" : n       (numeric) the number of confirmations\n"
2469             "    \"spendable\" : true|false  (boolean) true if note can be spent by wallet, false if note has zero confirmations, false if address is watchonly\n"
2470             "    \"address\" : \"address\",    (string) the shielded address\n"
2471             "    \"amount\": xxxxx,          (numeric) the amount of value in the note\n"
2472             "    \"memo\": xxxxx,            (string) hexademical string representation of memo field\n"
2473             "    \"change\": true|false,     (boolean) true if the address that received the note is also one of the sending addresses\n"
2474             "  }\n"
2475             "  ,...\n"
2476             "]\n"
2477
2478             "\nExamples\n"
2479             + HelpExampleCli("z_listunspent", "")
2480             + HelpExampleCli("z_listunspent", "6 9999999 false \"[\\\"ztbx5DLDxa5ZLFTchHhoPNkKs57QzSyib6UqXpEdy76T1aUdFxJt1w9318Z8DJ73XzbnWHKEZP9Yjg712N5kMmP4QzS9iC9\\\",\\\"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\\\"]\"")
2481             + HelpExampleRpc("z_listunspent", "6 9999999 false \"[\\\"ztbx5DLDxa5ZLFTchHhoPNkKs57QzSyib6UqXpEdy76T1aUdFxJt1w9318Z8DJ73XzbnWHKEZP9Yjg712N5kMmP4QzS9iC9\\\",\\\"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\\\"]\"")
2482         );
2483
2484     RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)(UniValue::VNUM)(UniValue::VBOOL)(UniValue::VARR));
2485
2486     int nMinDepth = 1;
2487     if (params.size() > 0) {
2488         nMinDepth = params[0].get_int();
2489     }
2490     if (nMinDepth < 0) {
2491         throw JSONRPCError(RPC_INVALID_PARAMETER, "Minimum number of confirmations cannot be less than 0");
2492     }
2493
2494     int nMaxDepth = 9999999;
2495     if (params.size() > 1) {
2496         nMaxDepth = params[1].get_int();
2497     }
2498     if (nMaxDepth < nMinDepth) {
2499         throw JSONRPCError(RPC_INVALID_PARAMETER, "Maximum number of confirmations must be greater or equal to the minimum number of confirmations");
2500     }
2501
2502     std::set<libzcash::PaymentAddress> zaddrs = {};
2503
2504     bool fIncludeWatchonly = false;
2505     if (params.size() > 2) {
2506         fIncludeWatchonly = params[2].get_bool();
2507     }
2508
2509     LOCK2(cs_main, pwalletMain->cs_wallet);
2510
2511     // User has supplied zaddrs to filter on
2512     if (params.size() > 3) {
2513         UniValue addresses = params[3].get_array();
2514         if (addresses.size()==0)
2515             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, addresses array is empty.");
2516
2517         // Keep track of addresses to spot duplicates
2518         set<std::string> setAddress;
2519
2520         // Sources
2521         for (const UniValue& o : addresses.getValues()) {
2522             if (!o.isStr()) {
2523                 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected string");
2524             }
2525             string address = o.get_str();
2526             auto zaddr = DecodePaymentAddress(address);
2527             if (IsValidPaymentAddress(zaddr)) {
2528                 // TODO: Add Sapling support. For now, ensure we can freely convert.
2529                 assert(boost::get<libzcash::SproutPaymentAddress>(&zaddr) != nullptr);
2530                 libzcash::SproutPaymentAddress addr = boost::get<libzcash::SproutPaymentAddress>(zaddr);
2531                 if (!fIncludeWatchonly && !pwalletMain->HaveSpendingKey(addr)) {
2532                     throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, spending key for address does not belong to wallet: ") + address);
2533                 }
2534                 zaddrs.insert(addr);
2535             } else {
2536                 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, address is not a valid zaddr: ") + address);
2537             }
2538
2539             if (setAddress.count(address)) {
2540                 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ") + address);
2541             }
2542             setAddress.insert(address);
2543         }
2544     }
2545     else {
2546         // User did not provide zaddrs, so use default i.e. all addresses
2547         // TODO: Add Sapling support
2548         std::set<libzcash::SproutPaymentAddress> sproutzaddrs = {};
2549         pwalletMain->GetPaymentAddresses(sproutzaddrs);
2550         zaddrs.insert(sproutzaddrs.begin(), sproutzaddrs.end());
2551     }
2552
2553     UniValue results(UniValue::VARR);
2554
2555     if (zaddrs.size() > 0) {
2556         std::vector<CUnspentSproutNotePlaintextEntry> entries;
2557         pwalletMain->GetUnspentFilteredNotes(entries, zaddrs, nMinDepth, nMaxDepth, !fIncludeWatchonly);
2558         std::set<std::pair<PaymentAddress, uint256>> nullifierSet = pwalletMain->GetNullifiersForAddresses(zaddrs);
2559         for (CUnspentSproutNotePlaintextEntry & entry : entries) {
2560             UniValue obj(UniValue::VOBJ);
2561             obj.push_back(Pair("txid", entry.jsop.hash.ToString()));
2562             obj.push_back(Pair("jsindex", (int)entry.jsop.js ));
2563             obj.push_back(Pair("jsoutindex", (int)entry.jsop.n));
2564             obj.push_back(Pair("confirmations", entry.nHeight));
2565             obj.push_back(Pair("spendable", pwalletMain->HaveSpendingKey(boost::get<libzcash::SproutPaymentAddress>(entry.address))));
2566             obj.push_back(Pair("address", EncodePaymentAddress(entry.address)));
2567             obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.plaintext.value()))));
2568             std::string data(entry.plaintext.memo().begin(), entry.plaintext.memo().end());
2569             obj.push_back(Pair("memo", HexStr(data)));
2570             obj.push_back(Pair("change", pwalletMain->IsNoteChange(nullifierSet, entry.address, entry.jsop)));
2571             results.push_back(obj);
2572         }
2573     }
2574
2575     return results;
2576 }
2577
2578
2579 UniValue fundrawtransaction(const UniValue& params, bool fHelp)
2580 {
2581     if (!EnsureWalletIsAvailable(fHelp))
2582         return NullUniValue;
2583
2584     if (fHelp || params.size() != 1)
2585         throw runtime_error(
2586                             "fundrawtransaction \"hexstring\"\n"
2587                             "\nAdd inputs to a transaction until it has enough in value to meet its out value.\n"
2588                             "This will not modify existing inputs, and will add one change output to the outputs.\n"
2589                             "Note that inputs which were signed may need to be resigned after completion since in/outputs have been added.\n"
2590                             "The inputs added will not be signed, use signrawtransaction for that.\n"
2591                             "\nArguments:\n"
2592                             "1. \"hexstring\"    (string, required) The hex string of the raw transaction\n"
2593                             "\nResult:\n"
2594                             "{\n"
2595                             "  \"hex\":       \"value\", (string)  The resulting raw transaction (hex-encoded string)\n"
2596                             "  \"fee\":       n,         (numeric) The fee added to the transaction\n"
2597                             "  \"changepos\": n          (numeric) The position of the added change output, or -1\n"
2598                             "}\n"
2599                             "\"hex\"             \n"
2600                             "\nExamples:\n"
2601                             "\nCreate a transaction with no inputs\n"
2602                             + HelpExampleCli("createrawtransaction", "\"[]\" \"{\\\"myaddress\\\":0.01}\"") +
2603                             "\nAdd sufficient unsigned inputs to meet the output value\n"
2604                             + HelpExampleCli("fundrawtransaction", "\"rawtransactionhex\"") +
2605                             "\nSign the transaction\n"
2606                             + HelpExampleCli("signrawtransaction", "\"fundedtransactionhex\"") +
2607                             "\nSend the transaction\n"
2608                             + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"")
2609                             );
2610
2611     RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR));
2612
2613     // parse hex string from parameter
2614     CTransaction origTx;
2615     if (!DecodeHexTx(origTx, params[0].get_str()))
2616         throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
2617
2618     CMutableTransaction tx(origTx);
2619     CAmount nFee;
2620     string strFailReason;
2621     int nChangePos = -1;
2622     if(!pwalletMain->FundTransaction(tx, nFee, nChangePos, strFailReason))
2623         throw JSONRPCError(RPC_INTERNAL_ERROR, strFailReason);
2624
2625     UniValue result(UniValue::VOBJ);
2626     result.push_back(Pair("hex", EncodeHexTx(tx)));
2627     result.push_back(Pair("changepos", nChangePos));
2628     result.push_back(Pair("fee", ValueFromAmount(nFee)));
2629
2630     return result;
2631 }
2632
2633 UniValue zc_sample_joinsplit(const UniValue& params, bool fHelp)
2634 {
2635     if (fHelp) {
2636         throw runtime_error(
2637             "zcsamplejoinsplit\n"
2638             "\n"
2639             "Perform a joinsplit and return the JSDescription.\n"
2640             );
2641     }
2642
2643     LOCK(cs_main);
2644
2645     uint256 joinSplitPubKey;
2646     uint256 anchor = ZCIncrementalMerkleTree().root();
2647     JSDescription samplejoinsplit(true,
2648                                   *pzcashParams,
2649                                   joinSplitPubKey,
2650                                   anchor,
2651                                   {JSInput(), JSInput()},
2652                                   {JSOutput(), JSOutput()},
2653                                   0,
2654                                   0);
2655
2656     CDataStream ss(SER_NETWORK, SAPLING_TX_VERSION | (1 << 31));
2657     ss << samplejoinsplit;
2658
2659     return HexStr(ss.begin(), ss.end());
2660 }
2661
2662 UniValue zc_benchmark(const UniValue& params, bool fHelp)
2663 {
2664     if (!EnsureWalletIsAvailable(fHelp)) {
2665         return NullUniValue;
2666     }
2667
2668     if (fHelp || params.size() < 2) {
2669         throw runtime_error(
2670             "zcbenchmark benchmarktype samplecount\n"
2671             "\n"
2672             "Runs a benchmark of the selected type samplecount times,\n"
2673             "returning the running times of each sample.\n"
2674             "\n"
2675             "Output: [\n"
2676             "  {\n"
2677             "    \"runningtime\": runningtime\n"
2678             "  },\n"
2679             "  {\n"
2680             "    \"runningtime\": runningtime\n"
2681             "  }\n"
2682             "  ...\n"
2683             "]\n"
2684             );
2685     }
2686
2687     LOCK(cs_main);
2688
2689     std::string benchmarktype = params[0].get_str();
2690     int samplecount = params[1].get_int();
2691
2692     if (samplecount <= 0) {
2693         throw JSONRPCError(RPC_TYPE_ERROR, "Invalid samplecount");
2694     }
2695
2696     std::vector<double> sample_times;
2697
2698     JSDescription samplejoinsplit;
2699
2700     if (benchmarktype == "verifyjoinsplit") {
2701         CDataStream ss(ParseHexV(params[2].get_str(), "js"), SER_NETWORK, SAPLING_TX_VERSION | (1 << 31));
2702         ss >> samplejoinsplit;
2703     }
2704
2705     for (int i = 0; i < samplecount; i++) {
2706         if (benchmarktype == "sleep") {
2707             sample_times.push_back(benchmark_sleep());
2708         } else if (benchmarktype == "parameterloading") {
2709             sample_times.push_back(benchmark_parameter_loading());
2710         } else if (benchmarktype == "createjoinsplit") {
2711             if (params.size() < 3) {
2712                 sample_times.push_back(benchmark_create_joinsplit());
2713             } else {
2714                 int nThreads = params[2].get_int();
2715                 std::vector<double> vals = benchmark_create_joinsplit_threaded(nThreads);
2716                 // Divide by nThreads^2 to get average seconds per JoinSplit because
2717                 // we are running one JoinSplit per thread.
2718                 sample_times.push_back(std::accumulate(vals.begin(), vals.end(), 0.0) / (nThreads*nThreads));
2719             }
2720         } else if (benchmarktype == "verifyjoinsplit") {
2721             sample_times.push_back(benchmark_verify_joinsplit(samplejoinsplit));
2722 #ifdef ENABLE_MINING
2723         } else if (benchmarktype == "solveequihash") {
2724             if (params.size() < 3) {
2725                 sample_times.push_back(benchmark_solve_equihash());
2726             } else {
2727                 int nThreads = params[2].get_int();
2728                 std::vector<double> vals = benchmark_solve_equihash_threaded(nThreads);
2729                 sample_times.insert(sample_times.end(), vals.begin(), vals.end());
2730             }
2731 #endif
2732         } else if (benchmarktype == "verifyequihash") {
2733             sample_times.push_back(benchmark_verify_equihash());
2734         } else if (benchmarktype == "validatelargetx") {
2735             // Number of inputs in the spending transaction that we will simulate
2736             int nInputs = 11130;
2737             if (params.size() >= 3) {
2738                 nInputs = params[2].get_int();
2739             }
2740             sample_times.push_back(benchmark_large_tx(nInputs));
2741         } else if (benchmarktype == "trydecryptnotes") {
2742             int nAddrs = params[2].get_int();
2743             sample_times.push_back(benchmark_try_decrypt_notes(nAddrs));
2744         } else if (benchmarktype == "incnotewitnesses") {
2745             int nTxs = params[2].get_int();
2746             sample_times.push_back(benchmark_increment_note_witnesses(nTxs));
2747         } else if (benchmarktype == "connectblockslow") {
2748             if (Params().NetworkIDString() != "regtest") {
2749                 throw JSONRPCError(RPC_TYPE_ERROR, "Benchmark must be run in regtest mode");
2750             }
2751             sample_times.push_back(benchmark_connectblock_slow());
2752         } else if (benchmarktype == "sendtoaddress") {
2753             if (Params().NetworkIDString() != "regtest") {
2754                 throw JSONRPCError(RPC_TYPE_ERROR, "Benchmark must be run in regtest mode");
2755             }
2756             auto amount = AmountFromValue(params[2]);
2757             sample_times.push_back(benchmark_sendtoaddress(amount));
2758         } else if (benchmarktype == "loadwallet") {
2759             if (Params().NetworkIDString() != "regtest") {
2760                 throw JSONRPCError(RPC_TYPE_ERROR, "Benchmark must be run in regtest mode");
2761             }
2762             sample_times.push_back(benchmark_loadwallet());
2763         } else if (benchmarktype == "listunspent") {
2764             sample_times.push_back(benchmark_listunspent());
2765         } else {
2766             throw JSONRPCError(RPC_TYPE_ERROR, "Invalid benchmarktype");
2767         }
2768     }
2769
2770     UniValue results(UniValue::VARR);
2771     for (auto time : sample_times) {
2772         UniValue result(UniValue::VOBJ);
2773         result.push_back(Pair("runningtime", time));
2774         results.push_back(result);
2775     }
2776
2777     return results;
2778 }
2779
2780 UniValue zc_raw_receive(const UniValue& params, bool fHelp)
2781 {
2782     if (!EnsureWalletIsAvailable(fHelp)) {
2783         return NullUniValue;
2784     }
2785
2786     if (fHelp || params.size() != 2) {
2787         throw runtime_error(
2788             "zcrawreceive zcsecretkey encryptednote\n"
2789             "\n"
2790             "DEPRECATED. Decrypts encryptednote and checks if the coin commitments\n"
2791             "are in the blockchain as indicated by the \"exists\" result.\n"
2792             "\n"
2793             "Output: {\n"
2794             "  \"amount\": value,\n"
2795             "  \"note\": noteplaintext,\n"
2796             "  \"exists\": exists\n"
2797             "}\n"
2798             );
2799     }
2800
2801     RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VSTR));
2802
2803     LOCK(cs_main);
2804
2805     auto spendingkey = DecodeSpendingKey(params[0].get_str());
2806     if (!IsValidSpendingKey(spendingkey)) {
2807         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key");
2808     }
2809     if (boost::get<libzcash::SproutSpendingKey>(&spendingkey) == nullptr) {
2810         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Only works with Sprout spending keys");
2811     }
2812     SproutSpendingKey k = boost::get<libzcash::SproutSpendingKey>(spendingkey);
2813
2814     uint256 epk;
2815     unsigned char nonce;
2816     ZCNoteEncryption::Ciphertext ct;
2817     uint256 h_sig;
2818
2819     {
2820         CDataStream ssData(ParseHexV(params[1], "encrypted_note"), SER_NETWORK, PROTOCOL_VERSION);
2821         try {
2822             ssData >> nonce;
2823             ssData >> epk;
2824             ssData >> ct;
2825             ssData >> h_sig;
2826         } catch(const std::exception &) {
2827             throw runtime_error(
2828                 "encrypted_note could not be decoded"
2829             );
2830         }
2831     }
2832
2833     ZCNoteDecryption decryptor(k.receiving_key());
2834
2835     SproutNotePlaintext npt = SproutNotePlaintext::decrypt(
2836         decryptor,
2837         ct,
2838         epk,
2839         h_sig,
2840         nonce
2841     );
2842     SproutPaymentAddress payment_addr = k.address();
2843     SproutNote decrypted_note = npt.note(payment_addr);
2844
2845     assert(pwalletMain != NULL);
2846     std::vector<boost::optional<ZCIncrementalWitness>> witnesses;
2847     uint256 anchor;
2848     uint256 commitment = decrypted_note.cm();
2849     pwalletMain->WitnessNoteCommitment(
2850         {commitment},
2851         witnesses,
2852         anchor
2853     );
2854
2855     CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
2856     ss << npt;
2857
2858     UniValue result(UniValue::VOBJ);
2859     result.push_back(Pair("amount", ValueFromAmount(decrypted_note.value())));
2860     result.push_back(Pair("note", HexStr(ss.begin(), ss.end())));
2861     result.push_back(Pair("exists", (bool) witnesses[0]));
2862     return result;
2863 }
2864
2865
2866
2867 UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp)
2868 {
2869     if (!EnsureWalletIsAvailable(fHelp)) {
2870         return NullUniValue;
2871     }
2872
2873     if (fHelp || params.size() != 5) {
2874         throw runtime_error(
2875             "zcrawjoinsplit rawtx inputs outputs vpub_old vpub_new\n"
2876             "  inputs: a JSON object mapping {note: zcsecretkey, ...}\n"
2877             "  outputs: a JSON object mapping {zcaddr: value, ...}\n"
2878             "\n"
2879             "DEPRECATED. Splices a joinsplit into rawtx. Inputs are unilaterally confidential.\n"
2880             "Outputs are confidential between sender/receiver. The vpub_old and\n"
2881             "vpub_new values are globally public and move transparent value into\n"
2882             "or out of the confidential value store, respectively.\n"
2883             "\n"
2884             "Note: The caller is responsible for delivering the output enc1 and\n"
2885             "enc2 to the appropriate recipients, as well as signing rawtxout and\n"
2886             "ensuring it is mined. (A future RPC call will deliver the confidential\n"
2887             "payments in-band on the blockchain.)\n"
2888             "\n"
2889             "Output: {\n"
2890             "  \"encryptednote1\": enc1,\n"
2891             "  \"encryptednote2\": enc2,\n"
2892             "  \"rawtxn\": rawtxout\n"
2893             "}\n"
2894             );
2895     }
2896
2897     LOCK(cs_main);
2898
2899     CTransaction tx;
2900     if (!DecodeHexTx(tx, params[0].get_str()))
2901         throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
2902
2903     UniValue inputs = params[1].get_obj();
2904     UniValue outputs = params[2].get_obj();
2905
2906     CAmount vpub_old(0);
2907     CAmount vpub_new(0);
2908
2909     if (params[3].get_real() != 0.0)
2910         vpub_old = AmountFromValue(params[3]);
2911
2912     if (params[4].get_real() != 0.0)
2913         vpub_new = AmountFromValue(params[4]);
2914
2915     std::vector<JSInput> vjsin;
2916     std::vector<JSOutput> vjsout;
2917     std::vector<SproutNote> notes;
2918     std::vector<SproutSpendingKey> keys;
2919     std::vector<uint256> commitments;
2920
2921     for (const string& name_ : inputs.getKeys()) {
2922         auto spendingkey = DecodeSpendingKey(inputs[name_].get_str());
2923         if (!IsValidSpendingKey(spendingkey)) {
2924             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key");
2925         }
2926         if (boost::get<libzcash::SproutSpendingKey>(&spendingkey) == nullptr) {
2927             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Only works with Sprout spending keys");
2928         }
2929         SproutSpendingKey k = boost::get<libzcash::SproutSpendingKey>(spendingkey);
2930
2931         keys.push_back(k);
2932
2933         SproutNotePlaintext npt;
2934
2935         {
2936             CDataStream ssData(ParseHexV(name_, "note"), SER_NETWORK, PROTOCOL_VERSION);
2937             ssData >> npt;
2938         }
2939
2940         SproutPaymentAddress addr = k.address();
2941         SproutNote note = npt.note(addr);
2942         notes.push_back(note);
2943         commitments.push_back(note.cm());
2944     }
2945
2946     uint256 anchor;
2947     std::vector<boost::optional<ZCIncrementalWitness>> witnesses;
2948     pwalletMain->WitnessNoteCommitment(commitments, witnesses, anchor);
2949
2950     assert(witnesses.size() == notes.size());
2951     assert(notes.size() == keys.size());
2952
2953     {
2954         for (size_t i = 0; i < witnesses.size(); i++) {
2955             if (!witnesses[i]) {
2956                 throw runtime_error(
2957                     "joinsplit input could not be found in tree"
2958                 );
2959             }
2960
2961             vjsin.push_back(JSInput(*witnesses[i], notes[i], keys[i]));
2962         }
2963     }
2964
2965     while (vjsin.size() < ZC_NUM_JS_INPUTS) {
2966         vjsin.push_back(JSInput());
2967     }
2968
2969     for (const string& name_ : outputs.getKeys()) {
2970         auto addrTo = DecodePaymentAddress(name_);
2971         if (!IsValidPaymentAddress(addrTo)) {
2972             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid recipient address.");
2973         }
2974         if (boost::get<libzcash::SproutPaymentAddress>(&addrTo) == nullptr) {
2975             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Only works with Sprout payment addresses");
2976         }
2977         CAmount nAmount = AmountFromValue(outputs[name_]);
2978
2979         vjsout.push_back(JSOutput(boost::get<libzcash::SproutPaymentAddress>(addrTo), nAmount));
2980     }
2981
2982     while (vjsout.size() < ZC_NUM_JS_OUTPUTS) {
2983         vjsout.push_back(JSOutput());
2984     }
2985
2986     // TODO
2987     if (vjsout.size() != ZC_NUM_JS_INPUTS || vjsin.size() != ZC_NUM_JS_OUTPUTS) {
2988         throw runtime_error("unsupported joinsplit input/output counts");
2989     }
2990
2991     uint256 joinSplitPubKey;
2992     unsigned char joinSplitPrivKey[crypto_sign_SECRETKEYBYTES];
2993     crypto_sign_keypair(joinSplitPubKey.begin(), joinSplitPrivKey);
2994
2995     CMutableTransaction mtx(tx);
2996     mtx.nVersion = 2;
2997     mtx.joinSplitPubKey = joinSplitPubKey;
2998
2999     JSDescription jsdesc(false,
3000                          *pzcashParams,
3001                          joinSplitPubKey,
3002                          anchor,
3003                          {vjsin[0], vjsin[1]},
3004                          {vjsout[0], vjsout[1]},
3005                          vpub_old,
3006                          vpub_new);
3007
3008     {
3009         auto verifier = libzcash::ProofVerifier::Strict();
3010         assert(jsdesc.Verify(*pzcashParams, verifier, joinSplitPubKey));
3011     }
3012
3013     mtx.vjoinsplit.push_back(jsdesc);
3014
3015     // Empty output script.
3016     CScript scriptCode;
3017     CTransaction signTx(mtx);
3018     auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
3019     uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId);
3020
3021     // Add the signature
3022     assert(crypto_sign_detached(&mtx.joinSplitSig[0], NULL,
3023                          dataToBeSigned.begin(), 32,
3024                          joinSplitPrivKey
3025                         ) == 0);
3026
3027     // Sanity check
3028     assert(crypto_sign_verify_detached(&mtx.joinSplitSig[0],
3029                                        dataToBeSigned.begin(), 32,
3030                                        mtx.joinSplitPubKey.begin()
3031                                       ) == 0);
3032
3033     CTransaction rawTx(mtx);
3034
3035     CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
3036     ss << rawTx;
3037
3038     std::string encryptedNote1;
3039     std::string encryptedNote2;
3040     {
3041         CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION);
3042         ss2 << ((unsigned char) 0x00);
3043         ss2 << jsdesc.ephemeralKey;
3044         ss2 << jsdesc.ciphertexts[0];
3045         ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey);
3046
3047         encryptedNote1 = HexStr(ss2.begin(), ss2.end());
3048     }
3049     {
3050         CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION);
3051         ss2 << ((unsigned char) 0x01);
3052         ss2 << jsdesc.ephemeralKey;
3053         ss2 << jsdesc.ciphertexts[1];
3054         ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey);
3055
3056         encryptedNote2 = HexStr(ss2.begin(), ss2.end());
3057     }
3058
3059     UniValue result(UniValue::VOBJ);
3060     result.push_back(Pair("encryptednote1", encryptedNote1));
3061     result.push_back(Pair("encryptednote2", encryptedNote2));
3062     result.push_back(Pair("rawtxn", HexStr(ss.begin(), ss.end())));
3063     return result;
3064 }
3065
3066 UniValue zc_raw_keygen(const UniValue& params, bool fHelp)
3067 {
3068     if (!EnsureWalletIsAvailable(fHelp)) {
3069         return NullUniValue;
3070     }
3071
3072     if (fHelp || params.size() != 0) {
3073         throw runtime_error(
3074             "zcrawkeygen\n"
3075             "\n"
3076             "DEPRECATED. Generate a zcaddr which can send and receive confidential values.\n"
3077             "\n"
3078             "Output: {\n"
3079             "  \"zcaddress\": zcaddr,\n"
3080             "  \"zcsecretkey\": zcsecretkey,\n"
3081             "  \"zcviewingkey\": zcviewingkey,\n"
3082             "}\n"
3083             );
3084     }
3085
3086     auto k = SproutSpendingKey::random();
3087     auto addr = k.address();
3088     auto viewing_key = k.viewing_key();
3089
3090     UniValue result(UniValue::VOBJ);
3091     result.push_back(Pair("zcaddress", EncodePaymentAddress(addr)));
3092     result.push_back(Pair("zcsecretkey", EncodeSpendingKey(k)));
3093     result.push_back(Pair("zcviewingkey", EncodeViewingKey(viewing_key)));
3094     return result;
3095 }
3096
3097
3098 UniValue z_getnewaddress(const UniValue& params, bool fHelp)
3099 {
3100     if (!EnsureWalletIsAvailable(fHelp))
3101         return NullUniValue;
3102
3103     if (fHelp || params.size() > 0)
3104         throw runtime_error(
3105             "z_getnewaddress\n"
3106             "\nReturns a new zaddr for receiving payments.\n"
3107             "\nArguments:\n"
3108             "\nResult:\n"
3109             "\"zcashaddress\"    (string) The new zaddr\n"
3110             "\nExamples:\n"
3111             + HelpExampleCli("z_getnewaddress", "")
3112             + HelpExampleRpc("z_getnewaddress", "")
3113         );
3114
3115     LOCK2(cs_main, pwalletMain->cs_wallet);
3116
3117     EnsureWalletIsUnlocked();
3118
3119     auto zaddr = pwalletMain->GenerateNewZKey();
3120     return EncodePaymentAddress(zaddr);
3121 }
3122
3123
3124 UniValue z_listaddresses(const UniValue& params, bool fHelp)
3125 {
3126     if (!EnsureWalletIsAvailable(fHelp))
3127         return NullUniValue;
3128
3129     if (fHelp || params.size() > 1)
3130         throw runtime_error(
3131             "z_listaddresses ( includeWatchonly )\n"
3132             "\nReturns the list of zaddr belonging to the wallet.\n"
3133             "\nArguments:\n"
3134             "1. includeWatchonly (bool, optional, default=false) Also include watchonly addresses (see 'z_importviewingkey')\n"
3135             "\nResult:\n"
3136             "[                     (json array of string)\n"
3137             "  \"zaddr\"           (string) a zaddr belonging to the wallet\n"
3138             "  ,...\n"
3139             "]\n"
3140             "\nExamples:\n"
3141             + HelpExampleCli("z_listaddresses", "")
3142             + HelpExampleRpc("z_listaddresses", "")
3143         );
3144
3145     LOCK2(cs_main, pwalletMain->cs_wallet);
3146
3147     bool fIncludeWatchonly = false;
3148     if (params.size() > 0) {
3149         fIncludeWatchonly = params[0].get_bool();
3150     }
3151
3152     UniValue ret(UniValue::VARR);
3153     // TODO: Add Sapling support
3154     std::set<libzcash::SproutPaymentAddress> addresses;
3155     pwalletMain->GetPaymentAddresses(addresses);
3156     for (auto addr : addresses ) {
3157         if (fIncludeWatchonly || pwalletMain->HaveSpendingKey(addr)) {
3158             ret.push_back(EncodePaymentAddress(addr));
3159         }
3160     }
3161     return ret;
3162 }
3163
3164 CAmount getBalanceTaddr(std::string transparentAddress, int minDepth=1, bool ignoreUnspendable=true) {
3165     std::set<CTxDestination> destinations;
3166     vector<COutput> vecOutputs;
3167     CAmount balance = 0;
3168
3169     if (transparentAddress.length() > 0) {
3170         CTxDestination taddr = DecodeDestination(transparentAddress);
3171         if (!IsValidDestination(taddr)) {
3172             throw std::runtime_error("invalid transparent address");
3173         }
3174         destinations.insert(taddr);
3175     }
3176
3177     LOCK2(cs_main, pwalletMain->cs_wallet);
3178
3179     pwalletMain->AvailableCoins(vecOutputs, false, NULL, true);
3180
3181     BOOST_FOREACH(const COutput& out, vecOutputs) {
3182         if (out.nDepth < minDepth) {
3183             continue;
3184         }
3185
3186         if (ignoreUnspendable && !out.fSpendable) {
3187             continue;
3188         }
3189
3190         if (destinations.size()) {
3191             CTxDestination address;
3192             if (!ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) {
3193                 continue;
3194             }
3195
3196             if (!destinations.count(address)) {
3197                 continue;
3198             }
3199         }
3200
3201         CAmount nValue = out.tx->vout[out.i].nValue;
3202         balance += nValue;
3203     }
3204     return balance;
3205 }
3206
3207 CAmount getBalanceZaddr(std::string address, int minDepth = 1, bool ignoreUnspendable=true) {
3208     CAmount balance = 0;
3209     std::vector<CSproutNotePlaintextEntry> entries;
3210     LOCK2(cs_main, pwalletMain->cs_wallet);
3211     pwalletMain->GetFilteredNotes(entries, address, minDepth, true, ignoreUnspendable);
3212     for (auto & entry : entries) {
3213         balance += CAmount(entry.plaintext.value());
3214     }
3215     return balance;
3216 }
3217
3218
3219 UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp)
3220 {
3221     if (!EnsureWalletIsAvailable(fHelp))
3222         return NullUniValue;
3223
3224     if (fHelp || params.size()==0 || params.size() >2)
3225         throw runtime_error(
3226             "z_listreceivedbyaddress \"address\" ( minconf )\n"
3227             "\nReturn a list of amounts received by a zaddr belonging to the node’s wallet.\n"
3228             "\nArguments:\n"
3229             "1. \"address\"      (string) The private address.\n"
3230             "2. minconf          (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
3231             "\nResult:\n"
3232             "{\n"
3233             "  \"txid\": xxxxx,           (string) the transaction id\n"
3234             "  \"amount\": xxxxx,         (numeric) the amount of value in the note\n"
3235             "  \"memo\": xxxxx,           (string) hexademical string representation of memo field\n"
3236             "  \"change\": true|false,    (boolean) true if the address that received the note is also one of the sending addresses\n"
3237             "}\n"
3238             "\nExamples:\n"
3239             + HelpExampleCli("z_listreceivedbyaddress", "\"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\"")
3240             + HelpExampleRpc("z_listreceivedbyaddress", "\"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\"")
3241         );
3242
3243     LOCK2(cs_main, pwalletMain->cs_wallet);
3244
3245     int nMinDepth = 1;
3246     if (params.size() > 1) {
3247         nMinDepth = params[1].get_int();
3248     }
3249     if (nMinDepth < 0) {
3250         throw JSONRPCError(RPC_INVALID_PARAMETER, "Minimum number of confirmations cannot be less than 0");
3251     }
3252
3253     // Check that the from address is valid.
3254     auto fromaddress = params[0].get_str();
3255
3256     auto zaddr = DecodePaymentAddress(fromaddress);
3257     if (!IsValidPaymentAddress(zaddr)) {
3258         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr.");
3259     }
3260     // TODO: Add Sapling support. For now, ensure we can freely convert.
3261     assert(boost::get<libzcash::SproutPaymentAddress>(&zaddr) != nullptr);
3262     auto sproutzaddr = boost::get<libzcash::SproutPaymentAddress>(zaddr);
3263
3264     if (!(pwalletMain->HaveSpendingKey(sproutzaddr) || pwalletMain->HaveViewingKey(sproutzaddr))) {
3265         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key or viewing key not found.");
3266     }
3267
3268
3269     UniValue result(UniValue::VARR);
3270     std::vector<CSproutNotePlaintextEntry> entries;
3271     pwalletMain->GetFilteredNotes(entries, fromaddress, nMinDepth, false, false);
3272     std::set<std::pair<PaymentAddress, uint256>> nullifierSet = pwalletMain->GetNullifiersForAddresses({zaddr});
3273     for (CSproutNotePlaintextEntry & entry : entries) {
3274         UniValue obj(UniValue::VOBJ);
3275         obj.push_back(Pair("txid", entry.jsop.hash.ToString()));
3276         obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.plaintext.value()))));
3277         std::string data(entry.plaintext.memo().begin(), entry.plaintext.memo().end());
3278         obj.push_back(Pair("memo", HexStr(data)));
3279         // (txid, jsindex, jsoutindex) is needed to globally identify a note
3280         obj.push_back(Pair("jsindex", entry.jsop.js));
3281         obj.push_back(Pair("jsoutindex", entry.jsop.n));
3282         obj.push_back(Pair("change", pwalletMain->IsNoteChange(nullifierSet, entry.address, entry.jsop)));
3283         result.push_back(obj);
3284     }
3285     return result;
3286 }
3287
3288 UniValue z_getbalance(const UniValue& params, bool fHelp)
3289 {
3290     if (!EnsureWalletIsAvailable(fHelp))
3291         return NullUniValue;
3292
3293     if (fHelp || params.size()==0 || params.size() >2)
3294         throw runtime_error(
3295             "z_getbalance \"address\" ( minconf )\n"
3296             "\nReturns the balance of a taddr or zaddr belonging to the node’s wallet.\n"
3297             "\nCAUTION: If address is a watch-only zaddr, the returned balance may be larger than the actual balance,"
3298             "\nbecause spends cannot be detected with incoming viewing keys.\n"
3299             "\nArguments:\n"
3300             "1. \"address\"      (string) The selected address. It may be a transparent or private address.\n"
3301             "2. minconf          (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
3302             "\nResult:\n"
3303             "amount              (numeric) The total amount in " + CURRENCY_UNIT + " received for this address.\n"
3304             "\nExamples:\n"
3305             "\nThe total amount received by address \"myaddress\"\n"
3306             + HelpExampleCli("z_getbalance", "\"myaddress\"") +
3307             "\nThe total amount received by address \"myaddress\" at least 5 blocks confirmed\n"
3308             + HelpExampleCli("z_getbalance", "\"myaddress\" 5") +
3309             "\nAs a json rpc call\n"
3310             + HelpExampleRpc("z_getbalance", "\"myaddress\", 5")
3311         );
3312
3313     LOCK2(cs_main, pwalletMain->cs_wallet);
3314
3315     int nMinDepth = 1;
3316     if (params.size() > 1) {
3317         nMinDepth = params[1].get_int();
3318     }
3319     if (nMinDepth < 0) {
3320         throw JSONRPCError(RPC_INVALID_PARAMETER, "Minimum number of confirmations cannot be less than 0");
3321     }
3322
3323     // Check that the from address is valid.
3324     auto fromaddress = params[0].get_str();
3325     bool fromTaddr = false;
3326     CTxDestination taddr = DecodeDestination(fromaddress);
3327     fromTaddr = IsValidDestination(taddr);
3328     if (!fromTaddr) {
3329         auto res = DecodePaymentAddress(fromaddress);
3330         if (!IsValidPaymentAddress(res)) {
3331             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address, should be a taddr or zaddr.");
3332         }
3333         // TODO: Add Sapling support. For now, ensure we can freely convert.
3334         assert(boost::get<libzcash::SproutPaymentAddress>(&res) != nullptr);
3335         auto zaddr = boost::get<libzcash::SproutPaymentAddress>(res);
3336         if (!(pwalletMain->HaveSpendingKey(zaddr) || pwalletMain->HaveViewingKey(zaddr))) {
3337              throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key or viewing key not found.");
3338         }
3339     }
3340
3341     CAmount nBalance = 0;
3342     if (fromTaddr) {
3343         nBalance = getBalanceTaddr(fromaddress, nMinDepth, false);
3344     } else {
3345         nBalance = getBalanceZaddr(fromaddress, nMinDepth, false);
3346     }
3347
3348     return ValueFromAmount(nBalance);
3349 }
3350
3351
3352 UniValue z_gettotalbalance(const UniValue& params, bool fHelp)
3353 {
3354     if (!EnsureWalletIsAvailable(fHelp))
3355         return NullUniValue;
3356
3357     if (fHelp || params.size() > 2)
3358         throw runtime_error(
3359             "z_gettotalbalance ( minconf includeWatchonly )\n"
3360             "\nReturn the total value of funds stored in the node’s wallet.\n"
3361             "\nCAUTION: If the wallet contains watch-only zaddrs, the returned private balance may be larger than the actual balance,"
3362             "\nbecause spends cannot be detected with incoming viewing keys.\n"
3363             "\nArguments:\n"
3364             "1. minconf          (numeric, optional, default=1) Only include private and transparent transactions confirmed at least this many times.\n"
3365             "2. includeWatchonly (bool, optional, default=false) Also include balance in watchonly addresses (see 'importaddress' and 'z_importviewingkey')\n"
3366             "\nResult:\n"
3367             "{\n"
3368             "  \"transparent\": xxxxx,     (numeric) the total balance of transparent funds\n"
3369             "  \"private\": xxxxx,         (numeric) the total balance of private funds\n"
3370             "  \"total\": xxxxx,           (numeric) the total balance of both transparent and private funds\n"
3371             "}\n"
3372             "\nExamples:\n"
3373             "\nThe total amount in the wallet\n"
3374             + HelpExampleCli("z_gettotalbalance", "") +
3375             "\nThe total amount in the wallet at least 5 blocks confirmed\n"
3376             + HelpExampleCli("z_gettotalbalance", "5") +
3377             "\nAs a json rpc call\n"
3378             + HelpExampleRpc("z_gettotalbalance", "5")
3379         );
3380
3381     LOCK2(cs_main, pwalletMain->cs_wallet);
3382
3383     int nMinDepth = 1;
3384     if (params.size() > 0) {
3385         nMinDepth = params[0].get_int();
3386     }
3387     if (nMinDepth < 0) {
3388         throw JSONRPCError(RPC_INVALID_PARAMETER, "Minimum number of confirmations cannot be less than 0");
3389     }
3390
3391     bool fIncludeWatchonly = false;
3392     if (params.size() > 1) {
3393         fIncludeWatchonly = params[1].get_bool();
3394     }
3395
3396     // getbalance and "getbalance * 1 true" should return the same number
3397     // but they don't because wtx.GetAmounts() does not handle tx where there are no outputs
3398     // pwalletMain->GetBalance() does not accept min depth parameter
3399     // so we use our own method to get balance of utxos.
3400     CAmount nBalance = getBalanceTaddr("", nMinDepth, !fIncludeWatchonly);
3401     CAmount nPrivateBalance = getBalanceZaddr("", nMinDepth, !fIncludeWatchonly);
3402     CAmount nTotalBalance = nBalance + nPrivateBalance;
3403     UniValue result(UniValue::VOBJ);
3404     result.push_back(Pair("transparent", FormatMoney(nBalance)));
3405     result.push_back(Pair("private", FormatMoney(nPrivateBalance)));
3406     result.push_back(Pair("total", FormatMoney(nTotalBalance)));
3407     return result;
3408 }
3409
3410 UniValue z_getoperationresult(const UniValue& params, bool fHelp)
3411 {
3412     if (!EnsureWalletIsAvailable(fHelp))
3413         return NullUniValue;
3414
3415     if (fHelp || params.size() > 1)
3416         throw runtime_error(
3417             "z_getoperationresult ([\"operationid\", ... ]) \n"
3418             "\nRetrieve the result and status of an operation which has finished, and then remove the operation from memory."
3419             + HelpRequiringPassphrase() + "\n"
3420             "\nArguments:\n"
3421             "1. \"operationid\"         (array, optional) A list of operation ids we are interested in.  If not provided, examine all operations known to the node.\n"
3422             "\nResult:\n"
3423             "\"    [object, ...]\"      (array) A list of JSON objects\n"
3424             "\nExamples:\n"
3425             + HelpExampleCli("z_getoperationresult", "'[\"operationid\", ... ]'")
3426             + HelpExampleRpc("z_getoperationresult", "'[\"operationid\", ... ]'")
3427         );
3428
3429     // This call will remove finished operations
3430     return z_getoperationstatus_IMPL(params, true);
3431 }
3432
3433 UniValue z_getoperationstatus(const UniValue& params, bool fHelp)
3434 {
3435    if (!EnsureWalletIsAvailable(fHelp))
3436         return NullUniValue;
3437
3438     if (fHelp || params.size() > 1)
3439         throw runtime_error(
3440             "z_getoperationstatus ([\"operationid\", ... ]) \n"
3441             "\nGet operation status and any associated result or error data.  The operation will remain in memory."
3442             + HelpRequiringPassphrase() + "\n"
3443             "\nArguments:\n"
3444             "1. \"operationid\"         (array, optional) A list of operation ids we are interested in.  If not provided, examine all operations known to the node.\n"
3445             "\nResult:\n"
3446             "\"    [object, ...]\"      (array) A list of JSON objects\n"
3447             "\nExamples:\n"
3448             + HelpExampleCli("z_getoperationstatus", "'[\"operationid\", ... ]'")
3449             + HelpExampleRpc("z_getoperationstatus", "'[\"operationid\", ... ]'")
3450         );
3451
3452    // This call is idempotent so we don't want to remove finished operations
3453    return z_getoperationstatus_IMPL(params, false);
3454 }
3455
3456 UniValue z_getoperationstatus_IMPL(const UniValue& params, bool fRemoveFinishedOperations=false)
3457 {
3458     LOCK2(cs_main, pwalletMain->cs_wallet);
3459
3460     std::set<AsyncRPCOperationId> filter;
3461     if (params.size()==1) {
3462         UniValue ids = params[0].get_array();
3463         for (const UniValue & v : ids.getValues()) {
3464             filter.insert(v.get_str());
3465         }
3466     }
3467     bool useFilter = (filter.size()>0);
3468
3469     UniValue ret(UniValue::VARR);
3470     std::shared_ptr<AsyncRPCQueue> q = getAsyncRPCQueue();
3471     std::vector<AsyncRPCOperationId> ids = q->getAllOperationIds();
3472
3473     for (auto id : ids) {
3474         if (useFilter && !filter.count(id))
3475             continue;
3476
3477         std::shared_ptr<AsyncRPCOperation> operation = q->getOperationForId(id);
3478         if (!operation) {
3479             continue;
3480             // It's possible that the operation was removed from the internal queue and map during this loop
3481             // throw JSONRPCError(RPC_INVALID_PARAMETER, "No operation exists for that id.");
3482         }
3483
3484         UniValue obj = operation->getStatus();
3485         std::string s = obj["status"].get_str();
3486         if (fRemoveFinishedOperations) {
3487             // Caller is only interested in retrieving finished results
3488             if ("success"==s || "failed"==s || "cancelled"==s) {
3489                 ret.push_back(obj);
3490                 q->popOperationForId(id);
3491             }
3492         } else {
3493             ret.push_back(obj);
3494         }
3495     }
3496
3497     std::vector<UniValue> arrTmp = ret.getValues();
3498
3499     // sort results chronologically by creation_time
3500     std::sort(arrTmp.begin(), arrTmp.end(), [](UniValue a, UniValue b) -> bool {
3501         const int64_t t1 = find_value(a.get_obj(), "creation_time").get_int64();
3502         const int64_t t2 = find_value(b.get_obj(), "creation_time").get_int64();
3503         return t1 < t2;
3504     });
3505
3506     ret.clear();
3507     ret.setArray();
3508     ret.push_backV(arrTmp);
3509
3510     return ret;
3511 }
3512
3513
3514 // JSDescription size depends on the transaction version
3515 #define V3_JS_DESCRIPTION_SIZE    (GetSerializeSize(JSDescription(), SER_NETWORK, (OVERWINTER_TX_VERSION | (1 << 31))))
3516 // Here we define the maximum number of zaddr outputs that can be included in a transaction.
3517 // If input notes are small, we might actually require more than one joinsplit per zaddr output.
3518 // For now though, we assume we use one joinsplit per zaddr output (and the second output note is change).
3519 // We reduce the result by 1 to ensure there is room for non-joinsplit CTransaction data.
3520 #define Z_SENDMANY_MAX_ZADDR_OUTPUTS_BEFORE_SAPLING    ((MAX_TX_SIZE_BEFORE_SAPLING / V3_JS_DESCRIPTION_SIZE) - 1)
3521
3522 // transaction.h comment: spending taddr output requires CTxIn >= 148 bytes and typical taddr txout is 34 bytes
3523 #define CTXIN_SPEND_DUST_SIZE   148
3524 #define CTXOUT_REGULAR_SIZE     34
3525
3526 UniValue z_sendmany(const UniValue& params, bool fHelp)
3527 {
3528     if (!EnsureWalletIsAvailable(fHelp))
3529         return NullUniValue;
3530
3531     if (fHelp || params.size() < 2 || params.size() > 4)
3532         throw runtime_error(
3533             "z_sendmany \"fromaddress\" [{\"address\":... ,\"amount\":...},...] ( minconf ) ( fee )\n"
3534             "\nSend multiple times. Amounts are double-precision floating point numbers."
3535             "\nChange from a taddr flows to a new taddr address, while change from zaddr returns to itself."
3536             "\nWhen sending coinbase UTXOs to a zaddr, change is not allowed. The entire value of the UTXO(s) must be consumed."
3537             + strprintf("\nBefore Sapling activates, the maximum number of zaddr outputs is %d due to transaction size limits.\n", Z_SENDMANY_MAX_ZADDR_OUTPUTS_BEFORE_SAPLING)
3538             + HelpRequiringPassphrase() + "\n"
3539             "\nArguments:\n"
3540             "1. \"fromaddress\"         (string, required) The taddr or zaddr to send the funds from.\n"
3541             "2. \"amounts\"             (array, required) An array of json objects representing the amounts to send.\n"
3542             "    [{\n"
3543             "      \"address\":address  (string, required) The address is a taddr or zaddr\n"
3544             "      \"amount\":amount    (numeric, required) The numeric amount in " + CURRENCY_UNIT + " is the value\n"
3545             "      \"memo\":memo        (string, optional) If the address is a zaddr, raw data represented in hexadecimal string format\n"
3546             "    }, ... ]\n"
3547             "3. minconf               (numeric, optional, default=1) Only use funds confirmed at least this many times.\n"
3548             "4. fee                   (numeric, optional, default="
3549             + strprintf("%s", FormatMoney(ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE)) + ") The fee amount to attach to this transaction.\n"
3550             "\nResult:\n"
3551             "\"operationid\"          (string) An operationid to pass to z_getoperationstatus to get the result of the operation.\n"
3552             "\nExamples:\n"
3553             + HelpExampleCli("z_sendmany", "\"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" '[{\"address\": \"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\" ,\"amount\": 5.0}]'")
3554             + HelpExampleRpc("z_sendmany", "\"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", [{\"address\": \"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\" ,\"amount\": 5.0}]")
3555         );
3556
3557     LOCK2(cs_main, pwalletMain->cs_wallet);
3558
3559     // Check that the from address is valid.
3560     auto fromaddress = params[0].get_str();
3561     bool fromTaddr = false;
3562     CTxDestination taddr = DecodeDestination(fromaddress);
3563     fromTaddr = IsValidDestination(taddr);
3564     libzcash::SproutPaymentAddress zaddr;
3565     if (!fromTaddr) {
3566         auto res = DecodePaymentAddress(fromaddress);
3567         if (!IsValidPaymentAddress(res)) {
3568             // invalid
3569             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address, should be a taddr or zaddr.");
3570         }
3571         // TODO: Add Sapling support. For now, ensure we can freely convert.
3572         assert(boost::get<libzcash::SproutPaymentAddress>(&res) != nullptr);
3573         zaddr = boost::get<libzcash::SproutPaymentAddress>(res);
3574     }
3575
3576     // Check that we have the spending key
3577     if (!fromTaddr) {
3578         if (!pwalletMain->HaveSpendingKey(zaddr)) {
3579              throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key not found.");
3580         }
3581     }
3582
3583     UniValue outputs = params[1].get_array();
3584
3585     if (outputs.size()==0)
3586         throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, amounts array is empty.");
3587
3588     // Keep track of addresses to spot duplicates
3589     set<std::string> setAddress;
3590
3591     // Recipients
3592     std::vector<SendManyRecipient> taddrRecipients;
3593     std::vector<SendManyRecipient> zaddrRecipients;
3594     CAmount nTotalOut = 0;
3595
3596     for (const UniValue& o : outputs.getValues()) {
3597         if (!o.isObject())
3598             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected object");
3599
3600         // sanity check, report error if unknown key-value pairs
3601         for (const string& name_ : o.getKeys()) {
3602             std::string s = name_;
3603             if (s != "address" && s != "amount" && s!="memo")
3604                 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown key: ")+s);
3605         }
3606
3607         string address = find_value(o, "address").get_str();
3608         bool isZaddr = false;
3609         CTxDestination taddr = DecodeDestination(address);
3610         if (!IsValidDestination(taddr)) {
3611             if (IsValidPaymentAddressString(address)) {
3612                 isZaddr = true;
3613             } else {
3614                 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ")+address );
3615             }
3616         }
3617
3618         if (setAddress.count(address))
3619             throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+address);
3620         setAddress.insert(address);
3621
3622         UniValue memoValue = find_value(o, "memo");
3623         string memo;
3624         if (!memoValue.isNull()) {
3625             memo = memoValue.get_str();
3626             if (!isZaddr) {
3627                 throw JSONRPCError(RPC_INVALID_PARAMETER, "Memo cannot be used with a taddr.  It can only be used with a zaddr.");
3628             } else if (!IsHex(memo)) {
3629                 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected memo data in hexadecimal format.");
3630             }
3631             if (memo.length() > ZC_MEMO_SIZE*2) {
3632                 throw JSONRPCError(RPC_INVALID_PARAMETER,  strprintf("Invalid parameter, size of memo is larger than maximum allowed %d", ZC_MEMO_SIZE ));
3633             }
3634         }
3635
3636         UniValue av = find_value(o, "amount");
3637         CAmount nAmount = AmountFromValue( av );
3638         if (nAmount < 0)
3639             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, amount must be positive");
3640
3641         if (isZaddr) {
3642             zaddrRecipients.push_back( SendManyRecipient(address, nAmount, memo) );
3643         } else {
3644             taddrRecipients.push_back( SendManyRecipient(address, nAmount, memo) );
3645         }
3646
3647         nTotalOut += nAmount;
3648     }
3649
3650     int nextBlockHeight = chainActive.Height() + 1;
3651     CMutableTransaction mtx;
3652     mtx.fOverwintered = true;
3653     mtx.nVersionGroupId = SAPLING_VERSION_GROUP_ID;
3654     mtx.nVersion = SAPLING_TX_VERSION;
3655     unsigned int max_tx_size = MAX_TX_SIZE_AFTER_SAPLING;
3656     if (!NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) {
3657         if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
3658             mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID;
3659             mtx.nVersion = OVERWINTER_TX_VERSION;
3660         } else {
3661             mtx.fOverwintered = false;
3662             mtx.nVersion = 2;
3663         }
3664
3665         max_tx_size = MAX_TX_SIZE_BEFORE_SAPLING;
3666
3667         // Check the number of zaddr outputs does not exceed the limit.
3668         if (zaddrRecipients.size() > Z_SENDMANY_MAX_ZADDR_OUTPUTS_BEFORE_SAPLING)  {
3669             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, too many zaddr outputs");
3670         }
3671     }
3672
3673     // As a sanity check, estimate and verify that the size of the transaction will be valid.
3674     // Depending on the input notes, the actual tx size may turn out to be larger and perhaps invalid.
3675     size_t txsize = 0;
3676     for (int i = 0; i < zaddrRecipients.size(); i++) {
3677         // TODO Check whether the recipient is a Sprout or Sapling address
3678         JSDescription jsdesc;
3679
3680         if (mtx.fOverwintered && (mtx.nVersion >= SAPLING_TX_VERSION)) {
3681             jsdesc.proof = GrothProof();
3682         }
3683
3684         mtx.vjoinsplit.push_back(jsdesc);
3685     }
3686     CTransaction tx(mtx);
3687     txsize += GetSerializeSize(tx, SER_NETWORK, tx.nVersion);
3688     if (fromTaddr) {
3689         txsize += CTXIN_SPEND_DUST_SIZE;
3690         txsize += CTXOUT_REGULAR_SIZE;      // There will probably be taddr change
3691     }
3692     txsize += CTXOUT_REGULAR_SIZE * taddrRecipients.size();
3693     if (txsize > max_tx_size) {
3694         throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Too many outputs, size of raw transaction would be larger than limit of %d bytes", max_tx_size ));
3695     }
3696
3697     // Minimum confirmations
3698     int nMinDepth = 1;
3699     if (params.size() > 2) {
3700         nMinDepth = params[2].get_int();
3701     }
3702     if (nMinDepth < 0) {
3703         throw JSONRPCError(RPC_INVALID_PARAMETER, "Minimum number of confirmations cannot be less than 0");
3704     }
3705
3706     // Fee in Zatoshis, not currency format)
3707     CAmount nFee        = ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE;
3708     CAmount nDefaultFee = nFee;
3709
3710     if (params.size() > 3) {
3711         if (params[3].get_real() == 0.0) {
3712             nFee = 0;
3713         } else {
3714             nFee = AmountFromValue( params[3] );
3715         }
3716
3717         // Check that the user specified fee is not absurd.
3718         // This allows amount=0 (and all amount < nDefaultFee) transactions to use the default network fee
3719         // or anything less than nDefaultFee instead of being forced to use a custom fee and leak metadata
3720         if (nTotalOut < nDefaultFee) {
3721             if (nFee > nDefaultFee) {
3722                 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Small transaction amount %s has fee %s that is greater than the default fee %s", FormatMoney(nTotalOut), FormatMoney(nFee), FormatMoney(nDefaultFee)));
3723             }
3724         } else {
3725             // Check that the user specified fee is not absurd.
3726             if (nFee > nTotalOut) {
3727                 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Fee %s is greater than the sum of outputs %s and also greater than the default fee", FormatMoney(nFee), FormatMoney(nTotalOut)));
3728             }
3729         }
3730     }
3731
3732     // Use input parameters as the optional context info to be returned by z_getoperationstatus and z_getoperationresult.
3733     UniValue o(UniValue::VOBJ);
3734     o.push_back(Pair("fromaddress", params[0]));
3735     o.push_back(Pair("amounts", params[1]));
3736     o.push_back(Pair("minconf", nMinDepth));
3737     o.push_back(Pair("fee", std::stod(FormatMoney(nFee))));
3738     UniValue contextInfo = o;
3739
3740     // Contextual transaction we will build on
3741     CMutableTransaction contextualTx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextBlockHeight);
3742     bool isShielded = !fromTaddr || zaddrRecipients.size() > 0;
3743     if (contextualTx.nVersion == 1 && isShielded) {
3744         contextualTx.nVersion = 2; // Tx format should support vjoinsplits 
3745     }
3746
3747     // Create operation and add to global queue
3748     std::shared_ptr<AsyncRPCQueue> q = getAsyncRPCQueue();
3749     std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany(contextualTx, fromaddress, taddrRecipients, zaddrRecipients, nMinDepth, nFee, contextInfo) );
3750     q->addOperation(operation);
3751     AsyncRPCOperationId operationId = operation->getId();
3752     return operationId;
3753 }
3754
3755
3756 /**
3757 When estimating the number of coinbase utxos we can shield in a single transaction:
3758 1. Joinsplit description is 1802 bytes.
3759 2. Transaction overhead ~ 100 bytes
3760 3. Spending a typical P2PKH is >=148 bytes, as defined in CTXIN_SPEND_DUST_SIZE.
3761 4. Spending a multi-sig P2SH address can vary greatly:
3762    https://github.com/bitcoin/bitcoin/blob/c3ad56f4e0b587d8d763af03d743fdfc2d180c9b/src/main.cpp#L517
3763    In real-world coinbase utxos, we consider a 3-of-3 multisig, where the size is roughly:
3764     (3*(33+1))+3 = 105 byte redeem script
3765     105 + 1 + 3*(73+1) = 328 bytes of scriptSig, rounded up to 400 based on testnet experiments.
3766 */
3767 #define CTXIN_SPEND_P2SH_SIZE 400
3768
3769 #define SHIELD_COINBASE_DEFAULT_LIMIT 50
3770
3771 UniValue z_shieldcoinbase(const UniValue& params, bool fHelp)
3772 {
3773     if (!EnsureWalletIsAvailable(fHelp))
3774         return NullUniValue;
3775
3776     if (fHelp || params.size() < 2 || params.size() > 4)
3777         throw runtime_error(
3778             "z_shieldcoinbase \"fromaddress\" \"tozaddress\" ( fee ) ( limit )\n"
3779             "\nShield transparent coinbase funds by sending to a shielded zaddr.  This is an asynchronous operation and utxos"
3780             "\nselected for shielding will be locked.  If there is an error, they are unlocked.  The RPC call `listlockunspent`"
3781             "\ncan be used to return a list of locked utxos.  The number of coinbase utxos selected for shielding can be limited"
3782             "\nby the caller.  If the limit parameter is set to zero, and Overwinter is not yet active, the -mempooltxinputlimit"
3783             "\noption will determine the number of uxtos.  Any limit is constrained by the consensus rule defining a maximum"
3784             "\ntransaction size of "
3785             + strprintf("%d bytes before Sapling, and %d bytes once Sapling activates.", MAX_TX_SIZE_BEFORE_SAPLING, MAX_TX_SIZE_AFTER_SAPLING)
3786             + HelpRequiringPassphrase() + "\n"
3787             "\nArguments:\n"
3788             "1. \"fromaddress\"         (string, required) The address is a taddr or \"*\" for all taddrs belonging to the wallet.\n"
3789             "2. \"toaddress\"           (string, required) The address is a zaddr.\n"
3790             "3. fee                   (numeric, optional, default="
3791             + strprintf("%s", FormatMoney(SHIELD_COINBASE_DEFAULT_MINERS_FEE)) + ") The fee amount to attach to this transaction.\n"
3792             "4. limit                 (numeric, optional, default="
3793             + strprintf("%d", SHIELD_COINBASE_DEFAULT_LIMIT) + ") Limit on the maximum number of utxos to shield.  Set to 0 to use node option -mempooltxinputlimit (before Overwinter), or as many as will fit in the transaction (after Overwinter).\n"
3794             "\nResult:\n"
3795             "{\n"
3796             "  \"remainingUTXOs\": xxx       (numeric) Number of coinbase utxos still available for shielding.\n"
3797             "  \"remainingValue\": xxx       (numeric) Value of coinbase utxos still available for shielding.\n"
3798             "  \"shieldingUTXOs\": xxx        (numeric) Number of coinbase utxos being shielded.\n"
3799             "  \"shieldingValue\": xxx        (numeric) Value of coinbase utxos being shielded.\n"
3800             "  \"opid\": xxx          (string) An operationid to pass to z_getoperationstatus to get the result of the operation.\n"
3801             "}\n"
3802             "\nExamples:\n"
3803             + HelpExampleCli("z_shieldcoinbase", "\"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" \"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\"")
3804             + HelpExampleRpc("z_shieldcoinbase", "\"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", \"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\"")
3805         );
3806
3807     LOCK2(cs_main, pwalletMain->cs_wallet);
3808
3809     // Validate the from address
3810     auto fromaddress = params[0].get_str();
3811     bool isFromWildcard = fromaddress == "*";
3812     CTxDestination taddr;
3813     if (!isFromWildcard) {
3814         taddr = DecodeDestination(fromaddress);
3815         if (!IsValidDestination(taddr)) {
3816             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address, should be a taddr or \"*\".");
3817         }
3818     }
3819
3820     // Validate the destination address
3821     auto destaddress = params[1].get_str();
3822     if (!IsValidPaymentAddressString(destaddress)) {
3823         throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destaddress );
3824     }
3825
3826     // Convert fee from currency format to zatoshis
3827     CAmount nFee = SHIELD_COINBASE_DEFAULT_MINERS_FEE;
3828     if (params.size() > 2) {
3829         if (params[2].get_real() == 0.0) {
3830             nFee = 0;
3831         } else {
3832             nFee = AmountFromValue( params[2] );
3833         }
3834     }
3835
3836     int nLimit = SHIELD_COINBASE_DEFAULT_LIMIT;
3837     if (params.size() > 3) {
3838         nLimit = params[3].get_int();
3839         if (nLimit < 0) {
3840             throw JSONRPCError(RPC_INVALID_PARAMETER, "Limit on maximum number of utxos cannot be negative");
3841         }
3842     }
3843
3844     int nextBlockHeight = chainActive.Height() + 1;
3845     bool overwinterActive = NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER);
3846     unsigned int max_tx_size = MAX_TX_SIZE_AFTER_SAPLING;
3847     if (!NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) {
3848         max_tx_size = MAX_TX_SIZE_BEFORE_SAPLING;
3849     }
3850
3851     // Prepare to get coinbase utxos
3852     std::vector<ShieldCoinbaseUTXO> inputs;
3853     CAmount shieldedValue = 0;
3854     CAmount remainingValue = 0;
3855     size_t estimatedTxSize = 2000;  // 1802 joinsplit description + tx overhead + wiggle room
3856     size_t utxoCounter = 0;
3857     bool maxedOutFlag = false;
3858     size_t mempoolLimit = (nLimit != 0) ? nLimit : (overwinterActive ? 0 : (size_t)GetArg("-mempooltxinputlimit", 0));
3859
3860     // Set of addresses to filter utxos by
3861     std::set<CTxDestination> destinations = {};
3862     if (!isFromWildcard) {
3863         destinations.insert(taddr);
3864     }
3865
3866     // Get available utxos
3867     vector<COutput> vecOutputs;
3868     pwalletMain->AvailableCoins(vecOutputs, true, NULL, false, true);
3869
3870     // Find unspent coinbase utxos and update estimated size
3871     BOOST_FOREACH(const COutput& out, vecOutputs) {
3872         if (!out.fSpendable) {
3873             continue;
3874         }
3875
3876         CTxDestination address;
3877         if (!ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) {
3878             continue;
3879         }
3880         // If taddr is not wildcard "*", filter utxos
3881         if (destinations.size() > 0 && !destinations.count(address)) {
3882             continue;
3883         }
3884
3885         if (!out.tx->IsCoinBase()) {
3886             continue;
3887         }
3888
3889         utxoCounter++;
3890         CAmount nValue = out.tx->vout[out.i].nValue;
3891
3892         if (!maxedOutFlag) {
3893             size_t increase = (boost::get<CScriptID>(&address) != nullptr) ? CTXIN_SPEND_P2SH_SIZE : CTXIN_SPEND_DUST_SIZE;
3894             if (estimatedTxSize + increase >= max_tx_size ||
3895                 (mempoolLimit > 0 && utxoCounter > mempoolLimit))
3896             {
3897                 maxedOutFlag = true;
3898             } else {
3899                 estimatedTxSize += increase;
3900                 ShieldCoinbaseUTXO utxo = {out.tx->GetHash(), out.i, nValue};
3901                 inputs.push_back(utxo);
3902                 shieldedValue += nValue;
3903             }
3904         }
3905
3906         if (maxedOutFlag) {
3907             remainingValue += nValue;
3908         }
3909     }
3910
3911     size_t numUtxos = inputs.size();
3912
3913     if (numUtxos == 0) {
3914         throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Could not find any coinbase funds to shield.");
3915     }
3916
3917     if (shieldedValue < nFee) {
3918         throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS,
3919             strprintf("Insufficient coinbase funds, have %s, which is less than miners fee %s",
3920             FormatMoney(shieldedValue), FormatMoney(nFee)));
3921     }
3922
3923     // Check that the user specified fee is sane (if too high, it can result in error -25 absurd fee)
3924     CAmount netAmount = shieldedValue - nFee;
3925     if (nFee > netAmount) {
3926         throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Fee %s is greater than the net amount to be shielded %s", FormatMoney(nFee), FormatMoney(netAmount)));
3927     }
3928
3929     // Keep record of parameters in context object
3930     UniValue contextInfo(UniValue::VOBJ);
3931     contextInfo.push_back(Pair("fromaddress", params[0]));
3932     contextInfo.push_back(Pair("toaddress", params[1]));
3933     contextInfo.push_back(Pair("fee", ValueFromAmount(nFee)));
3934
3935     // Contextual transaction we will build on
3936     CMutableTransaction contextualTx = CreateNewContextualCMutableTransaction(
3937         Params().GetConsensus(), nextBlockHeight);
3938     if (contextualTx.nVersion == 1) {
3939         contextualTx.nVersion = 2; // Tx format should support vjoinsplits 
3940     }
3941
3942     // Create operation and add to global queue
3943     std::shared_ptr<AsyncRPCQueue> q = getAsyncRPCQueue();
3944     std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_shieldcoinbase(contextualTx, inputs, destaddress, nFee, contextInfo) );
3945     q->addOperation(operation);
3946     AsyncRPCOperationId operationId = operation->getId();
3947
3948     // Return continuation information
3949     UniValue o(UniValue::VOBJ);
3950     o.push_back(Pair("remainingUTXOs", static_cast<uint64_t>(utxoCounter - numUtxos)));
3951     o.push_back(Pair("remainingValue", ValueFromAmount(remainingValue)));
3952     o.push_back(Pair("shieldingUTXOs", static_cast<uint64_t>(numUtxos)));
3953     o.push_back(Pair("shieldingValue", ValueFromAmount(shieldedValue)));
3954     o.push_back(Pair("opid", operationId));
3955     return o;
3956 }
3957
3958
3959 #define MERGE_TO_ADDRESS_DEFAULT_TRANSPARENT_LIMIT 50
3960 #define MERGE_TO_ADDRESS_DEFAULT_SHIELDED_LIMIT 10
3961
3962 #define JOINSPLIT_SIZE GetSerializeSize(JSDescription(), SER_NETWORK, PROTOCOL_VERSION)
3963
3964 UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
3965 {
3966     if (!EnsureWalletIsAvailable(fHelp))
3967         return NullUniValue;
3968
3969     string enableArg = "zmergetoaddress";
3970     auto fEnableMergeToAddress = fExperimentalMode && GetBoolArg("-" + enableArg, false);
3971     std::string strDisabledMsg = "";
3972     if (!fEnableMergeToAddress) {
3973         strDisabledMsg = experimentalDisabledHelpMsg("z_mergetoaddress", enableArg);
3974     }
3975
3976     if (fHelp || params.size() < 2 || params.size() > 6)
3977         throw runtime_error(
3978             "z_mergetoaddress [\"fromaddress\", ... ] \"toaddress\" ( fee ) ( transparent_limit ) ( shielded_limit ) ( memo )\n"
3979             + strDisabledMsg +
3980             "\nMerge multiple UTXOs and notes into a single UTXO or note.  Coinbase UTXOs are ignored; use `z_shieldcoinbase`"
3981             "\nto combine those into a single note."
3982             "\n\nThis is an asynchronous operation, and UTXOs selected for merging will be locked.  If there is an error, they"
3983             "\nare unlocked.  The RPC call `listlockunspent` can be used to return a list of locked UTXOs."
3984             "\n\nThe number of UTXOs and notes selected for merging can be limited by the caller.  If the transparent limit"
3985             "\nparameter is set to zero, and Overwinter is not yet active, the -mempooltxinputlimit option will determine the"
3986             "\nnumber of UTXOs.  Any limit is constrained by the consensus rule defining a maximum transaction size of"
3987             + strprintf("\n%d bytes before Sapling, and %d bytes once Sapling activates.", MAX_TX_SIZE_BEFORE_SAPLING, MAX_TX_SIZE_AFTER_SAPLING)
3988             + HelpRequiringPassphrase() + "\n"
3989             "\nArguments:\n"
3990             "1. fromaddresses         (string, required) A JSON array with addresses.\n"
3991             "                         The following special strings are accepted inside the array:\n"
3992             "                             - \"*\": Merge both UTXOs and notes from all addresses belonging to the wallet.\n"
3993             "                             - \"ANY_TADDR\": Merge UTXOs from all t-addrs belonging to the wallet.\n"
3994             "                             - \"ANY_ZADDR\": Merge notes from all z-addrs belonging to the wallet.\n"
3995             "                         If a special string is given, any given addresses of that type will be ignored.\n"
3996             "    [\n"
3997             "      \"address\"          (string) Can be a t-addr or a z-addr\n"
3998             "      ,...\n"
3999             "    ]\n"
4000             "2. \"toaddress\"           (string, required) The t-addr or z-addr to send the funds to.\n"
4001             "3. fee                   (numeric, optional, default="
4002             + strprintf("%s", FormatMoney(MERGE_TO_ADDRESS_OPERATION_DEFAULT_MINERS_FEE)) + ") The fee amount to attach to this transaction.\n"
4003             "4. transparent_limit     (numeric, optional, default="
4004             + strprintf("%d", MERGE_TO_ADDRESS_DEFAULT_TRANSPARENT_LIMIT) + ") Limit on the maximum number of UTXOs to merge.  Set to 0 to use node option -mempooltxinputlimit (before Overwinter), or as many as will fit in the transaction (after Overwinter).\n"
4005             "4. shielded_limit        (numeric, optional, default="
4006             + strprintf("%d", MERGE_TO_ADDRESS_DEFAULT_SHIELDED_LIMIT) + ") Limit on the maximum number of notes to merge.  Set to 0 to merge as many as will fit in the transaction.\n"
4007             "5. \"memo\"                (string, optional) Encoded as hex. When toaddress is a z-addr, this will be stored in the memo field of the new note.\n"
4008             "\nResult:\n"
4009             "{\n"
4010             "  \"remainingUTXOs\": xxx               (numeric) Number of UTXOs still available for merging.\n"
4011             "  \"remainingTransparentValue\": xxx    (numeric) Value of UTXOs still available for merging.\n"
4012             "  \"remainingNotes\": xxx               (numeric) Number of notes still available for merging.\n"
4013             "  \"remainingShieldedValue\": xxx       (numeric) Value of notes still available for merging.\n"
4014             "  \"mergingUTXOs\": xxx                 (numeric) Number of UTXOs being merged.\n"
4015             "  \"mergingTransparentValue\": xxx      (numeric) Value of UTXOs being merged.\n"
4016             "  \"mergingNotes\": xxx                 (numeric) Number of notes being merged.\n"
4017             "  \"mergingShieldedValue\": xxx         (numeric) Value of notes being merged.\n"
4018             "  \"opid\": xxx          (string) An operationid to pass to z_getoperationstatus to get the result of the operation.\n"
4019             "}\n"
4020             "\nExamples:\n"
4021             + HelpExampleCli("z_mergetoaddress", "'[\"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\"]' ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf")
4022             + HelpExampleRpc("z_mergetoaddress", "[\"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\"], \"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\"")
4023         );
4024
4025     if (!fEnableMergeToAddress) {
4026         throw JSONRPCError(RPC_WALLET_ERROR, "Error: z_mergetoaddress is disabled.");
4027     }
4028
4029     LOCK2(cs_main, pwalletMain->cs_wallet);
4030
4031     bool useAny = false;
4032     bool useAnyUTXO = false;
4033     bool useAnyNote = false;
4034     std::set<CTxDestination> taddrs = {};
4035     std::set<libzcash::PaymentAddress> zaddrs = {};
4036
4037     UniValue addresses = params[0].get_array();
4038     if (addresses.size()==0)
4039         throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, fromaddresses array is empty.");
4040
4041     // Keep track of addresses to spot duplicates
4042     std::set<std::string> setAddress;
4043
4044     // Sources
4045     for (const UniValue& o : addresses.getValues()) {
4046         if (!o.isStr())
4047             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected string");
4048
4049         std::string address = o.get_str();
4050         if (address == "*") {
4051             useAny = true;
4052         } else if (address == "ANY_TADDR") {
4053             useAnyUTXO = true;
4054         } else if (address == "ANY_ZADDR") {
4055             useAnyNote = true;
4056         } else {
4057             CTxDestination taddr = DecodeDestination(address);
4058             if (IsValidDestination(taddr)) {
4059                 // Ignore any listed t-addrs if we are using all of them
4060                 if (!(useAny || useAnyUTXO)) {
4061                     taddrs.insert(taddr);
4062                 }
4063             } else {
4064                 auto zaddr = DecodePaymentAddress(address);
4065                 if (IsValidPaymentAddress(zaddr)) {
4066                     // Ignore listed z-addrs if we are using all of them
4067                     if (!(useAny || useAnyNote)) {
4068                         zaddrs.insert(zaddr);
4069                     }
4070                 } else {
4071                     throw JSONRPCError(
4072                         RPC_INVALID_PARAMETER,
4073                         string("Invalid parameter, unknown address format: ") + address);
4074                 }
4075             }
4076         }
4077
4078         if (setAddress.count(address))
4079             throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ") + address);
4080         setAddress.insert(address);
4081     }
4082
4083     // Validate the destination address
4084     auto destaddress = params[1].get_str();
4085     bool isToZaddr = false;
4086     CTxDestination taddr = DecodeDestination(destaddress);
4087     if (!IsValidDestination(taddr)) {
4088         if (IsValidPaymentAddressString(destaddress)) {
4089             isToZaddr = true;
4090         } else {
4091             throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destaddress );
4092         }
4093     }
4094
4095     // Convert fee from currency format to zatoshis
4096     CAmount nFee = SHIELD_COINBASE_DEFAULT_MINERS_FEE;
4097     if (params.size() > 2) {
4098         if (params[2].get_real() == 0.0) {
4099             nFee = 0;
4100         } else {
4101             nFee = AmountFromValue( params[2] );
4102         }
4103     }
4104
4105     int nUTXOLimit = MERGE_TO_ADDRESS_DEFAULT_TRANSPARENT_LIMIT;
4106     if (params.size() > 3) {
4107         nUTXOLimit = params[3].get_int();
4108         if (nUTXOLimit < 0) {
4109             throw JSONRPCError(RPC_INVALID_PARAMETER, "Limit on maximum number of UTXOs cannot be negative");
4110         }
4111     }
4112
4113     int nNoteLimit = MERGE_TO_ADDRESS_DEFAULT_SHIELDED_LIMIT;
4114     if (params.size() > 4) {
4115         nNoteLimit = params[4].get_int();
4116         if (nNoteLimit < 0) {
4117             throw JSONRPCError(RPC_INVALID_PARAMETER, "Limit on maximum number of notes cannot be negative");
4118         }
4119     }
4120
4121     std::string memo;
4122     if (params.size() > 5) {
4123         memo = params[5].get_str();
4124         if (!isToZaddr) {
4125             throw JSONRPCError(RPC_INVALID_PARAMETER, "Memo can not be used with a taddr.  It can only be used with a zaddr.");
4126         } else if (!IsHex(memo)) {
4127             throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected memo data in hexadecimal format.");
4128         }
4129         if (memo.length() > ZC_MEMO_SIZE*2) {
4130             throw JSONRPCError(RPC_INVALID_PARAMETER,  strprintf("Invalid parameter, size of memo is larger than maximum allowed %d", ZC_MEMO_SIZE ));
4131         }
4132     }
4133
4134     MergeToAddressRecipient recipient(destaddress, memo);
4135
4136     int nextBlockHeight = chainActive.Height() + 1;
4137     bool overwinterActive = NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER);
4138     unsigned int max_tx_size = MAX_TX_SIZE_AFTER_SAPLING;
4139     if (!NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) {
4140         max_tx_size = MAX_TX_SIZE_BEFORE_SAPLING;
4141     }
4142
4143     // Prepare to get UTXOs and notes
4144     std::vector<MergeToAddressInputUTXO> utxoInputs;
4145     std::vector<MergeToAddressInputNote> noteInputs;
4146     CAmount mergedUTXOValue = 0;
4147     CAmount mergedNoteValue = 0;
4148     CAmount remainingUTXOValue = 0;
4149     CAmount remainingNoteValue = 0;
4150     size_t utxoCounter = 0;
4151     size_t noteCounter = 0;
4152     bool maxedOutUTXOsFlag = false;
4153     bool maxedOutNotesFlag = false;
4154     size_t mempoolLimit = (nUTXOLimit != 0) ? nUTXOLimit : (overwinterActive ? 0 : (size_t)GetArg("-mempooltxinputlimit", 0));
4155
4156     size_t estimatedTxSize = 200;  // tx overhead + wiggle room
4157     if (isToZaddr) {
4158         estimatedTxSize += JOINSPLIT_SIZE;
4159     }
4160
4161     if (useAny || useAnyUTXO || taddrs.size() > 0) {
4162         // Get available utxos
4163         vector<COutput> vecOutputs;
4164         pwalletMain->AvailableCoins(vecOutputs, true, NULL, false, false);
4165
4166         // Find unspent utxos and update estimated size
4167         for (const COutput& out : vecOutputs) {
4168             if (!out.fSpendable) {
4169                 continue;
4170             }
4171
4172             CTxDestination address;
4173             if (!ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) {
4174                 continue;
4175             }
4176             // If taddr is not wildcard "*", filter utxos
4177             if (taddrs.size() > 0 && !taddrs.count(address)) {
4178                 continue;
4179             }
4180
4181             utxoCounter++;
4182             CAmount nValue = out.tx->vout[out.i].nValue;
4183
4184             if (!maxedOutUTXOsFlag) {
4185                 size_t increase = (boost::get<CScriptID>(&address) != nullptr) ? CTXIN_SPEND_P2SH_SIZE : CTXIN_SPEND_DUST_SIZE;
4186                 if (estimatedTxSize + increase >= max_tx_size ||
4187                     (mempoolLimit > 0 && utxoCounter > mempoolLimit))
4188                 {
4189                     maxedOutUTXOsFlag = true;
4190                 } else {
4191                     estimatedTxSize += increase;
4192                     COutPoint utxo(out.tx->GetHash(), out.i);
4193                     utxoInputs.emplace_back(utxo, nValue);
4194                     mergedUTXOValue += nValue;
4195                 }
4196             }
4197
4198             if (maxedOutUTXOsFlag) {
4199                 remainingUTXOValue += nValue;
4200             }
4201         }
4202     }
4203
4204     if (useAny || useAnyNote || zaddrs.size() > 0) {
4205         // Get available notes
4206         std::vector<CSproutNotePlaintextEntry> entries;
4207         pwalletMain->GetFilteredNotes(entries, zaddrs);
4208
4209         // Find unspent notes and update estimated size
4210         for (CSproutNotePlaintextEntry& entry : entries) {
4211             noteCounter++;
4212             CAmount nValue = entry.plaintext.value();
4213
4214             if (!maxedOutNotesFlag) {
4215                 // If we haven't added any notes yet and the merge is to a
4216                 // z-address, we have already accounted for the first JoinSplit.
4217                 size_t increase = (noteInputs.empty() && !isToZaddr) || (noteInputs.size() % 2 == 0) ? JOINSPLIT_SIZE : 0;
4218                 if (estimatedTxSize + increase >= max_tx_size ||
4219                     (nNoteLimit > 0 && noteCounter > nNoteLimit))
4220                 {
4221                     maxedOutNotesFlag = true;
4222                 } else {
4223                     estimatedTxSize += increase;
4224                     // TODO: Add Sapling support
4225                     auto zaddr = boost::get<SproutPaymentAddress>(entry.address);
4226                     SproutSpendingKey zkey;
4227                     pwalletMain->GetSpendingKey(zaddr, zkey);
4228                     noteInputs.emplace_back(entry.jsop, entry.plaintext.note(zaddr), nValue, zkey);
4229                     mergedNoteValue += nValue;
4230                 }
4231             }
4232
4233             if (maxedOutNotesFlag) {
4234                 remainingNoteValue += nValue;
4235             }
4236         }
4237     }
4238
4239     size_t numUtxos = utxoInputs.size();
4240     size_t numNotes = noteInputs.size();
4241
4242     if (numUtxos == 0 && numNotes == 0) {
4243         throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Could not find any funds to merge.");
4244     }
4245
4246     // Sanity check: Don't do anything if:
4247     // - We only have one from address
4248     // - It's equal to toaddress
4249     // - The address only contains a single UTXO or note
4250     if (setAddress.size() == 1 && setAddress.count(destaddress) && (numUtxos + numNotes) == 1) {
4251         throw JSONRPCError(RPC_INVALID_PARAMETER, "Destination address is also the only source address, and all its funds are already merged.");
4252     }
4253
4254     CAmount mergedValue = mergedUTXOValue + mergedNoteValue;
4255     if (mergedValue < nFee) {
4256         throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS,
4257             strprintf("Insufficient funds, have %s, which is less than miners fee %s",
4258             FormatMoney(mergedValue), FormatMoney(nFee)));
4259     }
4260
4261     // Check that the user specified fee is sane (if too high, it can result in error -25 absurd fee)
4262     CAmount netAmount = mergedValue - nFee;
4263     if (nFee > netAmount) {
4264         throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Fee %s is greater than the net amount to be shielded %s", FormatMoney(nFee), FormatMoney(netAmount)));
4265     }
4266
4267     // Keep record of parameters in context object
4268     UniValue contextInfo(UniValue::VOBJ);
4269     contextInfo.push_back(Pair("fromaddresses", params[0]));
4270     contextInfo.push_back(Pair("toaddress", params[1]));
4271     contextInfo.push_back(Pair("fee", ValueFromAmount(nFee)));
4272
4273     // Contextual transaction we will build on
4274     CMutableTransaction contextualTx = CreateNewContextualCMutableTransaction(
4275         Params().GetConsensus(),
4276         nextBlockHeight);
4277     bool isShielded = numNotes > 0 || isToZaddr;
4278     if (contextualTx.nVersion == 1 && isShielded) {
4279         contextualTx.nVersion = 2; // Tx format should support vjoinsplit
4280     }
4281
4282     // Create operation and add to global queue
4283     std::shared_ptr<AsyncRPCQueue> q = getAsyncRPCQueue();
4284     std::shared_ptr<AsyncRPCOperation> operation(
4285         new AsyncRPCOperation_mergetoaddress(contextualTx, utxoInputs, noteInputs, recipient, nFee, contextInfo) );
4286     q->addOperation(operation);
4287     AsyncRPCOperationId operationId = operation->getId();
4288
4289     // Return continuation information
4290     UniValue o(UniValue::VOBJ);
4291     o.push_back(Pair("remainingUTXOs", static_cast<uint64_t>(utxoCounter - numUtxos)));
4292     o.push_back(Pair("remainingTransparentValue", ValueFromAmount(remainingUTXOValue)));
4293     o.push_back(Pair("remainingNotes", static_cast<uint64_t>(noteCounter - numNotes)));
4294     o.push_back(Pair("remainingShieldedValue", ValueFromAmount(remainingNoteValue)));
4295     o.push_back(Pair("mergingUTXOs", static_cast<uint64_t>(numUtxos)));
4296     o.push_back(Pair("mergingTransparentValue", ValueFromAmount(mergedUTXOValue)));
4297     o.push_back(Pair("mergingNotes", static_cast<uint64_t>(numNotes)));
4298     o.push_back(Pair("mergingShieldedValue", ValueFromAmount(mergedNoteValue)));
4299     o.push_back(Pair("opid", operationId));
4300     return o;
4301 }
4302
4303
4304 UniValue z_listoperationids(const UniValue& params, bool fHelp)
4305 {
4306     if (!EnsureWalletIsAvailable(fHelp))
4307         return NullUniValue;
4308
4309     if (fHelp || params.size() > 1)
4310         throw runtime_error(
4311             "z_listoperationids\n"
4312             "\nReturns the list of operation ids currently known to the wallet.\n"
4313             "\nArguments:\n"
4314             "1. \"status\"         (string, optional) Filter result by the operation's state e.g. \"success\".\n"
4315             "\nResult:\n"
4316             "[                     (json array of string)\n"
4317             "  \"operationid\"       (string) an operation id belonging to the wallet\n"
4318             "  ,...\n"
4319             "]\n"
4320             "\nExamples:\n"
4321             + HelpExampleCli("z_listoperationids", "")
4322             + HelpExampleRpc("z_listoperationids", "")
4323         );
4324
4325     LOCK2(cs_main, pwalletMain->cs_wallet);
4326
4327     std::string filter;
4328     bool useFilter = false;
4329     if (params.size()==1) {
4330         filter = params[0].get_str();
4331         useFilter = true;
4332     }
4333
4334     UniValue ret(UniValue::VARR);
4335     std::shared_ptr<AsyncRPCQueue> q = getAsyncRPCQueue();
4336     std::vector<AsyncRPCOperationId> ids = q->getAllOperationIds();
4337     for (auto id : ids) {
4338         std::shared_ptr<AsyncRPCOperation> operation = q->getOperationForId(id);
4339         if (!operation) {
4340             continue;
4341         }
4342         std::string state = operation->getStateAsString();
4343         if (useFilter && filter.compare(state)!=0)
4344             continue;
4345         ret.push_back(id);
4346     }
4347
4348     return ret;
4349 }
This page took 0.275498 seconds and 4 git commands to generate.