Note: This article assumes you know what replay protection, UTXO’s and how replay protection works.

Replay protection had been one of the hot topics in Bitcoin space when there was no replay protection segwit2x Hard fork. Here are a couple of interesting things which I learnt through many discussions about providing replay protection in segwit2x fork.

Native replay protected transaction:

A transaction which is valid on one chain and not valid on other chain and not valid on the other chain by consensus rules. An important characteristic here is that even in reorgs of blockchain, Native replay protected transactions cannot be replayed on the other chain.

Native replay protection using blocksize Limit:

Even though segwit2x chain has base transaction size limit of 1000000(possibly added to prevent quadratic hashing), it can cleverly used to make a transaction that is valid only in segwit2x chain but not on bitcoin chain.

Bitcoin Block Size = Bitcoin Header + Coinbase + Rest of transactions

Rest of transaction<= Bitcoin block size - header - Coinbase

Max single transaction size <= 1000000 - 80 </code>

A transaction which is slightly less than 1000000 can’t be a transaction in bitcoin block, but it can fit in segwit2x block. Note that this transaction is however does not pass the isStandard() checks in most reference clients. So, it is accepted or repaly by any node. It can still be mined by any miner.

Native replay protection using sigOps Limit:

The best way to attack bitcoin using the sigops limit per block was discussed at length in this bitcoin talk post. We use a similar bitcoin script to inflate the sigops count so that is accepted in segwit2x chain, but not in the bitcoin chain. Bitcoin uses SigOps limit 20,000k per block as a consensus rule. Also, because of the 520 bytes contraint on P2SH redeem script size, it is only possible to make a transaction with 15 such inputs(~225 SIGOPS) to pass bitcoin IsStandard() test. Therefore, this way would also require miner co-operation because making more sigops per transaction would fail IsStandard().

Providing replay protection as a service:

With the above native replay protection methods, you can get your coins split without relying on double-spending methods(like rbf with nlocktime) which are prone to re-org attacks. Once, you split your coins,

Sighash Types:

Most bitcoin transactions require signature to spend UTXO’s. An important question which is not discussed often is which data used in the signature. That is determined by the sighash. Here, I would just list the relevant sighash types for this experiment, but others can be found at bitcoin wiki. SIGHASH_SINGLE the only output signed is the one corresponding to this input (the output with the same output index number as this input), ensuring nobody can change your part of the transaction but allowing other signers to change their part of the transaction. SIGHASH_SINGLE can be combined with the SIGHASH_ANYONECANPAY (anyone can pay) SIGHASH_SINGLE BITWISEOR SIGHASH_ANYONECANPAY signs this one input and its corresponding output. Allows anyone to add or remove other inputs.

How to provide replay-transaction as a service?

Suppose you have already split coins by any method. That is you have different UTXO’s on both the chains.

Simply, create a transaction with 1 input and 1 output and sign it with SIGHASH_SINGLE and SIGHASH_ANYONECANPAY(bitwise OR), with the output amount being slightly higher than the input amount. Note that both the output address is also controlled by the sender, that way you get some extra fees for providing replay protection as a service. Thus, this way provides non-custodial non-interactive replay protection.This is non-custodial because all the signing takes places at offline at client side and it is non-interactive because this type of transactions are just shoot and forget and hope some will add outputs and mine it.

Then, you simply broadcast this transaction via the internet, reddit posts etc. People can add their own inputs/outputs with SIGHASH_ALL and get their coins split. Since the transaction spends 1 UTXO which is only valid in 1 chain, it is replay protected, plus it is also re-org protected if the UTXO was generated by native replay protection methods.

Consequences:

This will create a market for transactions, since people can easily add/remove outputs from this transaction, it is likely that the person paying the most fees will get his coins split first. But, the important part here is that this is non-interactive, so there is no co-ordination required between parties. This is a huge plus compared to approaches which involve interactive coin-join setup between parties.

Acknowledgments:

Ideas are derived from community learning through slack groups. If there is any fault in the article, please comment to let me know.