# How much does the weight of 2-of-3 multisignature inputs differ between P2SH and P2SH-P2WSH?

I'm trying to calculate the weight of a 2-of-3 multisignature P2SH-P2WSH input. I found the related question Predict multi signature transaction size, which I've calculated with `m=2, n=3` here:

``````pubkeySize=33
sigSize=72

SizeOfRedeemScript = 1+n*(1+pubkeySize)+1+1
// 2-of-3: SizeOfRedeemScript = 1+3*(1+33)+1+1 = 105

SizeOfScriptSig = 1+m*(1+sigSize)+SizeOfPushDataFor(RedeemScript)+SizeOfRedeemScript
// 2-of-3: SizeOfScriptSig = 1+2*(1+72)+2+105 = 1 + 146 + 2 + 105 = 254

sizeOf(input) = 32+4+SizeOfCsuintFor(SizeOfScriptSig) + SizeOfScriptSig + 4
// 2-of-3: sizeOf(input) = 32+4+3+254+4 = 297
``````

The size of 2-of-3 input in P2SH has 293 to 297 bytes1. Thus, this would correspond to up to `297*4 bytes = 1188 wu`.

How would I calculate the corresponding weight for a 2-of-3 multisignature P2SH-P2WSH input?

1Note that if both signatures are 71 bytes, the scriptSig is 252 bytes which as a length can be encoded in 1 byte, but in the worst case both signatures are 72 bytes and the length of the scriptSig needs 3 bytes.

To calculate the block weight, you need to know the size in bytes of the non-witness data and the size in bytes of the witness data.

With a P2SH-P2WSH input, your scriptSig will always be 36 bytes. This makes the size in bytes of the inputs to be `36 + 36 + 4 = 76`. The witnesses contain your signatures and scripts, so the witness for that input will be `1+m*(1 + sigSize) + SizeOfVarIntFor(RedeemScript) + SizeOfRedeemScript`. For a 2-of-3 multsig input, you will thus have `1 + 2*(1 + 72) + 2 + 105 = 254` as the size in bytes of your witness.

The formula for calculating block weight is `base size * 3 + total size`. The base size is the size of all non-witness data, so your base size is 76 bytes. The total size is the size of all data, including witnesses, so your total size will be `76 + 254 = 330`. Plugging this into the formula gets `76 * 3 + 330 = 558`. Thus the weight of the P2SH-P2WSH 2-of-3 multisig is 558.

*Note that `SizeOfVarIntFor(RedeemScript)` is actually two bytes because you need to use OP_PUSHDATA1 since the length of the redeemscript is longer than 75 bytes.

• If `SizeOfVarIntFor(RedeemScript)` would be be two bytes because redeemscript is longer than 75 bytes, wouldn't the same apply to `SizeOfVarIntFor(SizeOfScriptSig)` since `SizeOfScriptSig` is 251?
– Murch
Aug 8, 2017 at 22:42
• @Murch No. There are two ways of representing the size of things in transactions. Within a script itself, we actually use pushdata opcodes. We need two bytes for scripts longer than 75 bytes because we then need to use the OP_PUSHDATA1 opcode before the size byte. However for sizes of things outside of scripts like `SizeOfScriptSig`, we use Compact Size Unsigned Integers. The csuint only needs an additional byte on top of the number itself when the number itself needs more than 1 byte. You can see how csuint works here: bitcoin.org/en/… Aug 8, 2017 at 22:58

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
``````

## 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)