Use script matching rather than destination matching for watch-only.

This changes the keystore data format, wallet format and IsMine logic
to detect watch-only outputs based on direct script matching rather
than first trying to convert outputs to destinations (addresses).

The reason is that we don't know how the software that has the spending
keys works. It may support the same types of scripts as us, but that is
not guaranteed. Furthermore, it removes the ambiguity between addresses
used as identifiers for output scripts or identifiers for public keys.

One practical implication is that adding a normal pay-to-pubkey-hash
address via importaddress will not cause payments to the corresponding
full public key to be detected as IsMine. If that is wanted, add those
scripts directly (importaddress now also accepts any hex-encoded script).

Conflicts:
	src/wallet.cpp
This commit is contained in:
Pieter Wuille
2014-06-09 21:11:59 +02:00
committed by JaSK
parent 0fa2f8899a
commit d5087d1ba0
9 changed files with 47 additions and 47 deletions

View File

@@ -145,7 +145,7 @@ bool CWallet::LoadCScript(const CScript& redeemScript)
return CCryptoKeyStore::AddCScript(redeemScript);
}
bool CWallet::AddWatchOnly(const CTxDestination &dest)
bool CWallet::AddWatchOnly(const CScript &dest)
{
if (!CCryptoKeyStore::AddWatchOnly(dest))
return false;
@@ -155,9 +155,8 @@ bool CWallet::AddWatchOnly(const CTxDestination &dest)
return CWalletDB(strWalletFile).WriteWatchOnly(dest);
}
bool CWallet::LoadWatchOnly(const CTxDestination &dest)
bool CWallet::LoadWatchOnly(const CScript &dest)
{
LogPrintf("Loaded %s!\n", CBitcoinAddress(dest).ToString().c_str());
return CCryptoKeyStore::AddWatchOnly(dest);
}
@@ -729,17 +728,19 @@ int64_t CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const
bool CWallet::IsChange(const CTxOut& txout) const
{
CTxDestination address;
// TODO: fix handling of 'change' outputs. The assumption is that any
// payment to a TX_PUBKEYHASH that is mine but isn't in the address book
// payment to a script that is ours, but is not in the address book
// is change. That assumption is likely to break when we implement multisignature
// wallets that return change back into a multi-signature-protected address;
// a better way of identifying which outputs are 'the send' and which are
// 'the change' will need to be implemented (maybe extend CWalletTx to remember
// which output, if any, was change).
if (ExtractDestination(txout.scriptPubKey, address) && ::IsMine(*this, address) == MINE_SPENDABLE)
if (::IsMine(*this, txout.scriptPubKey))
{
CTxDestination address;
if (!ExtractDestination(txout.scriptPubKey, address))
return true;
LOCK(cs_wallet);
if (!mapAddressBook.count(address))
return true;