@@ -226,7 +226,7 @@ bool static CheckMinimalPush(const valtype& data, opcodetype opcode) {
226
226
return true ;
227
227
}
228
228
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)
230
230
{
231
231
static const CScriptNum bnZero (0 );
232
232
static const CScriptNum bnOne (1 );
@@ -835,7 +835,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
835
835
// serror is set
836
836
return false ;
837
837
}
838
- bool fSuccess = checker.CheckSig (vchSig, vchPubKey, scriptCode);
838
+ bool fSuccess = checker.CheckSig (vchSig, vchPubKey, scriptCode, sigversion );
839
839
840
840
popstack (stack);
841
841
popstack (stack);
@@ -903,7 +903,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
903
903
}
904
904
905
905
// Check signature
906
- bool fOk = checker.CheckSig (vchSig, vchPubKey, scriptCode);
906
+ bool fOk = checker.CheckSig (vchSig, vchPubKey, scriptCode, sigversion );
907
907
908
908
if (fOk ) {
909
909
isig++;
@@ -1066,8 +1066,64 @@ class CTransactionSignatureSerializer {
1066
1066
1067
1067
} // anon namespace
1068
1068
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 )
1070
1070
{
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
+
1071
1127
static const uint256 one (uint256S (" 0000000000000000000000000000000000000000000000000000000000000001" ));
1072
1128
if (nIn >= txTo.vin .size ()) {
1073
1129
// nIn out of range
@@ -1096,7 +1152,7 @@ bool TransactionSignatureChecker::VerifySignature(const std::vector<unsigned cha
1096
1152
return pubkey.Verify (sighash, vchSig);
1097
1153
}
1098
1154
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
1100
1156
{
1101
1157
CPubKey pubkey (vchPubKey);
1102
1158
if (!pubkey.IsValid ())
@@ -1109,7 +1165,7 @@ bool TransactionSignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn
1109
1165
int nHashType = vchSig.back ();
1110
1166
vchSig.pop_back ();
1111
1167
1112
- uint256 sighash = SignatureHash (scriptCode, *txTo, nIn, nHashType);
1168
+ uint256 sighash = SignatureHash (scriptCode, *txTo, nIn, nHashType, amount, sigversion );
1113
1169
1114
1170
if (!VerifySignature (vchSig, pubkey, sighash))
1115
1171
return false ;
@@ -1182,7 +1238,7 @@ static bool VerifyWitnessProgram(const CScriptWitness& witness, int witversion,
1182
1238
return set_success (serror);
1183
1239
}
1184
1240
1185
- if (!EvalScript (stack, scriptPubKey, flags, checker, serror)) {
1241
+ if (!EvalScript (stack, scriptPubKey, flags, checker, 1 , serror)) {
1186
1242
return false ;
1187
1243
}
1188
1244
// Scripts inside witness implicitly require cleanstack behaviour
@@ -1208,12 +1264,12 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const C
1208
1264
}
1209
1265
1210
1266
vector<vector<unsigned char > > stack, stackCopy;
1211
- if (!EvalScript (stack, scriptSig, flags, checker, serror))
1267
+ if (!EvalScript (stack, scriptSig, flags, checker, 0 , serror))
1212
1268
// serror is set
1213
1269
return false ;
1214
1270
if (flags & SCRIPT_VERIFY_P2SH)
1215
1271
stackCopy = stack;
1216
- if (!EvalScript (stack, scriptPubKey, flags, checker, serror))
1272
+ if (!EvalScript (stack, scriptPubKey, flags, checker, 0 , serror))
1217
1273
// serror is set
1218
1274
return false ;
1219
1275
if (stack.empty ())
@@ -1259,7 +1315,7 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const C
1259
1315
CScript pubKey2 (pubKeySerialized.begin (), pubKeySerialized.end ());
1260
1316
popstack (stack);
1261
1317
1262
- if (!EvalScript (stack, pubKey2, flags, checker, serror))
1318
+ if (!EvalScript (stack, pubKey2, flags, checker, 0 , serror))
1263
1319
// serror is set
1264
1320
return false ;
1265
1321
if (stack.empty ())
0 commit comments