Skip to content

Commit 88d15d0

Browse files
committed
Rename contract to SPVGateway & update README
1 parent cd1b37d commit 88d15d0

File tree

9 files changed

+258
-266
lines changed

9 files changed

+258
-266
lines changed

README.md

Lines changed: 71 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# 🛡️ SPV Contract: Bitcoin Light Client on EVM
2-
Welcome to the **SPV Contract**, a robust and efficient Solidity implementation for verifying Bitcoin block headers directly on an EVM-compatible blockchain. This contract empowers dApps to act as a **Simplified Payment Verification (SPV)** client, allowing them to validate the existence and inclusion of Bitcoin transactions without needing to run a full Bitcoin node.
1+
# 🛡️ SPV Gateway: Bitcoin Light Client on EVM
2+
Welcome to the **SPV Gateway**, a robust and efficient Solidity implementation for verifying Bitcoin block headers directly on an EVM-compatible blockchain. This contract empowers dApps to act as a **Simplified Payment Verification (SPV)** client, allowing them to validate the existence and inclusion of Bitcoin transactions without needing to run a full Bitcoin node.
33

4-
# ✨ Why this SPV Contract?
5-
In the decentralized world, connecting different blockchain ecosystems securely is paramount. This SPV contract provides a trust-minimized bridge, enabling smart contracts on EVM chains to cryptographically verify the state of the Bitcoin blockchain. This opens doors for exciting use cases like:
4+
# ✨ Why this SPV Gateway?
5+
In the decentralized world, connecting different blockchain ecosystems securely is paramount. This SPV Gateway provides a trust-minimized bridge, enabling smart contracts on EVM chains to cryptographically verify the state of the Bitcoin blockchain. This opens doors for exciting use cases like:
66
- **Cross-chain bridges** for Bitcoin-backed assets
77
- **Light clients** for dApps that need to confirm Bitcoin transaction finality
88
- **Decentralized custodianship** solutions
@@ -26,98 +26,98 @@ In the decentralized world, connecting different blockchain ecosystems securely
2626
# ⚙️ How it Works (Under the Hood)
2727
The contract operates by receiving raw Bitcoin block headers, which are then parsed and validated against Bitcoin's strict consensus rules.
2828

29-
1. **Header Parsing:** Raw 80-byte Bitcoin block headers are parsed into a structured *BlockHeaderData* format. This involves handling Bitcoin's unique little-endian byte ordering.
29+
1. **Header Parsing:** Raw 80-byte Bitcoin block headers are parsed into a structured *BlockHeader.HeaderData* format. This involves handling Bitcoin's unique little-endian byte ordering.
3030
2. **Double SHA256 Hashing:** Each block header is double SHA256 hashed to derive its unique block hash, which is then byte-reversed for standard representation.
3131
3. **Proof-of-Work Verification:** The calculated block hash is checked against the current network difficulty target (derived from the *bits* field in the header).
3232
4. **Chain Extension & Reorganization:** New blocks are added to a data structure that allows for tracking multiple chains. When a new block extends a chain with higher cumulative work, the *mainchainHead* is updated, reflecting potential chain reorganizations.
3333
5. **Difficulty Adjustment:** Every 2016 blocks, the contract calculates a new difficulty target based on the time taken to mine the preceding epoch. This ensures the 10-minute average block time is maintained.
3434

3535
# 📊 Flow Diagrams
36-
These diagrams outline the step-by-step process for adding block headers to the SPV Contract.
36+
These diagrams outline the step-by-step process for adding block headers to the SPV Gateway.
3737

3838
### `addBlockHeader(bytes calldata blockHeaderRaw_)` Sequence Diagram
3939

4040
```mermaid
4141
sequenceDiagram
4242
participant Caller
43-
participant SPVContract
43+
participant SPVGateway
4444
participant BlockHeaderLib
4545
participant TargetsHelperLib
4646
47-
Caller->>SPVContract: addBlockHeader(blockHeaderRaw)
48-
activate SPVContract
47+
Caller->>SPVGateway: addBlockHeader(blockHeaderRaw)
48+
activate SPVGateway
4949
50-
SPVContract->>BlockHeaderLib: 1. Parse blockHeaderRaw_ (parseBlockHeaderData)
50+
SPVGateway->>BlockHeaderLib: 1. Parse blockHeaderRaw_ (parseBlockHeaderData)
5151
activate BlockHeaderLib
52-
BlockHeaderLib-->>SPVContract: 1.1. Check length (80 bytes) & LE to BE
52+
BlockHeaderLib-->>SPVGateway: 1.1. Check length (80 bytes) & LE to BE
5353
alt Length Invalid
54-
BlockHeaderLib--xSPVContract: Error: InvalidBlockHeaderDataLength
55-
SPVContract--xCaller: Revert
54+
BlockHeaderLib--xSPVGateway: Error: InvalidBlockHeaderDataLength
55+
SPVGateway--xCaller: Revert
5656
end
57-
BlockHeaderLib-->>SPVContract: 1.2. Return BlockHeaderData & blockHash
57+
BlockHeaderLib-->>SPVGateway: 1.2. Return BlockHeaderData & blockHash
5858
deactivate BlockHeaderLib
5959
60-
SPVContract->>SPVContract: 1.3. Check blockHash existence
60+
SPVGateway->>SPVGateway: 1.3. Check blockHash existence
6161
alt BlockHash Exists
62-
SPVContract--xCaller: Error: BlockAlreadyExists
62+
SPVGateway--xCaller: Error: BlockAlreadyExists
6363
end
6464
65-
SPVContract->>SPVContract: 2. Check prevBlockHash existence
65+
SPVGateway->>SPVGateway: 2. Check prevBlockHash existence
6666
alt Prev Block Missing
67-
SPVContract--xCaller: Error: PrevBlockDoesNotExist
67+
SPVGateway--xCaller: Error: PrevBlockDoesNotExist
6868
end
6969
70-
SPVContract->>SPVContract: 3. Calculate newBlockHeight = prevBlockHeight + 1
70+
SPVGateway->>SPVGateway: 3. Calculate newBlockHeight = prevBlockHeight + 1
7171
72-
SPVContract->>SPVContract: 4. Get Current Target
73-
SPVContract->>SPVContract: 4.1. Get target from prevBlockBits
74-
SPVContract->>TargetsHelperLib: Check if newBlockHeight is Recalculation Block (isTargetAdjustmentBlock)
72+
SPVGateway->>SPVGateway: 4. Get Current Target
73+
SPVGateway->>SPVGateway: 4.1. Get target from prevBlockBits
74+
SPVGateway->>TargetsHelperLib: Check if newBlockHeight is Recalculation Block (isTargetAdjustmentBlock)
7575
activate TargetsHelperLib
7676
alt Recalculation Block
77-
SPVContract->>SPVContract: Recalculate target & Save lastEpochCumulativeWork
78-
TargetsHelperLib-->>SPVContract: Return newNetworkTarget
77+
SPVGateway->>SPVGateway: Recalculate target & Save lastEpochCumulativeWork
78+
TargetsHelperLib-->>SPVGateway: Return newNetworkTarget
7979
else Not Recalculation Block
80-
TargetsHelperLib-->>SPVContract: Use prevBlockTarget as networkTarget
80+
TargetsHelperLib-->>SPVGateway: Use prevBlockTarget as networkTarget
8181
end
8282
deactivate TargetsHelperLib
8383
84-
SPVContract->>SPVContract: 5. Check Block Rules
85-
SPVContract->>TargetsHelperLib: 5.1. Check Header Target == Contract Target
84+
SPVGateway->>SPVGateway: 5. Check Block Rules
85+
SPVGateway->>TargetsHelperLib: 5.1. Check Header Target == Contract Target
8686
activate TargetsHelperLib
87-
TargetsHelperLib-->>SPVContract: Result
87+
TargetsHelperLib-->>SPVGateway: Result
8888
deactivate TargetsHelperLib
8989
alt Invalid Target
90-
SPVContract--xCaller: Error: InvalidTarget
90+
SPVGateway--xCaller: Error: InvalidTarget
9191
end
9292
93-
SPVContract->>SPVContract: 5.2. Check newBlockHash <= networkTarget (PoW)
93+
SPVGateway->>SPVGateway: 5.2. Check newBlockHash <= networkTarget (PoW)
9494
alt Invalid Block Hash
95-
SPVContract--xCaller: Error: InvalidBlockHash
95+
SPVGateway--xCaller: Error: InvalidBlockHash
9696
end
9797
98-
SPVContract->>SPVContract: 5.3. Check newBlockTime >= medianTime
98+
SPVGateway->>SPVGateway: 5.3. Check newBlockTime >= medianTime
9999
alt Invalid Block Time
100-
SPVContract--xCaller: Error: InvalidBlockTime
100+
SPVGateway--xCaller: Error: InvalidBlockTime
101101
end
102102
103-
SPVContract->>SPVContract: 6. Add Block To Chain
104-
SPVContract->>SPVContract: 6.1. Save newBlockHeader & newBlockHash to Storage
103+
SPVGateway->>SPVGateway: 6. Add Block To Chain
104+
SPVGateway->>SPVGateway: 6.1. Save newBlockHeader & newBlockHash to Storage
105105
106-
SPVContract->>SPVContract: 6.2. Update Mainchain
106+
SPVGateway->>SPVGateway: 6.2. Update Mainchain
107107
alt 6.2.1. prevBlockHash == mainchainHead?
108-
SPVContract->>SPVContract: Move mainchainHead to newBlockHash
108+
SPVGateway->>SPVGateway: Move mainchainHead to newBlockHash
109109
else
110-
SPVContract->>SPVContract: 6.2.2. Calculate New Block & Current Head Cumulative Work
111-
SPVContract->>SPVContract: 6.2.3. newBlock Cumulative Work > Current Head?
110+
SPVGateway->>SPVGateway: 6.2.2. Calculate New Block & Current Head Cumulative Work
111+
SPVGateway->>SPVGateway: 6.2.3. newBlock Cumulative Work > Current Head?
112112
alt New Block Has Higher Work
113-
SPVContract->>SPVContract: Set New Block as mainchainHead
114-
SPVContract->>SPVContract: Recursively update mainchain path backwards (do-while loop)
113+
SPVGateway->>SPVGateway: Set New Block as mainchainHead
114+
SPVGateway->>SPVGateway: Recursively update mainchain path backwards (do-while loop)
115115
end
116116
end
117117
118-
SPVContract->>SPVContract: Emit BlockHeaderAdded
119-
SPVContract-->>Caller: Transaction Complete
120-
deactivate SPVContract
118+
SPVGateway->>SPVGateway: Emit BlockHeaderAdded
119+
SPVGateway-->>Caller: Transaction Complete
120+
deactivate SPVGateway
121121
```
122122

123123
### `addBlockHeaderBatch(bytes[] calldata blockHeaderRawArr_)` Sequence Diagram
@@ -127,75 +127,72 @@ This function processes multiple block headers in a single transaction, iteratin
127127
```mermaid
128128
sequenceDiagram
129129
participant Caller
130-
participant SPVContract
130+
participant SPVGateway
131131
participant BlockHeaderLib
132132
participant TargetsHelperLib
133133
134-
Caller->>SPVContract: addBlockHeaderBatch(blockHeaderRawArray_)
135-
activate SPVContract
134+
Caller->>SPVGateway: addBlockHeaderBatch(blockHeaderRawArray_)
135+
activate SPVGateway
136136
137-
SPVContract->>SPVContract: Check if Header Array is Empty
137+
SPVGateway->>SPVGateway: Check if Header Array is Empty
138138
alt Array Empty
139-
SPVContract--xCaller: Error: EmptyBlockHeaderArray
139+
SPVGateway--xCaller: Error: EmptyBlockHeaderArray
140140
end
141141
142-
SPVContract->>BlockHeaderLib: 1. Parse Block Headers Array (_parseBlockHeadersRaw)
142+
SPVGateway->>BlockHeaderLib: 1. Parse Block Headers Array (_parseBlockHeadersRaw)
143143
activate BlockHeaderLib
144-
BlockHeaderLib-->>SPVContract: Returns BlockHeaderData[] & bytes32[]
144+
BlockHeaderLib-->>SPVGateway: Returns BlockHeaderData[] & bytes32[]
145145
deactivate BlockHeaderLib
146146
147147
loop For each blockHeader in parsed array (from i=0 to length-1)
148-
SPVContract->>SPVContract: 2. Check prevBlockHash for current block
148+
SPVGateway->>SPVGateway: 2. Check prevBlockHash for current block
149149
alt First block in batch
150-
SPVContract->>SPVContract: Check prevBlockHash existence (like addBlockHeader)
150+
SPVGateway->>SPVGateway: Check prevBlockHash existence (like addBlockHeader)
151151
alt Prev Block Missing
152-
SPVContract--xCaller: Error: PrevBlockDoesNotExist
152+
SPVGateway--xCaller: Error: PrevBlockDoesNotExist
153153
end
154154
else Subsequent blocks
155-
SPVContract->>SPVContract: Check prevBlockHash == blockHash of (i-1)th block
155+
SPVGateway->>SPVGateway: Check prevBlockHash == blockHash of (i-1)th block
156156
alt Order Invalid
157-
SPVContract--xCaller: Error: InvalidBlockHeadersOrder
157+
SPVGateway--xCaller: Error: InvalidBlockHeadersOrder
158158
end
159159
end
160160
161-
SPVContract->>SPVContract: 3. Calculate currentBlockHeight = prevBlockHeight + 1
161+
SPVGateway->>SPVGateway: 3. Calculate currentBlockHeight = prevBlockHeight + 1
162162
163-
SPVContract->>SPVContract: 4. Get Current Target (like addBlockHeader)
164-
SPVContract->>TargetsHelperLib: Check for Recalculation Block & Recalculate if needed
163+
SPVGateway->>SPVGateway: 4. Get Current Target (like addBlockHeader)
164+
SPVGateway->>TargetsHelperLib: Check for Recalculation Block & Recalculate if needed
165165
activate TargetsHelperLib
166-
TargetsHelperLib-->>SPVContract: Return networkTarget
166+
TargetsHelperLib-->>SPVGateway: Return networkTarget
167167
deactivate TargetsHelperLib
168168
169-
SPVContract->>SPVContract: 5. Get Median Time
169+
SPVGateway->>SPVGateway: 5. Get Median Time
170170
alt 5.1. Num blocks added < 12
171-
SPVContract->>SPVContract: Use _getStorageMedianTime (like addBlockHeader)
171+
SPVGateway->>SPVGateway: Use _getStorageMedianTime (like addBlockHeader)
172172
else 5.2. Num blocks added >= 12
173-
SPVContract->>SPVContract: Use _getMemoryMedianTime (from batch data)
173+
SPVGateway->>SPVGateway: Use _getMemoryMedianTime (from batch data)
174174
end
175175
176-
SPVContract->>SPVContract: 6. Validate Block Rules (_validateBlockRules)
176+
SPVGateway->>SPVGateway: 6. Validate Block Rules (_validateBlockRules)
177177
alt Validation Fails
178-
SPVContract--xCaller: Error: InvalidTarget / InvalidBlockHash / InvalidBlockTime
178+
SPVGateway--xCaller: Error: InvalidTarget / InvalidBlockHash / InvalidBlockTime
179179
end
180180
181-
SPVContract->>SPVContract: 7. Add Block To Chain (_addBlock)
182-
SPVContract->>SPVContract: Emit BlockHeaderAdded
181+
SPVGateway->>SPVGateway: 7. Add Block To Chain (_addBlock)
182+
SPVGateway->>SPVGateway: Emit BlockHeaderAdded
183183
end
184184
185-
SPVContract-->>Caller: Transaction Complete
186-
deactivate SPVContract
185+
SPVGateway-->>Caller: Transaction Complete
186+
deactivate SPVGateway
187187
```
188188

189189

190190
# 📦 Contract Components
191-
The solution is primarily composed of the main SPV contract and two essential helper libraries that manage the intricacies of Bitcoin's block structure and difficulty adjustments.
191+
The solution primarily consists of the main SPV Gateway contract and the TargetsHelper library, which manages difficulty adjustments.
192192

193-
## SPVContract
193+
## SPVGateway
194194
This is the central contract that users will interact with. It serves as the primary interface for managing Bitcoin block headers on the EVM. It handles the core logic for adding and validating blocks, tracking the main Bitcoin chain, and providing querying functionalities. All custom errors and events related to the SPV operations are defined here, ensuring clear feedback and transparency during contract execution.
195195

196-
## BlockHeader Library
197-
This is a pure utility library specifically designed to handle the low-level details of Bitcoin block headers. It's responsible for the precise parsing of raw 80-byte Bitcoin block header data into a structured format that Solidity can easily work with. Crucially, it manages the byte order conversions, translating Bitcoin's little-endian format to Solidity's big-endian, and vice-versa. It also provides the essential function for calculating the double SHA256 hash of a block header, which is fundamental for verifying Proof-of-Work.
198-
199196
## TargetsHelper Library
200197
This library encapsulates all the complex mathematical and logical operations related to Bitcoin's difficulty targets. It provides functions to accurately calculate new difficulty targets based on elapsed time between blocks, ensuring the contract adheres to Bitcoin's dynamic difficulty adjustment rules. Additionally, it offers utilities for converting between the compact "bits" format (as found in Bitcoin block headers) and the full 256-bit target value, and it calculates the cumulative work associated with a given block or epoch, which is vital for determining the most valid chain.
201198

0 commit comments

Comments
 (0)