BIP: 300 source
  Layer: Consensus (soft fork)
  Title: Hashrate Escrows (Consensus layer)
  Author: Paul Sztorc <>
          CryptAxe <>
  Comments-Summary: No comments yet.
  Status: Draft
  Type: Standards Track
  Created: 2017-08-14
  License: BSD-2-Clause


A "Hashrate Escrow" is a clearer term for the concept of "locked to an SPV Proof", which is itself a restatement of the phrase "within a sidechain" as described in the 2014 Blockstream whitepaper.

A Hashrate Escrow resembles a 2-of-3 multisig escrow, where the 3rd party (who will arbitrate any disputes) is a decentralized group of people: the dynamic-membership set of Bitcoin Miners. However, the 3rd party does not sign escrow-withdrawal transactions with a private key. Instead, these are "signed" by the accumulation of hashpower over time.

This project has a website which includes an FAQ.


In practice these escrows are likely to be "asymmetric sidechains" of Bitcoin (such as Rootstock) or "virtual chains" within Bitcoin (such as proposed by Blockstack in mid-2016).

Sidechains have many potential benefits, including:

  1. Protect Bitcoin from competition from altcoins and spinoffs.
  2. Protect Bitcoin from hard fork campaigns. (Such campaigns represent an existential threat to Bitcoin, as well as an avenue for developer corruption.)
  3. Help with review, by making it much easier for reviewers to ignore bad ideas.
  4. Provide an avenue for good-but-confusing ideas to prove their value safely.



Hashrate Escrows are built of two types of component: [1] new databases, and [2] new message-interpretations.

1. New Databases
  • D1. "Escrow_DB" -- a database of "accounts" and their attributes.
  • D2. "Withdrawal_DB" -- a database of pending withdrawals from these accounts, and their statuses.

Please note that these structures (D1 and D2) will not literally exist anywhere in the blockchain. Instead they are constructed from messages...these messages, in contrast, *will* exist in the blockchain (with the exception of M4).

2. New Messages
  • M1. "Propose New Escrow"
  • M2. "ACK Escrow Proposal"
  • M3. "Propose Withdrawal"
  • M4. (implied) "ACK Withdrawal"
  • M5. "Execute Deposit" -- a transfer of BTC from-main-to-side
  • M6. "Execute Withdrawal" -- a transfer of BTC from-side-to-main

Adding Sidechains (D1, M1, M2)

D1 -- "Escrow_DB"

The table below enumerates the new database fields, their size in bytes, and their purpose. In general, an escrow designer (for example, a sidechain-designer), is free to choose any value for these.

Field No.LabelTypeDescription / Purpose
1Escrow Numberuint8_tA number assigned to the entire escrow. Used to make it easy to refer to each escrow.
2Sidechain Deposit Script HexstringThe script that will be deposited to, and update the CTIP of the sidechain.
3Sidechain Private KeystringThe private key of the sidechain deposit script.
4Escrow NamestringA human-readable name of the sidechain.
5Escrow DescriptionstringA human-readable name description of the sidechain. More than enough space to hold a 32 byte hash.
6Hash ID 1uint256A field of 32 bytes, which could be any bytes such as a sha256 hash.
7Hash ID 2uint256A field of 32 bytes, which could be any bytes such as a sha256 hash.
8"CTIP" -- Part 1 "TxID"uint256The CTIP, or "Critical (TxID, Index) Pair" is a variable for keeping track of where the escrow's money is (ie, which member of the UTXO set).
9"CTIP" -- Part 2 "Index"int32_tOf the CTIP, this is second element of the pair: the Index. See #9 above.

D1 is updated via M1 and M2.

( The following messages were modeled on SegWit -- see here and here. )

M1 -- "Propose New Sidechain"

   1-byte - OP_RETURN (0x6a)
4-byte - Commitment header (0xD5E0C4AF)
N-byte - The serialization of the sidechain.

M2 -- "ACK Sidechain Proposal"

   1-byte - OP_RETURN (0x6a)
4-byte - Commitment header (0xD6E1C5BF)
32-byte - Commitment hash: sha256D hash of sidechain's serialization

New Block Validation Rules

  1. Escrows are added in a procedure that resembles BIP 9 soft fork activation: the network must see a properly-formatted M1, followed by "acknowledgment" of the sidechain in 95% of the following 2016 blocks.
  2. It is possible to "overwrite" an escrow. This requires 6 months (26298 blocks) of M2s, instead of 2 weeks (XXXX). This possibility does not change the security assumptions (because we already assume that users perform extra-protocolic validation at a rate of 1 bit per 26298 blocks).

Withdrawing from Escrows (D2, M3, M4)

D2 -- "Withdrawal_DB"

D2 changes deterministically with respect to M3, M4, M5, and M6.

Field No.LabelTypeDescription / Purpose
1Escrow Numberuint8_tLinks the withdrawal-request to a specific escrow.
2WT^ Hashuint256This is a "blinded transaction id" (ie, the double-Sha256 of a txn that has had two fields zeroed out, see M6) of a withdrawal-attempt.
3ACKs (Work Score)uint16_tThe current total number of ACKs (PoW)
4Blocks Remaining (Age)uint16_tThe number of blocks which this WT^ has remaining to accumulate ACKs

New Block Validation Rules for D2

  1. A hash commitment to D2 exists in each block (even if D2 is blank).
  2. Withdrawals in D2 are sorted first by field #1 (Escrow Number) and second by field #4 (Age). This imposes a unique sort.
  3. From one block to the next, "Age" fields must increase by exactly 1.
  4. Withdrawals are stored in D2 until they fail ("Age" = "MaxAge"), or they succeed (the blockchain contains a txn whose blinded txID matches "WT^").

In addition, there are special rules for the "ACKs" field (see M4 below).

M3 -- "Propose Withdrawal"

   1-byte - OP_RETURN (0x6a)
1-byte - Push the following 36 bytes (0x24)
4-byte - Commitment header (0xD45AA943)
32-byte - The WT^ hash to populate a new D2 entry

New Block Validation Rules for M3

  1. If the network detects a properly-formatted M3, it must add an entry to D2 in the very next block. The starting values of fields #3 and #4 are zero, and #5 is pulled over by extracting the relevant value from D1.
  2. Each block can only contain one M3 per sidechain.

M4 -- "ACK Withdrawal"

M4 is a way of describing changes to the "ACKs" column of D2.

From one block to the next, "ACKs" can only change as follows:

  • The ACK-counter of any withdrawal can only change by (-1,0,+1).
  • Within a sidechain-group, upvoting one withdrawal ("+1") requires you to downvote all other withdrawals in that group. However, the minimum ACK-value is zero (and, therefore, downvotes cannot reduce it below zero).
  • While only one withdrawal can be upvoted at once, they can all be unchanged at once ("abstain") and they can all be downvoted at once ("alarm").

One option for explicit transmission of M4 is:

   4-byte - Message identifier (0x????????)
1-byte - Version of this message
1-byte - Length (in bytes) of this message; total number of withdrawal attempts; y = ceiling( sum_i(m_i +2)/8 ). Nodes should already know what length to expect, because they know the sequence of M3s and therefore the vector of WT^s.
N-byte - stream of bits (not bytes), with a 1 indicating the position of the chosen action [downvote all, abstain, upvote1, upvote2, ...]

But sometimes M4 does not need to be transmitted at all! If there are n Escrows and m Withdrawals-per-escrow, then there are (m+2)^n total candidates for the next D2. So, when m and n are low, all of the possible D2s can be trivially computed in advance.

Miners can impose a "soft limit" on m, blocking new withdrawal-attempts until previous ones expire. For a worst-case scenario of n=200 and m=1,000, honest nodes can communicate M4 with ~25 KB per block [4+1+1+(200\*(1000+1+1)/8)].

Depositing and Withdrawing (M5, M6)

Both M5 and M6 are regular Bitcoin txns. They are identified by meeting an important criteria: they select a one of the Critical TxID-index Pairs (a "CTIP") as one of their inputs.

Just as these txns must select a CTIP input, they must create a new CTIP output. D1 is then updated to match only the latest CTIP output. The purpose of this is to have all of the escrow's money (ie all of the sidechain's money) in one TxID, so that depositors immediately undo any UTXO bloat they may cause.

Deposits ("M5") are distinguished from withdrawals ("M6") by simply checking to see if money is "going in", or "out".

M5. "Make a Deposit" -- a transfer of BTC from-main-to-side

As far as mainchain consensus is concerned, deposits to the escrow are always valid.

However, in practice there will be additional requirements. The escrow account (ie the "sidechain") needs to know how to credit depositors. One well-known method, is for mainchain depositors to append a zero-value OP Return to a Deposit txn, so that the sidechain knows how to credit funds. Mainchain users must upgrade their wallet software, of course, (on an individual basis) in order to become aware of and take advantage of new deposit-methods.

M6. "Execute Withdrawal" -- a transfer of BTC from-side-to-main

We come, finally, to the critical matter: where users can take their money *out* of the escrow account, and return it to the "regular" UTXO set. As previously mentioned, this txn is one which (a) spends from a CTIP and (b) reduces the quantity of BTC in an account's CTIP. Most of the work has already been done by D1, M3, M4, and D2. Furthermore, existing Bitcoin tx-rules prevent the sidechain from ever withdrawing more money than has been placed into it.

In each block, a withdrawal in D2 is considered "approved" if its "ACKs" value meets the threshold (13,150).

Approved withdrawals give the green light to their respective "WT^". A "WT^" is 32-bytes which aspire to represent the withdrawing transaction (the txn that actually withdraws funds from the escrow). The two cannot match exactly, because "WT^" is defined at onset, and the withdrawing TxID depends on the its CTIP input (which is constantly changing).

To solve this, we define a "blinded TxID" as a way of hashing a txn, in which some bytes are first overwritten with zeros. Specifically, these bytes are the first input and the first output.

So, withdrawals must meet the following three criteria:

  1. "Be ACKed" -- The "blinded TxID" of this txn must be member of the "approved candidate" set in the D2 of this block.
  2. "Return Change to Account" -- TxOut0 must pay to the "critical account" (see D1) that corresponds to the CTIP that was selected as a TxIn.
  3. "Return *all* Change to Account" -- Sum of inputs must equal the sum of outputs. No traditional tx fee is possible.

Backward compatibility

As a soft fork, older software will continue to operate without modification. Non-upgraded nodes will see a number of phenomena that they don't understand -- coinbase txns with non-txn data, value accumulating in anyone-can-spend UTXOs for months at a time, and then random amounts leaving the UTXO in single, infrequent bursts. However, these phenomena don't affect them, or the validity of the money that they receive.

( As a nice bonus, note that the sidechains themselves inherit a resistance to hard forks. The only way to guarantee that the WT^s reported by different clients will continue to match identically, is to upgrade sidechains via soft forks of themselves. )


This BIP will be deployed by "version bits" BIP9 with the name "hrescrow" and using bit 4.

// Deployment of Drivechains (BIPX, BIPY)
consensus.vDeployments[Consensus::DEPLOYMENT_DRIVECHAINS].bit = 4;
consensus.vDeployments[Consensus::DEPLOYMENT_DRIVECHAINS].nStartTime = 1579072881; // January 15th, 2020.
consensus.vDeployments[Consensus::DEPLOYMENT_DRIVECHAINS].nTimeout = 1610695281; // January 15th, 2021.

Reference Implementation


Also, for interest, see an example sidechain here:




Thanks to everyone who contributed to the discussion, especially: ZmnSCPxj, Adam Back, Peter Todd, Dan Anderson, Sergio Demian Lerner, Chris Stewart, Matt Corallo, Sjors Provoost, Tier Nolan, Erik Aronesty, Jason Dreyzehner, Joe Miyamoto, Ben Goldhaber.

This BIP is licensed under the BSD 2-clause license.