IConfirmedBlockHeightExists
An interface to verify that a specified block has been confirmed on an external blockchain and to calculate block production rates.
Sourced from IConfirmedBlockHeightExists.sol
on GitHub.
Overview
The IConfirmedBlockHeightExists interface allows smart contracts to verify that a specific block number exists and has reached the required confirmation threshold on an external blockchain. Additionally, it provides data to calculate block production rates over a specified time window, which can be useful for estimating transaction finality times or implementing time-dependent logic.
Supported Chains
Network Type | Supported Chains |
---|---|
Mainnet | BTC (Bitcoin), DOGE (Dogecoin), XRP (XRP Ledger) |
Testnet | testBTC (Bitcoin Testnet v3), testDOGE , testXRP |
Chain-Specific Confirmation Requirements
Chain | Chain ID | Required Confirmations | Timestamp Source |
---|---|---|---|
BTC | 0 | 6 | mediantime |
DOGE | 2 | 60 | mediantime |
XRP | 3 | 3 | close_time |
Interface Definition
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6 <0.9;
/**
* @custom:name IConfirmedBlockHeightExists
* @custom:id 0x02
* @custom:supported BTC, DOGE, XRP
* @author Flare
* @notice An assertion that a block with `blockNumber` is confirmed.
* It also provides data to compute the block production rate in the given time range.
* @custom:verification It is checked that the block with `blockNumber` is confirmed by at
* least `numberOfConfirmations`.
* If it is not, the request is rejected. We note a block on the tip of the chain is confirmed by 1 block.
* Then `lowestQueryWindowBlock` is determined and its number and timestamp are extracted.
*
*
* Current confirmation heights consensus:
*
*
* | `Chain` | `chainId` | `numberOfConfirmations` | `timestamp ` |
* | ------- | --------- | ----------------------- | ------------ |
* | `BTC` | 0 | 6 | mediantime |
* | `DOGE` | 2 | 60 | mediantime |
* | `XRP` | 3 | 3 | close_time |
*
*
* @custom:lut `lowestQueryWindowBlockTimestamp`
* @custom:lutlimit `0x127500`, `0x127500`, `0x127500`
*/
interface IConfirmedBlockHeightExists {
/**
* @notice Toplevel request
* @param attestationType ID of the attestation type.
* @param sourceId ID of the data source.
* @param messageIntegrityCode `MessageIntegrityCode` that is derived from the expected response as defined.
* @param requestBody Data defining the request. Type and interpretation is determined by the `attestationType`.
*/
struct Request {
bytes32 attestationType;
bytes32 sourceId;
bytes32 messageIntegrityCode;
RequestBody requestBody;
}
/**
* @notice Toplevel response
* @param attestationType Extracted from the request.
* @param sourceId Extracted from the request.
* @param votingRound The ID of the State Connector round in which the request was considered.
* @param lowestUsedTimestamp The lowest timestamp used to generate the response.
* @param requestBody Extracted from the request.
* @param responseBody Data defining the response. The verification rules for the construction of the
* response body and the type are defined per specific `attestationType`.
*/
struct Response {
bytes32 attestationType;
bytes32 sourceId;
uint64 votingRound;
uint64 lowestUsedTimestamp;
RequestBody requestBody;
ResponseBody responseBody;
}
/**
* @notice Toplevel proof
* @param merkleProof Merkle proof corresponding to the attestation response.
* @param data Attestation response.
*/
struct Proof {
bytes32[] merkleProof;
Response data;
}
/**
* @notice Request body for ConfirmedBlockHeightExistsType attestation type
* @param blockNumber The number of the block the request wants a confirmation of.
* @param queryWindow The length of the period in which the block production rate is to be computed.
*/
struct RequestBody {
uint64 blockNumber;
uint64 queryWindow;
}
/**
* @notice Response body for ConfirmedBlockHeightExistsType attestation type
* @custom:below `blockNumber`, `lowestQueryWindowBlockNumber`, `blockTimestamp`, `lowestQueryWindowBlockTimestamp`
* can be used to compute the average block production time in the specified block range.
* @param blockTimestamp The timestamp of the block with `blockNumber`.
* @param numberOfConfirmations The depth at which a block is considered confirmed depending on the chain.
* All attestation providers must agree on this number.
* @param lowestQueryWindowBlockNumber The block number of the latest block that has a timestamp strictly smaller
* than `blockTimestamp` - `queryWindow`.
* @param lowestQueryWindowBlockTimestamp The timestamp of the block at height `lowestQueryWindowBlockNumber`.
*/
struct ResponseBody {
uint64 blockTimestamp;
uint64 numberOfConfirmations;
uint64 lowestQueryWindowBlockNumber;
uint64 lowestQueryWindowBlockTimestamp;
}
}
Structs
Request
Toplevel request structure.
Parameters
attestationType
: ID of the attestation type (0x02 for ConfirmedBlockHeightExists)sourceId
: ID of the data source (e.g., BTC, DOGE, XRP)messageIntegrityCode
: MessageIntegrityCode derived from the expected responserequestBody
: Data defining the request
Response
Toplevel response structure.
Parameters
attestationType
: Extracted from the requestsourceId
: Extracted from the requestvotingRound
: The ID of the State Connector round in which the request was consideredlowestUsedTimestamp
: The lowest timestamp used to generate the responserequestBody
: Extracted from the requestresponseBody
: Data defining the response
Proof
Toplevel proof structure for verification.
Parameters
merkleProof
: Merkle proof corresponding to the attestation responsedata
: Attestation response
RequestBody
Request body specific to block height confirmation.
Parameters
blockNumber
: The number of the block to confirmqueryWindow
: Time period in seconds to calculate block production rate
ResponseBody
Response body specific to block height confirmation.
Parameters
blockTimestamp
: Timestamp of the block withblockNumber
numberOfConfirmations
: Required confirmations for the specific chainlowestQueryWindowBlockNumber
: Block number of the latest block with timestamp <blockTimestamp - queryWindow
lowestQueryWindowBlockTimestamp
: Timestamp of the block atlowestQueryWindowBlockNumber
Implementation Notes
- Attestation ID:
0x02
- Timestamp values vary by chain (mediantime for BTC/DOGE, close_time for XRP)
- The
lowestUsedTimestamp
parameter uses the value oflowestQueryWindowBlockTimestamp
- The
lutlimit
(Lowest Used Timestamp limit) is0x127500
(1,209,600 seconds = 14 days) for all supported chains
Calculating Block Production Rate
The response fields allow developers to calculate the average block production rate using the formula:
blocks_produced = blockNumber - lowestQueryWindowBlockNumber
time_elapsed = blockTimestamp - lowestQueryWindowBlockTimestamp
average_block_time = time_elapsed / blocks_produced
Usage Example
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcHub.sol";
import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcVerification.sol";
import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/fdc/IConfirmedBlockHeightExists.sol";
contract BlockchainMonitor {
IFdcHub private fdcHub;
IFdcVerification private fdcVerification;
bytes32 private constant ATTESTATION_TYPE_CONFIRMED_BLOCK = 0x0200000000000000000000000000000000000000000000000000000000000000;
bytes32 private constant SOURCE_ID_BTC = 0x4254430000000000000000000000000000000000000000000000000000000000;
constructor(address _fdcHubAddress, address _fdcVerificationAddress) {
fdcHub = IFdcHub(_fdcHubAddress);
fdcVerification = IFdcVerification(_fdcVerificationAddress);
}
// Request confirmation of a block
function requestBlockConfirmation(uint64 blockNumber, uint64 queryWindow) external payable {
// Create request body
IConfirmedBlockHeightExists.RequestBody memory requestBody = IConfirmedBlockHeightExists.RequestBody({
blockNumber: blockNumber,
queryWindow: queryWindow
});
// Encode the full request
bytes memory encodedRequest = abi.encode(
ATTESTATION_TYPE_CONFIRMED_BLOCK,
SOURCE_ID_BTC,
bytes32(0), // messageIntegrityCode (would need to be calculated properly)
requestBody
);
// Submit the request with payment
fdcHub.requestAttestation{value: msg.value}(encodedRequest);
}
// Verify a provided proof and calculate block rate
function verifyBlockAndCalculateRate(IConfirmedBlockHeightExists.Proof calldata _proof)
external view
returns (
bool blockConfirmed,
uint64 avgBlockTimeSeconds
)
{
// Verify the proof using FdcVerification
bool proofVerified = fdcVerification.verifyConfirmedBlockHeightExists(_proof);
if (proofVerified) {
// Extract data for calculation
uint64 blockNumber = _proof.data.requestBody.blockNumber;
uint64 blockTimestamp = _proof.data.responseBody.blockTimestamp;
uint64 lowestNumber = _proof.data.responseBody.lowestQueryWindowBlockNumber;
uint64 lowestTimestamp = _proof.data.responseBody.lowestQueryWindowBlockTimestamp;
// Calculate average block time
uint64 blocksProduced = blockNumber - lowestNumber;
uint64 timeElapsed = blockTimestamp - lowestTimestamp;
if (blocksProduced > 0) {
avgBlockTimeSeconds = timeElapsed / blocksProduced;
}
return (true, avgBlockTimeSeconds);
}
return (false, 0);
}
}
Related Interfaces
- IFdcHub: Primary interface for requesting attestations
- IFdcVerification: Interface for verifying attestation proofs