Scaling Bitcoin workshop : Stanford 2017

Atomically trading with roger gambling on the success of a hard fork

Atomically Trading with Roger: Gambling on the success of a hard-fork


Ethan Heilman

This is joint work with Patrick McCorry, Andrew Miller and myslef. Patrick was originally going to give this talk but he was unable to make it. I'll give the talk with his slides. I want to acknowledge Roger Ver for permission to use his name in the title of the talk. We asked permission.

I will only be talking about some of the information in the paper. This talk is going to desribe how to do a hard-fork atomic trade protocol for bitcoin. We're looking at how to setup the trade prior to the hard-fork. Two parties can commit to trade, and then once the hard-fork happens, they are forced to trade their coins. So one party has all the coins in fork 1, and the other side has all the coins in fork 2.

This is na interesting lesson because designing this without transaction malleability was non-trivial. It's very complex. We're going to get into how to do that. But when you see how to do it when transaction malleability is fixed, it becomes incredibly simple. It's amazing, it's night and day in terms of complexity.

In our paper, but not in this talk, we have a history of hard and soft-forks in bitcoin and ethereum. If you ever wanted to know how many occurred, you can read our paper for that. We also have a survey for replay protection proposals, including migration inputs. We also did this protocol for ethereum, but I am not going to talk about that here.

This paper came about earlier this year there was talk about bitcoin unlimited doing a hard-fork and Loaded proposed doing a bet with Roger Ver. He said, let's bet 60k coins. Roger would send him 60k BTC in one fork, and Roger would receive 60k BTC in the other. Roger Ver accepted this bet. The interesting thing for me happened when they were discussing how to make this bet happen.

One way they could have done it is to put their transactions in a 2-of-3 multisig and have some trusted third party send out on one fork and then send out another transaction on another fork. Loaded said he would like to do this with an atomic swap method, where you don't need a trusted third-party. I thought this was an interesting idea and there was no protocol yet. So I posted on twitter that it would be col to do this and Patrick McCorry tweeted at me with some ideas on how to do it and we started discussing it, and we realized there was known proposal for doing it at the time, so we began working on a protocol to do this.

Before I describe how we do it, I want to describe what we're trying to achieve. I am going to refer to Alice and Bob rather than Roger and Loaded because this is a general protocol not specific to them. So Alice and Bob... Alice has a coin, Bob has a coin on the pre-fork blockchain. They deposit their coins into a transaction on the blockchain. Then several blocks will occur. Later, a hard-fork will happen. Alice will get all of those coins both hers and Bob's coins in fork 2, and Bob will get all of those coins in fork 1. So they have essentially put their coins up. Alice's coin in fork 1 will be controlled by Bob basically.

Transaction malleability becomes very important to how you design this protocol. The txid of a transaction is just a hash of the transaction but it's malleable because some part is not covered by the cryptographic signature. So this is called malleability. Some third-party or maybe even one of the signers will see a complete transaction and make it so that the transaction itself has a different txid. This makes it really hard to do a chain of unconfirmed transactions, because the second transaction has to refer to the txid that gets into the blockchain. So this eliminates the ability to do long chains of unconfirmed transactions. Without transaction malleability, when we deposit coins on the blockchain-- when Alice and Bob put these coins in a funding transaction, they have to wait for that funding transaction to be confirmed, and then they have to sign additional transactions that depend on it. If they sign the funding transactions... before they sign the funding transactions, if the funding transaction was malleated and the trading transactions would become invalid. If you have segwit (a transaction malleability fix), then you can sign the funding transaction and have other transactions spending it and you don't have to worry about it getting confirmed. This might seem like a small detail, but it's an enormous difference. It becomes much easier to design bitcoin contracts.

I am going to go over the steps we're going to do. The first step is the funding stage. Both parties are going to deposit their coins into a funding transaction on the blockchain. No hard-fork yet. Alice is going to sign a special transaction, called a cancel transaction, which will allow Bob to cancel the atomic swap before some number of blocks in the future. Up until the point, Bob can post a transaction. Next, we're going to setup the trade. Both Alice and Bob are going to exchange and sign transfer transactions. And this is, if you're familiar with atomic swaps, it looks very similar. Alice is going to choose a value r, and the hash will be in the funding transaction. She can only take her money by revealing r, and by doing that, Bob is able to know the value as well and he can do it too. Because Alice is the party that triggers the trade of the swap, we want to make sure she can't back out. She agrees to it and then maybe she decides to back out-- but we want to force Alice to go through with it. So once she signs the forfeit transactions.. if she doesn't trigger the trade, then the money goes to Bob in both chains. Also there's one that cancels Bob's ability to cancel the atomic swap, and then they become locked in, and then the atomic trade is going to occur.

We have a funding transaction with 3 outputs. One output is Alice's deposit. One output is Bob's deposit. The other output is this cancel timer that I am going to explain in more detail. It's how Bob can cancel the transaction. This funding transaction gets confirmed in block 1. It has to be confirmed on block 1 because we're worried about malleability. This isn't the one with the malleability fix. This is the cancelation transaction over here. Bob is going to ask Alice to sign it. It refunds both parties. If Alice refuses to sign it, then Bob can wait for the timeout and they both get refunded. Once Alice signs it, Bob can still cancel the swap by posting into the blockchain. This is, say, 3 blocks from the funding transaction. Alice and Bob are going to sign transfer or swap transactions. This transaction here, allows-- sends Alice's coins to Bob's transfer. And they can only be claimed if Alice reveals the secret r and H(r) encoded in the funding transaction. Similar transaction sends Bob's coins to Alice. They use replay protection to protect-- to lock each of those transactinos into one of the two forks. This protocol requires mandatory replay protection. The Alice to Bob transfer, and the Bob to Alice transfer, only work in particular forks as a consequence of replay protection. Alice is going to sign forfeit transactions, so if she doesn't sign the transfer transaction, then she loses her coins. Alice might say she wont sign forfeit transactions.. so you want to force her, or let Bob out of the protocol. This is the purpose of the cancel transaction. Bob can post the cancel transaction, and then everyone gets refunded. After 3 blocks, there is a commit transaction that Alice can post. It spends this cancel timer and once the cancel timer is spent, the cancelation transaction is no longer valid because the cancelation transaction spends all 3 of the outputs. So this allows Alice to cancel Bob's ability to ancel the transaction. Both parties are locked in. The transaction is funded. It's committed in the blockchain. We've setup cancelation. The atomic trade. The forfeit. And we've committed to the trade. And now we can run the atomic trade.

Hard-fork occurs in, say, block 5. Alice posts the .. Bob to Alice transfer. Bob uses the value r from that transfer to claim his funds in fork 1. And now both parties have received... Bob has got all the coins in fork 1.. and Alice has got all the coins in fork 2. And we can look at how this works under different conditions of failure. At the top we see, where the exchange is successful. Alice gets all the coins in fork 2, Bob gets all the coins in fork 1. We see that if Alice doesn't sign the cancel, then they both get their refund after a timeout. If Alice signs the cancel but then stops signing other transactions, then Bob can post the cancel, abort it, they both get their money back instantly. If Alice signs the forfeit transactions and signs everything, then she gets... and then she doesn't trigger it, then Bob gets all the money. When she signs a forfeit transaction she has to go through the trade.

This protocol is elaborate. It requires 4 off-chain transactions. We have a lot of bitcoin script in the appendix and it's complex. If Alice doesn't sign the cancelation transaction, then ... the ... And the hard-fork time has to be fixed. We can provide a window for the hard-fork to occur in, but if it gets delayed and Alice has committed already, she has betted on the hard-fork occurring and then it doesn't.

But what if we have segwit, and it fixes transaction malleability? Well this becomes a far mor esimple transaction. You create a transaction which is only valid in fork 2 which spends from the funding transaction. You create a transaction only valid in fork 1 that spends the money. Both parties sign these claim transactions. Once they both know that they are signed, then they sign the funding transaction, and then post to the blockchain. And this ensures that the two claim transactions are atomic, because the act of posting the funding transaction enables both of them. So as you can see, it's a far simpler transaction scheme. It only requires 2 off-chain transactions. It's very easy to setup. It's similar to establishing a payment channel. There's no need for either party to trigger the exchange. The hard-fork time still must be fixed, but there's no requirement for an elaborate setup. The coins are not locked up for a long time. The two transactions you post can be like one block after the hard-fork, although you probably want to post the transactions more than 1 block after the hard-fork just in case of other problems.

If there was mandatory replay protection incorporated in segwit2x, you would be able to bet on which chain you wanted all your coins. These bets don't have to be 1-to-1, they could be 1-to-2 or any sort of value you want to bet.

In conclusion, we have a protocol to gamble and trade prior to a hard-fork. We can do it without a transaction malleability fix such as segwit. If you want to learn more about hard-forks and soft-forks for bitcoin and ethereum, see our paper. We also have an overview of replay protection schemes, so if you want to compare the methods, then see our paper. We also have a similar protocol for ethereum.

If you compare this protocol after a transaction malleability fix and before, it's so much simpler with segwit. There's an enormous engineering benefit of not having to worry about transaction malleability.