5

I was looking for answer everywhere. Basically is there any way of calculate multi-sig transaction size when the transaction is creating, before the signing procedure? I was trying to find any pattern for that, with no results.

Informations I have:

  • num of inputs;
  • num of outputs;
  • num of required signatures

I will appreciate any clue to solve this problem.

4
  • Are you asking about transactions with several inputs or about input/output from/to msig-address?
    – amaclin
    Commented Sep 18, 2014 at 14:19
  • About transaction from multisig address. So I have few transactions belonging to multisig address and I want to send money to whatever address. Before broadcast to the network multisig transaction require signing, in my case two signatures. The base transaction after calling './bitcoin-cli createrawtransaction trans_list recipients' is quite small, after first sign becoming around 1000 bytes and after second 2000 bytes it also depending from how many transactions is coming as input
    – Mr.Coffee
    Commented Sep 18, 2014 at 14:57
  • OK, next question is: bare multisig output or p2sh multisig?
    – amaclin
    Commented Sep 18, 2014 at 15:00
  • It is p2sh script, created by './bitcoin-cli createmultisig <num required> <addresses|pubkeys>'
    – Mr.Coffee
    Commented Sep 18, 2014 at 15:11

3 Answers 3

2
pubkeySize=33
sigSize=72


SizeOfRedeemScript = 1+n*pubkeySize+1+1
SizeOfScriptSig = 1+m*(1+sigSize)+SizeOfVarIntFor(RedeemScript)+SizeOfRedeemScript
sizeOf(input) = 32+4+SizeOfVarIntFor(SizeOfScriptSig) + SizeOfScriptSig + 4

SizeOfScriptPubKey = SizeOfVarIntFor(SizeOfRedeemScript) + len(script)
sizeOf(output) = 8 + SizeOfScriptPubKey

sizeOf(tx) = 4 + SizeOfVarIntFor(numInputs) + sum(SizeOfInputsArray) + SizeOfVarIntFor(numOutputs) + sum(SizeOfOutputsArray) + 4

Basically, once you know m & n (for your multisig), whether public keys are compressed (pubkeySize), plus the number of inputs and outputs, plus the types of outputs, you can come up with a pretty accurate figure for the size.

7
  • I've added "sum(SizeOfOutputsArray)" to the last line, because it seemed to be missing.
    – Murch
    Commented Aug 2, 2017 at 18:25
  • @karimkorun what means SizeOfVarIntFor Commented Aug 30, 2017 at 16:06
  • 1
    what is len(script) here ? should SizeOfVarIntFor(RedeemScript) be SizeOfVarIntFor(SizeOfRedeemScript) ? is lengthOfScript the same as SizeOfScriptSig? If not, how is lengthOfScript generated?
    – tipu
    Commented Dec 26, 2018 at 19:15
  • 1
    These equations are very incomplete, ambiguous, and inconsistent, as others have mentioned. What is len(script)? Downvoted.
    – B T
    Commented Jan 5, 2020 at 7:25
  • 1
    len(script) is the length of the script.. in bytes.. @BT - it's pseudocode. it's not supposed to be complete. Here's an implementation I wrote, using exactly these functions github.com/blocktrail/blocktrail-sdk-php/blob/master/src/…
    – karimkorun
    Commented Jan 16, 2020 at 16:52
0

I stepped over this while trying to solve a similiar question: "how much tx fees do I need to prepare?"... Though this is an older question, I thought it would be good still be ok to reply, so that others might benefit from the same research.

https://en.bitcoin.it/wiki/Elliptic_Curve_Digital_Signature_Algorithm

... Signatures are either 73, 72, or 71 bytes long, with probabilities approximately 25%, 50% and 25% respectively, although sizes even smaller than that are possible with exponentially decreasing probability.

Behind the Sigs there is normally the pubkey in hex, adding 33 Bytes for compressed, and 65 Bytes for uncompressed keys. So I calculate for a standard TX roughly 100 Bytes per sig. You already have your figures for inputs and outputs. My std 2 inputs/2 outputs TX is roughly 400Bytes. The Inputs part of a TX depends on the number of

1
  • 2
    Since the low-S rules was introduced, signature are 50% of the time 72 bytes and 50% of the time 71. Commented Jul 10, 2017 at 19:27
0

I wrote some code to calculate an estimate for multisig transaction size based on Karimkorun's almost unreadable answer and based off the (incomplete) documentation here.

The code:

var pubkeySize = 33
var sigSize = 72
// An approximation based on the example in
// https://en.bitcoin.it/wiki/Protocol_documentation#tx
var pubkeyScriptSize = 25 

var m = 2, n = 3

var result = tx([input(m,n)], [output(1,1), output(m,n)])
console.log(result)


// All functions calculate sizes

function input(m, n) {
  var outpoint = 32 + 4
  var sequence = 4
  return outpoint + varIntAndValue(sigScript(m, n)) + sequence
}
function sigScript(m, n) {
  return 1 + m * (1 + sigSize) + varIntAndValue(redeemScript(n))
}
function redeemScript(n) {
  return 1 + n * pubkeySize + 1 + 1
}

function output(m, n) {
  var outputValue = 8
  return outputValue + pubkeyScript(m, n)
}
function pubkeyScript(m, n) {
  return varIntAndValue(pubkeyScriptSize)
}

function tx(inputs, outputs) {
  var versionSize = 4
  var lockTime = 4
  return versionSize + varInt(inputs.length) + sum(inputs)
       + varInt(outputs.length) + sum(outputs) + lockTime
}

// The size of a variable integer for the given value.
// See https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer
function varInt(value) {
  if (value < 0xFD) {
    return 1
  } else if (value <= 0xFFFF) {
    return 3
  } else if (value <= 0xFFFFFFFF) {
    return 5
  } else {
    return 9
  }
}
function varIntAndValue(value) {
  return varInt(value) + value    
}
function sum(list) {
  return list.reduce((acc, x) => acc + x, 0) 
}

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.