-// Copyright (c) 2009-2011 Satoshi Nakamoto & Bitcoin developers
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2011 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
return true;
if (!IsCrypted())
return CWalletDB(strWalletFile).WriteKey(key.GetPubKey(), key.GetPrivKey());
+ return true;
}
bool CWallet::AddCryptedKey(const vector<unsigned char> &vchPubKey, const vector<unsigned char> &vchCryptedSecret)
bool CWallet::EncryptWallet(const string& strWalletPassphrase)
{
- CRITICAL_BLOCK(cs_mapPubKeys)
CRITICAL_BLOCK(cs_KeyStore)
CRITICAL_BLOCK(cs_vMasterKey)
CRITICAL_BLOCK(cs_pwalletdbEncryption)
if (fInsertedNew || fUpdated)
if (!wtx.WriteToDisk())
return false;
-
+#ifndef QT_GUI
// If default receiving address gets used, replace it with a new one
CScript scriptDefaultKey;
scriptDefaultKey.SetBitcoinAddress(vchDefaultKey);
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
{
if (txout.scriptPubKey == scriptDefaultKey)
+ {
SetDefaultKey(GetOrReuseKeyFromPool());
+ SetAddressBookName(CBitcoinAddress(vchDefaultKey), "");
+ }
}
-
+#endif
// Notify UI
vWalletUpdated.push_back(hash);
return nRequests;
}
-void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, list<pair<string, int64> >& listReceived,
- list<pair<string, int64> >& listSent, int64& nFee, string& strSentAccount) const
+void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, list<pair<CBitcoinAddress, int64> >& listReceived,
+ list<pair<CBitcoinAddress, int64> >& listSent, int64& nFee, string& strSentAccount) const
{
nGeneratedImmature = nGeneratedMature = nFee = 0;
listReceived.clear();
// but non-standard clients might (so return a list of address/amount pairs)
BOOST_FOREACH(const CTxOut& txout, vout)
{
- string address;
- uint160 hash160;
+ CBitcoinAddress address;
vector<unsigned char> vchPubKey;
- if (ExtractHash160(txout.scriptPubKey, hash160))
- address = Hash160ToAddress(hash160);
- else if (ExtractPubKey(txout.scriptPubKey, NULL, vchPubKey))
- address = PubKeyToAddress(vchPubKey);
- else
+ if (!ExtractAddress(txout.scriptPubKey, NULL, address))
{
printf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
this->GetHash().ToString().c_str());
int64 allGeneratedImmature, allGeneratedMature, allFee;
allGeneratedImmature = allGeneratedMature = allFee = 0;
string strSentAccount;
- list<pair<string, int64> > listReceived;
- list<pair<string, int64> > listSent;
+ list<pair<CBitcoinAddress, int64> > listReceived;
+ list<pair<CBitcoinAddress, int64> > listSent;
GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount);
if (strAccount == "")
nGenerated = allGeneratedMature;
if (strAccount == strSentAccount)
{
- BOOST_FOREACH(const PAIRTYPE(string,int64)& s, listSent)
+ BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& s, listSent)
nSent += s.second;
nFee = allFee;
}
CRITICAL_BLOCK(pwallet->cs_mapAddressBook)
{
- BOOST_FOREACH(const PAIRTYPE(string,int64)& r, listReceived)
+ BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listReceived)
{
if (pwallet->mapAddressBook.count(r.first))
{
- map<string, string>::const_iterator mi = pwallet->mapAddressBook.find(r.first);
+ map<CBitcoinAddress, string>::const_iterator mi = pwallet->mapAddressBook.find(r.first);
if (mi != pwallet->mapAddressBook.end() && (*mi).second == strAccount)
nReceived += r.second;
}
return nTotal;
}
+int64 CWallet::GetUnconfirmedBalance() const
+{
+ int64 nTotal = 0;
+ CRITICAL_BLOCK(cs_mapWallet)
+ {
+ for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
+ {
+ const CWalletTx* pcoin = &(*it).second;
+ if (pcoin->IsFinal() && pcoin->IsConfirmed())
+ continue;
+ nTotal += pcoin->GetAvailableCredit();
+ }
+ }
+ return nTotal;
+}
bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const
{
dPriority += (double)nCredit * pcoin.first->GetDepthInMainChain();
}
- // Fill a vout back to self with any change
- int64 nChange = nValueIn - nTotalValue;
- if (nChange >= CENT)
+ int64 nChange = nValueIn - nValue - nFeeRet;
+ // if sub-cent change is required, the fee must be raised to at least MIN_TX_FEE
+ // or until nChange becomes zero
+ if (nFeeRet < MIN_TX_FEE && nChange > 0 && nChange < CENT)
+ {
+ int64 nMoveToFee = min(nChange, MIN_TX_FEE - nFeeRet);
+ nChange -= nMoveToFee;
+ nFeeRet += nMoveToFee;
+ }
+
+ if (nChange > 0)
{
// Note: We use a new key here to keep it from being obvious which side is the change.
// The drawback is that by not reusing a previous key, the change may be lost if a
// Fill a vout to ourself, using same address type as the payment
CScript scriptChange;
- if (vecSend[0].first.GetBitcoinAddressHash160() != 0)
+ if (vecSend[0].first.GetBitcoinAddress().IsValid())
scriptChange.SetBitcoinAddress(vchPubKey);
else
scriptChange << vchPubKey << OP_CHECKSIG;
// requires cs_main lock
-string CWallet::SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
+string CWallet::SendMoneyToBitcoinAddress(const CBitcoinAddress& address, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
{
// Check amount
if (nValue <= 0)
// Parse bitcoin address
CScript scriptPubKey;
- if (!scriptPubKey.SetBitcoinAddress(strAddress))
- return _("Invalid bitcoin address");
+ scriptPubKey.SetBitcoinAddress(address);
return SendMoney(scriptPubKey, nValue, wtxNew, fAskFee);
}
-bool CWallet::LoadWallet(bool& fFirstRunRet)
+int CWallet::LoadWallet(bool& fFirstRunRet)
{
if (!fFileBacked)
return false;
return nLoadWalletRet;
fFirstRunRet = vchDefaultKey.empty();
- if (!HaveKey(vchDefaultKey))
+ if (!HaveKey(Hash160(vchDefaultKey)))
{
// Create new keyUser and set as default key
RandAddSeedPerfmon();
SetDefaultKey(GetOrReuseKeyFromPool());
- if (!SetAddressBookName(PubKeyToAddress(vchDefaultKey), ""))
- return false;
+ if (!SetAddressBookName(CBitcoinAddress(vchDefaultKey), ""))
+ return DB_LOAD_FAIL;
}
CreateThread(ThreadFlushWalletDB, &strWalletFile);
- return true;
+ return DB_LOAD_OK;
}
-bool CWallet::SetAddressBookName(const string& strAddress, const string& strName)
+bool CWallet::SetAddressBookName(const CBitcoinAddress& address, const string& strName)
{
- mapAddressBook[strAddress] = strName;
+ mapAddressBook[address] = strName;
if (!fFileBacked)
return false;
- return CWalletDB(strWalletFile).WriteName(strAddress, strName);
+ return CWalletDB(strWalletFile).WriteName(address.ToString(), strName);
}
-bool CWallet::DelAddressBookName(const string& strAddress)
+bool CWallet::DelAddressBookName(const CBitcoinAddress& address)
{
- mapAddressBook.erase(strAddress);
+ mapAddressBook.erase(address);
if (!fFileBacked)
return false;
- return CWalletDB(strWalletFile).EraseName(strAddress);
+ return CWalletDB(strWalletFile).EraseName(address.ToString());
}
setKeyPool.erase(setKeyPool.begin());
if (!walletdb.ReadPool(nIndex, keypool))
throw runtime_error("ReserveKeyFromKeyPool() : read failed");
- if (!HaveKey(keypool.vchPubKey))
+ if (!HaveKey(Hash160(keypool.vchPubKey)))
throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool");
assert(!keypool.vchPubKey.empty());
printf("keypool reserve %"PRI64d"\n", nIndex);
{
CKeyPool keypool;
pwallet->ReserveKeyFromKeyPool(nIndex, keypool);
- vchPubKey = keypool.vchPubKey;
+ if (nIndex != -1)
+ vchPubKey = keypool.vchPubKey;
+ else
+ {
+ printf("CReserveKey::GetReservedKey(): Warning: using default key instead of a new key, top up your keypool.");
+ vchPubKey = pwallet->vchDefaultKey;
+ }
}
assert(!vchPubKey.empty());
return vchPubKey;