I want to understand how P2SH (no multisig) works
To understand that you first have to realize that despite what bitcoin wiki says bitcoin script evaluation is not as simple as running a Forth-like language. More precisely it is not 1) read 2) run
. Instead it is more like 1) read 2) interpret (decide how to run) 3) construct the entire script based on 2 4) run
. And it is not only "left to right" evaluation. Instead it always starts from looking at far right (PubkeyScript
of the previous transaction ie. the tx being spent) then continues from left (which may be different now).
Focusing on P2SH, here are some examples (assuming reader knows what each OP code does, otherwise first take a look at the wiki link above):
- First fetch
PubkeyScript
of the transaction that is being spent and evaluate it to decide how to continue. Here we focus only on P2SH that has this pattern: OP_HASH160 <20 bytes push> OP_EQUAL
. Because it is P2SH we continue like this:
- Start from
SignatureScript
and "run" only that script. It must contain at least one PushData
operation at the end (the script can only be 1 push, or it could be other OPs ending with 1 mandatory push)
- Duplicate that mandatory push
- Run
PubkeyScript
with that duplicated item (pop1>hash>pushResult>push20>pop2>equalityCheck
) if they were equal continue otherwise fail.
- Evaluate the mandatory push as a script (ie.
RedeemScript
) and decide how to continue.
- Here are different cases:
6.1. RedeemScript = OP_0 <20 bytes push>
6.2. RedeemScript = OP_0 <32 bytes push>
6.3. RedeemScript = whatever else
(I don't think there is any more special patterns other than above 2)
Case 6.3 is probably the easiest since it simply "runs" the RedeemScript
. I say "whatever else" because as long as it is not a "special pattern" the evaluation is very simple and "normal". You can see this in all legacy multi-signature P2SH transactions easily found on the blockchain. But here is another example with a very simple RedeemScript to show what "whatever else" means: 463782617f0e6a69102530caa9ba2fe48f996128378af99ee437a22660afc5a7 that uses OP_2 OP_3 OP_ADD OP_5 OP_EQUAL
as the RedeemScript
(only 1 mandatory push).
Cases 6.1 and 6.2 are harder and a bit tricky because during the evaluation you have to "run" OP codes that don't even exist in the scripts! For example in case of 6.1 or the P2SH-P2WPKH you continue like this:
- Make sure there was no more than the single
PushData
in SignatureScript
.
- Look among witnesses and expect 2 items, extract those
- Run a special
OP_CheckSig
(although it doesn't exist) for SegWit transactions. That means: first item in step 8 was a signature, the second one was a public key. Compute sigHash
as descibed in BIP-143, run ECDSA.Verify(signature,sigHash,pubkey)
.
With 6.2 things get more complicated since there is now a WitnessScript
which should be evaluated separately (a bit similar to RedeemScript
).