Bitcoin has a built-in functionality, called CHECKMULTISIG, where you can require two or more private keys in order to spend a transaction. There are an incredible number of ways you could theoretically use CHECKMULTISIG, but the most obvious use case is a secure escrow functionality. A quick glance at the history of Bitcoin powered services over the last 3 years shows how much the community could benefit from better ways to escrow payments.
Typically, an escrow involves three parties, where a neutral third party holds the funds while goods are delivered. The escrow agent can either return payment to the buyer, release payment to the seller, or provide for some split in case of disputes. The escrow agent model doesn’t require any fancy crypto; full trust is placed in the escrow agent by both the buyer and seller, and funds are sent from buyer → escrow → seller as usual. However, the CHECKMULTISIG code offers two different ways to run an escrow which changes things up a bit.
In the Bitcoin world, the only encumbrance on an ‘unspent output’ (an account balance) is the private keys or private knowledge which are required to spend it. Lawful possession or knowledge of the key is de facto ownership of the coins. So when talking about people or ‘parties’ to a transaction, I might get a bit sloppy with the language, because generally speaking, the person is the key, and the key is the person.
One option is for the buyer to send funds into a 2-of-3 multisig transaction instead of directly to the escrow agent. The buyer collects one of their own public keys, plus a public key each from the escrow agent and the seller, and then sends the desired number of their own coins into a new account (‘output’) with the requirement that those coins can only be spent if 2 of 3 parties sign off.
In this approach, no individual party can control the coins, but any two parties can. The buyer and seller can release (spend) the coins without needing the third party to be involved at all, as long as they agree on how they should be sent. If the buyer and seller can’t agree, the third party must break the tie. But in this case, the escrow agent can’t quite independently decide the matter, since they need either the buyer or the seller to also sign off on the release. Notably, this prevents the escrow agent from absconding with the coins, or perhaps more likely, prevents the coins from being seized from the escrow agent themselves. Bitcoin also supports partial release from escrow, where some portion of the coins are sent to the buyer and/or seller, and the remaining coins are sent back into the escrow.
Even more interesting in my opinion, is the two party escrow using a 2-of-2 multisig transaction. When Alice sends funds into a 2-of-2 signature MULTISIG address with Alice and Bob’s public keys, what she’s doing is giving Bob a say in how to spend those coins. Alice and Bob must agree on how to spend them, or else the coins cannot be spent. Removing the third party presents an interesting case where simpler structure leads to more complex behavior. What if Alice and Bob simply can’t agree on how to release the coins? How might Alice or Bob try to exploit this?
When Alice sends funds into the 2-of-2 multisig, she’s put those coins at risk. If Bob does nothing, and signs nothing, Bob never lifted a finger, but for Alice those coins are effectively lost. This basic asymmetry undermines the core value of a two party escrow, so we are encouraged to find some ways to remedy the situation. We either need Bob to have some skin in the game, so Alice feels more comfortable putting her coins at risk, or we need some fail-safe mechanism to give Alice some downside protection. Bitcoin lets us do either, or both.
The first option is to lock up some of Bob’s coins along with Alice’s. That way, Bob can’t simply troll Alice into losing money without losing some of his own. Technically, what we need to do is collect properly sized inputs (account balances) from both Alice and Bob, and then collect all the coins together into a single multisig output. Doing everything within a single transaction is important, because that way the operation is atomic — either both Alice and Bob’s coins end up in escrow, or nothing ends up in escrow. The coordination level required in order to construct such a transaction is trivial for a centralized service holding both Alice and Bob’s wallets, but highly unusable assuming client-hosted wallets where Alice and Bob only communicate over PGP and Tor.
The second option is to setup an automatic release from the escrow where coins are either sent back to Alice, or split some way between Alice and Bob, at some predefined points in the future. This can be done using a similar approach to how I implemented micro-payment channels where Alice creates the initial transaction sending her coins into escrow, and she signs the transaction in order to determine its transaction ID (TxID), but then instead of broadcasting the transaction, she keeps the transaction itself secret.
Alice sends just the TxID of the not-yet-escrowed coins to Bob, and tells Bob he must sign a new transaction which sends the coins from the escrow back to Alice (or split somehow between Alice and Bob). But this refund transaction will be locked, so that it can only be redeemed some specified time in the future, using a feature called nLockTime. Alice only broadcasts the transaction which releases her coins into the escrow after she gets back the signed, post-dated refund transaction(s) from Bob. In other words, Bitcoin lets Bob commit to the fail-safe before Alice commits her coins to escrow, which is frankly pretty awesome.
Of course, the problem with Bob providing Alice a fail-safe is that now Bob might be worried about Alice simply waiting him out. But the fail-safe can be as ‘strong’ or ‘weak’ as the two parties want to make it, so it’s likely they can agree on something. For example, 25% refund back to Alice after 6 months, or 50/50 split after 2 years, anything is possible.