Skip to content

Commit 458c42f

Browse files
docs: the design documentation
1 parent 8789a5d commit 458c42f

File tree

2 files changed

+209
-1
lines changed

2 files changed

+209
-1
lines changed

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,16 @@
55
> [!WARNING]
66
> This repository is still in the proof-of-concept stage.
77
8-
A [Bitcoin] SPV library, which is used to write contracts in [CKB].
8+
A [Bitcoin] SPV library, which is used to develop Bitcoin SPV on [CKB].
99

1010
[License]: https://img.shields.io/badge/License-MIT-blue.svg
1111

12+
## Resources
13+
14+
- [The Design of CKB Bitcoin SPV](docs/Design.md)
15+
16+
- [The Official Reference Implementation](https://github.com/ckb-cell/ckb-bitcoin-spv-contracts)
17+
1218
## License
1319

1420
Licensed under [MIT License].

docs/Design.md

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
# The Design of CKB Bitcoin SPV
2+
3+
CKB Bitcoin SPV is a library, for doing Bitcoin simplified payment
4+
verification on CKB.
5+
6+
## Abstract
7+
8+
This document describes the design and explains the technical details of CKB
9+
Bitcoin SPV, which allows users to do on-chain verification for bitcoin
10+
transactions on CKB chain.
11+
12+
## Background
13+
14+
For understanding this document, the knowledge of the following concepts are
15+
**required**.\
16+
But we won't discuss them here, please learn them on their own documents.
17+
18+
### Simplified Payment Verification (SPV)
19+
20+
[Simple Payment Verification][SPV], usually abbreviated to SPV, is noted in
21+
Bitcoin whitepaper. It allows a transaction recipient to prove that the
22+
sender has control of the source funds of the payment they are offering
23+
without downloading the full Blockchain, by utilizing the properties of
24+
Merkle proofs.
25+
26+
### Bitcoin Difficulty Adjustments
27+
28+
Every 2016 blocks (which should take two weeks if this goal is kept
29+
perfectly), every Bitcoin client compares the actual time it took to
30+
generate these blocks with the 2 weeks goal and modifies the target by the
31+
percentage difference.[^1]
32+
33+
> [!Note]
34+
> The difficulty re-target being based on the time taken for the previous
35+
> 2015 blocks instead of 2016 blocks.[^2]
36+
37+
### Bitcoin Merkle Proof
38+
39+
A proof that proves a transaction (in fact, just transaction hash) was
40+
included in a block.
41+
42+
It could be fetched through the RPC API [`gettxoutproof`], and be verified
43+
with the RPC API [`verifytxoutproof`].
44+
45+
### Merkle Mountain Range (MMR)
46+
47+
A [Merkle Mountain Range (MMR)][MMR] is a binary hash tree that allows for
48+
efficient appends of new leaves without changing the value of existing nodes.
49+
50+
An MMR proof could be used to prove whether an item is included in an MMR
51+
root or not.
52+
53+
## Overview
54+
55+
First, we could divide the whole problem into 2 smaller and standalone problems.
56+
57+
### 1. On CKB, prove a header belongs to the bitcoin chain
58+
59+
#### 1.1. Data preparation stage
60+
61+
Since we want to do on-chain verification, so the resources are limited, for
62+
example, we couldn't afford 100 MiB storage or 30 seconds expensive
63+
computation, on CKB.
64+
65+
So, we introduce the [Merkle Mountain Range (MMR)][MMR] to solve this
66+
problem: we only save the MMR root of bitcoin headers on CKB.
67+
68+
- First, we initialize a cell with a bitcoin header at any height.
69+
70+
An MMR tree will be constructed with this header only, and its root will
71+
be saved in the cell data.
72+
73+
No on-chain verification will be done for this data.
74+
Users have to check the data off-chain, then trust it.
75+
76+
- Also, there will be a service, which builds the same MMR tree but off-chain.
77+
78+
This service will listen to the bitcoin chain and wait for the next block.
79+
80+
When the next bitcoin block is mined, this service will append this new
81+
bitcoin block into the MMR tree, calculate a new MMR root, then send the
82+
new MMR root and the new header to the CKB chain.
83+
84+
- An on-chain script will check those new data.
85+
86+
- First, check the new header with two parts:
87+
88+
- The field "previous block header hash" in headers[^3] should be correct.
89+
90+
- The POW for the block should be valid.
91+
92+
For security, the on-chain script has to calculate the POW target for
93+
the next block by itself.
94+
95+
So, there are two more data have to be cached on chain:
96+
97+
- The start time of the first block after difficulty adjustment.
98+
99+
- If the next block is one of the first blocks after difficulty
100+
adjustment, its target should be calculated and cached.
101+
102+
- Then, check the new MMR root:
103+
104+
- The new MMR root should be constructed based on the previous MMR root,
105+
and only the new header should be appended.
106+
107+
After the above checks passed, then save the new data into the cell.
108+
109+
> [!NOTE]
110+
> In bitcoin headers, the height is not stored, but we have to store all
111+
> heights on CKB chain.\
112+
> The heights are required for two reasons: calculate the index of MMR and
113+
> calculate the block confirmations.
114+
115+
#### 1.2. Verification stage
116+
117+
With the stored MMR root on CKB, an on-chain script can check whether a
118+
bitcoin header is contained in that MMR tree.
119+
120+
There are 3 items required to be submitted to the CKB chain:
121+
- The MMR proof of the header which is required to be proven.
122+
- The full data of the header, or its hash.
123+
- The height of the header.
124+
125+
As the PoW of the header has been verified, if a header is contained within the
126+
MMR tree on CKB, it implies that the corresponding header is part of the Bitcoin
127+
chain.
128+
129+
### 2. On CKB, prove a transaction is in a bitcoin block
130+
131+
#### 2.1. Data preparation stage
132+
133+
No more data is required to be stored in the CKB chain for transactions
134+
verification.
135+
136+
#### 2.2. Verification stage
137+
138+
There is a field "merkle root hash" in bitcoin headers[^3].
139+
140+
A merkle root is derived from the hashes of all transactions included in
141+
that block, ensuring that none of those transactions can be modified without
142+
modifying the header.
143+
144+
So, a transaction could be verified whether it's in a header, with the
145+
merkle root hash and a merkle proof which contains it.
146+
147+
## Optimization
148+
149+
Save any data on chain will occupy the capacity of CKBytes permanently. And,
150+
not all bitcoin headers will be used.\
151+
So, we won't save all bitcoin headers on the chain.\
152+
For verification, we can just put them into the witnesses.
153+
154+
When users want to verify a bitcoin header, they should submit that header
155+
to CKB chain, or only its hash is enough.
156+
157+
But when verifies a bitcoin transaction, the full header is required to be
158+
submitted to CKB chain; because the "merkle root hash" in the header is
159+
required. \
160+
An interesting fact is, that the merkle proof of the transaction already
161+
contains the full header.[^4] So the header doesn't have to be submitted
162+
alone.
163+
164+
## Disadvantages
165+
166+
- Calculate the MMR proof is not simple for normal users.
167+
168+
A service is required, to collect all headers which are contained in the
169+
MMR root.
170+
171+
## References
172+
173+
- [`CalculateNextWorkRequired(..)`]
174+
175+
The function, which is used to calculate the next target.
176+
177+
- [`CPartialMerkleTree::ExtractMatches(..)`]
178+
179+
The function ensures that the partial Merkle tree is correctly constructed.
180+
It is used to verify that a proof points to transactions.
181+
182+
- [Merkle Mountain Ranges][MMR]
183+
184+
<!--
185+
186+
Links
187+
188+
-->
189+
190+
[^1]: [Bitcoin Target](https://en.bitcoin.it/wiki/Target)
191+
[^2]: [Gaming the "off-by-one" bug (difficulty re-target based on 2015 instead of 2016 block time span)?](https://bitcoin.stackexchange.com/questions/1511)
192+
[^3]: [Bitcoin Block Headers](https://developer.bitcoin.org/reference/block_chain.html#block-headers)
193+
[^4]: [Bitcoin serialization format: Merkle proof](https://daniel.perez.sh/blog/2020/bitcoin-format/#merkle-proof)
194+
195+
[`gettxoutproof`]: https://developer.bitcoin.org/reference/rpc/gettxoutproof.html
196+
[`verifytxoutproof`]: https://developer.bitcoin.org/reference/rpc/verifytxoutproof.html
197+
198+
[`CalculateNextWorkRequired(..)`]: https://github.com/bitcoin/bitcoin/blob/v26.0/src/pow.cpp#L49
199+
[`CPartialMerkleTree::ExtractMatches(..)`]: https://github.com/bitcoin/bitcoin/blob/v26.0/src/merkleblock.cpp#L149
200+
201+
[SPV]: https://bitcoinwiki.org/wiki/simplified-payment-verification
202+
[MMR]: https://github.com/opentimestamps/opentimestamps-server/blob/master/doc/merkle-mountain-range.md

0 commit comments

Comments
 (0)