1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
|
<pre>
BIP: 300
Layer: Consensus (soft fork)
Title: Hashrate Escrows (Consensus layer)
Author: Paul Sztorc <truthcoin@gmail.com>
CryptAxe <cryptaxe@gmail.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0300
Status: Draft
Type: Standards Track
Created: 2017-08-14
License: BSD-2-Clause
Post-History: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2017-May/014364.html
</pre>
==Abstract==
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 [https://blockstream.com/sidechains.pdf 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 [http://www.drivechain.info/ a website] which includes [http://www.drivechain.info/faq/index.html an FAQ].
==Motivation==
In practice these escrows are likely to be "asymmetric sidechains" of Bitcoin (such as [http://www.rsk.co/ Rootstock]) or "virtual chains" within Bitcoin (such as [https://github.com/blockstack/virtualchain proposed by Blockstack] in mid-2016).
Sidechains have many potential benefits, including:
# Protect Bitcoin from competition from altcoins and spinoffs.
# Protect Bitcoin from hard fork campaigns. (Such campaigns represent an existential threat to Bitcoin, as well as an avenue for developer corruption.)
# Help with review, by making it much easier for reviewers to ignore bad ideas.
# Provide an avenue for good-but-confusing ideas to prove their value safely.
==Specification==
==== Components ====
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.
{| class="wikitable"
! Field No.
! Label
! Type
! Description / Purpose
|-
| 1
| Escrow Number
| uint8_t
| A number assigned to the entire escrow. Used to make it easy to refer to each escrow.
|-
| 2
| Sidechain Deposit Script Hex
| string
| The script that will be deposited to, and update the CTIP of the sidechain.
|-
| 3
| Sidechain Private Key
| string
| The private key of the sidechain deposit script.
|-
| 4
| Escrow Name
| string
| A human-readable name of the sidechain.
|-
| 5
| Escrow Description
| string
| A human-readable name description of the sidechain. More than enough space to hold a 32 byte hash.
|-
| 6
| Hash ID 1
| uint256
| A field of 32 bytes, which could be any bytes such as a sha256 hash.
|-
| 7
| Hash ID 2
| uint256
| A field of 32 bytes, which could be any bytes such as a sha256 hash.
|-
| 8
| "CTIP" -- Part 1 "TxID"
| uint256
| The 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_t
| Of 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 [https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#commitment-structure here] and [https://github.com/DriveNetTESTDRIVE/DriveNet/blob/564516653c1d876429382971a011f5f6119f7eb4/src/validation.cpp#L3348-L3375 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 ====
# 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.
# 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.
{| class="wikitable"
! Field No.
! Label
! Type
! Description / Purpose
|-
| 1
| Escrow Number
| uint8_t
| Links the withdrawal-request to a specific escrow.
|-
| 2
| WT^ Hash
| uint256
| This 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.
|-
| 3
| ACKs (Work Score)
| uint16_t
| The current total number of ACKs (PoW)
|-
| 4
| Blocks Remaining (Age)
| uint16_t
| The number of blocks which this WT^ has remaining to accumulate ACKs
|}
==== New Block Validation Rules for D2 ====
# A hash commitment to D2 exists in each block (even if D2 is blank).
# Withdrawals in D2 are sorted first by field #1 (Escrow Number) and second by field #4 (Age). This imposes a unique sort.
# From one block to the next, "Age" fields must increase by exactly 1.
# 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 ====
# 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.
# 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".
https://github.com/DriveNetTESTDRIVE/DriveNet/blob/564516653c1d876429382971a011f5f6119f7eb4/src/validation.cpp#L647-L742
==== 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:
# "Be ACKed" -- The "blinded TxID" of this txn must be member of the "approved candidate" set in the D2 of this block.
# "Return Change to Account" -- TxOut0 must pay to the "critical account" (see D1) that corresponds to the CTIP that was selected as a TxIn.
# "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. )
==Deployment==
This BIP will be deployed by "version bits" BIP9 with the name "hrescrow" and using bit 4.
<pre>
// 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.
</pre>
==Reference Implementation==
See: https://github.com/DriveNetTESTDRIVE/DriveNet
Also, for interest, see an example sidechain here: https://github.com/drivechain-project/bitcoin/tree/sidechainBMM
==References==
See http://www.drivechain.info/literature/index.html
==Credits==
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.
==Copyright==
This BIP is licensed under the BSD 2-clause license.
|