7

In a standard P2PKH configuration, the scripts look like:

Pubkey script: OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
Signature script: <sig> <pubkey> 

When redeeming P2PKH outputs, OP_DUP is done because the pubkey is used twice, once in the hash and then verifying the hashes match, and then again in verifying the signature. So, here it seems like OP_HASH160 is consuming the top stack element and replacing it with the HASH160() of what was there.

In P2SH transactions, the scripts look like:

Pubkey script: OP_HASH160 <Hash160(redeemScript)> OP_EQUAL
Signature script: <sig> [sig] [sig...] <redeemScript>

When redeeming P2SH outputs, there is no OP_DUP. Won't this mean that the redeemScript will be consumed by the OP_HASH160? How can the redeemScript be executed if it was consumed by the OP_HASH160? I think I am missing something here.

1 Answer 1

6

Yes, OP_HASH160 consumes the top stack element and replaces it with its hash.

So how does P2SH work, if the script is consumed after HASH160 runs?

Here's how P2SH transactions are processed:

  1. Execute the input script (from this transaction)
    This is the transaction that only contains push-data-onto-stack commands.
    AKA scriptSig
  2. Execute the output script (from the previous transaction)
    AKA scriptPubKey
  3. Does the output script error out? If so, this transaction's invalid.
  4. Does the output script end with a truthy value at the top of the stack? If not, this transaction's invalid.
  5. Does this output script :

    1. Start with OP_HASH160,
    2. have 20 bytes of data,
    3. and end with OP_EQUAL?

    If so, this is P2SH. (source)

  6. If P2SH, erase the stack and run the input script again.
  7. If P2SH, pop the top element of the stack off, and run it as a script. (source)
  8. If that script errors out, then this transactions is invalid.
5
  • 1
    Also: good question! Any question that forces me to look the answer up is good. :)
    – Nick ODell
    Oct 20, 2014 at 21:31
  • Thanks! So it seems like there just custom code that says, if P2SH {do this extra checking, interpreting the top element of scriptSig as a script}. Is there no way to just do all this P2SH specific stuff with the OP codes that exist? Seems like no. Would it be possible to build in such an opcode, like OP_SCRIPT_DATA to signal that this is both data to be pushed and a script in itself to be run and verified?
    – morsecoder
    Oct 20, 2014 at 22:13
  • Where would I see this process you referenced shown in the source code?
    – morsecoder
    Oct 20, 2014 at 22:15
  • @StephenM347 (responding to first comment) No. The original Bitcoin spec did not allow for looping or evaluating subscripts, in order to make them easy to statically analyse. Would it be possible to build in such an opcode, like OP_SCRIPT_DATA Sure, but the existing push-thing-on-stack commands do the trick just fine.
    – Nick ODell
    Oct 20, 2014 at 22:37
  • @StephenM347 (second comment) Added. The embarrassing thing is that I found out that I was wrong when I looked at the source code. Oh well, fixed.
    – Nick ODell
    Oct 20, 2014 at 22:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.