diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index fce881578..e8d2463f1 100755 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1057,13 +1057,15 @@ private: const bool fAnyoneCanPay; //!< whether the hashtype has the SIGHASH_ANYONECANPAY flag set const bool fHashSingle; //!< whether the hashtype is SIGHASH_SINGLE const bool fHashNone; //!< whether the hashtype is SIGHASH_NONE + const bool fOmitTxComment; //!< whether the hashtype has the SIGHASH_OMIT_TX_COMMENT flag set public: CTransactionSignatureSerializer(const CTransaction &txToIn, const CScript &scriptCodeIn, unsigned int nInIn, int nHashTypeIn) : txTo(txToIn), scriptCode(scriptCodeIn), nIn(nInIn), fAnyoneCanPay(!!(nHashTypeIn & SIGHASH_ANYONECANPAY)), fHashSingle((nHashTypeIn & 0x1f) == SIGHASH_SINGLE), - fHashNone((nHashTypeIn & 0x1f) == SIGHASH_NONE) {} + fHashNone((nHashTypeIn & 0x1f) == SIGHASH_NONE), + fOmitTxComment(!!(nHashTypeIn & SIGHASH_OMIT_TX_COMMENT)){} /** Serialize the passed scriptCode, skipping OP_CODESEPARATORs */ template @@ -1138,7 +1140,7 @@ public: // Serialize nLockTime ::Serialize(s, txTo.nLockTime); // Serialize strTxComment - if (txTo.nVersion >= 2) + if (txTo.nVersion >= 2 && fOmitTxComment == 0) ::Serialize(s, txTo.strTxComment); } }; @@ -1246,6 +1248,9 @@ uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsig // Serialize and hash CHashWriter ss(SER_GETHASH, 0); + nHashType &= ~SIGHASH_OMIT_TX_COMMENT; // clear SIGHASH_OMIT_TX_COMMENT - Flag is only used for 0.10.4 compat + // it's used internally but must not actually appear in the result + ss << txTmp << nHashType; return ss.GetHash(); } @@ -1270,8 +1275,20 @@ bool TransactionSignatureChecker::CheckSig(const std::vector& vch uint256 sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion, this->txdata); - if (!VerifySignature(vchSig, pubkey, sighash)) - return false; + if (!VerifySignature(vchSig, pubkey, sighash)){ + // Verification failed, toggle SIGHASH_OMIT_TX_COMMENT and try again + nHashType ^= SIGHASH_OMIT_TX_COMMENT; + + // need a new vchSig + std::vector vchSig2(vchSigIn); + // pop the hash type + vchSig2.pop_back(); + + sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion, this->txdata); + + if (!VerifySignature(vchSig2, pubkey, sighash)) + return false; + } return true; } diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 437826b5d..7ade4e6a5 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -25,6 +25,7 @@ enum SIGHASH_NONE = 2, SIGHASH_SINGLE = 3, SIGHASH_ANYONECANPAY = 0x80, + SIGHASH_OMIT_TX_COMMENT = (1U << 6), }; /** Script verification flags */