Make BaseSignatureCreator a pure interface

This commit is contained in:
Pieter Wuille 2018-03-27 13:15:10 -07:00
parent 8d651ae320
commit 190b8d2dcf
7 changed files with 39 additions and 45 deletions

View File

@ -644,7 +644,7 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)
SignatureData sigdata; SignatureData sigdata;
// Only sign SIGHASH_SINGLE if there's a corresponding output: // Only sign SIGHASH_SINGLE if there's a corresponding output:
if (!fHashSingle || (i < mergedTx.vout.size())) if (!fHashSingle || (i < mergedTx.vout.size()))
ProduceSignature(MutableTransactionSignatureCreator(&keystore, &mergedTx, i, amount, nHashType), prevPubKey, sigdata); ProduceSignature(keystore, MutableTransactionSignatureCreator(&mergedTx, i, amount, nHashType), prevPubKey, sigdata);
// ... and merge in other signatures: // ... and merge in other signatures:
for (const CTransaction& txv : txVariants) for (const CTransaction& txv : txVariants)

View File

@ -831,7 +831,7 @@ UniValue SignTransaction(CMutableTransaction& mtx, const UniValue& prevTxsUnival
SignatureData sigdata; SignatureData sigdata;
// Only sign SIGHASH_SINGLE if there's a corresponding output: // Only sign SIGHASH_SINGLE if there's a corresponding output:
if (!fHashSingle || (i < mtx.vout.size())) { if (!fHashSingle || (i < mtx.vout.size())) {
ProduceSignature(MutableTransactionSignatureCreator(keystore, &mtx, i, amount, nHashType), prevPubKey, sigdata); ProduceSignature(*keystore, MutableTransactionSignatureCreator(&mtx, i, amount, nHashType), prevPubKey, sigdata);
} }
sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(mtx, i)); sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(mtx, i));

View File

@ -146,7 +146,7 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey, bool&
if (keystore.HaveWatchOnly(scriptPubKey)) { if (keystore.HaveWatchOnly(scriptPubKey)) {
// TODO: This could be optimized some by doing some work after the above solver // TODO: This could be optimized some by doing some work after the above solver
SignatureData sigs; SignatureData sigs;
return ProduceSignature(DummySignatureCreator(&keystore), scriptPubKey, sigs) ? ISMINE_WATCH_SOLVABLE : ISMINE_WATCH_UNSOLVABLE; return ProduceSignature(keystore, DummySignatureCreator(), scriptPubKey, sigs) ? ISMINE_WATCH_SOLVABLE : ISMINE_WATCH_UNSOLVABLE;
} }
return ISMINE_NO; return ISMINE_NO;
} }

View File

@ -14,12 +14,12 @@
typedef std::vector<unsigned char> valtype; typedef std::vector<unsigned char> valtype;
TransactionSignatureCreator::TransactionSignatureCreator(const SigningProvider* provider, const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : BaseSignatureCreator(provider), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn) {} TransactionSignatureCreator::TransactionSignatureCreator(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn) {}
bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& address, const CScript& scriptCode, SigVersion sigversion) const bool TransactionSignatureCreator::CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& address, const CScript& scriptCode, SigVersion sigversion) const
{ {
CKey key; CKey key;
if (!m_provider->GetKey(address, key)) if (!provider.GetKey(address, key))
return false; return false;
// Signing with uncompressed keys is disabled in witness scripts // Signing with uncompressed keys is disabled in witness scripts
@ -33,16 +33,16 @@ bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig,
return true; return true;
} }
static bool Sign1(const CKeyID& address, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector<valtype>& ret, SigVersion sigversion) static bool Sign1(const SigningProvider& provider, const CKeyID& address, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector<valtype>& ret, SigVersion sigversion)
{ {
std::vector<unsigned char> vchSig; std::vector<unsigned char> vchSig;
if (!creator.CreateSig(vchSig, address, scriptCode, sigversion)) if (!creator.CreateSig(provider, vchSig, address, scriptCode, sigversion))
return false; return false;
ret.push_back(vchSig); ret.push_back(vchSig);
return true; return true;
} }
static bool SignN(const std::vector<valtype>& multisigdata, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector<valtype>& ret, SigVersion sigversion) static bool SignN(const SigningProvider& provider, const std::vector<valtype>& multisigdata, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector<valtype>& ret, SigVersion sigversion)
{ {
int nSigned = 0; int nSigned = 0;
int nRequired = multisigdata.front()[0]; int nRequired = multisigdata.front()[0];
@ -50,7 +50,7 @@ static bool SignN(const std::vector<valtype>& multisigdata, const BaseSignatureC
{ {
const valtype& pubkey = multisigdata[i]; const valtype& pubkey = multisigdata[i];
CKeyID keyID = CPubKey(pubkey).GetID(); CKeyID keyID = CPubKey(pubkey).GetID();
if (Sign1(keyID, creator, scriptCode, ret, sigversion)) if (Sign1(provider, keyID, creator, scriptCode, ret, sigversion))
++nSigned; ++nSigned;
} }
return nSigned==nRequired; return nSigned==nRequired;
@ -62,7 +62,7 @@ static bool SignN(const std::vector<valtype>& multisigdata, const BaseSignatureC
* unless whichTypeRet is TX_SCRIPTHASH, in which case scriptSigRet is the redemption script. * unless whichTypeRet is TX_SCRIPTHASH, in which case scriptSigRet is the redemption script.
* Returns false if scriptPubKey could not be completely satisfied. * Returns false if scriptPubKey could not be completely satisfied.
*/ */
static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptPubKey, static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& scriptPubKey,
std::vector<valtype>& ret, txnouttype& whichTypeRet, SigVersion sigversion) std::vector<valtype>& ret, txnouttype& whichTypeRet, SigVersion sigversion)
{ {
CScript scriptRet; CScript scriptRet;
@ -82,20 +82,20 @@ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptP
return false; return false;
case TX_PUBKEY: case TX_PUBKEY:
keyID = CPubKey(vSolutions[0]).GetID(); keyID = CPubKey(vSolutions[0]).GetID();
return Sign1(keyID, creator, scriptPubKey, ret, sigversion); return Sign1(provider, keyID, creator, scriptPubKey, ret, sigversion);
case TX_PUBKEYHASH: case TX_PUBKEYHASH:
keyID = CKeyID(uint160(vSolutions[0])); keyID = CKeyID(uint160(vSolutions[0]));
if (!Sign1(keyID, creator, scriptPubKey, ret, sigversion)) if (!Sign1(provider, keyID, creator, scriptPubKey, ret, sigversion))
return false; return false;
else else
{ {
CPubKey vch; CPubKey vch;
creator.Provider().GetPubKey(keyID, vch); provider.GetPubKey(keyID, vch);
ret.push_back(ToByteVector(vch)); ret.push_back(ToByteVector(vch));
} }
return true; return true;
case TX_SCRIPTHASH: case TX_SCRIPTHASH:
if (creator.Provider().GetCScript(uint160(vSolutions[0]), scriptRet)) { if (provider.GetCScript(uint160(vSolutions[0]), scriptRet)) {
ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end())); ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
return true; return true;
} }
@ -103,7 +103,7 @@ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptP
case TX_MULTISIG: case TX_MULTISIG:
ret.push_back(valtype()); // workaround CHECKMULTISIG bug ret.push_back(valtype()); // workaround CHECKMULTISIG bug
return (SignN(vSolutions, creator, scriptPubKey, ret, sigversion)); return (SignN(provider, vSolutions, creator, scriptPubKey, ret, sigversion));
case TX_WITNESS_V0_KEYHASH: case TX_WITNESS_V0_KEYHASH:
ret.push_back(vSolutions[0]); ret.push_back(vSolutions[0]);
@ -111,7 +111,7 @@ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptP
case TX_WITNESS_V0_SCRIPTHASH: case TX_WITNESS_V0_SCRIPTHASH:
CRIPEMD160().Write(&vSolutions[0][0], vSolutions[0].size()).Finalize(h160.begin()); CRIPEMD160().Write(&vSolutions[0][0], vSolutions[0].size()).Finalize(h160.begin());
if (creator.Provider().GetCScript(h160, scriptRet)) { if (provider.GetCScript(h160, scriptRet)) {
ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end())); ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
return true; return true;
} }
@ -137,11 +137,11 @@ static CScript PushAll(const std::vector<valtype>& values)
return result; return result;
} }
bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPubKey, SignatureData& sigdata) bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& fromPubKey, SignatureData& sigdata)
{ {
std::vector<valtype> result; std::vector<valtype> result;
txnouttype whichType; txnouttype whichType;
bool solved = SignStep(creator, fromPubKey, result, whichType, SigVersion::BASE); bool solved = SignStep(provider, creator, fromPubKey, result, whichType, SigVersion::BASE);
bool P2SH = false; bool P2SH = false;
CScript subscript; CScript subscript;
sigdata.scriptWitness.stack.clear(); sigdata.scriptWitness.stack.clear();
@ -152,7 +152,7 @@ bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPu
// the final scriptSig is the signatures from that // the final scriptSig is the signatures from that
// and then the serialized subscript: // and then the serialized subscript:
subscript = CScript(result[0].begin(), result[0].end()); subscript = CScript(result[0].begin(), result[0].end());
solved = solved && SignStep(creator, subscript, result, whichType, SigVersion::BASE) && whichType != TX_SCRIPTHASH; solved = solved && SignStep(provider, creator, subscript, result, whichType, SigVersion::BASE) && whichType != TX_SCRIPTHASH;
P2SH = true; P2SH = true;
} }
@ -161,7 +161,7 @@ bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPu
CScript witnessscript; CScript witnessscript;
witnessscript << OP_DUP << OP_HASH160 << ToByteVector(result[0]) << OP_EQUALVERIFY << OP_CHECKSIG; witnessscript << OP_DUP << OP_HASH160 << ToByteVector(result[0]) << OP_EQUALVERIFY << OP_CHECKSIG;
txnouttype subType; txnouttype subType;
solved = solved && SignStep(creator, witnessscript, result, subType, SigVersion::WITNESS_V0); solved = solved && SignStep(provider, creator, witnessscript, result, subType, SigVersion::WITNESS_V0);
sigdata.scriptWitness.stack = result; sigdata.scriptWitness.stack = result;
result.clear(); result.clear();
} }
@ -169,7 +169,7 @@ bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPu
{ {
CScript witnessscript(result[0].begin(), result[0].end()); CScript witnessscript(result[0].begin(), result[0].end());
txnouttype subType; txnouttype subType;
solved = solved && SignStep(creator, witnessscript, result, subType, SigVersion::WITNESS_V0) && subType != TX_SCRIPTHASH && subType != TX_WITNESS_V0_SCRIPTHASH && subType != TX_WITNESS_V0_KEYHASH; solved = solved && SignStep(provider, creator, witnessscript, result, subType, SigVersion::WITNESS_V0) && subType != TX_SCRIPTHASH && subType != TX_WITNESS_V0_SCRIPTHASH && subType != TX_WITNESS_V0_KEYHASH;
result.push_back(std::vector<unsigned char>(witnessscript.begin(), witnessscript.end())); result.push_back(std::vector<unsigned char>(witnessscript.begin(), witnessscript.end()));
sigdata.scriptWitness.stack = result; sigdata.scriptWitness.stack = result;
result.clear(); result.clear();
@ -210,10 +210,10 @@ bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, C
assert(nIn < txTo.vin.size()); assert(nIn < txTo.vin.size());
CTransaction txToConst(txTo); CTransaction txToConst(txTo);
TransactionSignatureCreator creator(&provider, &txToConst, nIn, amount, nHashType); TransactionSignatureCreator creator(&txToConst, nIn, amount, nHashType);
SignatureData sigdata; SignatureData sigdata;
bool ret = ProduceSignature(creator, fromPubKey, sigdata); bool ret = ProduceSignature(provider, creator, fromPubKey, sigdata);
UpdateTransaction(txTo, nIn, sigdata); UpdateTransaction(txTo, nIn, sigdata);
return ret; return ret;
} }
@ -410,7 +410,7 @@ const BaseSignatureChecker& DummySignatureCreator::Checker() const
return dummyChecker; return dummyChecker;
} }
bool DummySignatureCreator::CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const bool DummySignatureCreator::CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const
{ {
// Create a dummy signature that is a valid DER-encoding // Create a dummy signature that is a valid DER-encoding
vchSig.assign(72, '\000'); vchSig.assign(72, '\000');
@ -432,12 +432,12 @@ bool IsSolvable(const SigningProvider& provider, const CScript& script)
// if we were to have the private keys. This is just to make sure that the script is valid and that, // if we were to have the private keys. This is just to make sure that the script is valid and that,
// if found in a transaction, we would still accept and relay that transaction. In particular, // if found in a transaction, we would still accept and relay that transaction. In particular,
// it will reject witness outputs that require signing with an uncompressed public key. // it will reject witness outputs that require signing with an uncompressed public key.
DummySignatureCreator creator(&provider); static const DummySignatureCreator creator;
SignatureData sigs; SignatureData sigs;
// Make sure that STANDARD_SCRIPT_VERIFY_FLAGS includes SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, the most // Make sure that STANDARD_SCRIPT_VERIFY_FLAGS includes SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, the most
// important property this function is designed to test for. // important property this function is designed to test for.
static_assert(STANDARD_SCRIPT_VERIFY_FLAGS & SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, "IsSolvable requires standard script flags to include WITNESS_PUBKEYTYPE"); static_assert(STANDARD_SCRIPT_VERIFY_FLAGS & SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, "IsSolvable requires standard script flags to include WITNESS_PUBKEYTYPE");
if (ProduceSignature(creator, script, sigs)) { if (ProduceSignature(provider, creator, script, sigs)) {
// VerifyScript check is just defensive, and should never fail. // VerifyScript check is just defensive, and should never fail.
assert(VerifyScript(sigs.scriptSig, script, &sigs.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker())); assert(VerifyScript(sigs.scriptSig, script, &sigs.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker()));
return true; return true;

View File

@ -26,19 +26,14 @@ public:
virtual bool GetKey(const CKeyID &address, CKey& key) const =0; virtual bool GetKey(const CKeyID &address, CKey& key) const =0;
}; };
/** Virtual base class for signature creators. */ /** Interface for signature creators. */
class BaseSignatureCreator { class BaseSignatureCreator {
protected:
const SigningProvider* m_provider;
public: public:
explicit BaseSignatureCreator(const SigningProvider* provider) : m_provider(provider) {}
const SigningProvider& Provider() const { return *m_provider; }
virtual ~BaseSignatureCreator() {} virtual ~BaseSignatureCreator() {}
virtual const BaseSignatureChecker& Checker() const =0; virtual const BaseSignatureChecker& Checker() const =0;
/** Create a singular (non-script) signature. */ /** Create a singular (non-script) signature. */
virtual bool CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const =0; virtual bool CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const =0;
}; };
/** A signature creator for transactions. */ /** A signature creator for transactions. */
@ -50,24 +45,23 @@ class TransactionSignatureCreator : public BaseSignatureCreator {
const TransactionSignatureChecker checker; const TransactionSignatureChecker checker;
public: public:
TransactionSignatureCreator(const SigningProvider* provider, const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn=SIGHASH_ALL); TransactionSignatureCreator(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn=SIGHASH_ALL);
const BaseSignatureChecker& Checker() const override { return checker; } const BaseSignatureChecker& Checker() const override { return checker; }
bool CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const override; bool CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const override;
}; };
class MutableTransactionSignatureCreator : public TransactionSignatureCreator { class MutableTransactionSignatureCreator : public TransactionSignatureCreator {
CTransaction tx; CTransaction tx;
public: public:
MutableTransactionSignatureCreator(const SigningProvider* provider, const CMutableTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : TransactionSignatureCreator(provider, &tx, nInIn, amountIn, nHashTypeIn), tx(*txToIn) {} MutableTransactionSignatureCreator(const CMutableTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : TransactionSignatureCreator(&tx, nInIn, amountIn, nHashTypeIn), tx(*txToIn) {}
}; };
/** A signature creator that just produces 72-byte empty signatures. */ /** A signature creator that just produces 72-byte empty signatures. */
class DummySignatureCreator : public BaseSignatureCreator { class DummySignatureCreator : public BaseSignatureCreator {
public: public:
explicit DummySignatureCreator(const SigningProvider* provider) : BaseSignatureCreator(provider) {}
const BaseSignatureChecker& Checker() const override; const BaseSignatureChecker& Checker() const override;
bool CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const override; bool CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const override;
}; };
struct SignatureData { struct SignatureData {
@ -79,7 +73,7 @@ struct SignatureData {
}; };
/** Produce a script signature using a generic signature creator. */ /** Produce a script signature using a generic signature creator. */
bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& scriptPubKey, SignatureData& sigdata); bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& scriptPubKey, SignatureData& sigdata);
/** Produce a script signature for a transaction. */ /** Produce a script signature for a transaction. */
bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType); bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType);

View File

@ -314,7 +314,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
// Sign // Sign
SignatureData sigdata; SignatureData sigdata;
ProduceSignature(MutableTransactionSignatureCreator(&keystore, &valid_with_witness_tx, 0, 11*CENT, SIGHASH_ALL), spend_tx.vout[1].scriptPubKey, sigdata); ProduceSignature(keystore, MutableTransactionSignatureCreator(&valid_with_witness_tx, 0, 11*CENT, SIGHASH_ALL), spend_tx.vout[1].scriptPubKey, sigdata);
UpdateTransaction(valid_with_witness_tx, 0, sigdata); UpdateTransaction(valid_with_witness_tx, 0, sigdata);
// This should be valid under all script flags. // This should be valid under all script flags.
@ -342,7 +342,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
// Sign // Sign
for (int i=0; i<2; ++i) { for (int i=0; i<2; ++i) {
SignatureData sigdata; SignatureData sigdata;
ProduceSignature(MutableTransactionSignatureCreator(&keystore, &tx, i, 11*CENT, SIGHASH_ALL), spend_tx.vout[i].scriptPubKey, sigdata); ProduceSignature(keystore, MutableTransactionSignatureCreator(&tx, i, 11*CENT, SIGHASH_ALL), spend_tx.vout[i].scriptPubKey, sigdata);
UpdateTransaction(tx, i, sigdata); UpdateTransaction(tx, i, sigdata);
} }

View File

@ -1535,7 +1535,7 @@ bool CWallet::DummySignInput(CTxIn &tx_in, const CTxOut &txout) const
const CScript& scriptPubKey = txout.scriptPubKey; const CScript& scriptPubKey = txout.scriptPubKey;
SignatureData sigdata; SignatureData sigdata;
if (!ProduceSignature(DummySignatureCreator(this), scriptPubKey, sigdata)) if (!ProduceSignature(*this, DummySignatureCreator(), scriptPubKey, sigdata))
{ {
return false; return false;
} else { } else {
@ -2579,7 +2579,7 @@ bool CWallet::SignTransaction(CMutableTransaction &tx)
const CScript& scriptPubKey = mi->second.tx->vout[input.prevout.n].scriptPubKey; const CScript& scriptPubKey = mi->second.tx->vout[input.prevout.n].scriptPubKey;
const CAmount& amount = mi->second.tx->vout[input.prevout.n].nValue; const CAmount& amount = mi->second.tx->vout[input.prevout.n].nValue;
SignatureData sigdata; SignatureData sigdata;
if (!ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, amount, SIGHASH_ALL), scriptPubKey, sigdata)) { if (!ProduceSignature(*this, TransactionSignatureCreator(&txNewConst, nIn, amount, SIGHASH_ALL), scriptPubKey, sigdata)) {
return false; return false;
} }
UpdateTransaction(tx, nIn, sigdata); UpdateTransaction(tx, nIn, sigdata);
@ -3008,7 +3008,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
const CScript& scriptPubKey = coin.txout.scriptPubKey; const CScript& scriptPubKey = coin.txout.scriptPubKey;
SignatureData sigdata; SignatureData sigdata;
if (!ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, coin.txout.nValue, SIGHASH_ALL), scriptPubKey, sigdata)) if (!ProduceSignature(*this, TransactionSignatureCreator(&txNewConst, nIn, coin.txout.nValue, SIGHASH_ALL), scriptPubKey, sigdata))
{ {
strFailReason = _("Signing transaction failed"); strFailReason = _("Signing transaction failed");
return false; return false;