From bf798734db4539a39edd6badf54a1c3aecf193e5 Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Wed, 28 Sep 2011 12:30:06 -0400 Subject: Support 3 new multisignature IsStandard transactions Initial support for (a and b), (a or b), and 2-of-3 escrow transactions (where a, b, and c are keys). --- src/wallet.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/wallet.cpp') diff --git a/src/wallet.cpp b/src/wallet.cpp index 87f5dfd65..a662111d4 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -997,12 +997,11 @@ bool CWallet::CreateTransaction(const vector >& vecSend, CW vector vchPubKey = reservekey.GetReservedKey(); // assert(mapKeys.count(vchPubKey)); - // Fill a vout to ourself, using same address type as the payment + // Fill a vout to ourself + // TODO: pass in scriptChange instead of reservekey so + // change transaction isn't always pay-to-bitcoin-address CScript scriptChange; - if (vecSend[0].first.GetBitcoinAddress().IsValid()) - scriptChange.SetBitcoinAddress(vchPubKey); - else - scriptChange << vchPubKey << OP_CHECKSIG; + scriptChange.SetBitcoinAddress(vchPubKey); // Insert change txn at random position: vector::iterator position = wtxNew.vout.begin()+GetRandInt(wtxNew.vout.size()); -- cgit v1.2.3 From e679ec969c8b22c676ebb10bea1038f6c8f13b33 Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Mon, 3 Oct 2011 13:05:43 -0400 Subject: OP_EVAL implementation OP_EVAL is a new opcode that evaluates an item on the stack as a script. It enables a new type of bitcoin address that needs an arbitrarily complex script to redeem. --- src/wallet.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'src/wallet.cpp') diff --git a/src/wallet.cpp b/src/wallet.cpp index a662111d4..5d44b1fb8 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -42,6 +42,15 @@ bool CWallet::AddCryptedKey(const vector &vchPubKey, const vector return false; } +bool CWallet::AddCScript(const uint160 &hash, const std::vector& data) +{ + if (!CCryptoKeyStore::AddCScript(hash, data)) + return false; + if (!fFileBacked) + return true; + return CWalletDB(strWalletFile).WriteCScript(hash, data); +} + bool CWallet::Unlock(const SecureString& strWalletPassphrase) { if (!IsLocked()) @@ -374,6 +383,16 @@ int64 CWallet::GetDebit(const CTxIn &txin) const return 0; } +bool CWallet::IsChange(const CTxOut& txout) const +{ + CBitcoinAddress address; + if (ExtractAddress(txout.scriptPubKey, this, address) && !address.IsScript()) + CRITICAL_BLOCK(cs_wallet) + if (!mapAddressBook.count(address)) + return true; + return false; +} + int64 CWalletTx::GetTxTime() const { return nTimeReceived; @@ -443,8 +462,7 @@ void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, l nFee = nDebit - nValueOut; } - // Sent/received. Standard client will never generate a send-to-multiple-recipients, - // but non-standard clients might (so return a list of address/amount pairs) + // Sent/received. BOOST_FOREACH(const CTxOut& txout, vout) { CBitcoinAddress address; -- cgit v1.2.3 From 2a45a494b0bec6a0f1fc6ab7f26c260b85e7ff3e Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Tue, 8 Nov 2011 13:20:29 -0500 Subject: Use block times for 'hard' OP_EVAL switchover, and refactored EvalScript so it takes a flag for how to interpret OP_EVAL. Also increased IsStandard size of scriptSigs to 500 bytes, so a 3-of-3 multisig transaction IsStandard. --- src/wallet.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src/wallet.cpp') diff --git a/src/wallet.cpp b/src/wallet.cpp index 5d44b1fb8..25eb6247f 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -42,13 +42,13 @@ bool CWallet::AddCryptedKey(const vector &vchPubKey, const vector return false; } -bool CWallet::AddCScript(const uint160 &hash, const std::vector& data) +bool CWallet::AddCScript(const uint160 &hash, const CScript& redeemScript) { - if (!CCryptoKeyStore::AddCScript(hash, data)) + if (!CCryptoKeyStore::AddCScript(hash, redeemScript)) return false; if (!fFileBacked) return true; - return CWalletDB(strWalletFile).WriteCScript(hash, data); + return CWalletDB(strWalletFile).WriteCScript(hash, redeemScript); } bool CWallet::Unlock(const SecureString& strWalletPassphrase) @@ -386,6 +386,14 @@ int64 CWallet::GetDebit(const CTxIn &txin) const bool CWallet::IsChange(const CTxOut& txout) const { CBitcoinAddress 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 + // 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 (ExtractAddress(txout.scriptPubKey, this, address) && !address.IsScript()) CRITICAL_BLOCK(cs_wallet) if (!mapAddressBook.count(address)) -- cgit v1.2.3 From be237c119e82a4c01f4ef3da4264faa6c900e9e3 Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Mon, 5 Dec 2011 10:32:35 -0500 Subject: Fix logic for IsChange() for send-to-self transactions. --- src/wallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/wallet.cpp') diff --git a/src/wallet.cpp b/src/wallet.cpp index 25eb6247f..3dc804c85 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -394,7 +394,7 @@ bool CWallet::IsChange(const CTxOut& txout) const // 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 (ExtractAddress(txout.scriptPubKey, this, address) && !address.IsScript()) + if (ExtractAddress(txout.scriptPubKey, this, address)) CRITICAL_BLOCK(cs_wallet) if (!mapAddressBook.count(address)) return true; -- cgit v1.2.3