PPCoin: Combine FixSpentCoins and CheckSpentCoins
[novacoin.git] / src / wallet.h
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Copyright (c) 2011-2012 The PPCoin developers
4 // Distributed under the MIT/X11 software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 #ifndef BITCOIN_WALLET_H
7 #define BITCOIN_WALLET_H
8
9 #include "main.h"
10 #include "key.h"
11 #include "keystore.h"
12 #include "script.h"
13
14 extern bool fWalletUnlockMintOnly;
15
16 class CWalletTx;
17 class CReserveKey;
18 class CWalletDB;
19
20 /** (client) version numbers for particular wallet features */
21 enum WalletFeature
22 {
23     FEATURE_BASE = 10500, // the earliest version new wallets supports (only useful for getinfo's clientversion output)
24
25     FEATURE_WALLETCRYPT = 40000, // wallet encryption
26     FEATURE_COMPRPUBKEY = 60000, // compressed public keys
27
28     FEATURE_LATEST = 60000
29 };
30
31
32 /** A key pool entry */
33 class CKeyPool
34 {
35 public:
36     int64 nTime;
37     std::vector<unsigned char> vchPubKey;
38
39     CKeyPool()
40     {
41         nTime = GetTime();
42     }
43
44     CKeyPool(const std::vector<unsigned char>& vchPubKeyIn)
45     {
46         nTime = GetTime();
47         vchPubKey = vchPubKeyIn;
48     }
49
50     IMPLEMENT_SERIALIZE
51     (
52         if (!(nType & SER_GETHASH))
53             READWRITE(nVersion);
54         READWRITE(nTime);
55         READWRITE(vchPubKey);
56     )
57 };
58
59 /** A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,
60  * and provides the ability to create new transactions.
61  */
62 class CWallet : public CCryptoKeyStore
63 {
64 private:
65     bool SelectCoinsMinConf(int64 nTargetValue, unsigned int nSpendTime, int nConfMine, int nConfTheirs, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const;
66     bool SelectCoins(int64 nTargetValue, unsigned int nSpendTime, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const;
67
68     CWalletDB *pwalletdbEncryption;
69
70     // the current wallet version: clients below this version are not able to load the wallet
71     int nWalletVersion;
72
73     // the maxmimum wallet format version: memory-only variable that specifies to what version this wallet may be upgraded
74     int nWalletMaxVersion;
75
76 public:
77     mutable CCriticalSection cs_wallet;
78
79     bool fFileBacked;
80     std::string strWalletFile;
81
82     std::set<int64> setKeyPool;
83
84
85     typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
86     MasterKeyMap mapMasterKeys;
87     unsigned int nMasterKeyMaxID;
88
89     CWallet()
90     {
91         nWalletVersion = FEATURE_BASE;
92         nWalletMaxVersion = FEATURE_BASE;
93         fFileBacked = false;
94         nMasterKeyMaxID = 0;
95         pwalletdbEncryption = NULL;
96     }
97     CWallet(std::string strWalletFileIn)
98     {
99         nWalletVersion = FEATURE_BASE;
100         nWalletMaxVersion = FEATURE_BASE;
101         strWalletFile = strWalletFileIn;
102         fFileBacked = true;
103         nMasterKeyMaxID = 0;
104         pwalletdbEncryption = NULL;
105     }
106
107     std::map<uint256, CWalletTx> mapWallet;
108     std::vector<uint256> vWalletUpdated;
109
110     std::map<uint256, int> mapRequestCount;
111
112     std::map<CBitcoinAddress, std::string> mapAddressBook;
113
114     std::vector<unsigned char> vchDefaultKey;
115
116     // check whether we are allowed to upgrade (or already support) to the named feature
117     bool CanSupportFeature(enum WalletFeature wf) { return nWalletMaxVersion >= wf; }
118
119     // keystore implementation
120     // Generate a new key
121     std::vector<unsigned char> GenerateNewKey();
122     // Adds a key to the store, and saves it to disk.
123     bool AddKey(const CKey& key);
124     // Adds a key to the store, without saving it to disk (used by LoadWallet)
125     bool LoadKey(const CKey& key) { return CCryptoKeyStore::AddKey(key); }
126
127     bool LoadMinVersion(int nVersion) { nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; }
128
129     // Adds an encrypted key to the store, and saves it to disk.
130     bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
131     // Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
132     bool LoadCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret) { SetMinVersion(FEATURE_WALLETCRYPT); return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); }
133     bool AddCScript(const CScript& redeemScript);
134     bool LoadCScript(const CScript& redeemScript) { return CCryptoKeyStore::AddCScript(redeemScript); }
135
136     bool Unlock(const SecureString& strWalletPassphrase);
137     bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase);
138     bool EncryptWallet(const SecureString& strWalletPassphrase);
139
140     void MarkDirty();
141     bool AddToWallet(const CWalletTx& wtxIn);
142     bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate = false, bool fFindBlock = false);
143     bool EraseFromWallet(uint256 hash);
144     void WalletUpdateSpent(const CTransaction& prevout);
145     int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false);
146     int ScanForWalletTransaction(const uint256& hashTx);
147     void ReacceptWalletTransactions();
148     void ResendWalletTransactions();
149     int64 GetBalance() const;
150     int64 GetUnconfirmedBalance() const;
151     int64 GetStake() const;
152     int64 GetNewMint() const;
153     bool CreateTransaction(const std::vector<std::pair<CScript, int64> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
154     bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
155     bool CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64 nSearchInterval, CTransaction& txNew);
156     bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
157     std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
158     std::string SendMoneyToBitcoinAddress(const CBitcoinAddress& address, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
159
160     bool NewKeyPool();
161     bool TopUpKeyPool();
162     int64 AddReserveKey(const CKeyPool& keypool);
163     void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool);
164     void KeepKey(int64 nIndex);
165     void ReturnKey(int64 nIndex);
166     bool GetKeyFromPool(std::vector<unsigned char> &key, bool fAllowReuse=true);
167     int64 GetOldestKeyPoolTime();
168     void GetAllReserveAddresses(std::set<CBitcoinAddress>& setAddress);
169
170     bool IsMine(const CTxIn& txin) const;
171     int64 GetDebit(const CTxIn& txin) const;
172     bool IsMine(const CTxOut& txout) const
173     {
174         return ::IsMine(*this, txout.scriptPubKey);
175     }
176     int64 GetCredit(const CTxOut& txout) const
177     {
178         if (!MoneyRange(txout.nValue))
179             throw std::runtime_error("CWallet::GetCredit() : value out of range");
180         return (IsMine(txout) ? txout.nValue : 0);
181     }
182     bool IsChange(const CTxOut& txout) const;
183     int64 GetChange(const CTxOut& txout) const
184     {
185         if (!MoneyRange(txout.nValue))
186             throw std::runtime_error("CWallet::GetChange() : value out of range");
187         return (IsChange(txout) ? txout.nValue : 0);
188     }
189     bool IsMine(const CTransaction& tx) const
190     {
191         BOOST_FOREACH(const CTxOut& txout, tx.vout)
192             if (IsMine(txout))
193                 return true;
194         return false;
195     }
196     bool IsFromMe(const CTransaction& tx) const
197     {
198         return (GetDebit(tx) > 0);
199     }
200     int64 GetDebit(const CTransaction& tx) const
201     {
202         int64 nDebit = 0;
203         BOOST_FOREACH(const CTxIn& txin, tx.vin)
204         {
205             nDebit += GetDebit(txin);
206             if (!MoneyRange(nDebit))
207                 throw std::runtime_error("CWallet::GetDebit() : value out of range");
208         }
209         return nDebit;
210     }
211     int64 GetCredit(const CTransaction& tx) const
212     {
213         int64 nCredit = 0;
214         BOOST_FOREACH(const CTxOut& txout, tx.vout)
215         {
216             nCredit += GetCredit(txout);
217             if (!MoneyRange(nCredit))
218                 throw std::runtime_error("CWallet::GetCredit() : value out of range");
219         }
220         return nCredit;
221     }
222     int64 GetChange(const CTransaction& tx) const
223     {
224         int64 nChange = 0;
225         BOOST_FOREACH(const CTxOut& txout, tx.vout)
226         {
227             nChange += GetChange(txout);
228             if (!MoneyRange(nChange))
229                 throw std::runtime_error("CWallet::GetChange() : value out of range");
230         }
231         return nChange;
232     }
233     void SetBestChain(const CBlockLocator& loc);
234
235     int LoadWallet(bool& fFirstRunRet);
236
237     bool SetAddressBookName(const CBitcoinAddress& address, const std::string& strName);
238
239     bool DelAddressBookName(const CBitcoinAddress& address);
240
241     void UpdatedTransaction(const uint256 &hashTx)
242     {
243         {
244             LOCK(cs_wallet);
245             vWalletUpdated.push_back(hashTx);
246         }
247     }
248
249     void PrintWallet(const CBlock& block);
250
251     void Inventory(const uint256 &hash)
252     {
253         {
254             LOCK(cs_wallet);
255             std::map<uint256, int>::iterator mi = mapRequestCount.find(hash);
256             if (mi != mapRequestCount.end())
257                 (*mi).second++;
258         }
259     }
260
261     int GetKeyPoolSize()
262     {
263         return setKeyPool.size();
264     }
265
266     bool GetTransaction(const uint256 &hashTx, CWalletTx& wtx);
267
268     bool SetDefaultKey(const std::vector<unsigned char> &vchPubKey);
269
270     // signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower
271     bool SetMinVersion(enum WalletFeature, CWalletDB* pwalletdbIn = NULL, bool fExplicit = false);
272
273     // change which version we're allowed to upgrade to (note that this does not immediately imply upgrading to that format)
274     bool SetMaxVersion(int nVersion);
275
276     // get the current wallet format (the oldest client version guaranteed to understand this wallet)
277     int GetVersion() { return nWalletVersion; }
278
279     void FixSpentCoins(int& nMismatchSpent, int64& nBalanceInQuestion, bool fCheckOnly = false);
280     void DisableTransaction(const CTransaction &tx);
281 };
282
283 /** A key allocated from the key pool. */
284 class CReserveKey
285 {
286 protected:
287     CWallet* pwallet;
288     int64 nIndex;
289     std::vector<unsigned char> vchPubKey;
290 public:
291     CReserveKey(CWallet* pwalletIn)
292     {
293         nIndex = -1;
294         pwallet = pwalletIn;
295     }
296
297     ~CReserveKey()
298     {
299         if (!fShutdown)
300             ReturnKey();
301     }
302
303     void ReturnKey();
304     std::vector<unsigned char> GetReservedKey();
305     void KeepKey();
306 };
307
308
309 /** A transaction with a bunch of additional info that only the owner cares about. 
310  * It includes any unrecorded transactions needed to link it back to the block chain.
311  */
312 class CWalletTx : public CMerkleTx
313 {
314 private:
315     const CWallet* pwallet;
316
317 public:
318     std::vector<CMerkleTx> vtxPrev;
319     std::map<std::string, std::string> mapValue;
320     std::vector<std::pair<std::string, std::string> > vOrderForm;
321     unsigned int fTimeReceivedIsTxTime;
322     unsigned int nTimeReceived;  // time received by this node
323     char fFromMe;
324     std::string strFromAccount;
325     std::vector<char> vfSpent; // which outputs are already spent
326
327     // memory only
328     mutable bool fDebitCached;
329     mutable bool fCreditCached;
330     mutable bool fAvailableCreditCached;
331     mutable bool fChangeCached;
332     mutable int64 nDebitCached;
333     mutable int64 nCreditCached;
334     mutable int64 nAvailableCreditCached;
335     mutable int64 nChangeCached;
336
337     CWalletTx()
338     {
339         Init(NULL);
340     }
341
342     CWalletTx(const CWallet* pwalletIn)
343     {
344         Init(pwalletIn);
345     }
346
347     CWalletTx(const CWallet* pwalletIn, const CMerkleTx& txIn) : CMerkleTx(txIn)
348     {
349         Init(pwalletIn);
350     }
351
352     CWalletTx(const CWallet* pwalletIn, const CTransaction& txIn) : CMerkleTx(txIn)
353     {
354         Init(pwalletIn);
355     }
356
357     void Init(const CWallet* pwalletIn)
358     {
359         pwallet = pwalletIn;
360         vtxPrev.clear();
361         mapValue.clear();
362         vOrderForm.clear();
363         fTimeReceivedIsTxTime = false;
364         nTimeReceived = 0;
365         fFromMe = false;
366         strFromAccount.clear();
367         vfSpent.clear();
368         fDebitCached = false;
369         fCreditCached = false;
370         fAvailableCreditCached = false;
371         fChangeCached = false;
372         nDebitCached = 0;
373         nCreditCached = 0;
374         nAvailableCreditCached = 0;
375         nChangeCached = 0;
376     }
377
378     IMPLEMENT_SERIALIZE
379     (
380         CWalletTx* pthis = const_cast<CWalletTx*>(this);
381         if (fRead)
382             pthis->Init(NULL);
383         char fSpent = false;
384
385         if (!fRead)
386         {
387             pthis->mapValue["fromaccount"] = pthis->strFromAccount;
388
389             std::string str;
390             BOOST_FOREACH(char f, vfSpent)
391             {
392                 str += (f ? '1' : '0');
393                 if (f)
394                     fSpent = true;
395             }
396             pthis->mapValue["spent"] = str;
397         }
398
399         nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion,ser_action);
400         READWRITE(vtxPrev);
401         READWRITE(mapValue);
402         READWRITE(vOrderForm);
403         READWRITE(fTimeReceivedIsTxTime);
404         READWRITE(nTimeReceived);
405         READWRITE(fFromMe);
406         READWRITE(fSpent);
407
408         if (fRead)
409         {
410             pthis->strFromAccount = pthis->mapValue["fromaccount"];
411
412             if (mapValue.count("spent"))
413                 BOOST_FOREACH(char c, pthis->mapValue["spent"])
414                     pthis->vfSpent.push_back(c != '0');
415             else
416                 pthis->vfSpent.assign(vout.size(), fSpent);
417         }
418
419         pthis->mapValue.erase("fromaccount");
420         pthis->mapValue.erase("version");
421         pthis->mapValue.erase("spent");
422     )
423
424     // marks certain txout's as spent
425     // returns true if any update took place
426     bool UpdateSpent(const std::vector<char>& vfNewSpent)
427     {
428         bool fReturn = false;
429         for (unsigned int i = 0; i < vfNewSpent.size(); i++)
430         {
431             if (i == vfSpent.size())
432                 break;
433
434             if (vfNewSpent[i] && !vfSpent[i])
435             {
436                 vfSpent[i] = true;
437                 fReturn = true;
438                 fAvailableCreditCached = false;
439             }
440         }
441         return fReturn;
442     }
443
444     // make sure balances are recalculated
445     void MarkDirty()
446     {
447         fCreditCached = false;
448         fAvailableCreditCached = false;
449         fDebitCached = false;
450         fChangeCached = false;
451     }
452
453     void BindWallet(CWallet *pwalletIn)
454     {
455         pwallet = pwalletIn;
456         MarkDirty();
457     }
458
459     void MarkSpent(unsigned int nOut)
460     {
461         if (nOut >= vout.size())
462             throw std::runtime_error("CWalletTx::MarkSpent() : nOut out of range");
463         vfSpent.resize(vout.size());
464         if (!vfSpent[nOut])
465         {
466             vfSpent[nOut] = true;
467             fAvailableCreditCached = false;
468         }
469     }
470
471     void MarkUnspent(unsigned int nOut)
472     {
473         if (nOut >= vout.size())
474             throw std::runtime_error("CWalletTx::MarkUnspent() : nOut out of range");
475         vfSpent.resize(vout.size());
476         if (vfSpent[nOut])
477         {
478             vfSpent[nOut] = false;
479             fAvailableCreditCached = false;
480         }
481     }
482
483     bool IsSpent(unsigned int nOut) const
484     {
485         if (nOut >= vout.size())
486             throw std::runtime_error("CWalletTx::IsSpent() : nOut out of range");
487         if (nOut >= vfSpent.size())
488             return false;
489         return (!!vfSpent[nOut]);
490     }
491
492     int64 GetDebit() const
493     {
494         if (vin.empty())
495             return 0;
496         if (fDebitCached)
497             return nDebitCached;
498         nDebitCached = pwallet->GetDebit(*this);
499         fDebitCached = true;
500         return nDebitCached;
501     }
502
503     int64 GetCredit(bool fUseCache=true) const
504     {
505         // Must wait until coinbase is safely deep enough in the chain before valuing it
506         if ((IsCoinBase() || IsCoinStake()) && GetBlocksToMaturity() > 0)
507             return 0;
508
509         // GetBalance can assume transactions in mapWallet won't change
510         if (fUseCache && fCreditCached)
511             return nCreditCached;
512         nCreditCached = pwallet->GetCredit(*this);
513         fCreditCached = true;
514         return nCreditCached;
515     }
516
517     int64 GetAvailableCredit(bool fUseCache=true) const
518     {
519         // Must wait until coinbase is safely deep enough in the chain before valuing it
520         if ((IsCoinBase() || IsCoinStake()) && GetBlocksToMaturity() > 0)
521             return 0;
522
523         if (fUseCache && fAvailableCreditCached)
524             return nAvailableCreditCached;
525
526         int64 nCredit = 0;
527         for (unsigned int i = 0; i < vout.size(); i++)
528         {
529             if (!IsSpent(i))
530             {
531                 const CTxOut &txout = vout[i];
532                 nCredit += pwallet->GetCredit(txout);
533                 if (!MoneyRange(nCredit))
534                     throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
535             }
536         }
537
538         nAvailableCreditCached = nCredit;
539         fAvailableCreditCached = true;
540         return nCredit;
541     }
542
543
544     int64 GetChange() const
545     {
546         if (fChangeCached)
547             return nChangeCached;
548         nChangeCached = pwallet->GetChange(*this);
549         fChangeCached = true;
550         return nChangeCached;
551     }
552
553     void GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, std::list<std::pair<CBitcoinAddress, int64> >& listReceived,
554                     std::list<std::pair<CBitcoinAddress, int64> >& listSent, int64& nFee, std::string& strSentAccount) const;
555
556     void GetAccountAmounts(const std::string& strAccount, int64& nGenerated, int64& nReceived, 
557                            int64& nSent, int64& nFee) const;
558
559     bool IsFromMe() const
560     {
561         return (GetDebit() > 0);
562     }
563
564     bool IsConfirmed() const
565     {
566         // Quick answer in most cases
567         if (!IsFinal())
568             return false;
569         if (GetDepthInMainChain() >= 1)
570             return true;
571         if (!IsFromMe()) // using wtx's cached debit
572             return false;
573
574         // If no confirmations but it's from us, we can still
575         // consider it confirmed if all dependencies are confirmed
576         std::map<uint256, const CMerkleTx*> mapPrev;
577         std::vector<const CMerkleTx*> vWorkQueue;
578         vWorkQueue.reserve(vtxPrev.size()+1);
579         vWorkQueue.push_back(this);
580         for (unsigned int i = 0; i < vWorkQueue.size(); i++)
581         {
582             const CMerkleTx* ptx = vWorkQueue[i];
583
584             if (!ptx->IsFinal())
585                 return false;
586             if (ptx->GetDepthInMainChain() >= 1)
587                 continue;
588             if (!pwallet->IsFromMe(*ptx))
589                 return false;
590
591             if (mapPrev.empty())
592             {
593                 BOOST_FOREACH(const CMerkleTx& tx, vtxPrev)
594                     mapPrev[tx.GetHash()] = &tx;
595             }
596
597             BOOST_FOREACH(const CTxIn& txin, ptx->vin)
598             {
599                 if (!mapPrev.count(txin.prevout.hash))
600                     return false;
601                 vWorkQueue.push_back(mapPrev[txin.prevout.hash]);
602             }
603         }
604         return true;
605     }
606
607     bool WriteToDisk();
608
609     int64 GetTxTime() const;
610     int GetRequestCount() const;
611
612     void AddSupportingTransactions(CTxDB& txdb);
613
614     bool AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs=true);
615     bool AcceptWalletTransaction();
616
617     void RelayWalletTransaction(CTxDB& txdb);
618     void RelayWalletTransaction();
619 };
620
621
622 /** Private key that includes an expiration date in case it never gets used. */
623 class CWalletKey
624 {
625 public:
626     CPrivKey vchPrivKey;
627     int64 nTimeCreated;
628     int64 nTimeExpires;
629     std::string strComment;
630     //// todo: add something to note what created it (user, getnewaddress, change)
631     ////   maybe should have a map<string, string> property map
632
633     CWalletKey(int64 nExpires=0)
634     {
635         nTimeCreated = (nExpires ? GetTime() : 0);
636         nTimeExpires = nExpires;
637     }
638
639     IMPLEMENT_SERIALIZE
640     (
641         if (!(nType & SER_GETHASH))
642             READWRITE(nVersion);
643         READWRITE(vchPrivKey);
644         READWRITE(nTimeCreated);
645         READWRITE(nTimeExpires);
646         READWRITE(strComment);
647     )
648 };
649
650
651
652
653
654
655 /** Account information.
656  * Stored in wallet with key "acc"+string account name.
657  */
658 class CAccount
659 {
660 public:
661     std::vector<unsigned char> vchPubKey;
662
663     CAccount()
664     {
665         SetNull();
666     }
667
668     void SetNull()
669     {
670         vchPubKey.clear();
671     }
672
673     IMPLEMENT_SERIALIZE
674     (
675         if (!(nType & SER_GETHASH))
676             READWRITE(nVersion);
677         READWRITE(vchPubKey);
678     )
679 };
680
681
682
683 /** Internal transfers.
684  * Database key is acentry<account><counter>.
685  */
686 class CAccountingEntry
687 {
688 public:
689     std::string strAccount;
690     int64 nCreditDebit;
691     int64 nTime;
692     std::string strOtherAccount;
693     std::string strComment;
694
695     CAccountingEntry()
696     {
697         SetNull();
698     }
699
700     void SetNull()
701     {
702         nCreditDebit = 0;
703         nTime = 0;
704         strAccount.clear();
705         strOtherAccount.clear();
706         strComment.clear();
707     }
708
709     IMPLEMENT_SERIALIZE
710     (
711         if (!(nType & SER_GETHASH))
712             READWRITE(nVersion);
713         // Note: strAccount is serialized as part of the key, not here.
714         READWRITE(nCreditDebit);
715         READWRITE(nTime);
716         READWRITE(strOtherAccount);
717         READWRITE(strComment);
718     )
719 };
720
721 bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut);
722
723 #endif