Skip to content

Instantly share code, notes, and snippets.

@gavinandresen
Created March 28, 2012 19:09
Show Gist options
  • Save gavinandresen/830ca16758fb9ad496d7 to your computer and use it in GitHub Desktop.
Save gavinandresen/830ca16758fb9ad496d7 to your computer and use it in GitHub Desktop.
Do-it-yourself escrow notes

Two-Party Escrow

Design notes for a workable "do-it-yourself" two-party escrow feature in Bitcoin clients.

Problem

Alice wants to pay Bob 11 BTC for something, but Alice and Bob don't fully trust each other. Neither want to bother finding/using/paying a third party to resolve a dispute if the transaction doesn't go well (perhaps it is a fairly low-value transaction, and it is not worth their time).

Simplest solution (that won't actually work in practice)

The simplest solution was described by Satoshi in a forum post in 2010:

Alice asks Bob for a public key ("B"). She also creates or re-uses one of her keys ("A"). She sends 11 BTC into a transaction that requires "A AND B" to be spent, sends the transaction ID to Bob, and asks him to ship her the product.

Bob waits until the A AND B transaction is confirmed, ships Alice the product, and sends her a half-signed transaction that spends the "A AND B" to any of Bob's keys (maybe just "B").

Alice holds onto the half-signed transaction, and when she gets the product in the mail she provides the second signature so Bob gets paid.

If she never gets the product, the Bitcoins are stuck until Alice and Bob come to some agreement on how to get them out of the "A AND B" transaction.

Problems with the simplest solution

The biggest problem with the the simplest solution is it requires that Alice not be lazy. If she does nothing, Bob doesn't get paid.

Having coins tied up in the "A AND B" transaction forever if Alice and Bob can't agree is not a great outcome; they're essentially lost forever. It would be better if the coins eventually went SOMEWHERE.

Also, Bob might like to have a way of automatically refunding the 11 BTC if he finds out he can't ship the product for some reason, without contacting Alice and asking her to give a signature for the "A AND B" transaction.

Three is the Magic Number

The solution I'm proposing comes from the observation that there are normally three possible outcomes from the escrow transaction:

  • "SUCCESS" : Alice gets the goods and is happy, Bob gets paid and is happy.
  • "REFUND" : Alice gets her money back and is mostly happy, Bob saves his reputation.
  • "DISPUTE" : Something bad happened. Hopefully this is rare.

These three outcomes will be anticipated in advance, at the same time Alice and Bob exchange public keys. Alice's Bitcoin software will create the "A AND B" transaction, but will also create 4 transactions that spend it. Two of the transactions will be given a "lockTime" so they cannot get into the blockchain until a particular time, all of them will require signatures from both Alice and Bob, but some will be pre-signed as follows:

  • SUCCESS : bitcoins go to Bob (pre-signed by Bob)
  • LAZY_ALICE : bitcoins go to Bob in 31 days (pre-signed by Alice and Bob)
  • REFUND : bitcoins go back to Alice (pre-signed by Alice)
  • DISPUTE : bitcoins go... somewhere in 30 days (see discussion below) (pre-signed by Alice and Bob)

All of this public key exchanging and transaction creation and signing should happen automatically, I don't imagine that Alice or Bob knows what is going on "under the covers". Alice just knows she is sending 11 BTC into an escrow involving Bob; somewhere in her Bitcoin client UI there will be a list of escrow transactions that she is involved in (as either sender or recipient) and what state they're in.

SUCCESS

If Alice receives the product from Bob, is happy with it, and isn't lazy, she will open up her Bitcoin software and press a "Complete Transaction"/"Pay Bob" button. Her software will provide the second signature for the SUCCESS transaction, announces it to the network, and Bob receives payment. After it has a few confirmations Bob and Alice's software can delete the LAZY_ALICE/REFUND/DISPUTE transactions, since they will never be valid (their input, the "A AND B" transaction, is spent).

LAZY_ALICE

If Alice receives the product but neglects to poke the "Pay Bob" button, Bob's bitcoin software automatically announces the LAZY_ALICE transaction if 31 days have passed, and, assuming Alice hasn't disputed the transaction in that time, gets paid.

REFUND

Bob pokes a "Refund Alice" button in his list of escrow transactions, and his software adds his signature to the REFUND transaction, announces it, and Alice gets her money back.

Disputes

Disputes are the tricky case -- what if Bob ships Alice a box full of bricks when she was expecting a new computer, or what if they disagree about whether or not Bob accurately described what he was going to send to Alice?

If there is a dispute that they cannot somehow resolve, then either of them can poke a button that says "The Other Person Cheated!" The DISPUTE transaction will be announced, and the 11 BTC will go... somewhere. I assume Alice and Bob agreed at the beginning of the transaction on what exactly happens; there are a few possible "somewheres" that make sense:

  1. DISPUTE could be a "fee only" transaction, with an 11 BTC input and a 0 BTC output-- all 11 BTC will go to the miner who includes the transaction in their block. However, if this is common then it is very likely a secondary market for these transactions will arise, with miners paying people to give them these disputed transactions directly instead of announcing them on the network. Bob might rip people off by advertising products he never intends to ship and make money by selling disputed transactions to miners.
  2. DISPUTE could send the bitcoins to some mutually trusted third party dispute resolution service, who would decide how much of the 11 BTC should go to A and how much to B (and how much they keep for providing the service).
  3. DISPUTE could be a mechanism for funding the development of Bitcoin client software; all 11 BTC could be sent to a donation address for the software that Alice is running. However, Bob needs some way of verifying that it really is a donation address, and not one of Alice's addresses.

Implementation Questions / Details

Notes on lockTime / transaction replacement:

Transactions with a non-final sequence number and a lockTime in the future are relayed and accepted into the memory pool but cannot be put into the block chain until after lockTime.

If another transaction spending the same inputs as a transaction in the memory pool is received it is just ignored. If another transaction spending the same inputs does make it into the block chain then the transaction waiting in the memory pool is just dropped.

Note: the exact sequence of who-signs-what-transactions-when is critical-- Alice does not want to tie up her funds if Bob disappears halfway through the setup process.

  • Alice creates the A AND B transaction, signs it, but does not broadcast it.
  • Alice creates the other 4 transactions (she knows A AND B's transaction ID, so can)
  • Alice gives Bob the A AND B transaction ID, but with her signature(s) blanked (so Bob can't broadcast it), and the other 4 transactions. What if Alice lies about A AND B's transaction ID?
  • Bob checks all the transactions, creates signatures (he can sign inputs that use A AND B even if he is missing the signatures on A AND B), and gives them to Alice.
  • Alice verifies that Bob signed everything properly, then locks up her money by broadcasting the A AND B transaction.

When A AND B is confirmed in the block-chain, Bob ships the product.

Reference / Prior discussion:

@bitcoinuser
Copy link

Hi,

1- I think third party escrow services sites should have a form where users fill the details of the escrow and other informations that will serve to escrow service decide where the bitcoins will be send in case of dispute.
2- After the user fill the form, will have an option to save the content of it on a file.
3- This file can be opened on satoshi client.
4- When the user open the file on satoshi client, will popup a window with all details of it.
5- The user that generated the form will send the file to the person he/she wants to trade.
6- The other person will open the same file on satoshi client and will too see the details of the escrow
7- In the window with escrow details will have a button asking if you agree with the terms.
8- If Alice and Bob agree. The transation is started

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment