hashi
  • Welcome
  • Introduction
    • What is Hashi?
    • Why Hashi?
    • Key Features
    • The SSN
  • Getting Started
    • How Hashi Works
    • Quick Start
      • Verifying foreign event
        • Setting the scene
        • Getting the Event Proof
        • Validating your statements
      • Reading foreign state
        • Setting the scene
        • Getting the Storage Proof
        • Validating your statements
      • Pushing a message
        • Writing your message sending contract
        • Implementing your callback
        • Waiting for the cross-chain execution
  • Core Concepts
    • Block Header Relaying
    • Message Dispatching
    • Oracles
    • Additive Security Model
  • Deployments
    • Blockchains
    • Oracles
  • Smart Contracts
    • Key Contracts
    • HashiProver API
  • TOOLS
    • SP1 storage proof verifier
    • Solana integration
  • APPS / INTEGRATIONS
    • Safe Crosschain
    • Aragon UCG
    • Openfort Chain Abstraction
  • META
    • Developer resources
    • Audits
    • Explorer
    • Community
Powered by GitBook
On this page
Export as PDF
  1. Getting Started
  2. Quick Start
  3. Verifying foreign event

Validating your statements

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

Deploying the Custom Verification Contract on Chiado

Here is a custom contract that deployed on Chiado can be used to read and verify the Transfer event on Sepolia:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import { HashiProver } from "./HashiProver.sol";

contract MockERC20Prover {

    event TransferEventVerified(uint256 indexed chainID, bytes rlpEncodedEvent);

    HashiProver public hashiProver;
    address public erc20Contract;
    uint256 public chainID;

    constructor(address shoyuBashi_, address erc20Contract_, uint256 chainID_) {
        hashiProver = HashiProver(shoyuBashi_);
        erc20Contract = erc20Contract_;
        chainID = chainID_;
    }

    function verifyTransferEvent(HashiProver.ReceiptProof calldata proof, bytes memory expectedRlpEncodedEvent) external {
        require(proof.chainId == chainID, "Invalid chain id"); 

        bytes memory rlpEncodedEvent = hashiProver.verifyForeignEvent(proof);

        require(keccak256(rlpEncodedEvent) == keccak256(expectedRlpEncodedEvent), "invalid event");
        emit TransferEventVerified(proof.chainId , rlpEncodedEvent);

        // TODO: Define custom logic here

    }
}

Deployment:

  • In this example, pass to the custom verification contract constructor <ShoyuBashi contract address on Chiado, the ERC20 contract address on Sepolia, from which the Transfer event is emitted, chain ID of the ERC20Contract (Sepolia: 11155111)>

verifyForeignEvent explanation:

Inputs:

  • proof: the HashiAPI retreived proof

Logic:

  • check that the proof chainID matches the origin chain chainId (Sepolia in this case).

  • The verifyForeignEvent function validates the event proof against the block header stored on Chiado, which was relayed from Sepolia.

  • check that rlpEncodedEvent returned from HashiProver.verifyForeignEvent matches the expectedRlpEncodedEvent that we passed as the function argument. This is useful to check that the Event infos encoded in the proof just verified actually match the Event we expect.

  • If the proof is valid, the contract emits the TransferEventVerified event. You may define your own logic after the proof has been verified.

Submitting the Proof

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

// Example of submitting the proof in Solidity (or via web3 call)
HashiProver.ReceiptProof memory proof = { /* fetched proof from curl command */ };
MockERC20Prover.verifyTransferEvent(proof, expectedRlpEncodedEvent);

This will trigger the contract to verify the proof using the block header stored in Hashi from Sepolia. If the proof is valid, the rplEncodedEvent will be emitted.

References

PreviousGetting the Event ProofNextReading foreign state

Last updated 4 months ago

HashiProver & ShoyuBashi are already deployed on a 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.

expectedRlpEncodedEvent : an bytes encoded format with the Event information: check out the in order to generate it starting from the Event topics and data.

Check verifyForeignEvent implementation .

helper script from Hashi-template
here
RLP encode event helper script
MockERC20Prover contract
HashiProver contract
ShoyuBashi contract
MockERC20Prover contract address on Chiado
list of networks
HashiProver & ShoyuBashi addresses