Goerli Testnet

Contract

0x67EA962864cdad3f2202118dc6f65Ff510F7BB4D
Source Code

Overview

ETH Balance

0 ETH

Multi Chain

Multichain Addresses

0 address found via
Transaction Hash
Method
Block
From
To
Value
Request Combined...98786052023-10-16 21:11:4852 days 6 hrs ago1697490708IN
0x67EA96...10F7BB4D
0 ETH0.000255333.00000001
Request Combined...98784882023-10-16 20:41:4852 days 6 hrs ago1697488908IN
0x67EA96...10F7BB4D
0 ETH0.000255363.00000001
Request Combined...98783602023-10-16 20:11:4852 days 7 hrs ago1697487108IN
0x67EA96...10F7BB4D
0 ETH0.000255363
Request Combined...98782302023-10-16 19:41:4852 days 7 hrs ago1697485308IN
0x67EA96...10F7BB4D
0 ETH0.000255363.00000001
Request Combined...98781142023-10-16 19:12:0052 days 8 hrs ago1697483520IN
0x67EA96...10F7BB4D
0 ETH0.000255363.00000001
Request Combined...98779942023-10-16 18:41:4852 days 8 hrs ago1697481708IN
0x67EA96...10F7BB4D
0 ETH0.000255363.00000001
Request Combined...98778732023-10-16 18:11:4852 days 9 hrs ago1697479908IN
0x67EA96...10F7BB4D
0 ETH0.000255363.00000001
Request Combined...98777582023-10-16 17:41:4852 days 9 hrs ago1697478108IN
0x67EA96...10F7BB4D
0 ETH0.000255363.00000001
Request Combined...98776462023-10-16 17:11:4852 days 10 hrs ago1697476308IN
0x67EA96...10F7BB4D
0 ETH0.000255363.00000001
Request Combined...98775272023-10-16 16:42:0052 days 10 hrs ago1697474520IN
0x67EA96...10F7BB4D
0 ETH0.000255363.00000001
Request Combined...98774052023-10-16 16:11:4852 days 11 hrs ago1697472708IN
0x67EA96...10F7BB4D
0 ETH0.000255363.00000002
Request Combined...98772772023-10-16 15:41:4852 days 11 hrs ago1697470908IN
0x67EA96...10F7BB4D
0 ETH0.000255363.00000001
Request Combined...98771622023-10-16 15:11:4852 days 12 hrs ago1697469108IN
0x67EA96...10F7BB4D
0 ETH0.000255363.00000001
Request Combined...98770382023-10-16 14:41:4852 days 12 hrs ago1697467308IN
0x67EA96...10F7BB4D
0 ETH0.000255363.00000001
Request Combined...98769212023-10-16 14:11:4852 days 13 hrs ago1697465508IN
0x67EA96...10F7BB4D
0 ETH0.000255363.00000001
Request Combined...98768062023-10-16 13:42:0052 days 13 hrs ago1697463720IN
0x67EA96...10F7BB4D
0 ETH0.000255363.00000001
Request Combined...98766852023-10-16 13:11:4852 days 14 hrs ago1697461908IN
0x67EA96...10F7BB4D
0 ETH0.000255363.00000001
Request Combined...98765662023-10-16 12:41:4852 days 14 hrs ago1697460108IN
0x67EA96...10F7BB4D
0 ETH0.000255363.00000001
Request Combined...98764422023-10-16 12:12:1252 days 15 hrs ago1697458332IN
0x67EA96...10F7BB4D
0 ETH0.000255363.00000001
Request Combined...98763282023-10-16 11:42:0052 days 15 hrs ago1697456520IN
0x67EA96...10F7BB4D
0 ETH0.000255363.00000001
Request Combined...98762132023-10-16 11:11:4852 days 16 hrs ago1697454708IN
0x67EA96...10F7BB4D
0 ETH0.000255363.00000001
Request Combined...98760952023-10-16 10:41:4852 days 16 hrs ago1697452908IN
0x67EA96...10F7BB4D
0 ETH0.000255363.00000001
Request Combined...98759742023-10-16 10:11:4852 days 17 hrs ago1697451108IN
0x67EA96...10F7BB4D
0 ETH0.000255363
Request Combined...98758512023-10-16 9:41:4852 days 17 hrs ago1697449308IN
0x67EA96...10F7BB4D
0 ETH0.000255363.00000001
Request Combined...98757332023-10-16 9:11:3652 days 18 hrs ago1697447496IN
0x67EA96...10F7BB4D
0 ETH0.000255363
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Txn Hash Block From To Value
98787512023-10-16 21:46:4852 days 5 hrs ago1697492808
0x67EA96...10F7BB4D
0 ETH
98786382023-10-16 21:19:2452 days 6 hrs ago1697491164
0x67EA96...10F7BB4D
0 ETH
98786052023-10-16 21:11:4852 days 6 hrs ago1697490708
0x67EA96...10F7BB4D
0 ETH
98785042023-10-16 20:46:4852 days 6 hrs ago1697489208
0x67EA96...10F7BB4D
0 ETH
98784882023-10-16 20:41:4852 days 6 hrs ago1697488908
0x67EA96...10F7BB4D
0 ETH
98783892023-10-16 20:18:1252 days 7 hrs ago1697487492
0x67EA96...10F7BB4D
0 ETH
98783602023-10-16 20:11:4852 days 7 hrs ago1697487108
0x67EA96...10F7BB4D
0 ETH
98782582023-10-16 19:48:1252 days 7 hrs ago1697485692
0x67EA96...10F7BB4D
0 ETH
98782302023-10-16 19:41:4852 days 7 hrs ago1697485308
0x67EA96...10F7BB4D
0 ETH
98781142023-10-16 19:12:0052 days 8 hrs ago1697483520
0x67EA96...10F7BB4D
0 ETH
98780142023-10-16 18:46:4852 days 8 hrs ago1697482008
0x67EA96...10F7BB4D
0 ETH
98779942023-10-16 18:41:4852 days 8 hrs ago1697481708
0x67EA96...10F7BB4D
0 ETH
98778962023-10-16 18:17:3652 days 9 hrs ago1697480256
0x67EA96...10F7BB4D
0 ETH
98778732023-10-16 18:11:4852 days 9 hrs ago1697479908
0x67EA96...10F7BB4D
0 ETH
98777802023-10-16 17:48:1252 days 9 hrs ago1697478492
0x67EA96...10F7BB4D
0 ETH
98777582023-10-16 17:41:4852 days 9 hrs ago1697478108
0x67EA96...10F7BB4D
0 ETH
98776632023-10-16 17:16:3652 days 10 hrs ago1697476596
0x67EA96...10F7BB4D
0 ETH
98776462023-10-16 17:11:4852 days 10 hrs ago1697476308
0x67EA96...10F7BB4D
0 ETH
98775442023-10-16 16:46:2452 days 10 hrs ago1697474784
0x67EA96...10F7BB4D
0 ETH
98775272023-10-16 16:42:0052 days 10 hrs ago1697474520
0x67EA96...10F7BB4D
0 ETH
98774272023-10-16 16:17:1252 days 11 hrs ago1697473032
0x67EA96...10F7BB4D
0 ETH
98774052023-10-16 16:11:4852 days 11 hrs ago1697472708
0x67EA96...10F7BB4D
0 ETH
98772922023-10-16 15:45:3652 days 11 hrs ago1697471136
0x67EA96...10F7BB4D
0 ETH
98772772023-10-16 15:41:4852 days 11 hrs ago1697470908
0x67EA96...10F7BB4D
0 ETH
98771742023-10-16 15:15:0052 days 12 hrs ago1697469300
0x67EA96...10F7BB4D
0 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ZKBlobstream

Compiler Version
v0.8.21+commit.d9974bed

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 11 : ZKBlobstream.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "@blobstream/DataRootTuple.sol";
import "@blobstream/lib/tree/binary/BinaryMerkleTree.sol";

import {IFunctionGateway} from "./interfaces/IFunctionGateway.sol";
import {IZKTendermintLightClient} from "@zk-tendermint/interfaces/IZKTendermintLightClient.sol";
import {IBlobstream} from "./IBlobstream.sol";

contract ZKBlobstream is IZKTendermintLightClient, IBlobstream {
    /////////////
    // Storage //
    /////////////

    /// @notice The address of the gateway contract.
    address public gateway;
    /// @notice The latest block that has been committed.
    uint64 public latestBlock;
    /// @notice The maximum number of blocks that can be skipped in a single request.
    uint64 public DATA_COMMITMENT_MAX = 1000;
    /// @notice Maps function names to their IDs.
    mapping(string => bytes32) public functionNameToId;
    /// @notice Maps block heights to their header hashes.
    mapping(uint64 => bytes32) public blockHeightToHeaderHash;
    /// @notice Maps block ranges to their data commitments. Block ranges are stored as keccak256(abi.encode(startBlock, endBlock)).
    mapping(bytes32 => bytes32) public dataCommitments;

    ////////////
    // Events //
    ////////////

    /// @notice Emitted when a combined step is requested.
    /// @param startBlock The start block of the combined step request.
    /// @param requestId The ID of the request.
    event CombinedStepRequested(uint64 indexed startBlock, bytes32 requestId);

    /// @notice Emitted when a combined step is fulfilled.
    /// @param startBlock The start block of the combined step request.
    /// @param targetHeader The header hash of the startBlock + 1.
    /// @param dataCommitment The data commitment of the block range [startBlock, startBlock + 1).
    event CombinedStepFulfilled(
        uint64 indexed startBlock,
        bytes32 targetHeader,
        bytes32 dataCommitment
    );

    /// @notice Emitted when a combined skip is requested.
    /// @param startBlock The start block of the combined skip request.
    /// @param targetBlock The target block of the combined skip request.
    /// @param requestId The ID of the request.
    event CombinedSkipRequested(
        uint64 indexed startBlock,
        uint64 indexed targetBlock,
        bytes32 requestId
    );

    /// @notice Emitted when a combined skip is fulfilled.
    /// @param startBlock The start block of the combined skip request.
    /// @param targetBlock The target block of the combined skip request.
    /// @param targetHeader The header hash of the target block.
    /// @param dataCommitment The data commitment of the block range [startBlock, targetBlock).
    event CombinedSkipFulfilled(
        uint64 indexed startBlock,
        uint64 indexed targetBlock,
        bytes32 targetHeader,
        bytes32 dataCommitment
    );

    ////////////
    // Errors //
    ////////////

    /// @notice Latest header not found.
    error LatestHeaderNotFound();
    /// @notice Function ID for name not found.
    error FunctionIdNotFound(string name);
    /// @notice Target block for proof must be greater than latest block.
    error TargetLessThanLatest();
    /// @notice The range of blocks in a request is greater than the maximum allowed.
    error ProofBlockRangeTooLarge();

    ///////////////
    // Modifiers //
    ///////////////

    /// @notice Modifier for restricting the gateway as the only caller for a function.
    modifier onlyGateway() {
        require(msg.sender == gateway, "Only gateway can call this function");
        _;
    }

    ///////////////
    // Functions //
    ///////////////

    /// @notice Initialize the contract with the address of the gateway contract.
    constructor(address _gateway) {
        gateway = _gateway;
    }

    /// @notice Update the address of the gateway contract.
    function updateGateway(address _gateway) external {
        gateway = _gateway;
    }

    /// @notice Update the function ID for a function name.
    function updateFunctionId(
        string memory name,
        bytes32 _functionId
    ) external {
        functionNameToId[name] = _functionId;
    }

    /// Note: Only for testnet. The genesis header should be set when initializing the contract.
    function setGenesisHeader(uint64 height, bytes32 header) external {
        blockHeightToHeaderHash[height] = header;
        latestBlock = height;
    }

    /// @notice Prove the validity of the header at requested block and a data commitment for the block range [latestBlock, requestedBlock).
    /// @param _requestedBlock The block to skip to.
    /// @dev Skip proof is valid if at least 1/3 of the voting power signed on requestedBlock is from validators in the validator set for latestBlock.
    /// Request will fail if the requested block is more than DATA_COMMITMENT_MAX blocks ahead of the latest block.
    /// Pass both the latest block and the requested block as context, as the latest block may change before the request is fulfilled.
    function requestCombinedSkip(uint64 _requestedBlock) external payable {
        bytes32 latestHeader = blockHeightToHeaderHash[latestBlock];
        if (latestHeader == bytes32(0)) {
            revert LatestHeaderNotFound();
        }
        bytes32 id = functionNameToId["combinedSkip"];
        if (id == bytes32(0)) {
            revert FunctionIdNotFound("combinedSkip");
        }

        // A request can be at most DATA_COMMITMENT_MAX blocks ahead of the latest block.
        if (_requestedBlock - latestBlock > DATA_COMMITMENT_MAX) {
            revert ProofBlockRangeTooLarge();
        }
        if (_requestedBlock <= latestBlock) {
            revert TargetLessThanLatest();
        }

        bytes32 requestId = IFunctionGateway(gateway).requestCallback{
            value: msg.value
        }(
            id,
            abi.encodePacked(latestBlock, latestHeader, _requestedBlock),
            abi.encode(latestBlock, _requestedBlock),
            this.callbackCombinedSkip.selector,
            500000
        );
        emit CombinedSkipRequested(latestBlock, _requestedBlock, requestId);
    }

    /// @notice Stores the new header for requestedBlock and the data commitment for the block range [latestBlock, requestedBlock).
    /// @param requestResult Contains the new header and data commitment.
    /// @param context Contains the latestBlock when skip was requested, and the requestedBlock to skip to.
    function callbackCombinedSkip(
        bytes memory requestResult,
        bytes memory context
    ) external onlyGateway {
        // Read the start block and target block of the skip proof from context.
        (uint64 skipStartBlock, uint64 skipTargetBlock) = abi.decode(
            context,
            (uint64, uint64)
        );
        // Read the target header and data commitment from request result.
        (bytes32 targetHeader, bytes32 dataCommitment) = abi.decode(
            requestResult,
            (bytes32, bytes32)
        );

        if (skipTargetBlock <= latestBlock) {
            revert TargetLessThanLatest();
        }

        blockHeightToHeaderHash[skipTargetBlock] = targetHeader;
        dataCommitments[
            keccak256(abi.encode(skipStartBlock, skipTargetBlock))
        ] = dataCommitment;
        latestBlock = skipTargetBlock;

        emit CombinedSkipFulfilled(
            skipStartBlock,
            skipTargetBlock,
            targetHeader,
            dataCommitment
        );
    }

    /// @notice Prove the validity of the header at latestBlock + 1 and a data commitment for the block range [latestBlock, latestBlock + 1).
    /// @dev Only used if 2/3 of voting power in a validator set changes in one block.
    function requestCombinedStep() external payable {
        bytes32 latestHeader = blockHeightToHeaderHash[latestBlock];
        if (latestHeader == bytes32(0)) {
            revert LatestHeaderNotFound();
        }
        bytes32 id = functionNameToId["combinedStep"];
        if (id == bytes32(0)) {
            revert FunctionIdNotFound("combinedStep");
        }

        bytes32 requestId = IFunctionGateway(gateway).requestCallback{
            value: msg.value
        }(
            id,
            abi.encodePacked(latestBlock, latestHeader),
            abi.encode(latestBlock),
            this.callbackCombinedStep.selector,
            500000
        );
        emit CombinedStepRequested(latestBlock, requestId);
    }

    /// @notice Stores the new header for latestBlock + 1 and the data commitment for the block range [latestBlock, latestBlock + 1).
    /// @param requestResult Contains the new header and data commitment.
    /// @param context Contains the latest block when step was requested.
    function callbackCombinedStep(
        bytes memory requestResult,
        bytes memory context
    ) external onlyGateway {
        // Read the prev block of the step proof from context.
        uint64 prevBlock = abi.decode(context, (uint64));
        // Read the new header and data commitment from request result.
        (bytes32 nextHeader, bytes32 dataCommitment) = abi.decode(
            requestResult,
            (bytes32, bytes32)
        );

        uint64 nextBlock = prevBlock + 1;
        if (nextBlock <= latestBlock) {
            revert TargetLessThanLatest();
        }

        blockHeightToHeaderHash[nextBlock] = nextHeader;
        dataCommitments[
            keccak256(abi.encode(prevBlock, nextBlock))
        ] = dataCommitment;
        latestBlock = nextBlock;

        emit CombinedStepFulfilled(prevBlock, nextHeader, dataCommitment);
    }

    /// @notice Get the function ID for a function name.
    function getFunctionId(string memory name) external view returns (bytes32) {
        return functionNameToId[name];
    }

    /// @notice Get the header hash for a block height.
    function getHeaderHash(uint64 height) external view returns (bytes32) {
        return blockHeightToHeaderHash[height];
    }

    /// @dev See "./IBlobstream.sol"
    function getDataCommitment(
        uint64 startBlock,
        uint64 endBlock
    ) external view returns (bytes32) {
        return dataCommitments[keccak256(abi.encode(startBlock, endBlock))];
    }

    /// @dev See "./IBlobstream.sol"
    function verifyMerkleProof(
        uint256 startBlock,
        uint256 endBlock,
        DataRootTuple memory _tuple,
        BinaryMerkleProof memory _proof
    ) external view returns (bool) {
        // Tuple must have been committed before.
        if (endBlock > latestBlock) {
            return false;
        }

        // Load the tuple root at the given index from storage.
        bytes32 root = dataCommitments[
            keccak256(abi.encode(startBlock, endBlock))
        ];

        // Verify the proof.
        bool isProofValid = BinaryMerkleTree.verify(
            root,
            _proof,
            abi.encode(_tuple)
        );

        return isProofValid;
    }
}

File 2 of 11 : DataRootTuple.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.19;

/// @notice A tuple of data root with metadata. Each data root is associated
///  with a Celestia block height.
/// @dev `availableDataRoot` in
///  https://github.com/celestiaorg/celestia-specs/blob/master/src/specs/data_structures.md#header
struct DataRootTuple {
    // Celestia block height the data root was included in.
    // Genesis block is height = 0.
    // First queryable block is height = 1.
    uint256 height;
    // Data root.
    bytes32 dataRoot;
}

File 3 of 11 : BinaryMerkleTree.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.19;

import "../Constants.sol";
import "../Utils.sol";
import "./TreeHasher.sol";
import "./BinaryMerkleProof.sol";

/// @title Binary Merkle Tree.
library BinaryMerkleTree {
    /// @notice Verify if element exists in Merkle tree, given data, proof, and root.
    /// @param root The root of the tree in which verify the given leaf.
    /// @param proof Binary Merkle proof for the leaf.
    /// @param data The data of the leaf to verify.
    /// @return `true` is proof is valid, `false` otherwise.
    /// @dev proof.numLeaves is necessary to determine height of subtree containing the data to prove.
    function verify(bytes32 root, BinaryMerkleProof memory proof, bytes memory data) internal pure returns (bool) {
        // Check proof is correct length for the key it is proving
        if (proof.numLeaves <= 1) {
            if (proof.sideNodes.length != 0) {
                return false;
            }
        } else if (proof.sideNodes.length != pathLengthFromKey(proof.key, proof.numLeaves)) {
            return false;
        }

        // Check key is in tree
        if (proof.key >= proof.numLeaves) {
            return false;
        }

        // A sibling at height 1 is created by getting the hash of the data to prove.
        bytes32 digest = leafDigest(data);

        // Null proof is only valid if numLeaves = 1
        // If so, just verify hash(data) is root
        if (proof.sideNodes.length == 0) {
            if (proof.numLeaves == 1) {
                return (root == digest);
            } else {
                return false;
            }
        }

        uint256 height = 1;
        uint256 stableEnd = proof.key;

        // While the current subtree (of height 'height') is complete, determine
        // the position of the next sibling using the complete subtree algorithm.
        // 'stableEnd' tells us the ending index of the last full subtree. It gets
        // initialized to 'key' because the first full subtree was the
        // subtree of height 1, created above (and had an ending index of
        // 'key').

        while (true) {
            // Determine if the subtree is complete. This is accomplished by
            // rounding down the key to the nearest 1 << 'height', adding 1
            // << 'height', and comparing the result to the number of leaves in the
            // Merkle tree.

            uint256 subTreeStartIndex = (proof.key / (1 << height)) * (1 << height);
            uint256 subTreeEndIndex = subTreeStartIndex + (1 << height) - 1;

            // If the Merkle tree does not have a leaf at index
            // 'subTreeEndIndex', then the subtree of the current height is not
            // a complete subtree.
            if (subTreeEndIndex >= proof.numLeaves) {
                break;
            }
            stableEnd = subTreeEndIndex;

            // Determine if the key is in the first or the second half of
            // the subtree.
            if (proof.sideNodes.length <= height - 1) {
                return false;
            }
            if (proof.key - subTreeStartIndex < (1 << (height - 1))) {
                digest = nodeDigest(digest, proof.sideNodes[height - 1]);
            } else {
                digest = nodeDigest(proof.sideNodes[height - 1], digest);
            }

            height += 1;
        }

        // Determine if the next hash belongs to an orphan that was elevated. This
        // is the case IFF 'stableEnd' (the last index of the largest full subtree)
        // is equal to the number of leaves in the Merkle tree.
        if (stableEnd != proof.numLeaves - 1) {
            if (proof.sideNodes.length <= height - 1) {
                return false;
            }
            digest = nodeDigest(digest, proof.sideNodes[height - 1]);
            height += 1;
        }

        // All remaining elements in the proof set will belong to a left sibling\
        // i.e proof sideNodes are hashed in "from the left"
        while (height - 1 < proof.sideNodes.length) {
            digest = nodeDigest(proof.sideNodes[height - 1], digest);
            height += 1;
        }

        return (digest == root);
    }
}

File 4 of 11 : IFunctionGateway.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

interface IFunctionGateway {
    function requestCallback(
        bytes32 _functionId,
        bytes memory _input,
        bytes memory _context,
        bytes4 _callbackSelector,
        uint32 _callbackGasLimit
    ) external payable returns (bytes32);

    function requestCall(
        bytes32 _functionId,
        bytes memory _input,
        address _address,
        bytes memory _data,
        uint32 _gasLimit
    ) external payable;

    function verifiedCall(
        bytes32 _functionId,
        bytes memory _input
    ) external view returns (bytes memory);

    function isCallback() external view returns (bool);
}

File 5 of 11 : IZKTendermintLightClient.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

interface IZKTendermintLightClient {
    /// @notice Gets the ID of a function.
    /// @param name The name of the function.
    function getFunctionId(string memory name) external view returns (bytes32);

    /// @notice Gets the header hash of a block.
    /// @param blockNumber The block number to get the header hash of.
    function getHeaderHash(uint64 blockNumber) external view returns (bytes32);

    /// @notice Gets the latest block number updated by the light client.
    function latestBlock() external view returns (uint64);
}

File 6 of 11 : IBlobstream.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "@blobstream/DataRootTuple.sol";
import "@blobstream/lib/tree/binary/BinaryMerkleTree.sol";

interface IBlobstream {
    /// @notice Get the data commitment for a block range [startBlock, endBlock).
    function getDataCommitment(
        uint64 startBlock,
        uint64 endBlock
    ) external view returns (bytes32);

    /// @notice Verify a merkle proof for a specific block's data root against a data commitment containing the block.
    /// @param startBlock The start block of the block range that contains the proof's block.
    /// @param endBlock The end block of the block range that contains the proof's block.
    /// @param _tuple The data root tuple which is the leaf node of the proof and contains the block's data root.
    /// @param _proof The merkle proof to verify against the data commitment.
    function verifyMerkleProof(
        uint256 startBlock,
        uint256 endBlock,
        DataRootTuple memory _tuple,
        BinaryMerkleProof memory _proof
    ) external view returns (bool);
}

File 7 of 11 : Constants.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.19;

import "./Types.sol";

library Constants {
    ///////////////
    // Constants //
    ///////////////

    /// @dev Maximum tree height
    uint256 internal constant MAX_HEIGHT = 256;

    /// @dev The prefixes of leaves and nodes
    bytes1 internal constant LEAF_PREFIX = 0x00;
    bytes1 internal constant NODE_PREFIX = 0x01;
}

/// @dev Parity share namespace.
/// utility function to provide the parity share namespace as a Namespace struct.
function PARITY_SHARE_NAMESPACE() pure returns (Namespace memory) {
    return Namespace(0xFF, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
}

File 8 of 11 : Utils.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.19;

import "./Constants.sol";

/// @notice Calculate the starting bit of the path to a leaf
/// @param numLeaves : The total number of leaves in the tree
/// @return startingBit : The starting bit of the path
// solhint-disable-next-line func-visibility
function getStartingBit(uint256 numLeaves) pure returns (uint256 startingBit) {
    // Determine height of the left subtree. This is the maximum path length, so all paths start at this offset from the right-most bit
    startingBit = 0;
    while ((1 << startingBit) < numLeaves) {
        startingBit += 1;
    }
    return Constants.MAX_HEIGHT - startingBit;
}

/// @notice Calculate the length of the path to a leaf
/// @param key: The key of the leaf
/// @param numLeaves: The total number of leaves in the tree
/// @return pathLength : The length of the path to the leaf
/// @dev A precondition to this function is that `numLeaves > 1`, so that `(pathLength - 1)` does not cause an underflow when pathLength = 0.
// solhint-disable-next-line func-visibility
function pathLengthFromKey(uint256 key, uint256 numLeaves) pure returns (uint256 pathLength) {
    // Get the height of the left subtree. This is equal to the offset of the starting bit of the path
    pathLength = Constants.MAX_HEIGHT - getStartingBit(numLeaves);

    // Determine the number of leaves in the left subtree
    uint256 numLeavesLeftSubTree = (1 << (pathLength - 1));

    // If leaf is in left subtree, path length is full height of left subtree
    if (key <= numLeavesLeftSubTree - 1) {
        return pathLength;
    }
    // If left sub tree has only one leaf but key is not there, path has one additional step
    else if (numLeavesLeftSubTree == 1) {
        return 1;
    }
    // Otherwise, add 1 to height and recurse into right subtree
    else {
        return 1 + pathLengthFromKey(key - numLeavesLeftSubTree, numLeaves - numLeavesLeftSubTree);
    }
}

File 9 of 11 : TreeHasher.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.19;

import "../Constants.sol";

/// @notice Calculate the digest of a node.
/// @param left The left child.
/// @param right The right child.
/// @return digest The node digest.
/// @dev More details in https://github.com/celestiaorg/celestia-specs/blob/master/src/specs/data_structures.md#binary-merkle-tree
// solhint-disable-next-line func-visibility
function nodeDigest(bytes32 left, bytes32 right) pure returns (bytes32 digest) {
    digest = sha256(abi.encodePacked(Constants.NODE_PREFIX, left, right));
}

/// @notice Calculate the digest of a leaf.
/// @param data The data of the leaf.
/// @return digest The leaf digest.
/// @dev More details in https://github.com/celestiaorg/celestia-specs/blob/master/src/specs/data_structures.md#binary-merkle-tree
// solhint-disable-next-line func-visibility
function leafDigest(bytes memory data) pure returns (bytes32 digest) {
    digest = sha256(abi.encodePacked(Constants.LEAF_PREFIX, data));
}

File 10 of 11 : BinaryMerkleProof.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.19;

/// @notice Merkle Tree Proof structure.
struct BinaryMerkleProof {
    // List of side nodes to verify and calculate tree.
    bytes32[] sideNodes;
    // The key of the leaf to verify.
    uint256 key;
    // The number of leaves in the tree
    uint256 numLeaves;
}

File 11 of 11 : Types.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.19;

/// @notice A representation of the Celestia-app namespace ID and its version.
/// See: https://celestiaorg.github.io/celestia-app/specs/namespace.html
struct Namespace {
    // The namespace version.
    bytes1 version;
    // The namespace ID.
    bytes28 id;
}

using {equalTo, lessThan, greaterThan, toBytes} for Namespace global;

function equalTo(Namespace memory l, Namespace memory r) pure returns (bool) {
    return l.toBytes() == r.toBytes();
}

function lessThan(Namespace memory l, Namespace memory r) pure returns (bool) {
    return l.toBytes() < r.toBytes();
}

function greaterThan(Namespace memory l, Namespace memory r) pure returns (bool) {
    return l.toBytes() > r.toBytes();
}

function toBytes(Namespace memory n) pure returns (bytes29) {
    return bytes29(abi.encodePacked(n.version, n.id));
}

function toNamespace(bytes29 n) pure returns (Namespace memory) {
    bytes memory id = new bytes(28);
    for (uint256 i = 1; i < 29; i++) {
        id[i - 1] = n[i];
    }
    return Namespace(n[0], bytes28(id));
}

Settings
{
  "remappings": [
    "@succinctx/=lib/succinctx/contracts/src/",
    "@blobstream/=lib/blobstream-contracts/src/",
    "@zk-tendermint/=../../zk-tendermint/contracts/src/",
    "@openzeppelin/contracts/=lib/blobstream-contracts/lib/openzeppelin-contracts-upgradeable/contracts/",
    "blobstream-contracts/=lib/blobstream-contracts/src/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "erc4626-tests/=lib/blobstream-contracts/lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
    "forge-std/=lib/forge-std/src/",
    "openzeppelin-contracts-upgradeable/=lib/blobstream-contracts/lib/openzeppelin-contracts-upgradeable/",
    "openzeppelin-contracts/=lib/blobstream-contracts/lib/openzeppelin-contracts/",
    "tree/=lib/blobstream-contracts/src/lib/tree/",
    "verifier/=lib/blobstream-contracts/src/lib/verifier/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "libraries": {}
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"_gateway","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"string","name":"name","type":"string"}],"name":"FunctionIdNotFound","type":"error"},{"inputs":[],"name":"LatestHeaderNotFound","type":"error"},{"inputs":[],"name":"ProofBlockRangeTooLarge","type":"error"},{"inputs":[],"name":"TargetLessThanLatest","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"startBlock","type":"uint64"},{"indexed":true,"internalType":"uint64","name":"targetBlock","type":"uint64"},{"indexed":false,"internalType":"bytes32","name":"targetHeader","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"dataCommitment","type":"bytes32"}],"name":"CombinedSkipFulfilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"startBlock","type":"uint64"},{"indexed":true,"internalType":"uint64","name":"targetBlock","type":"uint64"},{"indexed":false,"internalType":"bytes32","name":"requestId","type":"bytes32"}],"name":"CombinedSkipRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"startBlock","type":"uint64"},{"indexed":false,"internalType":"bytes32","name":"targetHeader","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"dataCommitment","type":"bytes32"}],"name":"CombinedStepFulfilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"startBlock","type":"uint64"},{"indexed":false,"internalType":"bytes32","name":"requestId","type":"bytes32"}],"name":"CombinedStepRequested","type":"event"},{"inputs":[],"name":"DATA_COMMITMENT_MAX","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"","type":"uint64"}],"name":"blockHeightToHeaderHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"requestResult","type":"bytes"},{"internalType":"bytes","name":"context","type":"bytes"}],"name":"callbackCombinedSkip","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"requestResult","type":"bytes"},{"internalType":"bytes","name":"context","type":"bytes"}],"name":"callbackCombinedStep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"dataCommitments","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"functionNameToId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gateway","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"startBlock","type":"uint64"},{"internalType":"uint64","name":"endBlock","type":"uint64"}],"name":"getDataCommitment","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"}],"name":"getFunctionId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"height","type":"uint64"}],"name":"getHeaderHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestBlock","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"_requestedBlock","type":"uint64"}],"name":"requestCombinedSkip","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestCombinedStep","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint64","name":"height","type":"uint64"},{"internalType":"bytes32","name":"header","type":"bytes32"}],"name":"setGenesisHeader","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"bytes32","name":"_functionId","type":"bytes32"}],"name":"updateFunctionId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gateway","type":"address"}],"name":"updateGateway","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"},{"components":[{"internalType":"uint256","name":"height","type":"uint256"},{"internalType":"bytes32","name":"dataRoot","type":"bytes32"}],"internalType":"struct DataRootTuple","name":"_tuple","type":"tuple"},{"components":[{"internalType":"bytes32[]","name":"sideNodes","type":"bytes32[]"},{"internalType":"uint256","name":"key","type":"uint256"},{"internalType":"uint256","name":"numLeaves","type":"uint256"}],"internalType":"struct BinaryMerkleProof","name":"_proof","type":"tuple"}],"name":"verifyMerkleProof","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]

6080604052600180546001600160401b0319166103e817905534801561002457600080fd5b506040516117c73803806117c783398101604081905261004391610068565b600080546001600160a01b0319166001600160a01b0392909216919091179055610098565b60006020828403121561007a57600080fd5b81516001600160a01b038116811461009157600080fd5b9392505050565b611720806100a76000396000f3fe6080604052600436106100fe5760003560e01c80638a34aa2b11610095578063b91deeb511610064578063b91deeb5146102ea578063c0346b201461030a578063c3e5517714610347578063ce353b341461039d578063d7e6c68b146103bd57600080fd5b80638a34aa2b1461026557806396139ebd14610295578063a68a62ae146102c2578063b053e8b5146102ca57600080fd5b8063223acffe116100d1578063223acffe146101da57806339a4d84b146101ef5780634710384e1461020f57806378802ef11461022f57600080fd5b806307e2da961461010357806308e93ea514610147578063116191b61461018257806320154c7d146101ba575b600080fd5b34801561010f57600080fd5b5060005461012a90600160a01b90046001600160401b031681565b6040516001600160401b0390911681526020015b60405180910390f35b34801561015357600080fd5b50610174610162366004611098565b60036020526000908152604090205481565b60405190815260200161013e565b34801561018e57600080fd5b506000546101a2906001600160a01b031681565b6040516001600160a01b03909116815260200161013e565b3480156101c657600080fd5b506101746101d53660046110b5565b6103f5565b6101ed6101e8366004611098565b610451565b005b3480156101fb57600080fd5b506101ed61020a3660046111ed565b6106d1565b34801561021b57600080fd5b5060015461012a906001600160401b031681565b34801561023b57600080fd5b5061017461024a366004611098565b6001600160401b031660009081526003602052604090205490565b34801561027157600080fd5b50610285610280366004611231565b6106f6565b604051901515815260200161013e565b3480156102a157600080fd5b506101746102b036600461135c565b60046020526000908152604090205481565b6101ed6107ad565b3480156102d657600080fd5b506101ed6102e5366004611375565b610997565b3480156102f657600080fd5b506101ed610305366004611375565b610af0565b34801561031657600080fd5b506101ed6103253660046113d8565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b34801561035357600080fd5b506101ed610362366004611401565b6001600160401b0391909116600081815260036020526040812092909255815467ffffffffffffffff60a01b1916600160a01b909102179055565b3480156103a957600080fd5b506101746103b836600461142d565b610c39565b3480156103c957600080fd5b506101746103d836600461142d565b805160208183018101805160028252928201919093012091525481565b60006004600084846040516020016104239291906001600160401b0392831681529116602082015260400190565b6040516020818303038152906040528051906020012081526020019081526020016000205490505b92915050565b60008054600160a01b90046001600160401b03168152600360205260409020548061048f576040516352065af960e11b815260040160405180910390fd5b600060026040516104b2906b0636f6d62696e6564536b69760a41b8152600c0190565b9081526040519081900360200190205490508061050657604051631d4604eb60e11b815260206004820152600c60248201526b0636f6d62696e6564536b69760a41b60448201526064015b60405180910390fd5b6001546000546001600160401b039182169161052a91600160a01b90041685611477565b6001600160401b0316111561055257604051630e9da4f960e21b815260040160405180910390fd5b6000546001600160401b03600160a01b909104811690841611610588576040516329e3451360e01b815260040160405180910390fd5b6000805460408051600160a01b830460c081811b6001600160c01b03199081166020850152602884018990529089901b166048830152825160308184030181526050830184526001600160401b0391821660708401529088166090808401919091528351808403909101815260b083019384905263b3f04fdf60e01b9093526001600160a01b039093169263b3f04fdf923492610639928892909163b91deeb560e01b906207a1209060b4016114e7565b60206040518083038185885af1158015610657573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061067c919061153c565b6000546040518281529192506001600160401b0386811692600160a01b90920416907f014d972621549e25527d9b73201fe71c02ef506769686afcdf81a92f7b9132ea9060200160405180910390a350505050565b806002836040516106e29190611555565b908152604051908190036020019020555050565b60008054600160a01b90046001600160401b0316841115610719575060006107a5565b600060046000878760405160200161073b929190918252602082015260400190565b60405160208183030381529060405280519060200120815260200190815260200160002054905060006107a082858760405160200161078c9190815181526020918201519181019190915260400190565b604051602081830303815290604052610c61565b925050505b949350505050565b60008054600160a01b90046001600160401b0316815260036020526040902054806107eb576040516352065af960e11b815260040160405180910390fd5b6000600260405161080e906b0636f6d62696e6564537465760a41b8152600c0190565b9081526040519081900360200190205490508061085d57604051631d4604eb60e11b815260206004820152600c60248201526b0636f6d62696e6564537465760a41b60448201526064016104fd565b600080546040516001600160c01b0319600160a01b830460c01b166020820152602881018590526001600160a01b039091169063b3f04fdf903490859060480160408051808303601f19018152828252600054600160a01b90046001600160401b03166020840152910160408051601f19818403018152908290526001600160e01b031960e087901b16825261090593929163b053e8b560e01b906207a120906004016114e7565b60206040518083038185885af1158015610923573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610948919061153c565b600054604051828152919250600160a01b90046001600160401b0316907f51e82940b688858ec5c82f6c17e146db2093bec0944f60b0fd921381ef74204c9060200160405180910390a2505050565b6000546001600160a01b031633146109c15760405162461bcd60e51b81526004016104fd90611571565b6000818060200190518101906109d791906115b4565b9050600080848060200190518101906109f091906115d1565b90925090506000610a028460016115f5565b6000549091506001600160401b03600160a01b909104811690821611610a3b576040516329e3451360e01b815260040160405180910390fd5b6001600160401b03818116600081815260036020908152604080832088905580519489168583018190528582018590528151808703830181526060870180845281519185019190912085526004909352908320879055825467ffffffffffffffff60a01b1916600160a01b9094029390931790915585905260808201849052907f880abacb3515d667ad5a5a9ee88b0218eca5d7bf2d824d69e73a01d7d31703139060a00160405180910390a2505050505050565b6000546001600160a01b03163314610b1a5760405162461bcd60e51b81526004016104fd90611571565b60008082806020019051810190610b319190611615565b9150915060008085806020019051810190610b4c91906115d1565b60005491935091506001600160401b03600160a01b909104811690841611610b87576040516329e3451360e01b815260040160405180910390fd5b6001600160401b03838116600081815260036020908152604080832087905580519489168583018190528582018590528151808703830181526060870180845281519185019190912085526004909352908320869055825467ffffffffffffffff60a01b1916600160a01b8502179092558590526080830184905290917fc2d89d9b17fae0ddb047b2164e03760f75b6fee6bdbb291dd9867519ff5581399060a00160405180910390a3505050505050565b6000600282604051610c4b9190611555565b9081526020016040518091039020549050919050565b60006001836040015111610c845782515115610c7f57506000610ecc565b610ca6565b610c9683602001518460400151610ed3565b83515114610ca657506000610ecc565b8260400151836020015110610cbd57506000610ecc565b6000610cc883610f60565b845151909150600003610cf4578360400151600103610cea5784149050610ecc565b6000915050610ecc565b60208401516001905b60208601516000906001841b90610d15908290611644565b610d1f9190611666565b905060006001610d3181861b8461167d565b610d3b9190611690565b905087604001518110610d4f575050610e15565b915081610d5d600185611690565b88515111610d7357600095505050505050610ecc565b610d7e600185611690565b6001901b828960200151610d929190611690565b1015610dcf578751610dc8908690610dab600188611690565b81518110610dbb57610dbb6116a3565b6020026020010151610fd5565b9450610e01565b8751610dfe90610de0600187611690565b81518110610df057610df06116a3565b602002602001015186610fd5565b94505b610e0c60018561167d565b93505050610cfd565b60018660400151610e269190611690565b8114610e6e57610e37600183611690565b86515111610e4b5760009350505050610ecc565b8551610e5e908490610dab600186611690565b9250610e6b60018361167d565b91505b855151610e7c600184611690565b1015610ec5578551610eb190610e93600185611690565b81518110610ea357610ea36116a3565b602002602001015184610fd5565b9250610ebe60018361167d565b9150610e6e565b5050841490505b9392505050565b6000610ede82611053565b610eea90610100611690565b90506000610ef9600183611690565b6001901b9050600181610f0c9190611690565b8411610f18575061044b565b80600103610f2a57600191505061044b565b610f46610f378286611690565b610f418386611690565b610ed3565b610f5190600161167d565b91505061044b565b5092915050565b60006002600060f81b83604051602001610f7b9291906116b9565b60408051601f1981840301815290829052610f9591611555565b602060405180830381855afa158015610fb2573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061044b919061153c565b604051600160f81b6020820152602181018390526041810182905260009060029060610160408051601f198184030181529082905261101391611555565b602060405180830381855afa158015611030573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610ecc919061153c565b60005b81816001901b10156110745761106d60018261167d565b9050611056565b61044b81610100611690565b6001600160401b038116811461109557600080fd5b50565b6000602082840312156110aa57600080fd5b8135610ecc81611080565b600080604083850312156110c857600080fd5b82356110d381611080565b915060208301356110e381611080565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715611126576111266110ee565b60405290565b604051606081016001600160401b0381118282101715611126576111266110ee565b604051601f8201601f191681016001600160401b0381118282101715611176576111766110ee565b604052919050565b600082601f83011261118f57600080fd5b81356001600160401b038111156111a8576111a86110ee565b6111bb601f8201601f191660200161114e565b8181528460208386010111156111d057600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561120057600080fd5b82356001600160401b0381111561121657600080fd5b6112228582860161117e565b95602094909401359450505050565b60008060008084860360a081121561124857600080fd5b8535945060208087013594506040603f198301121561126657600080fd5b61126e611104565b604088013581526060880135828201529350608087013591506001600160401b038083111561129c57600080fd5b918701916060838a0312156112b057600080fd5b6112b861112c565b8335828111156112c757600080fd5b8401601f81018b136112d857600080fd5b8035838111156112ea576112ea6110ee565b8060051b93506112fb85850161114e565b818152938201850193858101908d86111561131557600080fd5b928601925b858410156113335783358252928601929086019061131a565b808552505050508284013583820152604084013560408201528094505050505092959194509250565b60006020828403121561136e57600080fd5b5035919050565b6000806040838503121561138857600080fd5b82356001600160401b038082111561139f57600080fd5b6113ab8683870161117e565b935060208501359150808211156113c157600080fd5b506113ce8582860161117e565b9150509250929050565b6000602082840312156113ea57600080fd5b81356001600160a01b0381168114610ecc57600080fd5b6000806040838503121561141457600080fd5b823561141f81611080565b946020939093013593505050565b60006020828403121561143f57600080fd5b81356001600160401b0381111561145557600080fd5b6107a58482850161117e565b634e487b7160e01b600052601160045260246000fd5b6001600160401b03828116828216039080821115610f5957610f59611461565b60005b838110156114b257818101518382015260200161149a565b50506000910152565b600081518084526114d3816020860160208601611497565b601f01601f19169290920160200192915050565b85815260a06020820152600061150060a08301876114bb565b828103604084015261151281876114bb565b6001600160e01b0319959095166060840152505063ffffffff919091166080909101529392505050565b60006020828403121561154e57600080fd5b5051919050565b60008251611567818460208701611497565b9190910192915050565b60208082526023908201527f4f6e6c7920676174657761792063616e2063616c6c20746869732066756e637460408201526234b7b760e91b606082015260800190565b6000602082840312156115c657600080fd5b8151610ecc81611080565b600080604083850312156115e457600080fd5b505080516020909101519092909150565b6001600160401b03818116838216019080821115610f5957610f59611461565b6000806040838503121561162857600080fd5b825161163381611080565b60208401519092506110e381611080565b60008261166157634e487b7160e01b600052601260045260246000fd5b500490565b808202811582820484141761044b5761044b611461565b8082018082111561044b5761044b611461565b8181038181111561044b5761044b611461565b634e487b7160e01b600052603260045260246000fd5b6001600160f81b03198316815281516000906116dc816001850160208701611497565b91909101600101939250505056fea2646970667358221220f0de7cc063c2b8986d8843021c22c42110f5af8598bedc65583a9889c0978afb64736f6c63430008150033000000000000000000000000852a94f8309d445d27222edb1e92a4e83dddd2a8

Deployed Bytecode

0x6080604052600436106100fe5760003560e01c80638a34aa2b11610095578063b91deeb511610064578063b91deeb5146102ea578063c0346b201461030a578063c3e5517714610347578063ce353b341461039d578063d7e6c68b146103bd57600080fd5b80638a34aa2b1461026557806396139ebd14610295578063a68a62ae146102c2578063b053e8b5146102ca57600080fd5b8063223acffe116100d1578063223acffe146101da57806339a4d84b146101ef5780634710384e1461020f57806378802ef11461022f57600080fd5b806307e2da961461010357806308e93ea514610147578063116191b61461018257806320154c7d146101ba575b600080fd5b34801561010f57600080fd5b5060005461012a90600160a01b90046001600160401b031681565b6040516001600160401b0390911681526020015b60405180910390f35b34801561015357600080fd5b50610174610162366004611098565b60036020526000908152604090205481565b60405190815260200161013e565b34801561018e57600080fd5b506000546101a2906001600160a01b031681565b6040516001600160a01b03909116815260200161013e565b3480156101c657600080fd5b506101746101d53660046110b5565b6103f5565b6101ed6101e8366004611098565b610451565b005b3480156101fb57600080fd5b506101ed61020a3660046111ed565b6106d1565b34801561021b57600080fd5b5060015461012a906001600160401b031681565b34801561023b57600080fd5b5061017461024a366004611098565b6001600160401b031660009081526003602052604090205490565b34801561027157600080fd5b50610285610280366004611231565b6106f6565b604051901515815260200161013e565b3480156102a157600080fd5b506101746102b036600461135c565b60046020526000908152604090205481565b6101ed6107ad565b3480156102d657600080fd5b506101ed6102e5366004611375565b610997565b3480156102f657600080fd5b506101ed610305366004611375565b610af0565b34801561031657600080fd5b506101ed6103253660046113d8565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b34801561035357600080fd5b506101ed610362366004611401565b6001600160401b0391909116600081815260036020526040812092909255815467ffffffffffffffff60a01b1916600160a01b909102179055565b3480156103a957600080fd5b506101746103b836600461142d565b610c39565b3480156103c957600080fd5b506101746103d836600461142d565b805160208183018101805160028252928201919093012091525481565b60006004600084846040516020016104239291906001600160401b0392831681529116602082015260400190565b6040516020818303038152906040528051906020012081526020019081526020016000205490505b92915050565b60008054600160a01b90046001600160401b03168152600360205260409020548061048f576040516352065af960e11b815260040160405180910390fd5b600060026040516104b2906b0636f6d62696e6564536b69760a41b8152600c0190565b9081526040519081900360200190205490508061050657604051631d4604eb60e11b815260206004820152600c60248201526b0636f6d62696e6564536b69760a41b60448201526064015b60405180910390fd5b6001546000546001600160401b039182169161052a91600160a01b90041685611477565b6001600160401b0316111561055257604051630e9da4f960e21b815260040160405180910390fd5b6000546001600160401b03600160a01b909104811690841611610588576040516329e3451360e01b815260040160405180910390fd5b6000805460408051600160a01b830460c081811b6001600160c01b03199081166020850152602884018990529089901b166048830152825160308184030181526050830184526001600160401b0391821660708401529088166090808401919091528351808403909101815260b083019384905263b3f04fdf60e01b9093526001600160a01b039093169263b3f04fdf923492610639928892909163b91deeb560e01b906207a1209060b4016114e7565b60206040518083038185885af1158015610657573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061067c919061153c565b6000546040518281529192506001600160401b0386811692600160a01b90920416907f014d972621549e25527d9b73201fe71c02ef506769686afcdf81a92f7b9132ea9060200160405180910390a350505050565b806002836040516106e29190611555565b908152604051908190036020019020555050565b60008054600160a01b90046001600160401b0316841115610719575060006107a5565b600060046000878760405160200161073b929190918252602082015260400190565b60405160208183030381529060405280519060200120815260200190815260200160002054905060006107a082858760405160200161078c9190815181526020918201519181019190915260400190565b604051602081830303815290604052610c61565b925050505b949350505050565b60008054600160a01b90046001600160401b0316815260036020526040902054806107eb576040516352065af960e11b815260040160405180910390fd5b6000600260405161080e906b0636f6d62696e6564537465760a41b8152600c0190565b9081526040519081900360200190205490508061085d57604051631d4604eb60e11b815260206004820152600c60248201526b0636f6d62696e6564537465760a41b60448201526064016104fd565b600080546040516001600160c01b0319600160a01b830460c01b166020820152602881018590526001600160a01b039091169063b3f04fdf903490859060480160408051808303601f19018152828252600054600160a01b90046001600160401b03166020840152910160408051601f19818403018152908290526001600160e01b031960e087901b16825261090593929163b053e8b560e01b906207a120906004016114e7565b60206040518083038185885af1158015610923573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610948919061153c565b600054604051828152919250600160a01b90046001600160401b0316907f51e82940b688858ec5c82f6c17e146db2093bec0944f60b0fd921381ef74204c9060200160405180910390a2505050565b6000546001600160a01b031633146109c15760405162461bcd60e51b81526004016104fd90611571565b6000818060200190518101906109d791906115b4565b9050600080848060200190518101906109f091906115d1565b90925090506000610a028460016115f5565b6000549091506001600160401b03600160a01b909104811690821611610a3b576040516329e3451360e01b815260040160405180910390fd5b6001600160401b03818116600081815260036020908152604080832088905580519489168583018190528582018590528151808703830181526060870180845281519185019190912085526004909352908320879055825467ffffffffffffffff60a01b1916600160a01b9094029390931790915585905260808201849052907f880abacb3515d667ad5a5a9ee88b0218eca5d7bf2d824d69e73a01d7d31703139060a00160405180910390a2505050505050565b6000546001600160a01b03163314610b1a5760405162461bcd60e51b81526004016104fd90611571565b60008082806020019051810190610b319190611615565b9150915060008085806020019051810190610b4c91906115d1565b60005491935091506001600160401b03600160a01b909104811690841611610b87576040516329e3451360e01b815260040160405180910390fd5b6001600160401b03838116600081815260036020908152604080832087905580519489168583018190528582018590528151808703830181526060870180845281519185019190912085526004909352908320869055825467ffffffffffffffff60a01b1916600160a01b8502179092558590526080830184905290917fc2d89d9b17fae0ddb047b2164e03760f75b6fee6bdbb291dd9867519ff5581399060a00160405180910390a3505050505050565b6000600282604051610c4b9190611555565b9081526020016040518091039020549050919050565b60006001836040015111610c845782515115610c7f57506000610ecc565b610ca6565b610c9683602001518460400151610ed3565b83515114610ca657506000610ecc565b8260400151836020015110610cbd57506000610ecc565b6000610cc883610f60565b845151909150600003610cf4578360400151600103610cea5784149050610ecc565b6000915050610ecc565b60208401516001905b60208601516000906001841b90610d15908290611644565b610d1f9190611666565b905060006001610d3181861b8461167d565b610d3b9190611690565b905087604001518110610d4f575050610e15565b915081610d5d600185611690565b88515111610d7357600095505050505050610ecc565b610d7e600185611690565b6001901b828960200151610d929190611690565b1015610dcf578751610dc8908690610dab600188611690565b81518110610dbb57610dbb6116a3565b6020026020010151610fd5565b9450610e01565b8751610dfe90610de0600187611690565b81518110610df057610df06116a3565b602002602001015186610fd5565b94505b610e0c60018561167d565b93505050610cfd565b60018660400151610e269190611690565b8114610e6e57610e37600183611690565b86515111610e4b5760009350505050610ecc565b8551610e5e908490610dab600186611690565b9250610e6b60018361167d565b91505b855151610e7c600184611690565b1015610ec5578551610eb190610e93600185611690565b81518110610ea357610ea36116a3565b602002602001015184610fd5565b9250610ebe60018361167d565b9150610e6e565b5050841490505b9392505050565b6000610ede82611053565b610eea90610100611690565b90506000610ef9600183611690565b6001901b9050600181610f0c9190611690565b8411610f18575061044b565b80600103610f2a57600191505061044b565b610f46610f378286611690565b610f418386611690565b610ed3565b610f5190600161167d565b91505061044b565b5092915050565b60006002600060f81b83604051602001610f7b9291906116b9565b60408051601f1981840301815290829052610f9591611555565b602060405180830381855afa158015610fb2573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061044b919061153c565b604051600160f81b6020820152602181018390526041810182905260009060029060610160408051601f198184030181529082905261101391611555565b602060405180830381855afa158015611030573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610ecc919061153c565b60005b81816001901b10156110745761106d60018261167d565b9050611056565b61044b81610100611690565b6001600160401b038116811461109557600080fd5b50565b6000602082840312156110aa57600080fd5b8135610ecc81611080565b600080604083850312156110c857600080fd5b82356110d381611080565b915060208301356110e381611080565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715611126576111266110ee565b60405290565b604051606081016001600160401b0381118282101715611126576111266110ee565b604051601f8201601f191681016001600160401b0381118282101715611176576111766110ee565b604052919050565b600082601f83011261118f57600080fd5b81356001600160401b038111156111a8576111a86110ee565b6111bb601f8201601f191660200161114e565b8181528460208386010111156111d057600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561120057600080fd5b82356001600160401b0381111561121657600080fd5b6112228582860161117e565b95602094909401359450505050565b60008060008084860360a081121561124857600080fd5b8535945060208087013594506040603f198301121561126657600080fd5b61126e611104565b604088013581526060880135828201529350608087013591506001600160401b038083111561129c57600080fd5b918701916060838a0312156112b057600080fd5b6112b861112c565b8335828111156112c757600080fd5b8401601f81018b136112d857600080fd5b8035838111156112ea576112ea6110ee565b8060051b93506112fb85850161114e565b818152938201850193858101908d86111561131557600080fd5b928601925b858410156113335783358252928601929086019061131a565b808552505050508284013583820152604084013560408201528094505050505092959194509250565b60006020828403121561136e57600080fd5b5035919050565b6000806040838503121561138857600080fd5b82356001600160401b038082111561139f57600080fd5b6113ab8683870161117e565b935060208501359150808211156113c157600080fd5b506113ce8582860161117e565b9150509250929050565b6000602082840312156113ea57600080fd5b81356001600160a01b0381168114610ecc57600080fd5b6000806040838503121561141457600080fd5b823561141f81611080565b946020939093013593505050565b60006020828403121561143f57600080fd5b81356001600160401b0381111561145557600080fd5b6107a58482850161117e565b634e487b7160e01b600052601160045260246000fd5b6001600160401b03828116828216039080821115610f5957610f59611461565b60005b838110156114b257818101518382015260200161149a565b50506000910152565b600081518084526114d3816020860160208601611497565b601f01601f19169290920160200192915050565b85815260a06020820152600061150060a08301876114bb565b828103604084015261151281876114bb565b6001600160e01b0319959095166060840152505063ffffffff919091166080909101529392505050565b60006020828403121561154e57600080fd5b5051919050565b60008251611567818460208701611497565b9190910192915050565b60208082526023908201527f4f6e6c7920676174657761792063616e2063616c6c20746869732066756e637460408201526234b7b760e91b606082015260800190565b6000602082840312156115c657600080fd5b8151610ecc81611080565b600080604083850312156115e457600080fd5b505080516020909101519092909150565b6001600160401b03818116838216019080821115610f5957610f59611461565b6000806040838503121561162857600080fd5b825161163381611080565b60208401519092506110e381611080565b60008261166157634e487b7160e01b600052601260045260246000fd5b500490565b808202811582820484141761044b5761044b611461565b8082018082111561044b5761044b611461565b8181038181111561044b5761044b611461565b634e487b7160e01b600052603260045260246000fd5b6001600160f81b03198316815281516000906116dc816001850160208701611497565b91909101600101939250505056fea2646970667358221220f0de7cc063c2b8986d8843021c22c42110f5af8598bedc65583a9889c0978afb64736f6c63430008150033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000852a94f8309d445d27222edb1e92a4e83dddd2a8

-----Decoded View---------------
Arg [0] : _gateway (address): 0x852a94F8309D445D27222eDb1E92A4E83DdDd2a8

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000852a94f8309d445d27222edb1e92a4e83dddd2a8


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Txn Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.