| 1399 | } |
| 1400 | |
| 1401 | static bool VerifyWitnessProgram(const CScriptWitness& witness, int witversion, const std::vector<unsigned char>& program, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror) |
| 1402 | { |
| 1403 | vector<vector<unsigned char> > stack; |
| 1404 | CScript scriptPubKey; |
| 1405 | |
| 1406 | if (witversion == 0) { |
| 1407 | if (program.size() == 32) { |
| 1408 | // Version 0 segregated witness program: SHA256(CScript) inside the program, CScript + inputs in witness |
| 1409 | if (witness.stack.size() == 0) { |
| 1410 | return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_WITNESS_EMPTY); |
| 1411 | } |
| 1412 | scriptPubKey = CScript(witness.stack.back().begin(), witness.stack.back().end()); |
| 1413 | stack = std::vector<std::vector<unsigned char> >(witness.stack.begin(), witness.stack.end() - 1); |
| 1414 | uint256 hashScriptPubKey; |
| 1415 | CSHA256().Write(&scriptPubKey[0], scriptPubKey.size()).Finalize(hashScriptPubKey.begin()); |
| 1416 | if (memcmp(hashScriptPubKey.begin(), &program[0], 32)) { |
| 1417 | return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH); |
| 1418 | } |
| 1419 | } else if (program.size() == 20) { |
| 1420 | // Special case for pay-to-pubkeyhash; signature + pubkey in witness |
| 1421 | if (witness.stack.size() != 2) { |
| 1422 | return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH); // 2 items in witness |
| 1423 | } |
| 1424 | scriptPubKey << OP_DUP << OP_HASH160 << program << OP_EQUALVERIFY << OP_CHECKSIG; |
| 1425 | stack = witness.stack; |
| 1426 | } else { |
| 1427 | return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH); |
| 1428 | } |
| 1429 | } else if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM) { |
| 1430 | return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM); |
| 1431 | } else { |
| 1432 | // Higher version witness scripts return true for future softfork compatibility |
| 1433 | return set_success(serror); |
| 1434 | } |
| 1435 | |
| 1436 | // Disallow stack item size > MAX_SCRIPT_ELEMENT_SIZE in witness stack |
| 1437 | for (unsigned int i = 0; i < stack.size(); i++) { |
| 1438 | if (stack.at(i).size() > MAX_SCRIPT_ELEMENT_SIZE) |
| 1439 | return set_error(serror, SCRIPT_ERR_PUSH_SIZE); |
| 1440 | } |
| 1441 | |
| 1442 | if (!EvalScript(stack, scriptPubKey, flags, checker, SIGVERSION_WITNESS_V0, serror)) { |
| 1443 | return false; |
| 1444 | } |
| 1445 | |
| 1446 | // Scripts inside witness implicitly require cleanstack behaviour |
| 1447 | if (stack.size() != 1) |
| 1448 | return set_error(serror, SCRIPT_ERR_CLEANSTACK); |
| 1449 | if (!CastToBool(stack.back())) |
| 1450 | return set_error(serror, SCRIPT_ERR_EVAL_FALSE); |
| 1451 | return true; |
| 1452 | } |
| 1453 | |
| 1454 | bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CScriptWitness* witness, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror) |
| 1455 | { |
no test coverage detected