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