How do I calculate transaction fee for call to createpsbt()?

Bitcoin Asked on December 18, 2020

When my user invokes my app, he passes as an input parameter the desired value of the TX fee in satoshis per byte. I create a PSBT by calling createpsbt(). I exert complete control over the determination of inputs and outputs. For example, I don’t call walletcreatefundedpsbt(), because I don’t want bitcoind to select inputs on my behalf. I have a chicken and egg problem in that I need to call createpsbt() in order to determine the size of the TX in bytes, but I need to specify the fee amount before the call to createpsbt(). The best solution that I can think of is to execute a dummy call to createpsbt() using a dummy fee value, then measure the size of the TX, then do a real call to createpsbt() after correctly calculating the fee amount. Is there a better way?

Edit: I want to spend all UTXOs. I want two outputs, one to receive a fixed amount, the other to receive change less the fee. I have tried many incantations, I can’t get it to work. Here’s my latest attempt:

raw_psbt = rpc.walletcreatefundedpsbt(
    # all UTXOs, as returned by listunspent():
    # one recipient: [ { addr : amount } ]
    0,  # locktime
        "replaceable" : True,
        # I would like for the change less the fee to go here:
        "changeAddress" : xxx,
        "includeWatching" : True,
        "feeRate" : 0.005,

This fails with Signing transaction failed (-4). Any idea what I’m doing wrong?

Edit #2: I can’t use walletcreatefundedpsbt() as suggested below to create the PSBT, because that function requires that its inputs be “solvable”, which is not the case in my environment. More info at this link:

Errors with walletcreatefundedpsbt & non-solvable UTXOs

So my original question remains unresolved at this point.

Edit #3: So I asked on Slack. The problem is that our UTXOs are 1) not “solvable” and 2) cannot be expressed in the descriptor language, so Bitcoin Core has no way to calculate the TX size before the TX is signed. Apparently I would have to calculated it manually as explained in the attached screenshot.slack chat

One Answer

If you want to implement your coin selection, the only alternative to calculating the fee manually I can think of is the following:

  • You select which inputs you want to be used in your transaction based on your coin selection algorithm.
  • You then proceed to lock every input that is not the one you selected. You can get the list of all inputs through listunspent and you can lock an input with lockunspent false [{"txid":"hex", "vout":n}, ...].
  • Now you can use your walletcreatefundedpsbt without being afraid it will select any input that you don't want and you can pass the option {"feerate":your_feerate}.
  • After getting your raw transaction, you can unlock all previously locked inputs with lockunspent true

Answered by Pedro on December 18, 2020

Add your own answers!

Related Questions

Ask a Question

Get help from others!

© 2023 All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP