ERC-8002: Simplified Payment Verification Gateway
Trustless singleton contract for on-chain verification of Bitcoin transactions through block headers
Abstract
Introduce a singleton contract for on-chain verification of transactions that happened on Bitcoin. The contract is available at "0xTODO" , acting as a trustless Simplified Payment Verification (SPV) gateway where anyone can submit Bitcoin block headers. The gateway maintains the mainchain of blocks and allows the existence of Bitcoin transactions to be verified via Merkle proofs.
Motivation
Ethereum's long-term mission has always been to revolutionize the financial world through decentralization, trustlessness, and programmable value enabled by smart contracts. Many great use cases have been discovered so far, including the renaissance of Decentralized Finance (DeFi), emergence of Real-World Assets (RWA), and rise of privacy-preserving protocols.
However, one gem has been unreachable to date -- Bitcoin. Due to its extremely constrained programmability, one can only hold and transfer bitcoins in a trustless manner. This EIP tries to expand its capabilities by laying a solid foundation for bitcoins to be also used in various EVM-based DeFi protocols, unlocking a whole new trillion-dollar market.
The singleton SPV gateway contract defined in this proposal acts as a trustless one-way bridge between Bitcoin and Ethereum, already enabling use cases such as using native BTC as a lending collateral for stablecoin loans. Moreover, with the recent breakthroughs in the BitVM technology, the full-fledged, ownerless two-way bridge may soon become a reality, powering the permissionless and wrapless issuance of BTC on Ethereum.
Specification
The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
General
Bitcoin Block Header Structure
In Bitcoin, each block contains a header, which has a fixed size of 80 bytes and follows the following structure:
| Field | Size | Format | Description |
|---|---|---|---|
| Version | 4 bytes | little-endian | The version number of the block. |
| Previous Block | 32 bytes | natural byte order | The block hash of a previous block this block is building on top of. |
| Merkle Root | 32 bytes | natural byte order | A fingerprint for all of the transactions included in the block. |
| Time | 4 bytes | little-endian | The current time as a Unix timestamp. |
| Bits | 4 bytes | little-endian | A compact representation of the current target (difficulty). |
| Nonce | 4 bytes | little-endian | A 32-bit number which miners compute to find a valid block hash. |
The fields within the block header are sequentially ordered as presented in the table above.
Difficulty Adjustment Mechanism
Bitcoin's Proof-of-Work (PoW) consensus mechanism has a probabilistic finality, thus relying on a dynamic difficulty target adjustments. The target's initial value is set to 0x00000000ffff0000000000000000000000000000000000000000000000000000, which also serves as the minimum difficulty threshold.
The target is recalculated every 2016 blocks (approximately every two weeks), a period commonly referred to as a difficulty adjustment period.
The expected duration for each adjustment period is 1,209,600 seconds (2016 blocks * 10 minutes/block). The new target value is derived by multiplying the current target by the ratio of the actual time taken to mine the preceding 2016 blocks to this expected duration.
To prevent drastic difficulty fluctuations, the adjustment multiplier is capped at 4x and 1/4x respectively.
Block Header Validation Rules
For a Bitcoin block header to be considered valid and accepted into the chain, it MUST adhere to the following consensus rules:
-
Chain Cohesion: The
Previous Blockhash field MUST reference the hash of a valid block that is present in the set of existing block headers. -
Timestamp Rules:
- The
Timefield MUST be strictly greater than the Median Time Past (MTP) of the previous 11 blocks. - The
Timefield MUST NOT be more than 2 hours in the future relative to the validating node's network-adjusted time.
- The
-
PoW Constraint: When the block header is hashed twice using
SHA256, the resulting hash MUST be less than or equal to the currenttargetvalue, as derived from the difficulty adjustment mechanism.
Transaction Inclusion Structure
Every Bitcoin block header has a field Merkle Root that corresponds to a Merkle root of the transactions tree included in this block.
The transactions Merkle tree is built recursively performing double SHA256 hash on each pair of sibling nodes, where the tree leaves are the double SHA256 hash of the raw transaction bytes. In case the node has no siblings, the hashing is done over the node with itself.
To verify the transaction inclusion into the block, one SHOULD build the Merkle root from the ground up and compare it with the Merkle Root stored in the selected block header. The corresponding Merkle path and hashing direction bits can be obtained and processed by querying a Bitcoin full node.
Mainchain Definition
Bitcoin's mainchain is determined not just by its length, but by the greatest cumulative PoW among all valid competing chains. This cumulative work represents the total computational effort expended to mine all blocks within a specific chain.
The work contributed by a single block is inversely proportional to its target value. Specifically, the work of a block can be calculated as (2**256 - 1) / (target + 1). The target value for a block is derived from its Bits field, where the first byte encodes the required left hand bit shift, and the other three bytes the actual target value.
The total cumulative work of a chain is the sum of the work values of all blocks within that chain. A block is considered part of the mainchain if it extends the chain with the greatest cumulative PoW.
SPV Gateway
The SPVGateway contract MUST provide a permissionless mechanism for its initialization. This mechanism MUST allow for the submission of a valid Bitcoin block header, its corresponding block height, and the cumulative PoW up to that block, without requiring special permissions.
The SPVGateway MUST implement the following interface:
All fields within the BlockHeaderData struct MUST be converted to big-endian byte order for internal representation and processing within the smart contract.
The addBlockHeader function MUST perform the following checks:
- Validate that the submitted raw block header has a fixed size of 80 bytes.
- Enforce all block header validation rules as specified in the "Block Header Validation Rules" section.
- Integrate the new block header into the known chain by calculating its cumulative PoW and managing potential chain reorganizations as defined in the "Mainchain Definition" section.
- Emit a
BlockHeaderAddedevent upon successful addition of the block header. - Emit a
MainchainHeadUpdatedevent if the mainchain was updated.
The checkTxInclusion function MUST perform the following steps:
- Check whether the provided
blockHashis part of the mainchain and ensure its number of confirmations is at least equal to theminConfirmationsCountparameter. If any of these checks fail, the function MUST returnfalse. - Using the provided
merkleProof,txId, andtxIndex, the function MUST compute the Merkle root. - The computed Merkle root MUST be compared against the
Merkle Rootfield stored within the block header identified byblockHash. - If the computed Merkle root matches the stored
Merkle Root, the function MUST returntrue. Otherwise, it MUST returnfalse.
Rationale
During the design process of the SPVGateway contract, several decisions have been made that require clarification. The following initialization options of the smart contract were considered:
- Hardcoding the Bitcoin genesis block: This approach is the simplest for contract deployment as it embeds the initial state directly in the code. While offering absolute trustlessness of the starting point, it limits availability, as the full sync of the gateway would cost around ~100 ETH at the gas price of 1 gwei.
- Initialization from an arbitrary block height by trusting provided cumulative work and height: Currently, the gateway adopts this method as its initialization mechanism. While implying trust in the initial submitted values, it's a common practice for bootstrapping light clients and can be secured via off-chain mechanisms for initial validation (e.g., community-verified checkpoints).
- Initialization with Zero-Knowledge Proof (ZKP) for historical correctness: This advanced method involves proving the entire history of Bitcoin up to a specific block using ZKP.
Upon submitting the raw block header, the gateway expects the BlockHeaderData fields to be converted to big-endian byte order. This is required to maintain EVM's efficiency, which is contrary to Bitcoin's native little-endian integer serialization.
There are no "finality" rules in the SPVGateway contract. The determination of such is left to consuming protocols, allowing individual definition to meet required security thresholds.
The inclusion of an OPTIONAL addBlockHeaderBatch function offers significant gas optimizations. For batches exceeding 11 blocks, MTP can be calculated using timestamps from calldata, substantially reducing storage reads and transaction costs.
Backwards Compatibility
This EIP is fully backwards compatible.
Deployment Method
TBD
Test Cases
TBD
Reference Implementation
A reference implementation of the SPVGateway contract can be found here.
TargetsHelper is a supporting library that provides utility functions for working with Bitcoin's difficulty targets. It includes methods to convert the Bits field from a block header to the corresponding target value and vice versa, as well as functions to calculate the new difficulty target during adjustment periods.
Please note that the reference implementation depends on the
@openzeppelin/contracts v5.2.0,@solarity/solidity-lib v3.2.0andsolady v0.1.23.
Security Considerations
Among potential security issues, the following can be noted:
The security of the SPVGateway is directly dependent on the security of Bitcoin's underlying PoW consensus. A successful 51% attack on the Bitcoin network would allow an attacker to submit fraudulent block headers that would be accepted by the contract, compromising its state.
The block header validation rules require a Bitcoin node to check that the newly created block is not more than 2 hours ahead of the node's network-adjusted time. This check is impossible to implement on the SPVGateway smart contract, hence it is omitted.
Unlike other blockchain systems with deterministic finality, Bitcoin's consensus is probabilistic. The SPVGateway contract SHOULD be designed to handle chain reorganizations of arbitrary depth, but it cannot prevent them. As a result, transactions included in a block may not be permanently final. All dApps and protocols relying on this contract MUST implement their own security policies to determine a sufficient number of block confirmations before a transaction is considered "final" for their specific use case.
While the addBlockHeader function is permissionless and validates each new header cryptographically, the contract's initial state (its starting block header, height, and cumulative PoW) is a point of trust. The integrity of the entire chain history within the contract is built upon the correctness of this initial data. Although the EIP's design allows for flexible bootstrapping, the responsibility for verifying the initial state falls on the community and the dApps that choose to use a specific deployment of the SPVGateway.
Copyright
Copyright and related rights waived via CC0.