You are on page 1of 15

LocalCryptos Blog

The peer-to-peer cryptocurrency marketplace. Non-custodial & end-to-end


encrypted. Follow us on Twitter.

How LocalCryptos' Non-Custodial


Bitcoin Escrow Works
Published 19 November 2019

English ‫اﻟﻌرﺑﯾﺔ‬ Español Français

ह द , हंद 中文
LocalCryptos has launched — a new peer-to-peer crypto marketplace.

In November 2019, LocalCryptos launched Bitcoin escrows. We copied our


Ethereum-based concept and translated the code to a Bitcoin-compatible script.

In this article, we’ll explain how it works.

This article assumes you understand Bitcoin to a technical degree. We’ll try to
break down simple concepts, but if you don’t know what the term “UTXO” means,
it might be dif cult to follow.

This setup is non-custodial from start to nish. LocalCryptos’ servers only store
encrypted blobs which it can’t differentiate from gibberish. Our servers don’t
generate any transactions described here—it’s all your browser’s JavaScript.

Our roots in Ethereum


We were LocalEthereum before we renamed the platform to LocalCryptos.
LocalEthereum was the world’s rst peer-to-peer trading platform for Ethereum. It
was also the most popular P2P at-to-crypto ramp behind PaxFul and
LocalBitcoins.

LocalEthereum wasn’t a simple LocalBitcoins clone. Although the user journey


was similar, LocalEthereum was a beast when you popped the hood. It was the
only platform with end-to-end encrypted messages and a non-custodial web
wallet. It was also the rst to introduce a “non-custodial escrow”, which sounds
like an oxymoron. Let us explain what that means:

Instead of holding crypto in guarantee in a wallet on its server, it used an


Ethereum smart contract. Ether (ETH) would ow from the seller to into the smart
contract, and from the smart contract to the buyer. The smart contract set the
rules of the escrow in stone ahead of time in a decentralised manner. By using a
smart contract rather than a custodian, the escrow was intermediary-free.

Now we’ve built the same thing for Bitcoin. Except that Bitcoin doesn’t have smart
contracts—it has Scripts. Scripts are like smart contracts in some ways, but very
different in others.

What’s in a Bitcoin transaction?


Bitcoin transactions contain inputs and outputs. Each output contains a recipient
address—where you are sending the Bitcoin—and how much the address will get.
Inputs point to previous outputs—coins sent to you that you haven’t yet spent.

Bitcoin “addresses” are a strange concept to unpack. In a way, they’re not a part of
the protocol—they’re not mentioned in Satoshi Nakamoto’s white paper.


1MoNS93aYgeuCcojcYbAJpKxqDN9UuJa9C

There are different types of Bitcoin addresses. A Bitcoin address, when decoded,
contains two parts: a version identi er, and a payload. The version eld is at the
beginning, and it tells your Bitcoin wallet the type of address it’s dealing with. The
usage of the payload depends on the version.

An address that begins with a 1 is a Pay-to-Public-Key-Hash (P2PKH) address,


the most common address version. An address that begins with a 3 is a Pay-to-
Script-Hash (P2SH) address. You might see other address pre xes too, such as a
native SegWit address. For the sake of this article, only P2SH and P2PKH
addresses are relevant to understand.

Address standards describe how to create puzzles, and how to create solutions to
unlock them. The puzzle solution allows the recipient to use an output as an input
to another transaction.

Alice sends Bob some dough the old way

In a P2PKH address, the payload following the version is a hash of the recipient’s
public key. The hash function used is “hash160”, which translates to
RIPEMD160(SHA256(thing)) .

When Alice wants to send a payment to Bob, she creates a puzzle named a
ScriptPubKey that only Bob can solve. The puzzle becomes an output of her
Bitcoin transaction.

For Bob to spend this output, he needs to use it as an input in another Bitcoin
transaction. To do that, he needs to craft a valid ScriptSig corresponding to the
ScriptPubKey.

Any P2PKH ScriptPubKey always follows this template:

“ OP_DUP OP_HASH160 <PubKeyHash> OP_EQUAL OP_CHECKSIG

And a corresponding P2PKH ScriptSig is in the format of:

<Signature> <PubKey>
OP_Huh?

An output’s ScriptPubKey is a piece of code. It’s in a restricted stack-based
programming language unique to Bitcoin, named “Script”.

A ScriptSig is also a piece of code, but by Bitcoin’s consensus rules it can only
contain “push data”. In simple words, it can’t do anything except to add arbitrary
data to the stack.

In this P2PKH example, Bob’s ScriptSig is adding two things to the stack:

PubKey— Bob’s own public key. Alice was only given a hash of Bob’s public
key, not the real deal.

Signature — A signature of a hash of the transaction Bob has generated,


including all the outputs, created using the same PubKey. (Bitcoin signatures
are a bit more complex than that—too complex to describe here.)

Checking that ScriptSig is right

Before a miner can include this transaction in a block, they will con rm that
ScriptSig is correct for the ScriptPubKey.

The miner adds ScriptPubKey to the end of ScriptSig, and executes the code. After
the last line of code is ran, the stack must end with the top item being true (non-
zero). This is all it takes to verify a ScriptSig.

“ <Signature> <PubKey> OP_DUP OP_HASH160 <PubKeyHash>


OP_EQUALVERIFY OP_CHECKSIG
As you can see, the stack ends with “true”. If you want to learn more about P2PKH
and why it’s popular, there are a ton of resources on the web. Search Google for
“P2PKH” to nd out more.

What is a P2SH address?


Pay-to-Script-Hash addresses move the responsibility of supplying the payment
conditions to the spender.

Remember when I said a moment ago that the spender’s ScriptSig can’t include
non-data code? Forget that for a moment—P2SH changes everything.

Instead of writing spending conditions inside ScriptPubKey, that code goes inside
a RedeemScript. Yes, that’s a new term—in loose non-technical words, it refers to
the “real” puzzle for the output. When you send coins to a P2SH address, the
ScriptPubKey contains a hash of the spending coniditons code. It looks like:

“ OP_HASH160 <RedeemScriptHash> OP_EQUAL


A spender of a P2SH input provides two things in their ScriptSig:

RedeemScript — The spending conditions of the payment. It’s easy to think


of this as “the real ScriptPubKey”.

Signature — The push data to combine with the RedeemScript. In plain


terms, “the real ScriptSig”.

Miners will rst verify that the hash of RedeemScript matches the hash in
ScriptPubKey. If it does, it will unpack the RedeemScript, put Signature above it,
and execute.

What is a P2WSH address?


LocalCryptos uses Pay-to-Witness-Script-Hash (P2WSH) addresses for escrows
instead of P2SH. To be precise, we use a P2WSH wrapped inside of a P2SH (i.e.
P2SH-P2WSH).

The difference between a P2WSH and a P2SH is that in a P2WSH, the old
RedeemScript goes inside a new “Witness Script” eld.

If you haven’t learnt about SegWit, please pretend LocalCryptos’ escrow uses
standard P2SH. It will make as much sense. Using Segregated Witness improves
the escrow’s ef ciency and cost, and nothing more.

Why not use multi-signature?


Off the bat, there’s a good chance you’re assuming LocalCryptos uses multi-
signature addresses. You won’t nd OP_CHECKMULTISIG in the code.

In a multi-signature script, each signer is a party to the spending transaction. In


our model, LocalCryptos never has to sign any part of the transaction—even in a
payment dispute.
In true peer-to-peer fashion, we are never a party to any transaction. Because
we’re not a party, it’s impossible for us to impose spending conditions on escrows
—such as how and when the receiving party can spend Bitcoin.

Our mechanism is especially useful for in-person exchanges. Users are able to
release Bitcoin from escrow without access to the internet. It will be possible to
trigger a release by sending an SMS with a unique code, or by showing a QR to
the buyer. More on that later.

Generating and signing keys in bulk


The rst thing you do when you create a LocalCryptos account is generate a lot of
random keys and sign them. Of course, this happens in the background—ordinary
users won’t notice it.

These ephemeral keys come in three categories, two of which are relevant to BTC
escrows.

Generating end-to-end messaging keys

The unrelated category of random keys created at sign-up are end-to-end


encryption keys. These keys allow people to begin encrypted conversations with
you while you’re of ine. LocalCryptos borrows this idea from popular forward-
secret encrypted messaging apps such as Signal. You can learn more about it in
LocalEthereum’s original white paper.

Generating wallet addresses

When you generate a Bitcoin address in your non-custodial LocalCryptos wallet,


you also upload a signed version to LocalCryptos. When the web wallet is setting
itself up, it creates and signs hundreds of Bitcoin addresses.

Encrypted copies of your private keys are also uploaded to allow you to log in from
another device.
The same process occurs for our other web wallets, including Ethereum.

This allows others to open trades with you and fund escrows, even while you’re
of ine. Users fetch one of your addresses from us, and check the signature against
your public key. Doing so helps avoid the risk of a complex man-in-the-middle
attack.

Generating escrow keys

Escrow keys are unique to Bitcoin escrows, as Ethereum’s escrow system is


different.

Escrow keys are 32-byte secret codes which you can reveal later. You generate a
hash of the secret code (using hash160) and sign the hash. Then, you upload the
hashed code, signature, and an encrypted secret code to LocalCryptos.

Funding escrow
To put BTC in escrow, the seller creates a Bitcoin transaction containing two
outputs. One output is for the amount being escrowed, and the other is
LocalCryptos’ refundable fee.

Before doing so, the seller needs to fetch some details from LocalCryptos:

1. Hashed escrow key codes from the buyer, arbitrator, and seller (their own).

2. A signature from the buyer they can use to authenticate the hashed escrow
key code.

3. A hashed public key from the buyer, as well as their own.

4. A signature from the buyer to verify the public key belongs to the buyer.

5. The arbitrator’s hashed public key, so they can send a small fee.
The seller will con rm each of the buyer’s signatures are valid before proceeding.
An incorrect signature means that a hacker has attempted to tamper with the
escrow.

Escrow output

The escrow output, which carries the amount for the buyer, is a P2SH-P2WSH
address for the following Script:
OP_DUP OP_1 OP_EQUAL
OP_IF
# Release by seller
OP_DROP
<BuyerPubKeyHash>
<ReleaseCodeFromSellerHash>
OP_ELSE
OP_DUP OP_2 OP_EQUAL
OP_IF
# Release by arbitrator
OP_DROP
<BuyerPubKeyHash>
<ReleaseCodeFromArbitratorHash>
OP_ELSE
OP_DUP OP_3 OP_EQUAL
OP_IF
# Return by buyer
OP_DROP
<SellerPubKeyHash>
<ReturnCodeFromBuyerHash>
OP_ELSE
OP_4 OP_EQUALVERIFY
# Return by arbitrator
<SellerPubKeyHash>
<ReturnCodeFromArbitratorHash>
OP_ENDIF
OP_ENDIF
OP_ENDIF
OP_ROT
OP_HASH160
OP_EQUALVERIFY
OP_OVER
OP_HASH160
OP_EQUALVERIFY
OP_CHECKSIG

Fee output

The fee output carries an amount of Bitcoin approximately 1% of the trade’s size.
LocalCryptos will claim the fee if the trade is successful. If there’s a cancellation,
the seller can unlock the output to claim a full refund.
The fee output is a P2SH-P2WSH address for the folowing Script:

OP_DUP OP_3 OP_EQUAL


OP_IF
# Return by buyer
OP_DROP
OP_HASH160
<ReturnCodeFromBuyerHash>
OP_EQUALVERIFY
OP_DUP
OP_HASH160
<SellerPubKeyHash>
OP_EQUALVERIFY
OP_CHECKSIG
OP_ELSE
OP_DUP OP_4 OP_EQUAL
OP_IF
# Return by arbitrator
OP_DROP
OP_HASH160
<ReturnCodeFromArbitratorHash>
OP_EQUALVERIFY
OP_DUP
OP_HASH160
<SellerPubKeyHash>
OP_EQUALVERIFY
OP_CHECKSIG
OP_ELSE
# Spend by LocalCryptos
OP_DUP
OP_HASH160
<ArbitratorPubKeyHash>
OP_EQUALVERIFY
OP_CHECKSIG
OP_ENDIF
OP_ENDIF

Waiting for con rmations


LocalCryptos requires most Bitcoin escrows to have at least one block
con rmation. Larger trades need up to six con rmations depending on the size of
the exchange.

Revealing a secret code  Mi objetivo sería rescatar la BELLEZA de esta arquitectura de


ejecución y traspasarla al depósito en garantia para Stasis Euros

The buyer already has one of the two inputs needed to unlock the escrow
transaction: their own public key. The only missing piece is the seller’s secret
“releaseBySeller” code.

Likewise, the seller is only one input away from unlocking the escrow. If they get
their hands on the buyer’s secret “returnByBuyer” code, they can recall the
amount in escrow.

The arbitrator holds the secret code to the “releaseByArbitrator” and


“returnByArbitrator” escrow keys. If a payment dispute arises, the arbitrator can
make a resolution by revealing one of the secrets.

This is the crux of the non-custodial escrow system. The hashed script includes
the hash of each secret code, but not the real thing.

Using a secret code 


To spend an escrow output, the receiver needs to compile a signature with the
following items:

Signature — A signature of a hash of the transaction. The signature is


checked against the below public key to verify only the receiver can spend.

PubKey — The receiver’s public key, matching the hashed version in the
code.

SecretCode — The revealed escrow code from another party.

Action — One byte to identify the nal state of the escrow. 


The rst two items are identical to spending a P2PKH input, and the next two are
unique to LocalCryptos.

The “action” byte will tell the script which hashes to check. In a standard trade, a
buyer will use a “release by seller” code ( 0x01 ). If the rst item is 0x01 , the
script will expect the buyer’s public key and the seller’s release code.

There are four escrow actions, representing all the scenarios of an escrow:

Action Byte Expected code Expected PubKey

ReleaseBySeller 0x01 Seller’s Buyer’s

ReleaseByArbitrator 0x02 Arbitrator’s Buyer’s

ReturnByBuyer 0x03 Buyer’s Seller’s

ReturnByArbitrator 0x04 Arbitrator’s Seller’s

Recalling the fee output

In the case of an escrow cancellation, LocalCryptos doesn’t charge a a fee. We


only take a fee if the Bitcoin goes to the buyer.

With a return escrow code, the above signature is also compatible with fee output.
The seller can spend the fee output in the same way they spend a recalled escrow
UTXO.

Settle when you spend


Clicking “Release” in a LocalCryptos Bitcoin escrow doesn’t change anything on
the blockchain. It allows the receiving party to spend the coins from escrow (i.e.
unlock the UTXO).

The receiving party can choose to spend these coins immediately, or they can
wait. In the user-interface, an escrow UTXO will appear in the web wallet next to
your regular addresses.

After spending the coins, the escrow’s completion is permanently etched into the
blockchain.

Releasing without an internet connection 


All the buyer needs is the seller’s secret code to claim the escrow.

We can add a method for a seller to reveal their code without an internet
connection. The code is too long to write on paper, but it’s a perfect length to store
in your phone or a QR code.

LocalCryptos is going to add two new ways to reveal a code:

1. Reveal the code by sending it in an SMS to one of our phone numbers.


Our servers can compute the code’s hash to identify which trade it belongs to,
then forward the code to the buyer.

2. Show a QR code to the buyer. The buyer doesn’t need the internet to verify
the code; they only need a piece of software that can calculate a hash. This
method will enable in-person exchanges when neither has a stable internet
connection. It will be useful in Venezuela, where national power outages are a
common occurrence.

We’re working on the rst option today. The second option will become available
when we release the LocalCryptos mobile app.

How secure is this?


The best supercomputer can’t break a standard P2PKH address, which uses a
single hash. The key space of a hash160 is 160 bits. We use two hash160s: one
for the P2PKH part, and one for the hashed secret code. This brings the key space
to 320 bits for external attackers. (The math is more nuanced than that, but you
get the idea.)

LocalCryptos Bitcoin escrow addresses are—for all intents and purposes—


impossible to crack.

How much does it cost?


We’ve reduced network fees by upgrading to Segregated Witness. However, the
cost of a Bitcoin transaction is often higher than Ethereum.

The cost of a Bitcoin escrow depends on the network’s congestion. For small
trades under $10, we recommend choosing another crypto.

Is this the nal version?


This is likely not the nal version of the LocalCryptos’ non-custodial Bitcoin
escrow. In the future, we plan to optimise the system for cost and speed.

USE LOCALCRYPTOS

© 2019 LocalEthereum Pty Ltd

You might also like