Replay protection schemes in Segwit2X

Micah Lerner
Bitcoin Tech Talk
Published in
6 min readNov 1, 2017

With the recent Bitcoin Gold fork and planned Segwit2X fork in mid-November, the topic of keeping coins safe after disruptive events is especially relevant. As discussed previously on BitcoinTechTalk, a facet of maintaining the safety of one’s coins post-fork is replay protection — making sure that a transaction made on one Bitcoin fork cannot be spent (or replayed) on another.

The upcoming Segwit2X fork has been contentious partially because of how it approaches replay protection. After initially not planning to include it, this decision was reversed. An initial implementation was accepted, but that too was ultimately reverted.

Following this first implementation, several proposals for replay protection schemes were put forward. We will first go over why the original replay protection scheme was reverted, then dig into the other proposed ideas, along with the pros and cons of each.

How was Segwit2x replay protection originally implemented?

The first implementation of replay protection for Segwit2X involved sending your Bitcoin to a new address, or addresses, while also including a transaction output to 3Bit1xA4apyzgmFNT2k8Pvnd6zb6TnwcTi — this scheme is called Pay To Script Hash, or P2SH.

The output to this address had an unsecured redeem script, meaning that anyone could spend that output. While theoretically anyone could create a transaction spending this output, it is likely that miners would collect them and include them in a block first. This idea served as an incentive for miners to “sweep up” these outputs.

Before the fork, a transaction that included this script hash as an output would have been valid on both chains. After the fork, a transaction that included this output would only be valid on the Bitcoin Core chain. Thus, you could split your coins by sending them to an address you owned, and also including an output to the magic address above. This transaction would not be valid on the Segwit2x chain after the fork, meaning that it could not be replayed.

Why was the first replay protection scheme reverted?

While there was lengthy discussion about the aforementioned scheme, several factors stand out as reasons for reverting: the ease of use with wallets, and implications for technologies built on top of the Bitcoin protocol (like the Lightning Network).

Wallets were a main concern in terms of backwards compatibility. While many Bitcoin clients do support the option to send to multiple addresses at once, this option is not always friendly —many users of the network are only familiar with sending to a single address at a time.

The discovery of an exploit involving Lightning Network transactions was another reason for this scheme to be reverted. The main premise of Lightning is to allow for parties to transact off chain in channels. These channels allow for members of the network to transact without committing state to the chain (which incurs transaction fees).

To open a channel, a transaction is first committed to the chain. Commonly, redeeming this transaction requires the signatures of several parties, or can be spent after a certain period of time by one of the parties. If one party is sending Bitcoin to another, they may gradually transfer up to the maximum that was originally committed to. For example, with a 1 Bitcoin maximum commitment from Addison, Addison can send Bailey a transaction that allocates 0.1 Bitcoin to Bailey, and 0.9 back to Addison. Addison can later send another transaction with 0.2 to Bailey, and 0.8 to Addison. At any time, Bailey can redeem a transaction from Addison by publishing it to the chain, thereby closing their channel.

As described earlier, post-fork Segwit2x would reject transactions with the magic address contained in a transaction output. If Addison is malicious, they can sign a transaction, and send it to Bailey with a catch — the coins that are going to Addison point at this scheme’s magic address. If Bailey tries to commit this transaction after the fork, it will not be accepted. If the timeout for the original transaction passes, Addison can spend all 1 Bitcoin, and Bailey receives nothing.

After further discussion, the P2SH approach was reverted in favor of pursuing other promising replay protection schemes. The schemes we will go into have their pros and cons, which can be summarized into several categories: technical debt, compatibility, and ease-of-use.

What are other Segwit2X replay protection schemes?

While several replay protection schemes have been proposed, a handful have reached proof of concept:

  • Setting transaction version numbers
  • Opt-in replay protection for 2x chain (using SIGHASH)
  • Opt-in replay protection for 1x chain (using OP_RETURN)

It is worth noting that a code change in compatible clients is needed for these approaches. Including consensus-enforced replay-protection in other Bitcoin implementations can be a logistical challenge, especially on the shortened timescale of the Segwit2x release.

As an example, Bitcoin Unlimited is a fork that follows the chain with the most work, and intends to be compatible with Segwit2x. It, and other compatible Bitcoin implementations, would need to integrate Segwit2x’s chosen logic before the fork. If they don’t, Segwit2x and Bitcoin Unlimited would fork away from each other, as they would not replay protect the same transactions.

Setting transaction version numbers

This proposal involved setting transaction version numbers to signal whether the transaction is for a 1x or 2x chain. If the required version numbers are not set in a transaction to replay protect it, then it can be included in a block post-fork.

The simplicity of this idea is a main reason for its support. Additionally, it does not require more space on the chain (as we will learn the OP_RETURN approach does).

This approach consumes version numbers that may be need for a separate purpose in the future — these versions are a limited resource. Technical debt accrues without a plan to sunset versions as a method to replay-protect transactions.

Opt-in replay protection for 2x chain (using SIGHASH)

The second replay protection scheme involves allowing a new signature hash type following the Segwit2x fork. A signature hash is generated from signing different parts of a transaction — which parts of the transaction are signed depends on which SIGHASH options are used. After the first block of the fork, transaction signatures can be generated and verified using this new flag, if they should be replay protected.

Like with setting transaction version numbers, other clients would need to be aware of this approach. Additionally, it is possible that wallet applications would not be able to understand this scheme. Unfortunately, this would go against one of the stated goals for Segwit2x replay-protection schemes — not to break wallets.

Opt-in replay protection for 1x chain (using OP_RETURN)

This approach involves generating transactions with a special output containing the OP_RETURN method. This method allows adding arbitrary data to the blockchain, and can return up to 80 bytes of stored data. In this case, a replay-protected transaction returns “RP=!>1x”. Much like the original P2SH scheme described earlier, these transactions can not be included in Segwit2x blocks after the hard fork, and use a special transaction output. The proposal avoids jeopardizing Lightning Network transactions in the manner described previously, and some believe it is relatively easier for wallets to implement, compared to P2SH.

This approach does have some other advantages over the original P2SH scheme. Transaction outputs with OP_RETURN only store byte data, meaning that there is no way to redeem them. Many nodes in the Bitcoin network maintain a list of transactions that can be redeemed, and would immediately be able to prune the OP_RETURN transaction output from this set because it is not redeemable. This is not true of the P2SH scheme, which adds a valid unspent output that miners must clean up later.

Still, there are several downsides to this approach. The data after the OP_RETURN is several bytes and as a result, adds data to the 1x blockchain when this transaction is stored. Some view this as being unfair to the 1x chain — in order for Segwit2x to have replay protection, the 1x chain must store more data. This downside is counteracted by the intention to remove this technical debt eventually — there is a “sunsetting clause” after which it is assumed that all coins have split to the 1x or 2x chains (at the time of writing, the exact date of sunset is under debate).

Conclusion

It has been suggested that one or more of these schemes would be merged before the Segwit2x fork in mid-November. Excitingly, replay-protection schemes are an active area of development.

--

--

Micah Lerner
Bitcoin Tech Talk

Currently: Software Engineer with Bitwise Asset Management. Previously: Strava, Cornell