Author

Topic: Getting transaction size/fees before sending (Read 151 times)

member
Activity: 84
Merit: 22
Hi

I assume you're coding in PHP? if not i can rewrite it in another lang for you, but here is a working example i've built for you to specify an exact fee for a bitcoin transaction.. this also works for other alt coins.  Thank me later. Cool

Code:

   $unspentTransactions = $bitcoin->listunspent(0, 9999999); //First we find out all our unspent transactions from where we can withdraw

    $collectedTransactions = [];

    foreach ($unspentTransactions as $unspentTransaction) {

        if ($collectedAmount < $amountToSend) {
            $collectedTransactions[] = [
                'txid'  => $unspentTransaction['txid'],
                'vout'  => $unspentTransaction['vout']
            ];

           $collectedAmount += $unspentTransaction['amount'];
        } else {

            break;
        }
    }



$change_amount = $collectedAmount-$amount-$fee;


if ($change_amount <= 0.00000000) {


       $output2 = array(

          "".$recipient."" =>"".$amount-$fee.""
    );


   }

   else {

       $output2 = array(


          "".$recipient."" =>"".$amount."",

          "".$change_addr."" =>"".$change_amount."",
          
    );

   }
  

    $maketxnraw = $bitcoin->createrawtransaction($collectedTransactions, $output2);

    $signtxn = $bitcoin->signrawtransactionwithwallet($maketxnraw);

    $returnsignedhex = $signtxn['hex'];
    
    $sendpayment = $bitcoin->sendrawtransaction($returnsignedhex);

    $txid = $sendpayment;


You can then get the fee rates from any exchanger or wallet using their API's to fit your needs, or you can use bitcoin's smart fee.


ps. I could code the whole project for you, if you'd like to hire me.
legendary
Activity: 1568
Merit: 6660
bitcoincleanup.com / bitmixlist.org
However, this seems to be a bit "overkill" since every time a user enters a value to withdraw (even if they do not go through with it), I'd have to create a new transaction and this seems unnecessarily intensive.

The size of amount field in bytes never changes (I believe it's 4 bytes)  so you don't have to run the fee calculation when only the amount is changed, only when the number of inputs or outputs are changed.

Another idea I had was to ignore the part of actually creating the transaction but instead checking the minimal amount of transaction inputs/outputs that I'd need for the transaction with something like listunspent and then calculate the total tx fee with the formula: (n_in*148 + n_out*34 + 10) * feerate.

That would be better, considering size in Weight Units are calculated with a similar formula anyway and you can derive the transaction size in vbytes based on that.

As a follow up question, would I then have to create raw transactions to properly implement these fees? It seems that the JSON RPC commands like sendtoaddress and fundrawtransaction do not provide enough flexibility when setting user fees.

createrawtransaction does not set the fee rate, you have to do that from sendtoaddress using "fee_rate=x" where x is the amount in sats/vB, and set subtractfeefromamount to false.
legendary
Activity: 3038
Merit: 4418
Crypto Swap Exchange
Due to differing DER signature size, the actual TX size would probably be off by a few bytes. It shouldn't really matter, given that it is such a small proportion but it's good to know.

The formula that you've indicated only works for the calculation of raw size in P2PKH transactions. There are so many various types of transaction and their related forumula. You can take a look at this site[1] to see how you can calculate it.

[1] https://jlopp.github.io/bitcoin-transaction-size-calculator/
legendary
Activity: 2352
Merit: 6089
bitcoindata.science

Another idea I had was to ignore the part of actually creating the transaction but instead checking the minimal amount of transaction inputs/outputs that I'd need for the transaction with something like listunspent and then calculate the total tx fee with the formula: (n_in*148 + n_out*34 + 10) * feerate.

There isn't a single formula that will work for every address format. For legacy, native segwit and p2sh you need different formulad.

I made a tool that does exactly that calculation,  you can see it here live
https://bitcoindata.science/plot-your-transaction-in-mempool.html

There is a discussion about transaction size calculations here:
https://bitcointalksearch.org/topic/m.55206394
legendary
Activity: 3290
Merit: 16489
Thick-Skinned Gang Leader and Golden Feather 2021
I'm creating an application which allows users to have their own addresses from which they can deposit/withdraw from.
I can't really answer your questions, but allow me to take a few steps back: it sounds like you're creating a "web wallet" in which each user has their own addresses, but you control the private keys for the users. It sounds like you'll take the worst of both worlds: it's custodial, but without have the benefits of a shared address pool.
Wouldn't it be much better to either go full custodial, so you choose which address to withdraw from (like an exchange, with cold wallet), or go full non-custodial, so you don't own any private keys at all?

I'm curious what kind of users you expect to use your service.
tsl
newbie
Activity: 3
Merit: 15
Hello,

I'm creating an application which allows users to have their own addresses from which they can deposit/withdraw from. When users withdraw from an address generated from my wallet to their own personal wallet, I'd like to account for fees and let users aware of these fees before actually withdrawing.

My initial idea to do this would go as follows:

1) User inputs a desired value that they want to withdraw which sends a request to my backend
2) I then create a "mock" transaction (whether is be by manually creating it or with fundrawtransaction)
3) Get the resultant the number of inputs/outputs of the transaction/the resultant tx size in bytes
4) Use this resultant tx size to estimate the actual fee based off a certain feerate
Note: this feerate will be decided by user and based on whether they want a faster tx time w/ lower fees or a slower tx time w/ higher fees
5) Add this fee to the total withdraw amount

However, this seems to be a bit "overkill" since every time a user enters a value to withdraw (even if they do not go through with it), I'd have to create a new transaction and this seems unnecessarily intensive.

Another idea I had was to ignore the part of actually creating the transaction but instead checking the minimal amount of transaction inputs/outputs that I'd need for the transaction with something like listunspent and then calculate the total tx fee with the formula: (n_in*148 + n_out*34 + 10) * feerate.

As a follow up question, would I then have to create raw transactions to properly implement these fees? It seems that the JSON RPC commands like sendtoaddress and fundrawtransaction do not provide enough flexibility when setting user fees.

Any input would be appreciated! And if there is anything that I seem to be confused/wrong about, please let me know Smiley
Jump to: