Parts
- Description
- Notes
- Recipe
- Example
Description
This recipe describes a method of managing the fee and broadcast of a Bitcoin transaction.
If a transaction is not mined, a new version should be constructed with a higher fee. Once the previous version has been cleared from memory pools of accessible Bitcoin nodes, the new version can be broadcast. If you have access to a node that accepts replace-by-fee transactions, the new version can be broadcast immediately.
Notes
This recipe was originally published in the article Storing bitcoin on an offline Raspberry Pi, in the section Recipe For Managing The Fee And Broadcast Of A Bitcoin Transaction #2. The recipe shown here has been edited for republication.
A previous recipe with this title was published in the article Creating and signing a standard raw Bitcoin transaction, in the section Recipe For Managing The Fee And Broadcast Of A Bitcoin Transaction.
Several points concerning Bitcoin transactions:
- New transactions spend unspent-outputs-of-previous-transactions. These can also be called "inputs".
- The bitcoin balance of an address is the sum of the unspent outputs sent by previous transactions to this address.
- To spend bitcoin from an address, the bitcoin amount must be constructed from complete inputs. Any change can be sent in a new unspent output back to the original address or to another address that you control. Inputs cannot be broken into smaller inputs prior to spending - new inputs (larger or smaller) must be created by a new transaction.
If a transaction disappears from the network (i.e. the memory pools of all public nodes), this doesn't mean that it has vanished permanently. Anyone who stored it can rebroadcast it later - it will still be valid. In order to make it invalid, create a new transaction that uses at least one of the same inputs.
An input in a new transaction is an as-yet-unspent output of a previous transaction. Each unspent output can only ever be spent once. If a transaction is broadcast that uses at least one input that has already been spent, this transaction is invalid and will not be mined.
Recipe
Objectives:
- Fine control of the transaction fee.
- Ability to rebroadcast a new transaction with a higher fee if the previous transaction is not mined within a reasonable time period. This new transaction, if mined, should invalidate the previous transaction.
1) Gather / choose the required data for a new transaction. How to do this is not specified in this recipe. Include at least one "change address" output. Inputs should be added as necessary to achieve the desired output values. The sum of the inputs may be greater than the sum of the desired output values, i.e. some bitcoin may be left over. This left-over bitcoin should be sent to the change address output. Include an additional input that is specifically for paying the as-yet-unknown transaction fee.
2) Look at current Bitcoin network transaction fee rates. How to do this is not specified in this recipe. Choose a fee rate for the transaction.
3) Use a software tool to create and sign a transaction with the specified fee rate. This tool must be able to calculate an estimate of the transaction size in order to derive a fee value from the fee rate. This fee value should then be subtracted from the value assigned to the change address. After the tool has created and signed the transaction, it should calculate and report the actual fee rate of the final signed form of the transaction. The process / structure of the software tool is not specified in this recipe.
4) Broadcast the transaction to the Bitcoin network or upload the transaction to a service that can do this for you. How to do this is not specified in this recipe.
5) A node will store unconfirmed transactions in its memory pools for a particular time period. If the transaction is not mined (confirmed) within this period, the node will delete it from its memory pool. This period will vary depending on the node. Some reading indicates that the default period is 72 hours (3 days). I have observed this event during a previous project (Storing bitcoin on an offline Raspberry Pi) - the delay was about 48 hours (2 days). After broadcasting the transaction, wait 3 days + a small delay. If the transaction is mined during this period, stop here (and wait for the transaction to be 6 blocks deep in the Bitcoin blockchain). Otherwise, confirm that it has been deleted from the relevant node's memory pool (by e.g. looking up the transaction's txid) and continue to step (6).
Note: [untested idea] If you run a node that accepts replace-by-fee transactions (or have access to a service that does this), then you can upload a new version of the transaction immediately, without waiting for it to be removed from the node's memory pool. If there exists a path through the Bitcoin network from your node to a miner's node, consisting of nodes that all accept replace-by-fee transactions, then the new version of your transaction will propagate along this path, allowing you to quickly replace an unconfirmed transaction with a new version. The miner's node will probably be set to accept replace-by-fee transactions for mining, as the new version with the higher fee is necessarily more profitable to mine.
6) Look at current Bitcoin network transaction fee rates. How to do this is not specified in this recipe. Choose a higher fee rate than the one chosen in step (2).
7) Repeat steps (2)-(6) until the transaction is mined.
Example
I'll summarise a transaction sequence from the previous project Storing bitcoin on an offline Raspberry Pi that demonstrates the process of the creation and broadcast of a new version of a transaction with a higher fee.
The information here is taken from the Notes section in this previous project, in the parts "Addresses generated and/or used in this project" and "Transactions created during this project".
Initial conditions:
- I created a test address on an offline Raspberry Pi computer:
1vkb4YyPMFcxyC83Z5m5zuN45xASoHeNK
- My LocalBitcoins account receiving address 1:
369Dpo9CrJASneaHLdwWfKym7N84XTUyvH
Transaction sequence:
- tx0: I used LocalBitcoins to transfer some bitcoin to the test address. LocalBitcoins created a transaction that included this transfer.
- tx1a: I created a transaction on the offline Raspberry Pi that transferred the available bitcoin from the test address to my LocalBitcoins receiving address 1. I used a transaction-broadcasting service to broadcast it to the Bitcoin network. This transaction was never mined.
- [tx1b is not included here - it is not relevant to this summary.]
- tx1c: I created a transaction on the offline Raspberry Pi that transferred the available bitcoin from the test address to my LocalBitcoins receiving address 1, using a higher fee than in tx1a. This was a replace-by-fee transaction (only the fee was different), which is valid on the Bitcoin network (unlike a double-spend transaction), but the two transaction-broadcasting services still rejected it. I waited until tx1a had been cleared from the memory pool of one of the transaction-broadcasting services (I knew it had been cleared when looking up its txid on the service produced no results), and then uploaded tx1c again to that service. This time, the service accepted tx1c, which was later mined.
Transaction details:
1) tx0: I used LocalBitcoins to transfer some bitcoin to the test address. LocalBitcoins created a transaction that included this transfer.
txid0:
07cedb340f588dec2fb14472178a92d5803c70d8d90fc0d8593b03f34035e2cd
I did not obtain and use the raw byte sequence of transaction tx0. Instead, I used a service to get the information I needed about an output in tx0. To repeat my steps, browse to the link below, click "Advanced Details", and click "API Call". The result will be the service's information concerning tx0, not the raw form of tx0 as it is stored in the Bitcoin blockchain.
live.blockcypher.com/btc/tx/07cedb340f588dec2fb14472178a92d5803c70d8d90fc0d8593b03f34035e2cd
Key details:
- block_hash:
0000000000000000001b43b8af8973377619def5043634e9cb2d7dd584d973be
- block_height: 550741
- confirmed: 2018-11-19T19:46:37Z
- received: 2018-11-19T19:46:37Z
- txid:
07cedb340f588dec2fb14472178a92d5803c70d8d90fc0d8593b03f34035e2cd
- vout_sz (number of outputs): 32
tx0 sent a new unspent output to the test address.
From tx0, I acquired the following data of this particular unspent output, allowing me to use it as the input in tx1:
- index: 15
- value: 0.002 bitcoin
- The txid of tx0, which contains this unspent output, is:
07cedb340f588dec2fb14472178a92d5803c70d8d90fc0d8593b03f34035e2cd
2) tx1a: I created a transaction on the offline Raspberry Pi that transferred the available bitcoin from the test address to my LocalBitcoins receiving address 1. I used a transaction-broadcasting service to broadcast it to the Bitcoin network. This transaction was never mined.
txid1a:
add54b899f1aba8b6276e42af86c3c03b0120a864451640b4a8d3fec89a4a72d
tx1a (raw byte form):
0100000001cde23540f3033b59d8c00fd9d8703c80d5928a177244b12fec8d580f34dbce070f0000008a473044022005fc767d513f285c38f718f4c9cfb0909d4ba2d80131aed21b3f26aa630a79f0022044c9b3c0fb4a9d1a8b0c269915399112eea5ee4fd7e42fc0a430a47e5ecbb4520141043ab692792d6c8838fd30c2ff45bf3cbd44286a5cac52ba64dc06452810202b3206f5c7799c3b72ff77fd1976f105ced3cd7700b0412e11266f3888b88c3052c3ffffffff01630c03000000000017a91430d540a50d464852194a195529ebfa44af521bbb870000000001000000
3) tx1b: [not included here]
4) tx1c: I created a transaction on the offline Raspberry Pi that transferred the available bitcoin from the test address to my LocalBitcoins receiving address 1, using a higher fee than in tx1a. This was a replace-by-fee transaction (only the fee was different), which is valid on the Bitcoin network (unlike a double-spend transaction), but the two transaction-broadcasting services still rejected it. I waited until tx1a had been cleared from the memory pool of one of the transaction-broadcasting services (I knew it had been cleared when looking up its txid on the service produced no results), and then uploaded tx1c again to that service. This time, the service accepted tx1c, which was later mined.
txid1c:
8b0f7ba372b61b195cd237429c9a5d079aaf9887e72dd094f2fa942a0f7ccfc0
tx1c (raw byte form):
0100000001cde23540f3033b59d8c00fd9d8703c80d5928a177244b12fec8d580f34dbce070f0000008b483045022100af984f21f3096c47b9684d9cccf76988597accbdb55ff0b66992ef4b3006160802205f6bad0dce3fc5c01ac3128f643302d55b952edf656be25ee996049d74a0e41c0141043ab692792d6c8838fd30c2ff45bf3cbd44286a5cac52ba64dc06452810202b3206f5c7799c3b72ff77fd1976f105ced3cd7700b0412e11266f3888b88c3052c3ffffffff0146d402000000000017a91430d540a50d464852194a195529ebfa44af521bbb870000000001000000
Key details:
- block_hash:
000000000000000000091db255f327f3938cb33cd1076d7554b7bbd22b9c1000
- block_height: 551106
- confirmed: 2018-11-22T20:17:05Z
- received: 2018-11-22T17:46:01.324Z
- hash (txid):
8b0f7ba372b61b195cd237429c9a5d079aaf9887e72dd094f2fa942a0f7ccfc0
- vout_sz (number of outputs): 1