3

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():
    inputs,
    # one recipient: [ { addr : amount } ]
    outputs,
    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

1 Answer 1

0

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
3
  • I tried to implement this with a call to walletcreatefundedpsbt(), it fails with Signing transaction failed (-4), I updated my OP with more details, any idea what I'm doing wrong?
    – eric
    Dec 20, 2019 at 17:25
  • 1
    Not sure what that error message means... maybe try to remove the last set of arguments and work your way adding more and more arguments/options. Also, launching bitcoind with the debug=rpc option might give some valuable information in the debug.log
    – Pedro
    Dec 21, 2019 at 15:49
  • I figured out why I was getting Signing transaction failed (-4). It's because the input UTXO is not "solvable" as explained here: bitcoin.stackexchange.com/questions/91425/… My original problem remains unresolved.
    – eric
    Jan 8, 2020 at 20:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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