1

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 out 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 = 1188 bytes weight (BW).

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


1Correction: Note 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.

1

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 35 bytes. This makes the size in bytes of the inputs to be 36 + 35 + 4 = 75. 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 75 bytes. The total size is the size of all data, including witnesses, so your total size will be 75 + 254 = 329. Plugging this into the formula gets 75 * 3 + 329 = 554. Thus the weight of the P2SH-P2WSH 2-of-3 multisig is 554.

*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.

  • So, I should be getting 293 in my calculation in the question? – Murch Aug 2 '17 at 21:26
  • 2
    I believe it should be 292. – Andrew Chow Aug 2 '17 at 22:04
  • 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 '17 at 22:42
  • 1
    @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/… – Andrew Chow Aug 8 '17 at 22:58
  • I think I found an error in the calculation of my question making the redeem script 3 bytes larger. I've also edited your answer. Can you check whether you agree? – Murch Aug 22 '17 at 23:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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