Add support for watch-only addresses
Changes: * Add Add/Have WatchOnly methods to CKeyStore, and implementations in CBasicKeyStore. * Add similar methods to CWallet, and support entries for it in CWalletDB. * Make IsMine in script/wallet return a new enum 'isminetype', rather than a boolean. This allows distinguishing between spendable and unspendable coins. * Add a field fSpendable to COutput (GetAvailableCoins' return type). * Mark watchonly coins in listunspent as 'watchonly': true. * Add 'watchonly' to validateaddress, suppressing script/pubkey/... in this case. Based on a patch by Eric Lombrozo. Conflicts: src/qt/walletmodel.cpp src/rpcserver.cpp src/wallet.cpp
This commit is contained in:
@@ -145,6 +145,22 @@ bool CWallet::LoadCScript(const CScript& redeemScript)
|
||||
return CCryptoKeyStore::AddCScript(redeemScript);
|
||||
}
|
||||
|
||||
bool CWallet::AddWatchOnly(const CTxDestination &dest)
|
||||
{
|
||||
if (!CCryptoKeyStore::AddWatchOnly(dest))
|
||||
return false;
|
||||
nTimeFirstKey = 1; // No birthday information for watch-only keys.
|
||||
if (!fFileBacked)
|
||||
return true;
|
||||
return CWalletDB(strWalletFile).WriteWatchOnly(dest);
|
||||
}
|
||||
|
||||
bool CWallet::LoadWatchOnly(const CTxDestination &dest)
|
||||
{
|
||||
LogPrintf("Loaded %s!\n", CBitcoinAddress(dest).ToString().c_str());
|
||||
return CCryptoKeyStore::AddWatchOnly(dest);
|
||||
}
|
||||
|
||||
bool CWallet::Unlock(const SecureString& strWalletPassphrase)
|
||||
{
|
||||
CCrypter crypter;
|
||||
@@ -680,7 +696,7 @@ void CWallet::EraseFromWallet(const uint256 &hash)
|
||||
}
|
||||
|
||||
|
||||
bool CWallet::IsMine(const CTxIn &txin) const
|
||||
isminetype CWallet::IsMine(const CTxIn &txin) const
|
||||
{
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
@@ -689,11 +705,10 @@ bool CWallet::IsMine(const CTxIn &txin) const
|
||||
{
|
||||
const CWalletTx& prev = (*mi).second;
|
||||
if (txin.prevout.n < prev.vout.size())
|
||||
if (IsMine(prev.vout[txin.prevout.n]))
|
||||
return true;
|
||||
return IsMine(prev.vout[txin.prevout.n]);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return MINE_NO;
|
||||
}
|
||||
|
||||
int64_t CWallet::GetDebit(const CTxIn &txin) const
|
||||
@@ -1051,7 +1066,7 @@ int64_t CWallet::GetImmatureBalance() const
|
||||
return nTotal;
|
||||
}
|
||||
|
||||
// populate vCoins with vector of spendable COutputs
|
||||
// populate vCoins with vector of available COutputs.
|
||||
void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl) const
|
||||
{
|
||||
vCoins.clear();
|
||||
@@ -1077,10 +1092,11 @@ void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const
|
||||
continue;
|
||||
|
||||
for (unsigned int i = 0; i < pcoin->vout.size(); i++) {
|
||||
if (!(IsSpent(wtxid, i)) && IsMine(pcoin->vout[i]) &&
|
||||
isminetype mine = IsMine(pcoin->vout[i]);
|
||||
if (!(IsSpent(wtxid, i)) && mine != MINE_NO &&
|
||||
!IsLockedCoin((*it).first, i) && pcoin->vout[i].nValue > 0 &&
|
||||
(!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i)))
|
||||
vCoins.push_back(COutput(pcoin, i, nDepth));
|
||||
vCoins.push_back(COutput(pcoin, i, nDepth, mine & MINE_SPENDABLE));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1147,8 +1163,11 @@ bool CWallet::SelectCoinsMinConf(int64_t nTargetValue, int nConfMine, int nConfT
|
||||
|
||||
random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
|
||||
|
||||
BOOST_FOREACH(COutput output, vCoins)
|
||||
BOOST_FOREACH(const COutput &output, vCoins)
|
||||
{
|
||||
if (!output.fSpendable)
|
||||
continue;
|
||||
|
||||
const CWalletTx *pcoin = output.tx;
|
||||
|
||||
if (output.nDepth < (pcoin->IsFromMe() ? nConfMine : nConfTheirs))
|
||||
|
||||
Reference in New Issue
Block a user