| 1219 | } |
| 1220 | |
| 1221 | uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache) |
| 1222 | { |
| 1223 | assert(nIn < txTo.vin.size()); |
| 1224 | |
| 1225 | if (sigversion == SIGVERSION_WITNESS_V0) { |
| 1226 | uint256 hashPrevouts; |
| 1227 | uint256 hashSequence; |
| 1228 | uint256 hashOutputs; |
| 1229 | const bool cacheready = cache && cache->ready; |
| 1230 | |
| 1231 | if (!(nHashType & SIGHASH_ANYONECANPAY)) { |
| 1232 | hashPrevouts = cacheready ? cache->hashPrevouts : GetPrevoutHash(txTo); |
| 1233 | } |
| 1234 | |
| 1235 | if (!(nHashType & SIGHASH_ANYONECANPAY) && (nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) { |
| 1236 | hashSequence = cacheready ? cache->hashSequence : GetSequenceHash(txTo); |
| 1237 | } |
| 1238 | |
| 1239 | if ((nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) { |
| 1240 | hashOutputs = cacheready ? cache->hashOutputs : GetOutputsHash(txTo); |
| 1241 | } else if ((nHashType & 0x1f) == SIGHASH_SINGLE && nIn < txTo.vout.size()) { |
| 1242 | CHashWriter ss(SER_GETHASH, 0); |
| 1243 | ss << txTo.vout[nIn]; |
| 1244 | hashOutputs = ss.GetHash(); |
| 1245 | } |
| 1246 | |
| 1247 | CHashWriter ss(SER_GETHASH, 0); |
| 1248 | // Version |
| 1249 | ss << txTo.nVersion; |
| 1250 | // Input prevouts/nSequence (none/all, depending on flags) |
| 1251 | ss << hashPrevouts; |
| 1252 | ss << hashSequence; |
| 1253 | // The input being signed (replacing the scriptSig with scriptCode + amount) |
| 1254 | // The prevout may already be contained in hashPrevout, and the nSequence |
| 1255 | // may already be contain in hashSequence. |
| 1256 | ss << txTo.vin[nIn].prevout; |
| 1257 | ss << static_cast<const CScriptBase&>(scriptCode); |
| 1258 | ss << amount; |
| 1259 | ss << txTo.vin[nIn].nSequence; |
| 1260 | // Outputs (none/one/all, depending on flags) |
| 1261 | ss << hashOutputs; |
| 1262 | // Locktime |
| 1263 | ss << txTo.nLockTime; |
| 1264 | // Sighash type |
| 1265 | ss << nHashType; |
| 1266 | |
| 1267 | return ss.GetHash(); |
| 1268 | } |
| 1269 | |
| 1270 | static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001")); |
| 1271 | |
| 1272 | // Check for invalid use of SIGHASH_SINGLE |
| 1273 | if ((nHashType & 0x1f) == SIGHASH_SINGLE) { |
| 1274 | if (nIn >= txTo.vout.size()) { |
| 1275 | // nOut out of range |
| 1276 | return one; |
| 1277 | } |
| 1278 | } |