# IConfirmedBlockHeightExists

> Assert that a block number is confirmed.

> For the complete documentation index, see [llms.txt](/llms.txt). Markdown versions of documentation pages are available by appending `.md` to the page URL.

Source: https://dev.flare.network/fdc/reference/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](https://github.com/flare-foundation/flare-smart-contracts-v2/blob/main/contracts/userInterfaces/fdc/IConfirmedBlockHeightExists.sol).

## Overview[​](#overview "Direct link to 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[​](#supported-chains "Direct link to Supported Chains")

Network Type

Supported Chains

**Mainnet**

`BTC` (Bitcoin), `DOGE` (Dogecoin), `XRP` (XRP Ledger)

**Testnet**

`testBTC` (Bitcoin Testnet 4), `testDOGE`, `testXRP`

## Chain-Specific Confirmation Requirements[​](#chain-specific-confirmation-requirements "Direct link to 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[​](#interface-definition "Direct link to Interface Definition")

```
// SPDX-License-Identifier: MITpragma 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 FDC 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[​](#structs "Direct link to Structs")

### Request[​](#request "Direct link to Request")

Toplevel request structure.

#### Parameters[​](#parameters "Direct link to 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 response
-   `requestBody`: Data defining the request

### Response[​](#response "Direct link to Response")

Toplevel response structure.

#### Parameters[​](#parameters-1 "Direct link to Parameters")

-   `attestationType`: Extracted from the request
-   `sourceId`: Extracted from the request
-   `votingRound`: The ID of the FDC round in which the request was considered
-   `lowestUsedTimestamp`: The lowest timestamp used to generate the response
-   `requestBody`: Extracted from the request
-   `responseBody`: Data defining the response

### Proof[​](#proof "Direct link to Proof")

Toplevel proof structure for verification.

#### Parameters[​](#parameters-2 "Direct link to Parameters")

-   `merkleProof`: Merkle proof corresponding to the attestation response
-   `data`: Attestation response

### RequestBody[​](#requestbody "Direct link to RequestBody")

Request body specific to block height confirmation.

#### Parameters[​](#parameters-3 "Direct link to Parameters")

-   `blockNumber`: The number of the block to confirm
-   `queryWindow`: Time period in seconds to calculate block production rate

### ResponseBody[​](#responsebody "Direct link to ResponseBody")

Response body specific to block height confirmation.

#### Parameters[​](#parameters-4 "Direct link to Parameters")

-   `blockTimestamp`: Timestamp of the block with `blockNumber`
-   `numberOfConfirmations`: Required confirmations for the specific chain
-   `lowestQueryWindowBlockNumber`: Block number of the latest block with timestamp < `blockTimestamp - queryWindow`
-   `lowestQueryWindowBlockTimestamp`: Timestamp of the block at `lowestQueryWindowBlockNumber`

## Implementation Notes[​](#implementation-notes "Direct link to Implementation Notes")

-   Attestation ID: `0x02`
-   Timestamp values vary by chain (mediantime for BTC/DOGE, close\_time for XRP)
-   The `lowestUsedTimestamp` parameter uses the value of `lowestQueryWindowBlockTimestamp`
-   The `lutlimit` (Lowest Used Timestamp limit) is `0x127500` (1,209,600 seconds = 14 days) for all supported chains

## Calculating Block Production Rate[​](#calculating-block-production-rate "Direct link to Calculating Block Production Rate")

The response fields allow developers to calculate the average block production rate using the formula:

```
blocks_produced = blockNumber - lowestQueryWindowBlockNumbertime_elapsed = blockTimestamp - lowestQueryWindowBlockTimestampaverage_block_time = time_elapsed / blocks_produced
```

## Usage Example[​](#usage-example "Direct link to Usage Example")

BlockchainMonitor.sol

```
// SPDX-License-Identifier: MITpragma solidity >=0.8.0 <0.9.0;import {ContractRegistry} from "@flarenetwork/flare-periphery-contracts/coston2/ContractRegistry.sol";import {IFdcVerification} from "@flarenetwork/flare-periphery-contracts/coston2/IFdcVerification.sol";import {IConfirmedBlockHeightExists} from "@flarenetwork/flare-periphery-contracts/coston2/IConfirmedBlockHeightExists.sol";contract BlockchainMonitor {    uint64 public latestAverageBlockTimeSeconds;    event BlockTimeCalculated(        uint64 indexed blockNumber,        uint64 averageBlockTime    );    function processBlockHeightProof(        IConfirmedBlockHeightExists.Proof calldata _proof    ) external {        // 1. FDC Logic: Verify the proof's authenticity with the Flare network.        require(isProofValid(_proof), "Invalid block height proof");        // 2. Business Logic: Execute actions based on the verified proof data.        uint64 blockNumber = _proof.data.requestBody.blockNumber;        uint64 blockTimestamp = _proof.data.responseBody.blockTimestamp;        uint64 lowestNumber = _proof            .data            .responseBody            .lowestQueryWindowBlockNumber;        uint64 lowestTimestamp = _proof            .data            .responseBody            .lowestQueryWindowBlockTimestamp;        uint64 avgBlockTimeSeconds = 0;        if (blockNumber > lowestNumber) {            uint64 blocksProduced = blockNumber - lowestNumber;            uint64 timeElapsed = blockTimestamp - lowestTimestamp;            avgBlockTimeSeconds = timeElapsed / blocksProduced;        }        // Take action: update state and emit an event with the new data.        latestAverageBlockTimeSeconds = avgBlockTimeSeconds;        emit BlockTimeCalculated(blockNumber, avgBlockTimeSeconds);    }    function isProofValid(        IConfirmedBlockHeightExists.Proof memory _proof    ) public view returns (bool) {        IFdcVerification fdcVerification = ContractRegistry            .getFdcVerification();        return fdcVerification.verifyConfirmedBlockHeightExists(_proof);    }}
```

[Open example in Remix](https://remix.ethereum.org/#url=https://github.com/flare-foundation/developer-hub/blob/main/examples/developer-hub-solidity/BlockchainMonitor.sol&version=builtin&evmVersion=cancun&optimize=true&runs=200)

## Related Interfaces[​](#related-interfaces "Direct link to Related Interfaces")

-   [IFdcHub](/fdc/reference/IFdcHub): Primary interface for requesting attestations
-   [IFdcVerification](/fdc/reference/IFdcVerification): Interface for verifying attestation proofs
