Bitcoin Forum
June 09, 2025, 08:45:59 PM *
News: Latest Bitcoin Core release: 29.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: How do Input size and change work?  (Read 76 times)
notausername (OP)
Newbie
*
Offline Offline

Activity: 1
Merit: 3


View Profile
June 06, 2025, 02:45:09 AM
Merited by ABCbits (2), stwenhao (1)
 #1

I'm prototyping a project that receives BTC to an address A, then sends that BTC to an address B. The goal is to empty address A to leave as little BTC in it as possible, none if possible. (Before you ask, no I'm not coding malware so chill out)

I'm using python and the bitcoinlib package to do so.

I'm trying to find the best way to calculate how much BTC should be sent in the transaction and how much should be used to pay for the transaction's fee.




From my understanding, when BTC is received to an address B, the BTC isn't actually recorded as being in address B. It's rather the address A that sent that BTC that is recorded as an input in address B. Like how adding a 20$ bill to your wallet that has 80$ in it doesn't fuse all the money into a 100$ bill, but rather keeps it all separated as it was added to the wallet (a 20$ bill, a 50$ and a 10$ for example).

So considering the following situation:
We have address D that is empty (no inputs/no outputs)

Address A sends 1 BTC to address D

Address B sends 2 BTC to address D

Address C sends 0.5 BTC to address D


Address D "technically" doesn't have 3.5 BTC in it, it rather has 1 BTC and 2 BTC and 0.5 BTC (which is a total of 3 inputs into address D).
I know this is a very interpreted way of explaining it but do I get that right?






Now, if I were to send ~1 BTC (1 BTC - transaction fee) from address D to another. Am I the one that chooses which inputs from address D to send the BTC from or does the blockchain choose that? If so, would the input that would cause the lowest fees be Address A since it would only be 1 input and 1 output? Would it also make just 1 output as the entirety of the input of address A would be spent?



If I were to send ~0.25 BTC (0.25 BTC - transaction fee) from address D to address E. Using address C as input, that would mean there would be 2 outputs. One output being address E and another output being address D as change (considering address D was set as the change address). Is that right?







If I'm using a package/library that handles the choosing of inputs and outputs for me. When calculating the fee for a transaction, I'm assuming there isn't an accurate way to know the fee that transaction would cost as I wouldn't know how many inputs and outputs it would take to do that transaction? In this situation, what would be the best way to calculate the fees for said transaction?
stwenhao
Sr. Member
****
Offline Offline

Activity: 262
Merit: 446


View Profile
June 06, 2025, 03:58:29 AM
Merited by ABCbits (5), hosemary (4), nc50lc (2), Mia Chloe (1)
 #2

Quote
Address D "technically" doesn't have 3.5 BTC in it, it rather has 1 BTC and 2 BTC and 0.5 BTC (which is a total of 3 inputs into address D).
I know this is a very interpreted way of explaining it but do I get that right?
Yes.

Quote
Am I the one that chooses which inputs from address D to send the BTC from or does the blockchain choose that?
You can choose any of your inputs. Some wallets can do that for you, but from the protocol perspective, any user can pick any coins, and also decide about their order.

Quote
If so, would the input that would cause the lowest fees be Address A since it would only be 1 input and 1 output?
It depends on the final transaction size in virtual bytes. You can prepare your transaction with zero fees, sign it, and then check, how many virtual bytes it takes, and then decrease output amounts however you want, to make transaction fee out of that.

Quote
Would it also make just 1 output as the entirety of the input of address A would be spent?
User can pick any inputs in any order, and user can also make any outputs, with any amounts, in any order, and with any address types. From the protocol level, user can make any transaction. As long as it is valid, it will be accepted. Which means, that you can send all coins to one address, as a single coin, but you can also split it between many smaller coins. Even if splitting is unnecessary, as long as transaction is valid, it will work.

Quote
If I were to send ~0.25 BTC (0.25 BTC - transaction fee) from address D to address E. Using address C as input, that would mean there would be 2 outputs. One output being address E and another output being address D as change (considering address D was set as the change address). Is that right?
Code:
+-------------------------------------------+
|+------------------+    +-----------------+|
|| Daniel  0.25 BTC | -> | Elaine 0.40 BTC ||
|| Charlie 0.50 BTC |    | Dave   0.10 BTC ||
|+------------------+    +-----------------+|
+-------------------------------------------+
Is that what you wanted to achieve? All inputs of a given transaction are used to make all outputs of a given transaction. As long as things are signed with SIGHASH_ALL, everything is signed by each and every input. Which means, that you have just the sum of all inputs (0.25+0.50=0.75), and the sum of all outputs (0.40+0.10=0.50), and then the difference between them (0.75-0.50=0.25) is the transaction fee. Which means, that 0.40 BTC from Elaine does not come only from 0.25 BTC held by Daniel, or only from 0.50 BTC held by Charlie. It comes from both, unless you have signatures other than SIGHASH_ALL. And the same with Dave.

So, by default, you have all inputs, which are used to make all outputs, and nobody knows, which input was used to make which output. Of course, people can try to guess it, by looking at amounts, and judging, that if everyone transferred 0.01 BTC input to 0.009 BTC output, and one 1 BTC input was moved into one 0.999 BTC output, then they are likely to be connected, but from the protocol perspective, all inputs made all outputs, even if humans can guess it right, who sent what to whom.

Quote
In this situation, what would be the best way to calculate the fees for said transaction?
1. You prepare everything with zero fees.
2. You sign it with zero fees, and check, what is the size of your transaction.
3. You adjust output amounts, however you like.
4. Changing coin amounts does not affect transaction size, so it will have the same feerate.
5. You sign the final version, with non-zero fees, and broadcast it to the network.

mcdouglasx
Sr. Member
****
Offline Offline

Activity: 658
Merit: 280


View Profile WWW
June 06, 2025, 06:28:26 PM
Merited by nc50lc (1)
 #3

When you talk about the inputs of a transaction from the perspective you mentioned, the correct way to refer to it would be UTXO.

You can filter these UTXOs by address, which would be the most convenient in your case, however, you could filter them by amount or by age.

Regarding Python, You can use a Bitcoin node to interact with Bitcoinlib or an external API to create transactions at your own convenience.

also you could use an API to automate the estimation of the current fee(taking into account that these APIs have certain limits in their free versions), like:

Code:
import requests

def GetFees():
    url = "https://mempool.space/api/v1/fees/recommended"
    try:
        response = requests.get(url)
        response.raise_for_status()
        data = response.json()
        return data
    except requests.RequestException as e:
        print(f"Error: {e}")
        return None

def main():
    fees = GetFees()
    if fees:
        print("fees (sat/vB):")
        print(f"faster (fastestFee): {fees.get('fastestFee')} sat/vB")
        print(f"30 minutes (halfHourFee): {fees.get('halfHourFee')} sat/vB")
        print(f"1 hour (hourFee): {fees.get('hourFee')} sat/vB")
        if 'minimumFee' in fees:
            print(f"Minimun fees(minimumFee): {fees.get('minimumFee')} sat/vB")
    else:
        print("Error")

if __name__ == '__main__':
    main()


and then apply that data to the weight of your transaction to calculate the fees.

But I recommend taking a look at the BitcoinLib documentation, as this topic is sensitive and you could end up losing funds if you make a mistake.



4. Changing coin amounts does not affect transaction size, so it will have the same feerate.

This is only valid if the number of inputs and outputs does not change, if the new amount requires more UTXOs to complete the amount sent, the transaction will increase in size, which will affect the fees.
NotATether
Legendary
*
Offline Offline

Activity: 1988
Merit: 8575


Search? Try talksearch.io


View Profile WWW
June 08, 2025, 07:52:01 AM
 #4

You can't try to calculate the fee by itself without using an API because there is to native calculation for you to do for obtaining the fees unless you use an API or the Bitcoin Core RPC functions.

Fees are set by the current size of the mempool but there isn't an exact estimation that you can perform unless you gathered all the transactions and calculated the fee that they are paying.

██
██
██
██
██
██
██
██
██
██
██
██
██
... LIVECASINO.io    Play Live Games with up to 20% cashback!...██
██
██
██
██
██
██
██
██
██
██
██
██
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!