# Validating your statements

Once the proof has been fetched, we can now verify it using a custom contract on **Gnosis Chain**. The contract will use the **HashiProver** helper library to check the proof against the block header stored on **Gnosis Chain**.

**Deploying the custom Verification Contract on Gnosis Chain**

Here is a contract that deployed on **Gnosis Chain** can be used to read and verify the USDC total supply on **Optimism**:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import { HashiProver } from "https://github.com/gnosis/hashi/blob/feat/hashi-prover/packages/evm/contracts/prover/HashiProver.sol";

contract UsdcTotalSupplyReader is HashiProver {
    event UsdcTotalSupply(uint256 totalSupply);

    constructor(address shoyuBashi) HashiProver(shoyuBashi) {}

    function readTotalSupply(HashiProver.AccountAndStorageProof calldata proof) external {
        require(proof.chainId == 10, "Invalid chain id"); // Optimism
        require(proof.account == 0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85, "Invalid account");
        require(proof.storageKeys.length == 1 && proof.storageKeys[0] == bytes32(uint256(0xb)), "Invalid storage key");

        // Verify the proof against the latest block header stored in Hashi
        uint256 totalSupply = uint256(bytes32(verifyForeignStorage(proof)[0]));
        emit UsdcTotalSupply(totalSupply);
    }
}
```

#### Deployment:

* *HashiProver & ShoyuBashi* are already deployed on a [list of networks](https://crosschain-alliance.gitbook.io/hashi/deployments/blockchains#shoyubashi-and-hashi-prover) that can be called from the custom verification contract (this contract). In order to configure a custom oracle set for it is possible to deploy a new *ShoyuBashi* contract, inherit *HashiProver* contract and configure your oracle set in the *ShoyuBashi* contract.
* In this example, pass to the custom verification contract constructor <*ShoyuBashi* contract address on **Gnosis Chain**>

**`readTotalSupply` explanation**:

Inputs:

* `proof`: the HashiAPI retreived storage proof.

Logic:

* check that the proof chainID matches the origin chain chainID (**Optimism** in this case).
* check that the USDC contract address.
* check that storage key match the expected value.
* This contract uses **HashiProver** to verify on **Gnosis Chain** the storage proof coming from **Optimism** fetched earlier.
* It checks that the proof is from **Optimism** (chain ID 10), and that the USDC contract address and storage key match the expected values.
* The `verifyForeignStorage` function validates the proof against the block header stored on **Gnosis Chain**, which was relayed from **Optimism**.
* If the proof is valid, the contract emits the **total supply** of USDC on Optimism.

Check `verifyForeignStorage` implementation [here](https://github.com/gnosis/hashi/blob/main/packages/evm/contracts/prover/HashiProverLib.sol#L77).

**Submitting the Proof**

Once the contract is deployed on **Gnosis Chain**, you can submit the proof fetched from the API using the following command:

```solidity
// Example of submitting the proof in Solidity (or via web3 call)
HashiProver.AccountAndStorageProof memory proof = { /* fetched proof from curl command */ };
usdcTotalSupplyReader.readTotalSupply(proof);
```

This will trigger the contract to verify the proof using the block header stored in Hashi from **Optimism**. If the proof is valid, the **total supply of USDC** will be emitted.
