]> Git Repo - VerusCoin.git/blob - src/wallet/rpcdump.cpp
test
[VerusCoin.git] / src / wallet / rpcdump.cpp
1 // Copyright (c) 2009-2014 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5 #include "base58.h"
6 #include "rpcserver.h"
7 #include "init.h"
8 #include "main.h"
9 #include "script/script.h"
10 #include "script/standard.h"
11 #include "sync.h"
12 #include "util.h"
13 #include "utiltime.h"
14 #include "wallet.h"
15
16 #include <fstream>
17 #include <stdint.h>
18
19 #include <boost/algorithm/string.hpp>
20 #include <boost/date_time/posix_time/posix_time.hpp>
21
22 #include "json/json_spirit_value.h"
23
24 using namespace json_spirit;
25 using namespace std;
26
27 void EnsureWalletIsUnlocked();
28 bool EnsureWalletIsAvailable(bool avoidException);
29
30 Value dumpwallet_impl(const Array& params, bool fHelp, bool fDumpZKeys);
31 Value importwallet_impl(const Array& params, bool fHelp, bool fImportZKeys);
32
33
34 std::string static EncodeDumpTime(int64_t nTime) {
35     return DateTimeStrFormat("%Y-%m-%dT%H:%M:%SZ", nTime);
36 }
37
38 int64_t static DecodeDumpTime(const std::string &str) {
39     static const boost::posix_time::ptime epoch = boost::posix_time::from_time_t(0);
40     static const std::locale loc(std::locale::classic(),
41         new boost::posix_time::time_input_facet("%Y-%m-%dT%H:%M:%SZ"));
42     std::istringstream iss(str);
43     iss.imbue(loc);
44     boost::posix_time::ptime ptime(boost::date_time::not_a_date_time);
45     iss >> ptime;
46     if (ptime.is_not_a_date_time())
47         return 0;
48     return (ptime - epoch).total_seconds();
49 }
50
51 std::string static EncodeDumpString(const std::string &str) {
52     std::stringstream ret;
53     BOOST_FOREACH(unsigned char c, str) {
54         if (c <= 32 || c >= 128 || c == '%') {
55             ret << '%' << HexStr(&c, &c + 1);
56         } else {
57             ret << c;
58         }
59     }
60     return ret.str();
61 }
62
63 std::string DecodeDumpString(const std::string &str) {
64     std::stringstream ret;
65     for (unsigned int pos = 0; pos < str.length(); pos++) {
66         unsigned char c = str[pos];
67         if (c == '%' && pos+2 < str.length()) {
68             c = (((str[pos+1]>>6)*9+((str[pos+1]-'0')&15)) << 4) | 
69                 ((str[pos+2]>>6)*9+((str[pos+2]-'0')&15));
70             pos += 2;
71         }
72         ret << c;
73     }
74     return ret.str();
75 }
76
77 Value importprivkey(const Array& params, bool fHelp)
78 {
79     if (!EnsureWalletIsAvailable(fHelp))
80         return Value::null;
81     
82     if (fHelp || params.size() < 1 || params.size() > 3)
83         throw runtime_error(
84             "importprivkey \"zcashprivkey\" ( \"label\" rescan )\n"
85             "\nAdds a private key (as returned by dumpprivkey) to your wallet.\n"
86             "\nArguments:\n"
87             "1. \"zcashprivkey\"   (string, required) The private key (see dumpprivkey)\n"
88             "2. \"label\"            (string, optional, default=\"\") An optional label\n"
89             "3. rescan               (boolean, optional, default=true) Rescan the wallet for transactions\n"
90             "\nNote: This call can take minutes to complete if rescan is true.\n"
91             "\nExamples:\n"
92             "\nDump a private key\n"
93             + HelpExampleCli("dumpprivkey", "\"myaddress\"") +
94             "\nImport the private key with rescan\n"
95             + HelpExampleCli("importprivkey", "\"mykey\"") +
96             "\nImport using a label and without rescan\n"
97             + HelpExampleCli("importprivkey", "\"mykey\" \"testing\" false") +
98             "\nAs a JSON-RPC call\n"
99             + HelpExampleRpc("importprivkey", "\"mykey\", \"testing\", false")
100         );
101
102     LOCK2(cs_main, pwalletMain->cs_wallet);
103
104     EnsureWalletIsUnlocked();
105
106     string strSecret = params[0].get_str();
107     string strLabel = "";
108     if (params.size() > 1)
109         strLabel = params[1].get_str();
110
111     // Whether to perform rescan after import
112     bool fRescan = true;
113     if (params.size() > 2)
114         fRescan = params[2].get_bool();
115
116     CBitcoinSecret vchSecret;
117     bool fGood = vchSecret.SetString(strSecret);
118
119     if (!fGood) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key encoding");
120
121     CKey key = vchSecret.GetKey();
122     if (!key.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");
123
124     CPubKey pubkey = key.GetPubKey();
125     assert(key.VerifyPubKey(pubkey));
126     CKeyID vchAddress = pubkey.GetID();
127     {
128         pwalletMain->MarkDirty();
129         pwalletMain->SetAddressBook(vchAddress, strLabel, "receive");
130
131         // Don't throw error in case a key is already there
132         if (pwalletMain->HaveKey(vchAddress))
133             return Value::null;
134
135         pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = 1;
136
137         if (!pwalletMain->AddKeyPubKey(key, pubkey))
138             throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet");
139
140         // whenever a key is imported, we need to scan the whole chain
141         pwalletMain->nTimeFirstKey = 1; // 0 would be considered 'no value'
142
143         if (fRescan) {
144             pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true);
145         }
146     }
147
148     return Value::null;
149 }
150
151 Value importaddress(const Array& params, bool fHelp)
152 {
153     if (!EnsureWalletIsAvailable(fHelp))
154         return Value::null;
155     
156     if (fHelp || params.size() < 1 || params.size() > 3)
157         throw runtime_error(
158             "importaddress \"address\" ( \"label\" rescan )\n"
159             "\nAdds an address or script (in hex) that can be watched as if it were in your wallet but cannot be used to spend.\n"
160             "\nArguments:\n"
161             "1. \"address\"          (string, required) The address\n"
162             "2. \"label\"            (string, optional, default=\"\") An optional label\n"
163             "3. rescan               (boolean, optional, default=true) Rescan the wallet for transactions\n"
164             "\nNote: This call can take minutes to complete if rescan is true.\n"
165             "\nExamples:\n"
166             "\nImport an address with rescan\n"
167             + HelpExampleCli("importaddress", "\"myaddress\"") +
168             "\nImport using a label without rescan\n"
169             + HelpExampleCli("importaddress", "\"myaddress\" \"testing\" false") +
170             "\nAs a JSON-RPC call\n"
171             + HelpExampleRpc("importaddress", "\"myaddress\", \"testing\", false")
172         );
173
174     LOCK2(cs_main, pwalletMain->cs_wallet);
175
176     CScript script;
177
178     CBitcoinAddress address(params[0].get_str());
179     if (address.IsValid()) {
180         script = GetScriptForDestination(address.Get());
181     } else if (IsHex(params[0].get_str())) {
182         std::vector<unsigned char> data(ParseHex(params[0].get_str()));
183         script = CScript(data.begin(), data.end());
184     } else {
185         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Komodo address or script");
186     }
187
188     string strLabel = "";
189     if (params.size() > 1)
190         strLabel = params[1].get_str();
191
192     // Whether to perform rescan after import
193     bool fRescan = true;
194     if (params.size() > 2)
195         fRescan = params[2].get_bool();
196
197     {
198         if (::IsMine(*pwalletMain, script) == ISMINE_SPENDABLE)
199             throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script");
200
201         // add to address book or update label
202         if (address.IsValid())
203             pwalletMain->SetAddressBook(address.Get(), strLabel, "receive");
204
205         // Don't throw error in case an address is already there
206         if (pwalletMain->HaveWatchOnly(script))
207             return Value::null;
208
209         pwalletMain->MarkDirty();
210
211         if (!pwalletMain->AddWatchOnly(script))
212             throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
213
214         if (fRescan)
215         {
216             pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true);
217             pwalletMain->ReacceptWalletTransactions();
218         }
219     }
220
221     return Value::null;
222 }
223
224 Value z_importwallet(const Array& params, bool fHelp)
225 {
226     if (!EnsureWalletIsAvailable(fHelp))
227         return Value::null;
228
229     if (fHelp || params.size() != 1)
230         throw runtime_error(
231             "z_importwallet \"filename\"\n"
232             "\nImports taddr and zaddr keys from a wallet export file (see z_exportwallet).\n"
233             "\nArguments:\n"
234             "1. \"filename\"    (string, required) The wallet file\n"
235             "\nExamples:\n"
236             "\nDump the wallet\n"
237             + HelpExampleCli("z_exportwallet", "\"test\"") +
238             "\nImport the wallet\n"
239             + HelpExampleCli("z_importwallet", "\"test\"") +
240             "\nImport using the json rpc call\n"
241             + HelpExampleRpc("z_importwallet", "\"test\"")
242         );
243
244         return importwallet_impl(params, fHelp, true);
245 }
246
247 Value importwallet(const Array& params, bool fHelp)
248 {
249     if (!EnsureWalletIsAvailable(fHelp))
250         return Value::null;
251     
252     if (fHelp || params.size() != 1)
253         throw runtime_error(
254             "importwallet \"filename\"\n"
255             "\nImports taddr keys from a wallet dump file (see dumpwallet).\n"
256             "\nArguments:\n"
257             "1. \"filename\"    (string, required) The wallet file\n"
258             "\nExamples:\n"
259             "\nDump the wallet\n"
260             + HelpExampleCli("dumpwallet", "\"test\"") +
261             "\nImport the wallet\n"
262             + HelpExampleCli("importwallet", "\"test\"") +
263             "\nImport using the json rpc call\n"
264             + HelpExampleRpc("importwallet", "\"test\"")
265         );
266
267         return importwallet_impl(params, fHelp, false);
268 }
269
270 Value importwallet_impl(const Array& params, bool fHelp, bool fImportZKeys)
271 {
272     LOCK2(cs_main, pwalletMain->cs_wallet);
273
274     EnsureWalletIsUnlocked();
275
276     ifstream file;
277     file.open(params[0].get_str().c_str(), std::ios::in | std::ios::ate);
278     if (!file.is_open())
279         throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file");
280
281     int64_t nTimeBegin = chainActive.Tip()->GetBlockTime();
282
283     bool fGood = true;
284
285     int64_t nFilesize = std::max((int64_t)1, (int64_t)file.tellg());
286     file.seekg(0, file.beg);
287
288     pwalletMain->ShowProgress(_("Importing..."), 0); // show progress dialog in GUI
289     while (file.good()) {
290         pwalletMain->ShowProgress("", std::max(1, std::min(99, (int)(((double)file.tellg() / (double)nFilesize) * 100))));
291         std::string line;
292         std::getline(file, line);
293         if (line.empty() || line[0] == '#')
294             continue;
295
296         std::vector<std::string> vstr;
297         boost::split(vstr, line, boost::is_any_of(" "));
298         if (vstr.size() < 2)
299             continue;
300
301         // Let's see if the address is a valid Zcash spending key
302         if (fImportZKeys) {
303             try {
304                 CZCSpendingKey spendingkey(vstr[0]);
305                 libzcash::SpendingKey key = spendingkey.Get();
306                 libzcash::PaymentAddress addr = key.address();
307                 if (pwalletMain->HaveSpendingKey(addr)) {
308                     LogPrint("zrpc", "Skipping import of zaddr %s (key already present)\n", CZCPaymentAddress(addr).ToString());
309                     continue;
310                 }
311                 int64_t nTime = DecodeDumpTime(vstr[1]);
312                 LogPrint("zrpc", "Importing zaddr %s...\n", CZCPaymentAddress(addr).ToString());
313                 if (!pwalletMain->AddZKey(key)) {
314                     // Something went wrong
315                     fGood = false;
316                     continue;
317                 }
318                 // Successfully imported zaddr.  Now import the metadata.
319                 pwalletMain->mapZKeyMetadata[addr].nCreateTime = nTime;
320                 continue;
321             }
322             catch (const std::runtime_error &e) {
323                 LogPrint("zrpc","Importing detected an error: %s\n", e.what());
324                 // Not a valid spending key, so carry on and see if it's a Zcash style address.
325             }
326         }
327
328         CBitcoinSecret vchSecret;
329         if (!vchSecret.SetString(vstr[0]))
330             continue;
331         CKey key = vchSecret.GetKey();
332         CPubKey pubkey = key.GetPubKey();
333         assert(key.VerifyPubKey(pubkey));
334         CKeyID keyid = pubkey.GetID();
335         if (pwalletMain->HaveKey(keyid)) {
336             LogPrintf("Skipping import of %s (key already present)\n", CBitcoinAddress(keyid).ToString());
337             continue;
338         }
339         int64_t nTime = DecodeDumpTime(vstr[1]);
340         std::string strLabel;
341         bool fLabel = true;
342         for (unsigned int nStr = 2; nStr < vstr.size(); nStr++) {
343             if (boost::algorithm::starts_with(vstr[nStr], "#"))
344                 break;
345             if (vstr[nStr] == "change=1")
346                 fLabel = false;
347             if (vstr[nStr] == "reserve=1")
348                 fLabel = false;
349             if (boost::algorithm::starts_with(vstr[nStr], "label=")) {
350                 strLabel = DecodeDumpString(vstr[nStr].substr(6));
351                 fLabel = true;
352             }
353         }
354         LogPrintf("Importing %s...\n", CBitcoinAddress(keyid).ToString());
355         if (!pwalletMain->AddKeyPubKey(key, pubkey)) {
356             fGood = false;
357             continue;
358         }
359         pwalletMain->mapKeyMetadata[keyid].nCreateTime = nTime;
360         if (fLabel)
361             pwalletMain->SetAddressBook(keyid, strLabel, "receive");
362         nTimeBegin = std::min(nTimeBegin, nTime);
363     }
364     file.close();
365     pwalletMain->ShowProgress("", 100); // hide progress dialog in GUI
366
367     CBlockIndex *pindex = chainActive.Tip();
368     while (pindex && pindex->pprev && pindex->GetBlockTime() > nTimeBegin - 7200)
369         pindex = pindex->pprev;
370
371     if (!pwalletMain->nTimeFirstKey || nTimeBegin < pwalletMain->nTimeFirstKey)
372         pwalletMain->nTimeFirstKey = nTimeBegin;
373
374     LogPrintf("Rescanning last %i blocks\n", chainActive.Height() - pindex->nHeight + 1);
375     pwalletMain->ScanForWalletTransactions(pindex);
376     pwalletMain->MarkDirty();
377
378     if (!fGood)
379         throw JSONRPCError(RPC_WALLET_ERROR, "Error adding some keys to wallet");
380
381     return Value::null;
382 }
383
384 Value dumpprivkey(const Array& params, bool fHelp)
385 {
386     if (!EnsureWalletIsAvailable(fHelp))
387         return Value::null;
388     
389     if (fHelp || params.size() != 1)
390         throw runtime_error(
391             "dumpprivkey \"zcashaddress\"\n"
392             "\nReveals the private key corresponding to 'zcashaddress'.\n"
393             "Then the importprivkey can be used with this output\n"
394             "\nArguments:\n"
395             "1. \"zcashaddress\"   (string, required) The zcash address for the private key\n"
396             "\nResult:\n"
397             "\"key\"                (string) The private key\n"
398             "\nExamples:\n"
399             + HelpExampleCli("dumpprivkey", "\"myaddress\"")
400             + HelpExampleCli("importprivkey", "\"mykey\"")
401             + HelpExampleRpc("dumpprivkey", "\"myaddress\"")
402         );
403
404     LOCK2(cs_main, pwalletMain->cs_wallet);
405
406     EnsureWalletIsUnlocked();
407
408     string strAddress = params[0].get_str();
409     CBitcoinAddress address;
410     if (!address.SetString(strAddress))
411         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Komodo address");
412     CKeyID keyID;
413     if (!address.GetKeyID(keyID))
414         throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to a key");
415     CKey vchSecret;
416     if (!pwalletMain->GetKey(keyID, vchSecret))
417         throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " + strAddress + " is not known");
418     return CBitcoinSecret(vchSecret).ToString();
419 }
420
421
422
423 Value z_exportwallet(const Array& params, bool fHelp)
424 {
425     if (!EnsureWalletIsAvailable(fHelp))
426         return Value::null;
427     
428     if (fHelp || params.size() != 1)
429         throw runtime_error(
430             "z_exportwallet \"filename\"\n"
431             "\nExports all wallet keys, for taddr and zaddr, in a human-readable format.\n"
432             "\nArguments:\n"
433             "1. \"filename\"    (string, required) The filename\n"
434             "\nExamples:\n"
435             + HelpExampleCli("z_exportwallet", "\"test\"")
436             + HelpExampleRpc("z_exportwallet", "\"test\"")
437         );
438
439         return dumpwallet_impl(params, fHelp, true);
440 }
441
442 Value dumpwallet(const Array& params, bool fHelp)
443 {
444     if (!EnsureWalletIsAvailable(fHelp))
445         return Value::null;
446
447     if (fHelp || params.size() != 1)
448         throw runtime_error(
449             "dumpwallet \"filename\"\n"
450             "\nDumps taddr wallet keys in a human-readable format.\n"
451             "\nArguments:\n"
452             "1. \"filename\"    (string, required) The filename\n"
453             "\nExamples:\n"
454             + HelpExampleCli("dumpwallet", "\"test\"")
455             + HelpExampleRpc("dumpwallet", "\"test\"")
456         );
457
458         return dumpwallet_impl(params, fHelp, false);
459 }
460
461 Value dumpwallet_impl(const Array& params, bool fHelp, bool fDumpZKeys)
462 {
463     LOCK2(cs_main, pwalletMain->cs_wallet);
464
465     EnsureWalletIsUnlocked();
466
467     ofstream file;
468     file.open(params[0].get_str().c_str());
469     if (!file.is_open())
470         throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file");
471
472     std::map<CKeyID, int64_t> mapKeyBirth;
473     std::set<CKeyID> setKeyPool;
474     pwalletMain->GetKeyBirthTimes(mapKeyBirth);
475     pwalletMain->GetAllReserveKeys(setKeyPool);
476
477     // sort time/key pairs
478     std::vector<std::pair<int64_t, CKeyID> > vKeyBirth;
479     for (std::map<CKeyID, int64_t>::const_iterator it = mapKeyBirth.begin(); it != mapKeyBirth.end(); it++) {
480         vKeyBirth.push_back(std::make_pair(it->second, it->first));
481     }
482     mapKeyBirth.clear();
483     std::sort(vKeyBirth.begin(), vKeyBirth.end());
484
485     // produce output
486     file << strprintf("# Wallet dump created by Komodo %s (%s)\n", CLIENT_BUILD, CLIENT_DATE);
487     file << strprintf("# * Created on %s\n", EncodeDumpTime(GetTime()));
488     file << strprintf("# * Best block at time of backup was %i (%s),\n", chainActive.Height(), chainActive.Tip()->GetBlockHash().ToString());
489     file << strprintf("#   mined on %s\n", EncodeDumpTime(chainActive.Tip()->GetBlockTime()));
490     file << "\n";
491     for (std::vector<std::pair<int64_t, CKeyID> >::const_iterator it = vKeyBirth.begin(); it != vKeyBirth.end(); it++) {
492         const CKeyID &keyid = it->second;
493         std::string strTime = EncodeDumpTime(it->first);
494         std::string strAddr = CBitcoinAddress(keyid).ToString();
495         CKey key;
496         if (pwalletMain->GetKey(keyid, key)) {
497             if (pwalletMain->mapAddressBook.count(keyid)) {
498                 file << strprintf("%s %s label=%s # addr=%s\n", CBitcoinSecret(key).ToString(), strTime, EncodeDumpString(pwalletMain->mapAddressBook[keyid].name), strAddr);
499             } else if (setKeyPool.count(keyid)) {
500                 file << strprintf("%s %s reserve=1 # addr=%s\n", CBitcoinSecret(key).ToString(), strTime, strAddr);
501             } else {
502                 file << strprintf("%s %s change=1 # addr=%s\n", CBitcoinSecret(key).ToString(), strTime, strAddr);
503             }
504         }
505     }
506     file << "\n";
507
508     if (fDumpZKeys) {
509         std::set<libzcash::PaymentAddress> addresses;
510         pwalletMain->GetPaymentAddresses(addresses);
511         file << "\n";
512         file << "# Zkeys\n";
513         file << "\n";
514         for (auto addr : addresses ) {
515             libzcash::SpendingKey key;
516             if (pwalletMain->GetSpendingKey(addr, key)) {
517                 std::string strTime = EncodeDumpTime(pwalletMain->mapZKeyMetadata[addr].nCreateTime);
518                 file << strprintf("%s %s # zaddr=%s\n", CZCSpendingKey(key).ToString(), strTime, CZCPaymentAddress(addr).ToString());
519             }
520         }
521         file << "\n";
522     }
523
524     file << "# End of dump\n";
525     file.close();
526     return Value::null;
527 }
528
529
530 Value z_importkey(const Array& params, bool fHelp)
531 {
532     if (!EnsureWalletIsAvailable(fHelp))
533         return Value::null;
534
535     if (fHelp || params.size() < 1 || params.size() > 2)
536         throw runtime_error(
537             "z_importkey \"zkey\" ( rescan )\n"
538             "\nAdds a zkey (as returned by z_exportkey) to your wallet.\n"
539             "\nArguments:\n"
540             "1. \"zkey\"             (string, required) The zkey (see z_exportkey)\n"
541             "2. rescan             (boolean, optional, default=true) Rescan the wallet for transactions\n"
542             "\nNote: This call can take minutes to complete if rescan is true.\n"
543             "\nExamples:\n"
544             "\nExport a zkey\n"
545             + HelpExampleCli("z_exportkey", "\"myaddress\"") +
546             "\nImport the zkey with rescan\n"
547             + HelpExampleCli("z_importkey", "\"mykey\"") +
548             "\nAs a JSON-RPC call\n"
549             + HelpExampleRpc("z_importkey", "\"mykey\", false")
550         );
551
552     LOCK2(cs_main, pwalletMain->cs_wallet);
553
554     EnsureWalletIsUnlocked();
555
556     // Whether to perform rescan after import
557     bool fRescan = true;
558     if (params.size() > 1)
559         fRescan = params[1].get_bool();
560
561     string strSecret = params[0].get_str();
562     CZCSpendingKey spendingkey(strSecret);
563     auto key = spendingkey.Get();
564     auto addr = key.address();
565
566     {
567         // Don't throw error in case a key is already there
568         if (pwalletMain->HaveSpendingKey(addr))
569             return Value::null;
570
571         pwalletMain->MarkDirty();
572
573         if (!pwalletMain-> AddZKey(key))
574             throw JSONRPCError(RPC_WALLET_ERROR, "Error adding spending key to wallet");
575
576         pwalletMain->mapZKeyMetadata[addr].nCreateTime = 1;
577
578         // We want to scan for transactions and notes
579         if (fRescan) {
580             pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true);
581         }
582     }
583
584     return Value::null;
585 }
586
587
588 Value z_exportkey(const Array& params, bool fHelp)
589 {
590     if (!EnsureWalletIsAvailable(fHelp))
591         return Value::null;
592
593     if (fHelp || params.size() != 1)
594         throw runtime_error(
595             "z_exportkey \"zaddr\"\n"
596             "\nReveals the zkey corresponding to 'zaddr'.\n"
597             "Then the z_importkey can be used with this output\n"
598             "\nArguments:\n"
599             "1. \"zaddr\"   (string, required) The zaddr for the private key\n"
600             "\nResult:\n"
601             "\"key\"                  (string) The private key\n"
602             "\nExamples:\n"
603             + HelpExampleCli("z_exportkey", "\"myaddress\"")
604             + HelpExampleCli("z_importkey", "\"mykey\"")
605             + HelpExampleRpc("z_exportkey", "\"myaddress\"")
606         );
607
608     LOCK2(cs_main, pwalletMain->cs_wallet);
609
610     EnsureWalletIsUnlocked();
611
612     string strAddress = params[0].get_str();
613
614     CZCPaymentAddress address(strAddress);
615     auto addr = address.Get();
616
617     libzcash::SpendingKey k;
618     if (!pwalletMain->GetSpendingKey(addr, k))
619         throw JSONRPCError(RPC_WALLET_ERROR, "Wallet does not hold private zkey for this zaddr");
620
621     CZCSpendingKey spendingkey(k);
622     return spendingkey.ToString();
623 }
624
This page took 0.061059 seconds and 4 git commands to generate.