You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

wallet.h 20KB

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