Bitcoin exchange – What’s Needed

Transaction malleability is once again affecting the entire Bitcoin network. Generally, this causes a lot of confusion more than anything else, and results in seemingly duplicate transactions until the next block is mined. This can be seen as the following:

Your original transaction never confirming.

Another transaction, with the same amount of coins going to and from the same addresses, appearing. This has a different transaction ID.

Often, this different transaction ID will confirm, and in certain block explorers, you will see warnings about the original transaction being a double spend or otherwise being invalid.

Ultimately though, just one transaction, with the correct amount of Bitcoins being sent, should confirm. If no transactions confirm, or more than one confirm, then this probably isn’t directly linked to transaction malleability.

However, it was noticed that there were some transactions sent that have not been mutated, and also are failing to confirm. This is because they rely on a previous input that also won’t confirm.

Essentially, Bitcoin transactions involve spending inputs (which can be thought of as Bitcoins “inside” a Bitcoin address) and then getting some change back. For instance, if I had a single input of 10 BTC and wanted to send 1 BTC to someone, I would create a transaction as follows:

10 BTC -> 1 BTC (to the user) and 9 BTC (back to myself)

This way, there is a sort of chain that can be created for all Bitcoins from the initial mining transaction.

When Bitcoin core does a transaction like this, it trusts that it will get the 9 BTC change back, and it will because it generated this transaction itself, or at the very least, the whole transaction won’t confirm but nothing is lost. It can immediately send on this 9 BTC in a further transaction without waiting on this being confirmed because it knows where the coins are bitcoin atm going to and it knows the transaction information in the network.

However, this assumption is wrong.

If the transaction is mutated, Bitcoin core may end up trying to create a new transaction using the 9 BTC change, but based on wrong input information. This is because the actual transaction ID and related data has changed in the blockchain.

Hence, Bitcoin core should never trust itself in this instance, and should always wait on a confirmation for change before sending on this change.

Bitcoin exchanges can configure their primary Bitcoin node to no longer allow change, with zero confirmations, to be included in any Bitcoin transaction. This may be configured by running bitcoind with the -spendzeroconfchange=0 option.

This is not enough though, and this can result in a situation where transactions cannot be sent because there are not enough inputs available with at least one confirmation to send a new transaction. Thus, we also run a process which does the following:

Checks available, unspent but confirmed inputs by calling bitcoin-cli listunspent 1.

If there are less than x inputs (currently twelve) then do the following:

Work out what input is for around 10 BTC.

Work out how to split this into as many 1 BTC transactions as possible, leaving enough space for a fee on top.

Call bitcoin-cli sendmany to send that ~10 BTC input to around 10 output addresses, all owned by the Bitcoin marketplace.