The differences between P2SH, P2SH-P2WSH and P2WSH are the following:
- P2SH: the scriptPubKey has a P2SH program. The scriptSig provides the corresponding script arguments and redeemscript to satisfy the P2SH program.
- P2SH-P2WSH: the scriptPubKey has a P2SH program. The scriptSig has the witness program and forwards to the witness stack for evaluation. The witness stack provides the script arguments and witness script.
- P2WSH: the scriptPubKey has a witness program, the scriptSig is empty and the witness stack provides the script arguments and witness script.
- The witness stack is identical for equivalent P2SH-P2WSH and P2WSH inputs.
So to calculate the size of a P2SH-P2WSH multisig, the script arguments and redeemscript get moved to the witness stack as script arguments and witness script, and you need to add the cost of the forwarding script.
The scriptSig in P2SH-P2WSH is composed of scriptLength witnessProgramLength witnessVersion hashLength hash
or varInt PUSHBYTES OP_0 PUSHBYTES <hash>
. The length of the scriptSig can be expressed in a 1-byte varInt, so the scriptSig in total takes 1 + 1 + 1 + 1 + 32 = 36 B. This means that the non-witness bytes of the input are the outpoint (32+4 B), the scriptSig (36 B), and the nSequence (4 B) which sum to 76 B in total.
The witness stack has the count of the witness items (1 WU), the three script arguments, an empty dummy element because OP_CHECKMULTISIG pops an additional element of the stack and the two signatures (1+2×(1+72) = 147 WU), and the witness script, witnessScriptLength OP_m n×(PUSHBYTES+pubkey) OP_n OP_CHECKMULTISIG
(1+1+3×(1+33)+1+1 = 106 WU).
Altogether, the vsize of a 2-of-3 P2SH-P2WSH input is therefore:
txid:vout:scriptSig:nSeq::witLength:scriptArgs:witScript
32 + 4 + 36 + 4 + 1 + 147 + 106 = 76 + 254/4 = 139.5 vB
Full details of all three types follow below for your convenience.
P2SH
The size of a P2SH-based 2-of-3 multisig input works out to be 293, 296 or 297 bytes as described in the question.
PREVOUT:
hash (32 bytes)
index (4 bytes)
SCRIPTSIG:
length (varInt 1 or 3 bytes)
signatures¹ (1+2×(1+72²) bytes = 147 bytes)
dummy-OP_0
m×(PUSHBYTES+sig)
OP_PUSHDATA1 len(redeemscript) (2 bytes)
redeemscript (1+3×(1+33)+1+1 = 105 bytes)
OP_m n×(PUSHBYTES+pubkey) OP_n OP_CHECKMULTISIG
nSequence (4 bytes)
32 + 4 + 3 + 1 + 2×(1+72) + 2 + 1 + 3×(1+33) + 1 + 1 + 4 =
36 + 3 + 147 + 2 + 105 + 4 = 297 B
Since signatures can be 71 or 72 bytes, it works out that the input needs a 1-byte varInt to express the scriptSig's length for two low-r signatures. If either or both signatures are high-r it needs a 3-byte varInt to express the scriptSig's length.
P2SH-P2WSH
The weight of a P2SH-P2WSH 2-of-3 works out to be 556–558 WU, which translate to 139.0–139.5 vB.
PREVOUT:
hash (32 bytes)
index (4 bytes)
SCRIPTSIG:
length (varInt 1 byte)
witness program: (1 + 1 + 1 + 32 = 35 bytes)
length
version (OP_0)
PUSHBYTES <32-byte hash>
nSequence (4 bytes)
WITNESS STACK:
item count (1 WU)
script arguments (1 + 2×(1+72²) WU)
dummy-empty-element¹
m×(varInt+sig)
witnessScript (1+1+3×(1+33)+1+1 = 106 WU)
length (varInt 1 WU)
OP_m n×(PUSHBYTES+pubkey) OP_n OP_CHECKMULTISIG
32 + 4 + 1 + 1 + 1 + 1 + 32 + 4
+ [1 + 1 + 2×(1+72) + 1+1+3×(1+33)+1+1]/4
= 36 + 1 + 35 + 4 + [1 + 147 + 106]/4
= 76 + [254]/4
= 76 + 63.5
= 139.5 vB
P2WSH
The P2WSH has the same witness stack as the P2SH-P2WSH, so it saves exactly the 35 B from circumventing the redeemscript. The weight of a P2WSH 2-of-3 works out to be 416-418 WU which translate to 104.0–104.5 vB.
PREVOUT:
hash (32 bytes)
index (4 bytes)
SCRIPTSIG:
length (varInt 1 byte)
nSequence (4 bytes)
WITNESS STACK:
item count (1 WU)
script arguments (1 + 2×(1+72²) WU)
dummy-empty-element¹
m×(varInt+sig)
witnessScript (1+1+3×(1+33)+1+1 = 106 WU)
length (varInt 1 WU)
OP_m n×(PUSHBYTES+pubkey) OP_n OP_CHECKMULTISIG
32 + 4 + 1 + 4
+ [1 + 1 + 2×(1+72) + 1 + 1 + 3×(1+33) + 1 + 1]/4
= 36 + 1 + 4 + [1 + 147 + 106]/4
= 41 + [254]/4
= 41 + 63.5
= 104.5 vB
¹ OP_CHECKMULTISIG pops one extra element off the stack
² Signatures can be 71 or 72 bytes (or seldom even smaller)