mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-20 15:19:07 +01:00
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:
@@ -1456,36 +1456,57 @@ public:
|
||||
bool operator()(const CScriptID &scriptID) const { return keystore->HaveCScript(scriptID); }
|
||||
};
|
||||
|
||||
bool IsMine(const CKeyStore &keystore, const CTxDestination &dest)
|
||||
isminetype IsMine(const CKeyStore &keystore, const CTxDestination &dest)
|
||||
{
|
||||
return boost::apply_visitor(CKeyStoreIsMineVisitor(&keystore), dest);
|
||||
if (boost::apply_visitor(CKeyStoreIsMineVisitor(&keystore), dest))
|
||||
return MINE_SPENDABLE;
|
||||
if (keystore.HaveWatchOnly(dest))
|
||||
return MINE_WATCH_ONLY;
|
||||
return MINE_NO;
|
||||
}
|
||||
|
||||
bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
|
||||
isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
|
||||
{
|
||||
vector<valtype> vSolutions;
|
||||
txnouttype whichType;
|
||||
if (!Solver(scriptPubKey, whichType, vSolutions))
|
||||
return false;
|
||||
if (!Solver(scriptPubKey, whichType, vSolutions)) {
|
||||
if (keystore.HaveWatchOnly(scriptPubKey.GetID()))
|
||||
return MINE_WATCH_ONLY;
|
||||
return MINE_NO;
|
||||
}
|
||||
|
||||
CKeyID keyID;
|
||||
switch (whichType)
|
||||
{
|
||||
case TX_NONSTANDARD:
|
||||
case TX_NULL_DATA:
|
||||
return false;
|
||||
break;
|
||||
case TX_PUBKEY:
|
||||
keyID = CPubKey(vSolutions[0]).GetID();
|
||||
return keystore.HaveKey(keyID);
|
||||
if (keystore.HaveKey(keyID))
|
||||
return MINE_SPENDABLE;
|
||||
if (keystore.HaveWatchOnly(keyID))
|
||||
return MINE_WATCH_ONLY;
|
||||
break;
|
||||
case TX_PUBKEYHASH:
|
||||
keyID = CKeyID(uint160(vSolutions[0]));
|
||||
return keystore.HaveKey(keyID);
|
||||
if (keystore.HaveKey(keyID))
|
||||
return MINE_SPENDABLE;
|
||||
if (keystore.HaveWatchOnly(keyID))
|
||||
return MINE_WATCH_ONLY;
|
||||
break;
|
||||
case TX_SCRIPTHASH:
|
||||
{
|
||||
CScriptID scriptID = CScriptID(uint160(vSolutions[0]));
|
||||
CScript subscript;
|
||||
if (!keystore.GetCScript(CScriptID(uint160(vSolutions[0])), subscript))
|
||||
return false;
|
||||
return IsMine(keystore, subscript);
|
||||
if (keystore.GetCScript(scriptID, subscript)) {
|
||||
isminetype ret = IsMine(keystore, subscript);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
if (keystore.HaveWatchOnly(scriptID))
|
||||
return MINE_WATCH_ONLY;
|
||||
break;
|
||||
}
|
||||
case TX_MULTISIG:
|
||||
{
|
||||
@@ -1495,10 +1516,15 @@ bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
|
||||
// them) enable spend-out-from-under-you attacks, especially
|
||||
// in shared-wallet situations.
|
||||
vector<valtype> keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1);
|
||||
return HaveKeys(keys, keystore) == keys.size();
|
||||
if (HaveKeys(keys, keystore) == keys.size())
|
||||
return MINE_SPENDABLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
if (keystore.HaveWatchOnly(scriptPubKey.GetID()))
|
||||
return MINE_WATCH_ONLY;
|
||||
return MINE_NO;
|
||||
}
|
||||
|
||||
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
|
||||
|
||||
Reference in New Issue
Block a user