Skip to content

Commit 7414455

Browse files
committed
Add signature version 1 with updated sighash
Includes simplifications by Eric Lombrozo.
1 parent 6c53939 commit 7414455

10 files changed

+117
-59
lines changed

src/policy/policy.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
146146
// IsStandardTx() will have already returned false
147147
// and this method isn't called.
148148
std::vector<std::vector<unsigned char> > stack;
149-
if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker()))
149+
if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), 0))
150150
return false;
151151

152152
if (whichType == TX_SCRIPTHASH)

src/script/interpreter.cpp

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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())

src/script/interpreter.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,12 @@ enum
8989

9090
bool CheckSignatureEncoding(const std::vector<unsigned char> &vchSig, unsigned int flags, ScriptError* serror);
9191

92-
uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
92+
uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, const CAmount& amount, int sigversion);
9393

9494
class BaseSignatureChecker
9595
{
9696
public:
97-
virtual bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode) const
97+
virtual bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, int sigversion) const
9898
{
9999
return false;
100100
}
@@ -112,13 +112,14 @@ class TransactionSignatureChecker : public BaseSignatureChecker
112112
private:
113113
const CTransaction* txTo;
114114
unsigned int nIn;
115+
const CAmount amount;
115116

116117
protected:
117118
virtual bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const;
118119

119120
public:
120-
TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amount) : txTo(txToIn), nIn(nInIn) {}
121-
bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode) const;
121+
TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn) : txTo(txToIn), nIn(nInIn), amount(amountIn) {}
122+
bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, int sigversion) const;
122123
bool CheckLockTime(const CScriptNum& nLockTime) const;
123124
};
124125

@@ -131,7 +132,7 @@ class MutableTransactionSignatureChecker : public TransactionSignatureChecker
131132
MutableTransactionSignatureChecker(const CMutableTransaction* txToIn, unsigned int nInIn, const CAmount& amount) : TransactionSignatureChecker(&txTo, nInIn, amount), txTo(*txToIn) {}
132133
};
133134

134-
bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL);
135+
bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, int sigversion, ScriptError* error = NULL);
135136
bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CScriptWitness* witness, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror = NULL);
136137

137138
#endif // BITCOIN_SCRIPT_INTERPRETER_H

0 commit comments

Comments
 (0)