Technical notes on coin-splitting

When Bitcoin Cash split from Bitcoin SV to become some strange variation on what Bitcoin used to be, we were left with a problem. Transactions made for either blockchain were valid for the other blockchain. This meant that if a user sent unsplit Bitcoin SV, it would also move the Bitcoin Cash to the same payment destinations. And vice versa, sending the Bitcoin Cash would send the Bitcoin SV.

This article is not intended for non-technical users. It is intended to define the current technical state of coin-splitting for my own reference, as of the date of writing. If you are reading it and you are technically inclined, please point out anything I have recalled incorrectly or gotten wrong.

Nuances

There are a range of nuances to how coin-splitting has worked, since Bitcoin Cash split from Bitcoin SV — and how it works now. I will attempt to summarise them all, incorporating any notes I may have made about them at any point within the ElectrumSV channel of the Metanet.ICU slack.

An insightful comment I made months ago on Metanet.ICU for interested slack members.

The blockchain height of a transaction

When Bitcoin Cash split from Bitcoin SV, both blockchains had the Bitcoin Core altered mempool. This only accepted transactions valid in the next block, and would not accept non-final transactions valid for some future block beyond that.

However what wallets did, including the Bitcoin node wallet and ElectrumSV, was mark the inputs in their transactions as non-final and set the block height of the transaction to the next expected mining height. This prevented the transaction from being mined in any earlier block. The reason they did this was due to an imagined problem they called “fee sniping”. In their world, it was possible (though never observed for some reason) that miners would reorg the blockchain to mine selected high fee transactions themselves and steal them away from whatever miner had previously mined them. The mempool would accept transactions intended for the next block, and so these transactions would get mined and this fee sniping “problem” would be prevented.

So Electron Cash continued to make these non-final transactions, and ElectrumSV kind of accidentally stopped making them. Our lower level transaction manipulation code was rewritten by Neil, and our inputs went from having an nSequence value of 0xFFFFFFFE to 0xFFFFFFFF. We still set the block height of the next expected block on the transaction, but it was ignored as our transactions were now effectively finalised. But this was irrelevant anyway because fee sniping is an imagined problem and it brings us to the next point — the difference in blockchain heights.

The current Bitcoin Cash block height.
The current Bitcoin SV block height.

Because those parties who favoured Bitcoin Cash panicked and spent a lot of money on hired hash to mine it, the Bitcoin Cash blockchain ended up 330 or so blocks ahead of Bitcoin SV. This means that it takes Bitcoin SV around two days to reach the height Bitcoin Cash is at. A user could broadcast a transaction on Bitcoin Cash, and Bitcoin SV would ignore it as it could not accept it into the mempool. This would give them those two days to broadcast a different transaction on the Bitcoin SV blockchain, as the easiest way to split their own coins.

This is also not a solution regular people should try unless they have someone guiding them through the process. Anyway, it is now obsolete and cannot be relied upon.

Splitting by mixing with already split coins

The approach ElectrumSV went with was to use a faucet to obtain a small amount of already split Bitcoin SV. By combining this in a transaction with a user’s unsplit coins, it implicitly made that transaction Bitcoin SV only and split those coins.

The faucet splitting option from the coin-splitting tab.

Using the ElectrumSV UI that manages this faucet splitting process is more suitable for regular people, ignoring that the whole manage your own coins Bitcoin experience ElectrumSV presents kind of isn’t.

The addition of Schnorr signatures to Bitcoin Cash

Bitcoin Cash added support for Schnorr signatures. Electron Cash for instance enables them by default, and uses them for non-multi-signature and non-hardware wallet signing. When these are used any transaction constructed switches out the ECDSA signature for a Schnorr signature, using the same public key. The transaction will be invalid on Bitcoin SV as the nodes will see the signature as invalid, not knowing anything about Schnorr signatures.

This is also not a solution regular people should try unless they have someone guiding them through the process. What if they don’t pay attention to what they are signing, and it’s a hardware wallet? What if they have an existing wallet and the setting is not enabled?

Bitcoin Cash nodes and low Bitcoin SV fees

It is not uncommon these days for Bitcoin SV transactions to use a fee rate of 0.5 satoshis per byte. However, almost all Bitcoin Cash nodes will not accept these transactions — either directly from you via an Electron Cash server or propagated from another Electron Cash node who did accept them. It is very unlikely Bitcoin SV transactions with fees at this level will ever be mined on Bitcoin Cash.

This is also not a solution regular people should try unless they have someone guiding them through the process. What if somehow their transaction does get mined? I’m not providing no guarantees. What if they had an existing fee setting and it was high enough for the transaction to get relayed?

Splitting by using Bitcoin SV features

As an alternative to the faucet coin-splitting, ElectrumSV also offers another approach it calls “Direct splitting.” This adds an additional data output that is not valid on Bitcoin Cash, making the transaction incompatible.

The direct splitting option from the coin-splitting tab.

Using the ElectrumSV UI that manages this direct splitting process is more suitable for regular people, ignoring that the whole manage your own coins Bitcoin experience ElectrumSV presents kind of isn’t.

The restoration of a correct non-final mempool on Bitcoin SV

The Genesis upgrade to the Bitcoin SV protocol restored correct non-final transaction support. This means that all those Bitcoin Cash transactions that were non-final and had a block height a couple hundred blocks ahead of the current Bitcoin SV blockchain were now accepted into the Bitcoin SV mempool as non-final transactions. Relying on the blockheight, and broadcasting a transaction on Bitcoin Cash first as a means of coin-splitting no longer worked.

If a user does not split their coins and sends a Bitcoin Cash transaction, and did not or could not use Schnorr signatures, they have just over two days to construct a final version of the transaction that spends the same inputs in the same order with at least one higher nSequence value.

The relevant text from the Genesis upgrade document.

There is no known software which can do this, but a technically apt user can modify the ElectrumSV source code to do it — and at least one has successfully finalising the spending of the given coins and changing where they were going.

In theory, ElectrumSV could allow importing the Bitcoin Cash transaction and recognising it as non-final, allowing some general UI that updates and publishes updated versions whether final or not to the miners. But we have other priorities at this time. It may happen along the way, but not because of any special intention to support it.

ElectrumSV developer