Post
Topic
Board Bitcoin Technical Support
Merits 38 from 9 users
Re: Multisig question
by
pooya87
on 17/07/2023, 10:39:19 UTC
⭐ Merited by LoyceV (12) ,hosseinimr93 (6) ,BlackHatCoiner (6) ,ranochigo (5) ,o_e_l_e_o (4) ,Pmalek (2) ,Charles-Tim (1) ,Z-tight (1) ,DdmrDdmr (1)
pub_key OP_CHECKSIG
OP_IF (num of sig required) pub_key1 pub_key2 (total pubkeys) OP_CHECKMULTISIG
OP_ENDIF
OP_VERIFY

In your case, your P2SH would be:

A_Pubkey OP_CHECKSIG
OP_IF 1 B_PUBKEY C_PUBKEY D_PUBKEY 3 OP_CHECKMULTISIG
OP_ENDIF
OP_VERIFY
Anybody can spend these outputs by simply providing "OP_TRUE <fake_sig>" to the above redeem script.

The flaws in the script are:
- Using OP_CHECKSIG instead of OP_CHECKSIGVERIFY
When you use OP_CHECKSIG it will push the result of the verification to the stack when immediately after your OP_IF is going to pop an item from the stack which is the result of the signature verification. If it is false it won't even execute the branch under it which can be abused by passing a fake signature so that OP_CHECKSIG pushes OP_FALSE to the stack ergo the OP_IF is skipped. Which is where we reach OP_VERIFY which need an item on the stack, hence the first OP_TRUE.
- Using OP_IF
Since we want another signature apart from A in any case, there is no need to put the OP_CHECKMULTISIG in a conditional branch that could be avoided. Even if we needed a conditional it should be preceded by an OP_SWAP (assuming you want to use OP_CHECKSIG instead of OP_CHECKSIGVERIFY) to use the true/false value that the user provides in their scriptsig.

The correct redeem script that does what OP wants is:
Code:
<A_pubkey> OP_CHECKSIGVERIFY 1 B_PUBKEY C_PUBKEY D_PUBKEY 3 OP_CHECKMULTISIG
Note that the last OP has to be OP_CHECKMULTISIG not OP_CHECKMULTISIGVERIFY since after evaluating the redeem script, the interpreter needs to check the stack and see at least one item on the stack that evaluates to true.