3

Please refer to this question:

Calculator for estimated TX-Fees

I have a question for clarity, in response to James' answer as in his example of 2 inputs/1 output, I recently calculated using the formula provided in that question (and found all over the web) and confirming my inputs are both compressed:

size := X * 148 + Y * 34 + 10 +- X

I'm using a standard Electrum wallet with 2FA. I had 2 inputs each it's own address and a single output and wanted to spend them to a single address w/ no change address. 2-in/1-out

I calculated: (2 x 148) + (1 x 34) + 10 +- 2 = 338-342 bytes and James came up with 404 bytes (he used uncompressed inputs @ 180 bytes and the formula works out), yet the real transaction would up being 638 bytes (stuck in the pool now) which makes using formulas like the one above a little less trustworthy.

What am I missing? Why when using the formula above, some transactions are spot on and others are way off with no way for me to make sense of it, math doesn't lie so I must be using the formula wrong and I just can't see the forest through through the trees?

Short Answer (derived from the help of all 3 fine gents below): I am using a 2FA wallet and that inherently is a multi-signature wallet of which the formula (in my case, 2 signers) changes the formula to:

size := X * 295 + Y * 34 + 10 +- X
  • 2
    Could you tell us what wallet or software you're using? Is it possible that you are using a 2-of-3 multisignature wallet? 2-of-3 multisignature inputs are 295 bytes, and 295+295+34+10=634 (which is pretty close). – Murch Oct 30 '17 at 18:51
  • Electrum (up-to-date) standard wallet w/ 2FA. Again, a lot of past transactions using the same wallet add up perfectly using the compressed input sizes of 148bytes for calculation. – Philip Ingram Oct 30 '17 at 21:14
  • Or you had four inputs instead of two: 4*148+34+10 = 636. If you could link the transaction we would probably be able to tell you more. – Murch Oct 30 '17 at 21:23
  • 1
    related: bitcoin.stackexchange.com/q/30570/5406 – Murch Oct 30 '17 at 23:48
  • 1
    No, you don't double the input size, rather the script has a different size altogether. A single 2-of-3 multisig input comes in at approximately 295 bytes. – Murch Oct 31 '17 at 23:37
3

What am I missing?

  1. Public keys can be compressed or uncompressed
  2. Signature can has slightly different size

And yes, Murch is right in his comment. The formula works only for p2pkh inputs and p2pkh outputs. No p2sh, no segwit, no anything except p2pkh

  • 1. As mentioned in OP, they appear to be compressed when I look at other transactions using the same wallet and everything adds up perfectly multiplying inputs by 148. Shouldn't this be a consistent formula across all transactions using the same wallet? 2. Can the sigs add that much to the size? Is there any way to calculate this relatively accurately beforehand? I mean my calc of 340 is very different than 638 and got me into some trouble and I'm still clueless how to calculate it properly, this feels like a never-ending search for the holy grail of information. – Philip Ingram Oct 30 '17 at 21:24
  • I now understand w/ 2FA I have a multisig wallet and I understand why its done this way for security. I also realize now that I was not just calculating only "send" transactions and that was an oversight on my part. All send transactions historically work with the formula: (# of Inputs x (148 x 2)) + (# of Outputs x 34) + 10 +- # of Inputs. Don't have enough cred yet to vote your answer up but thx, you both have been very helpful. – Philip Ingram Oct 30 '17 at 22:01
1

Just as an example for the math: a two input/two output P2PKH transaction returns 746 chars, so it is in hex 373 Bytes.

$ printf 010000000253603B3FDB9D5E10DE2172305FF68F4B5227310BA6BD81D4E1BF60C0DE6183BC010000006A4730440220128487F04A591C43D7A6556FFF9158999B46D6119C1A4D4CF1F5D0AC1DD57A94022061556761E9E1B1E656C0A70AA7B3E83454CD61662DF61EBDC31E43196B5E0C10012102B12126A716CE7BBB84703BCFBF0AFA80283C75A7304A48CD311A5027EFD906C2FFFFFFFF0E52C4701577287B6DD02F422C2A8033FA0B4614F75FA9F0A5C4AB69634B5BA7000000006B483045022100A428348FF55B2B59BC55DDACB1A00F4ECDABE282707BA5185D39FE9CDF05D7F0022074232DAE76965B6311CEA2D9E5708A0F137F4EA2B0E36D0818450C67C9BA259D0121025F95E8A33556E9D7311FA748E9434B333A4ECFB590C773480A196DEAB0DEDEE1FFFFFFFF0290257300000000001976A914FCA68658B537382E27A85522D292E1AD9543FE0488AC98381100000000001976A9146AF1D17462C6146A8A61217E8648903ACD3335F188AC00000000 | wc -c

It has two inputs with signatures and compressed keys, and two P2PKH outputs. It can be decomposed this way:

VERSION 01000000
TX_IN COUNT [var_int]:                    hex=02, decimal=2
  TX_IN[0] OutPoint hash (char[32])       BC8361DEC060BFE1D481BDA60B3127524B8FF65F307221DE105E9DDB3F3B6053
  TX_IN[0] OutPoint index (uint32_t)      hex=01000000, reversed=00000001, decimal=1
  TX_IN[0] Script Length (var_int)        hex=6A, decimal=106
  TX_IN[0] Script Sig (uchar[])           4730440220128487F04A591C43D7A6556FFF9158999B46D6119C1A4D4CF1F5D0AC1DD57A94022061556761E9E1B1E656C0A70AA7B3E83454CD61662DF61EBDC31E43196B5E0C10012102B12126A716CE7BBB84703BCFBF0AFA80283C75A7304A48CD311A5027EFD906C2 
  TX_IN[0] Sequence (uint32_t)            FFFFFFFF
 TX_IN[1]
  TX_IN[1] OutPoint hash (char[32])       A75B4B6369ABC4A5F0A95FF714460BFA33802A2C422FD06D7B28771570C4520E
  TX_IN[1] OutPoint index (uint32_t)      hex=00000000, reversed=00000000, decimal=0
  TX_IN[1] Script Length (var_int)        hex=6B, decimal=107
  TX_IN[1] Script Sig (uchar[])           483045022100A428348FF55B2B59BC55DDACB1A00F4ECDABE282707BA5185D39FE9CDF05D7F0022074232DAE76965B6311CEA2D9E5708A0F137F4EA2B0E36D0818450C67C9BA259D0121025F95E8A33556E9D7311FA748E9434B333A4ECFB590C773480A196DEAB0DEDEE1 
  TX_IN[1] Sequence (uint32_t)            FFFFFFFF

TX_OUT COUNT                              hex=02, decimal=2
  TX_OUT[0] Value (uint64_t)              hex=9025730000000000, reversed_hex=0000000000732590, dec=7546256, bitcoin=0.07546256
  TX_OUT[0] PK_Script Length (var_int)    hex=19, dec=25
  TX_OUT[0] pk_script (uchar[])           76A914FCA68658B537382E27A85522D292E1AD9543FE0488AC
  TX_OUT[1] Value (uint64_t)              hex=9838110000000000, reversed_hex=0000000000113898, dec=1128600, bitcoin=0.01128600
  TX_OUT[1] PK_Script Length (var_int)    hex=19, dec=25
  TX_OUT[1] pk_script (uchar[])           76A9146AF1D17462C6146A8A61217E8648903ACD3335F188AC
 LOCK_TIME                                00000000

Based on the formula (X * 148 + Y * 34 + 10 +- X) it should give 2*148+2*34+2=366Bytes ... close. Ok.

Now comes a (2-of-2) multisig with 1 input, two outputs, 670 chars, 335 Bytes - compressed keys:

$ printf 0100000001B9C6777F2D8D710F1E0E3BB5FBFFA7CDFD6C814A2257A7CFCED9A2205448DD0601000000DA0048304502210083A93C7611F5AEEE6B0B4D1CBFF2D31556AF4CD1F951DE8341C768AE03F780730220063B5E6DFB461291B1FBD93D58A8111D04FD03C7098834BAC5CDF1D3C5FA90D0014730440220137C7320E03B73DA66E9CF89E5F5ED0D5743EBC65E776707B8385FF93039408802202C30BC57010B3DD20507393EBC79AFFC653473A7BAF03C5ABF19C14E2136C646014752210285CB139A82DD9062B9AC1091CB1F91A01C11AB9C6A46BD09D0754DAB86A38CC9210328C37F938748DCBBF15A0E5A9D1BA20F93F2C2D0EAD63C7C14A5A10959B5CE8952AEFFFFFFFF0280C42B03000000001976A914D199925B52D367220B1E2A2D8815E635B571512F88AC65A7B3010000000017A9145C4DD14B9DF138840B34237FDBE9159C420EDBBE8700000000 | wc -c

the difference is that you need to have two signatures, and the 3 pubkeys of the multisig. Decoded:

VERSION                                   01000000
TX_IN COUNT [var_int]:                    hex=01, decimal=1
  TX_IN[0] OutPoint hash (char[32])       06DD485420A2D9CECFA757224A816CFDCDA7FFFBB53B0E1E0F718D2D7F77C6B9
  TX_IN[0] OutPoint index (uint32_t)      hex=01000000, reversed=00000001, decimal=1
  TX_IN[0] Script Length (var_int)        hex=DA, decimal=218
  TX_IN[0] Script Sig 1 (uchar[])         0048304502210083A93C7611F5AEEE6B0B4D1CBFF2D31556AF4CD1F951DE8341C768AE03F780730220063B5E6DFB461291B1FBD93D58A8111D04FD03C7098834BAC5CDF1D3C5FA90D001
  TX_IN[0] Script Sig 2 (uchar[])         4730440220137C7320E03B73DA66E9CF89E5F5ED0D5743EBC65E776707B8385FF93039408802202C30BC57010B3DD20507393EBC79AFFC653473A7BAF03C5ABF19C14E2136C64601
  TX_IN[0] Multisig Pubkeys (decoded details): 

    47: OP_DATA_0x47:       push hex 47 (decimal 71) bytes on stack
    52: OP_2:               the number 2 is pushed onto stack
    21: OP_DATA_0x21:       compressed pub key (33 Bytes)
        0285CB139A82DD90:62B9AC1091CB1F91:A01C11AB9C6A46BD:09D0754DAB86A38C:C9
        This is MultiSig's compressed Public Key (X9.63 form)
        corresponding bitcoin address is:    1LcBDzTGSJiN5snVBHiyeWsT7SqRWUW7mp
    21: OP_DATA_0x21:       compressed pub key (33 Bytes)
        0328C37F938748DC:BBF15A0E5A9D1BA2:0F93F2C2D0EAD63C:7C14A5A10959B5CE:89
        This is MultiSig's compressed Public Key (X9.63 form)
        corresponding bitcoin address is:    1LisHErVXWhY1A1ZJqZSDdGYKrbGn1M6bx
    52: OP_2:               the number 2 is pushed onto stack
    AE: OP_CHECKMULTISIG:   terminating multisig  TX_IN[0] Sequence (uint32_t)

  TX_IN[0] Sequence (uint32)              FFFFFFFF
TX_OUT COUNT                              hex=02, decimal=2
  TX_OUT[0] Value (uint64_t)              hex=80C42B0300000000, reversed_hex=00000000032BC480, dec=53200000, bitcoin=.53200000
  TX_OUT[0] PK_Script Length (var_int)    hex=19, dec=25
  TX_OUT[0] pk_script (uchar[])           76A914D199925B52D367220B1E2A2D8815E635B571512F88AC
  TX_OUT[1] Value (uint64_t)              hex=65A7B30100000000, reversed_hex=0000000001B3A765, dec=28551013, bitcoin=.28551013
  TX_OUT[1] PK_Script Length (var_int)    hex=17, dec=23
  TX_OUT[1] pk_script (uchar[])           A9145C4DD14B9DF138840B34237FDBE9159C420EDBBE87
 LOCK_TIME                                00000000

one can easily change to 2-3 multisig or 3-of-7, which would increase the number of signatures and pubkeys accordingly. Signatures can have different length, starting with 00 (especially when having negative S-values), and then 0x47 or 0x48 as length indicator.
Pubkeys can be compressed (33 bytes) or uncompressed (66bytes).

Math can't be tricked :-)

  • Thx for the examples, calculating 2-3 multisig was what I needed. – Philip Ingram Nov 1 '17 at 5:59

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.