Skip to content

Instantly share code, notes, and snippets.

@gavinandresen
Created March 28, 2012 19:09
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • 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

I think should exist an option where Alice and Bob needs to previously send specific
amount of bitcoins. So:
1- Bob contract Alice to develop a webpage for 600btc
2- Bob send 620btc
3- Alice send 20btc

1- If all goes ok, Bob is refunded with 20btc and Alice receive 600btc and is refunded wih the 20btc she had previouly sent
2- If we have a dispute... The same thing you described on your text

obs: sorry for the bad english

@bitcoinuser
Copy link

Gavin:

In case of dispute, don't you think that the details of it should be previously in agreement between alice and bob?
So Alice and bob can early decide if the dispute will be resolved by a third party or...

@gavinandresen
Copy link
Author

Regarding Alice and Bob both put some money in, and both get refunded if they are happy at the end:

I will have to think about how Alice and Bob can BOTH contribute bitcoins at exactly the same time in a safe way.

I worry that is so different from the way we pay for things online now that it would never be used; it there any other system where both buyers and sellers deposit money at the beginning of a transaction?

RE: details previously in agreement: yes, that was my intent, I'll change the gist to make that clear. The "...something happens to the coins..." is "... something (agreed in advance between Alice and Bob) happens to the coins...."

@bitcoinuser
Copy link

Ok, see how i would like to buy bitcoins with fiat money with someone unknow and that i don't trust

1- Bob want to buy 20btc from Alice
2- Bob and Alice agree that if a dispute happens, this will be solved by a third party company called bitdispute
3- The bitdispute company charge a fee of 2% of the trade
4- Bob deposit 2btc
5- Alice deposit 22btc
6- In the end we have a dispute
7- Alice prove for the bitdispute company by proof bank screenshots that she deposited the fiat money
on Bob account.
8- Bitdispute account receive the 2btc from Bob
9- Bob receive 20btc
10- Alice receive back 2btc

@bitcoinuser
Copy link

I made a mistake on %.
10% of 20 is = 2

@etotheipi
Copy link

Gavin,
Alice and Bob can both contribute at the exact same time using multi-input transactions, made easier with alternate hashcodes. It's the same process as multi-sig signature collection, except that you are each signing different inputs:

"Risk Deposit" == 10%
Inputs:
Alice 22 BTC
Bob 2 BTC
Outputs:
2-of-3(Alice, Bob, ThirdParty), 24 BTC

This requires one party to construct the transaction with multi-inputs, and may require obtaining a public key from the other party that has enough BTC to fund it (though, you will have to exchange information anyway, so it can be done all at once). Alternatively, Alice could use a SIGHASH_ANYONECANPAY to sign an input for 22 BTC with a final output of 24 to the 2-of-3 address. This tx is not valid until someone (Bob) puts in another 2 BTC to complete the transaction, and then Alice doesn't need to know in advance what Bob's public key is. Either way, both parties are end up with their money in the 2-of-3, or neither of them do.

One issue is working out change addresses -- both parties can always create exact inputs, but it requires extra transactions. We can avoid one by having Alice include both the 2-of-3 output and a change output for her oversized input, but Bob would need exact since he can't add any more change outputs to the tx without breaking Alices signature.

I recognize that this "risk deposit" method is different. But there's a certain elegance to it, it serves both as a vehicle for improving "zero-trust" transactions, as well as providing a pre-arranged payment for a third party abitrator if they are needed. There's no reason that dispute resolution should be paid for by one party: both parties put in their 10%, and dispute resolution gets the 20% for their services. The third-party doesn't even have to know they are part of the tx until they are needed: they could give out publicly-verifiable addresses to be used for such transactions, and a fee schedule that says "if you expect us to arbitrate a dispute, you must make sure there is at least 15% deposit from both parties on tx less than 20 BTC, 10% on less than 100 BTC..." If there's not enough, then one party will have to foot the bill to get them involved.

It's different, and it requires explanation... but users already know things are a little different, because they're using Bitcoin. Getting them to accept an automatically-refunded deposit as part of the process may be weird at first, but this process probably won't be executed by people with zero-knowledge of how Bitcoin works. I could be wrong... and if I am -- then the knowledgeable users will use it, and the others will look for something else (and free market will prevail).

bitcoinuser,
That is exactly how I want to implement dispute resolution, except that the third-party would get both deposits (4BTC total) from each Bob and Alice. It is important that both parties contribute equally to dispute resolution, to be sure that both parties have something to lose by not cooperating. One user might be more inclined to go to dispute resolution to get a more-favorable outcome, knowing that the other party is always paying for it.

@bitcoinuser
Copy link

Etotheipi.

1-Sorry but really don't understand why both parties should pay the third party service.
2- If i want to trade bitcoin and someone is malicious, only who is malicious should be punished and pay the charge fee third party service..

@bitcoinuser
Copy link

Etotheipi,

Both parties deposit but who win the dispute is refunded.

Right?

@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