2

So, I was looking into how P2SH transactions are working and by looking at different blog post and in particular to this answer, I have the following question.

So, let's take the same transaction:

enter image description here

What I am not getting is how the operation are done.

  • Is the scriptSig executed first?
  • What is checked to be equal to 0b49fe...df1? How is it calculated ?
6
  • Does this answer your question? Full list of "special cases" during Bitcoin Script execution (p2sh, p2wsh, etc.)? Commented Jan 24, 2021 at 0:22
  • Well, it for sure help. What I dont get is that since the address 32ihz...QT is the result of base58(prefix + sha256(locking-script)), and the pkscript is checking just the ripemd160, there has to be the sha256 inside the sigscript right? or am I missing something?
    – fraccaman
    Commented Jan 24, 2021 at 0:33
  • No, it's base58(prefix + hash160(redeemscript)). hash160(x) = ripemd160(hash160(x)). And it's what OP_HASH160 does. Commented Jan 24, 2021 at 0:38
  • So, is the redeemscript part of the scriptSig? If yes, how can you tell which part of the scriptSig is the redeemscript and which are the "inputs" to "solve" it?
    – fraccaman
    Commented Jan 24, 2021 at 0:52
  • The rule for P2SH is that the final stack element is the redeemScript, and everything before it are inputs to it. Commented Jan 24, 2021 at 0:53

1 Answer 1

2

What I am not getting is how the operation are done.

The address encodes the hash160 of the redeemScript. That address was given to the sender, who used it to construct an output scriptPubKey of the form OP_HASH160 <scripthash> OP_EQUAL. The scripthash is really hash160(redeemScript), but the sender does not know that, as they aren't given the actual redeemScript, just its hash160. The <...> notation here means "script opcode that pushes ... onto the stack".

The redeemscript is OP_2 <pubkey1> <pubkey2> <pubkey3> OP_3 OP_CHECKMULTISIG. This script was created by the receiver, encoding their policy for spending, and then its hash160 was given in the form of a P2SH address (3...) to the sender.

The scriptSig is what is created by the receiver when they want to spend the coins. In this case it consists of OP_0 <sig1> <sig2> <redeemScript>.

During validation, what happens is:

  • First the scriptSig is executed, which pushes 4 items onto the stack (0, sig1, sig2, and redeemScript).
  • Then the scriptPubKey is executed, starting with the previous execution's final stack as initial state. It contains 3 opcodes, each modifying that stack:
    • OP_HASH160: takes the final element of the stack (the redeemScript) and replaces it with hash160(redeemScript).
    • <scripthash>: pushes the scripthash onto the stack, so now the stack is (0, sig1, sig2, hash160(redeemScript), scripthash).
    • OP_EQUALVERIFY: removes the top two items on the stack and compares them. If they are equal, a 1 is pushed onto the stack, otherwise a zero. In our case, the scripthash is equal to hash160(redeemScript) (because the spender revealed the correct redeemScript) and thus a 1 is pushed. The stack is now (0, sig1, sig2, 1).
  • The final stack is examined: validity rules require that the stack is not empty, and that its top element is nonzero. That is the case here: the top element is 1. If that wasn't the case, the spend would be marked invalid and execution would stop here.

That's it for the ordinary execution. However, because the scriptSig is exactly of the form OP_HASH160 <20-byte scripthash> OP_EQUAL, the BIP16 P2SH validation rules trigger for a secondary round of processing. This time:

  • It is verified that the scriptSig contains only push opcodes, and no other opcodes. If this is not true, the P2SH validation marks the transaction as invalid.
  • The stack we had just after executing the scriptSig is restored (0, sig1, sig2, redeemScript).
  • Its top element (the redeemScript) is removed from the stack, and reinterpreted as a script, and executed, with all the other stack elements as input. It consists of 6 opcodes:
    • OP_2: pushes a 2 onto the stack, which now becomes (0, sig1, sig2, 2).
    • <pubkey1>: pushes pubkey1 onto the stack, which becomes (0, sig1, sig2, 2, pubkey1).
    • <pubkey2>: pushes pubkey2 onto the stack, which becomes (0, sig1, sig2, 2, pubkey1, pubkey2).
    • <pubkey3>: pushes pubkey3 onto the stack, which becomes (0, sig1, sig2, 2, pubkey1, pubkey2, pubkey3).
    • OP_3: pushes a 2 onto the stack, which now becomes (0, sig1, sig2, 2, pubkey1, pubkey2, pubkey3, 3).
    • OP_CHECKMULTISIG inspects the stack, sees a 3 on top, removes it, as well as the 3 pubkeys that precede it. Then it encounters a 2 on top, removes, as well as the 2 signatures that precede it. Then it removes one more element (a historical bug that is very hard to fix). Then it checks those signatures against every subset of 2 of those 3 pubkeys. If matches are found, it puts a 1 on the stack, otherwise a 0. In this case, the signatures are valid for some subset of the public keys, and the stack becomes (1).
  • The final stack is inspected, requiring that it is not empty, and its top element is nonzero. As it is a 1 here, that is the case.
1
  • 1
    This is super clear, thank Pieter!
    – fraccaman
    Commented Jan 24, 2021 at 1:07

Your Answer

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

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