66

I know that I pay the transaction fee per kB, so how can I calculate how large the transaction will be before I send it via the RPC api. I run a site using bitcoins, and I cannot let the user's balance go negative, so I need to know if they have enough balance to cover the cost.

3 Answers 3

66

Assuming all the inputs you are spending are from regular "pay to address" transactions, each input will contribute 180 (plus or minus 1) bytes to the transaction. Each output adds 34 bytes to the transaction. And there's a fixed extra 10 bytes which are always present.

The "plus or minus 1" comes from the fact that each input needs a signature to be claimed. The signature contains two 32 byte values, but if either of the values has a first byte of 0x80 or more, it has a 0x00 byte prepended to it. So I'm assuming one of the two is high and the other is low. That way I'm off by at most one byte per input.

So if your transaction has in inputs and out outputs, the transaction size, in bytes will be:

in*180 + out*34 + 10 plus or minus 'in'

For example, this transaction has 40 inputs and 16 outputs. That gives us a transaction size of

40*180 + 16*34 + 10 +- 40

i.e. 7754 +- 40 bytes. The actual size is 7761 bytes.

If the inputs are from "pay to pubkey" transactions then the inputs are smaller than for "pay to address" transactions. And this will be different also for "pay to script hash" inputs too, depending on how/if that's implemented.

Edit: This transaction was made with bitcoins stolen in the Linode heist and shows a transaction size of 1337, possibly a deliberate use of leetspeak in the blockchain.

Edit2: Now that compressed public keys are commonplace, each input is 32 bytes shorter and so the transaction size is now:

in*148 + out*34 + 10 plus or minus 'in'
4
  • Is the formula described in Edit2 up to date with bitcoin v.0.9.0? Apr 1, 2014 at 9:45
  • 4
    What about the size of P2SH ?
    – Farghaly
    Apr 21, 2014 at 21:47
  • How do you find out how many inputs and outputs there are? Jul 6, 2017 at 18:57
  • @MarcAlexander see In-Counter and Out-Counter: en.bitcoin.it/wiki/Transaction#Input
    – JBaczuk
    Jul 18, 2018 at 18:32
26
+100

Here are some calculations based on the Protocol Documentation.

A Bitcoin Transaction is composed of the following:

  • Version (4 Bytes)
  • TxIn Count (1 ~ 9B)
  • For each TxIn:
    • Outpoint (36B)
    • Script Length (1 ~ 9B)
    • ScriptSig(?)
    • Sequence (4B)
  • TxOut Count (1 ~ 9B)
  • For each TxOut:
    • Value (8B)
    • Script Length(1 ~ 9B)*
    • Script (?)*
  • LockTime (4B)

Assuming a standard P2SH/P2PKH transaction is created, the script length marked in asterisk will be bound to 1byte as the Script Length is encoded as a variable integer; while the script size marked in asterisks will be bound to 24bytes as it will only contain a script hash.

So, in summary, we can assume that the maximum bound of each TxOut to be 34 bytes if we are paying to a P2SH/P2PKH address, since there are 4 opcodes in each output script. A great breakdown can be found here.

Assuming we are spending P2PKH outpoints for our TxIn. Our ScriptSig (composed of a 72byte DER Encoded Transaction Signature + 33byte Public Key) would be 146bytes in size and our script length will only consume 1byte as the size of the ScriptSig is less than 0xFD.

Therefore, a standard P2PKH/P2SH transaction spending a ONE UTXO redeemable with a basic ScriptSig paying to only ONE output is 189bytes. Otherwise, we can also further generalise this to:

in marks the number of TxIns

out marks the number of TxOuts

Assuming that in < 254 and out < 254.

Size of P2SH/P2PKH Transaction = in * 146 + out * 33 + 10

Computing the size of P2SH/P2PKH transaction that is being funded with complex inputs (i.e. UTXOs spendable with M-of-N signatures, hashed-timelocked contracts) is inherently difficult and is dependent on the complexity of the redeemScript used to produce the scriptHash of the prior P2SH transaction.

21

It is important to understand that the transaction fee you have to pay to make a payment is based on how you received the funds you are using to make the payment. The outgoing payment (assuming it's only to one place) is always going to be the same size. So the 'out' part will always have two standard "pay to address" scripts. The size of the 'in' part will depend on how many outputs you have to claim, which depends on how you got the funds.

So I wouldn't suggest charging the transaction fee to the person withdrawing, because then you're billing the user based on parameters the user has no control over. The transaction fees depend on things like how many transaction outputs you have to gather to get the coins needed. That's completely dependent on how your funds are structured.

Imagine if you walk into a candy store and are told that a candy bar is 35 cents, but then when they rang you up, they tacked on a 15 cent fee. When you asked them what it was for, they explained that the previous customer had paid them all in pennies, and in order to give you your change, they'd have to count all those pennies, and that takes more time.

I think you'd be pissed because that fee has to do with how their funds are structured and has nothing to do with your transaction. You would expect them to either eat those costs or build them into their prices. You wouldn't expect them to figure out exactly how much it costs to sell you a candy bar based on their internal business configuration and charge you personally based on that.

Either charge a flat fee per withdrawal (.01 BTC is currently common) or cover the transaction fees yourself. And use sensible strategies to reduce transaction fees. But, in my opinion, you really don't want to pass on that kind of cost to a customer.

2
  • 1
    "So the 'out' part will always have two standard "pay to address" scripts" isn't true. Sometimes you have the exact amount in a single coin and can avoid receiving change. See blockexplorer.com/tx/… for example, which I created with the official client. Feb 25, 2012 at 3:41
  • 3
    With the price of BTC at $7200, paying a fee of $72.00 for something small kinda sticks in the craw. .01 BTC/transaction is no longer a good idea. Nov 2, 2017 at 15:11

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