As of January 2021, "high-level" script validation with all active consensus rules on the network is approximately this:
Top level evaluation
- Execute the
scriptSig
, and call the resulting stack stack
. If execution aborts, fail.
- Execute the
scriptPubKey
with stack
as input, and call the resulting stack result
. If execution aborts, fail.
- If
result
is empty, or its top element has numerical value 0, fail.
- If
scriptPubKey
is exactly equal to an OP_n (with n between 0 and 16, inclusive) followed by a direct push of exactly 2 to 40 bytes inclusive:
- If
scriptSig
not empty, fail.
- Run segwit validation with the
scriptPubKey
as program, the n value as version, and witness
as input (see further). If this execution aborts, fail.
- If
scriptPubKey
is exactly equal to OP_HASH160 + a 20 byte push + OP_EQUAL, run P2SH validation:
- If
scriptSig
does not consists of only pushes, fail.
- If
result
is empty, fail.
- Interpret the top element of
result
as a script, and execute it, with the rest of result
as input. Call the resulting stack p2sh_result
. If this execution aborts, fail.
- If
p2sh_result
is empty, or its top element has numerical value 0, fail.
- If the top element of
result
is exactly OP_n (with n between 0 and 16 inclusive) followed by a direct push of 2 through 40 bytes inclusive:
- If
scriptSig
is not exactly a direct push of the top element of result
, fail.
- Run segwit validation with the
scriptPubKey
as program, the n value as version, and witness
as input (see further). If this execution aborts, fail.
- If no failure occurred before this point, the script is valid.
Segwit validation
Segwit validation for version version
, with program program
, and input input
:
- If the version is 0:
- If the program is not 20 or 32 bytes, fail.
- If the program is 20 bytes
hash
:
- Execute the script OP_DUP OP_HASH160
hash
OP_EQUALVERIFY OP_CHECKSIG, with initial stack input
. If execution aborts, fail.
- If the resulting stack is not exactly one element, or that element has numerical value 0, fail.
- If the program is 32 bytes
hash
:
- If
input
is empty, or its top element's SHA256 hash does not equal hash
, fail.
- Execute the top element of
input
as script, with the other elements as input. If execution aborts, fail.
- If the resulting stack is not exactly one element, or that element has numerical value 0, fail.
- If no failure occurred up to this point, return success.
This answer does not include the changes introduced by BIP341 and BIP342, as these are not active on the network. It also does not include various standardness/policy rules.
Source: https://github.com/bitcoin/bitcoin/blob/v0.20.1/src/script/interpreter.cpp, functions VerifyScript
, VerifyWitnessProgram
, ExecuteWitnessScript
.
TL;DR: only the BIP16 P2SH pattern (OP_HASH160 <20 bytes> OP_EQUAL) and the BIP141 segwit pattern (OP_n <2 to 40 bytes>) are actual special cases that trigger additional rules. But the details are more complex.