@@ -226,7 +226,7 @@ bool static CheckMinimalPush(const valtype& data, opcodetype opcode) {
226226 return true ;
227227}
228228
229- bool EvalScript (vector<vector<unsigned char > >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror)
229+ bool EvalScript (vector<vector<unsigned char > >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, int sigversion, ScriptError* serror)
230230{
231231 static const CScriptNum bnZero (0 );
232232 static const CScriptNum bnOne (1 );
@@ -835,7 +835,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
835835 // serror is set
836836 return false ;
837837 }
838- bool fSuccess = checker.CheckSig (vchSig, vchPubKey, scriptCode);
838+ bool fSuccess = checker.CheckSig (vchSig, vchPubKey, scriptCode, sigversion );
839839
840840 popstack (stack);
841841 popstack (stack);
@@ -903,7 +903,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
903903 }
904904
905905 // Check signature
906- bool fOk = checker.CheckSig (vchSig, vchPubKey, scriptCode);
906+ bool fOk = checker.CheckSig (vchSig, vchPubKey, scriptCode, sigversion );
907907
908908 if (fOk ) {
909909 isig++;
@@ -1066,8 +1066,64 @@ class CTransactionSignatureSerializer {
10661066
10671067} // anon namespace
10681068
1069- uint256 SignatureHash (const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType)
1069+ uint256 SignatureHash (const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, const CAmount& amount, int sigversion )
10701070{
1071+ if (sigversion == 1 ) {
1072+ uint256 hashPrevouts;
1073+ uint256 hashSequence;
1074+ uint256 hashOutputs;
1075+
1076+ if (!(nHashType & SIGHASH_ANYONECANPAY)) {
1077+ CHashWriter ss (SER_GETHASH, 0 );
1078+ for (unsigned int n = 0 ; n < txTo.vin .size (); n++) {
1079+ ss << txTo.vin [n].prevout ;
1080+ }
1081+ hashPrevouts = ss.GetHash (); // TODO: cache this value for all signatures in a transaction
1082+ }
1083+
1084+ if (!(nHashType & SIGHASH_ANYONECANPAY) && (nHashType & 0x1f ) != SIGHASH_SINGLE && (nHashType & 0x1f ) != SIGHASH_NONE) {
1085+ CHashWriter ss (SER_GETHASH, 0 );
1086+ for (unsigned int n = 0 ; n < txTo.vin .size (); n++) {
1087+ ss << txTo.vin [n].nSequence ;
1088+ }
1089+ hashSequence = ss.GetHash (); // TODO: cache this value for all signatures in a transaction
1090+ }
1091+
1092+ if ((nHashType & 0x1f ) != SIGHASH_SINGLE && (nHashType & 0x1f ) != SIGHASH_NONE) {
1093+ CHashWriter ss (SER_GETHASH, 0 );
1094+ for (unsigned int n = 0 ; n < txTo.vout .size (); n++) {
1095+ ss << txTo.vout [n];
1096+ }
1097+ hashOutputs = ss.GetHash (); // TODO: cache this value for all signatures in a transaction
1098+ } else if ((nHashType & 0x1f ) == SIGHASH_SINGLE && nIn < txTo.vout .size ()) {
1099+ CHashWriter ss (SER_GETHASH, 0 );
1100+ ss << txTo.vout [nIn];
1101+ hashOutputs = ss.GetHash ();
1102+ }
1103+
1104+ CHashWriter ss (SER_GETHASH, 0 );
1105+ // Version
1106+ ss << txTo.nVersion ;
1107+ // Input prevouts/nSequence (none/all, depending on flags)
1108+ ss << hashPrevouts;
1109+ ss << hashSequence;
1110+ // The input being signed (replacing the scriptSig with scriptCode + amount)
1111+ // The prevout may already be contained in hashPrevout, and the nSequence
1112+ // may already be contain in hashSequence.
1113+ ss << txTo.vin [nIn].prevout ;
1114+ ss << static_cast <const CScriptBase&>(scriptCode);
1115+ ss << amount;
1116+ ss << txTo.vin [nIn].nSequence ;
1117+ // Outputs (none/one/all, depending on flags)
1118+ ss << hashOutputs;
1119+ // Locktime
1120+ ss << txTo.nLockTime ;
1121+ // Sighash type
1122+ ss << nHashType;
1123+
1124+ return ss.GetHash ();
1125+ }
1126+
10711127 static const uint256 one (uint256S (" 0000000000000000000000000000000000000000000000000000000000000001" ));
10721128 if (nIn >= txTo.vin .size ()) {
10731129 // nIn out of range
@@ -1096,7 +1152,7 @@ bool TransactionSignatureChecker::VerifySignature(const std::vector<unsigned cha
10961152 return pubkey.Verify (sighash, vchSig);
10971153}
10981154
1099- bool TransactionSignatureChecker::CheckSig (const vector<unsigned char >& vchSigIn, const vector<unsigned char >& vchPubKey, const CScript& scriptCode) const
1155+ bool TransactionSignatureChecker::CheckSig (const vector<unsigned char >& vchSigIn, const vector<unsigned char >& vchPubKey, const CScript& scriptCode, int sigversion ) const
11001156{
11011157 CPubKey pubkey (vchPubKey);
11021158 if (!pubkey.IsValid ())
@@ -1109,7 +1165,7 @@ bool TransactionSignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn
11091165 int nHashType = vchSig.back ();
11101166 vchSig.pop_back ();
11111167
1112- uint256 sighash = SignatureHash (scriptCode, *txTo, nIn, nHashType);
1168+ uint256 sighash = SignatureHash (scriptCode, *txTo, nIn, nHashType, amount, sigversion );
11131169
11141170 if (!VerifySignature (vchSig, pubkey, sighash))
11151171 return false ;
@@ -1182,7 +1238,7 @@ static bool VerifyWitnessProgram(const CScriptWitness& witness, int witversion,
11821238 return set_success (serror);
11831239 }
11841240
1185- if (!EvalScript (stack, scriptPubKey, flags, checker, serror)) {
1241+ if (!EvalScript (stack, scriptPubKey, flags, checker, 1 , serror)) {
11861242 return false ;
11871243 }
11881244 // Scripts inside witness implicitly require cleanstack behaviour
@@ -1208,12 +1264,12 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const C
12081264 }
12091265
12101266 vector<vector<unsigned char > > stack, stackCopy;
1211- if (!EvalScript (stack, scriptSig, flags, checker, serror))
1267+ if (!EvalScript (stack, scriptSig, flags, checker, 0 , serror))
12121268 // serror is set
12131269 return false ;
12141270 if (flags & SCRIPT_VERIFY_P2SH)
12151271 stackCopy = stack;
1216- if (!EvalScript (stack, scriptPubKey, flags, checker, serror))
1272+ if (!EvalScript (stack, scriptPubKey, flags, checker, 0 , serror))
12171273 // serror is set
12181274 return false ;
12191275 if (stack.empty ())
@@ -1259,7 +1315,7 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const C
12591315 CScript pubKey2 (pubKeySerialized.begin (), pubKeySerialized.end ());
12601316 popstack (stack);
12611317
1262- if (!EvalScript (stack, pubKey2, flags, checker, serror))
1318+ if (!EvalScript (stack, pubKey2, flags, checker, 0 , serror))
12631319 // serror is set
12641320 return false ;
12651321 if (stack.empty ())
0 commit comments