FRAX Price: $0.86 (+6.68%)

Contract

0xb10cface69821Ff7b245Cf5f28f3e714fDbd86b8

Overview

FRAX Balance | FXTL Balance

0 FRAX | 6,715 FXTL

FRAX Value

$0.00

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Age:1H
Reset Filter

Transaction Hash
Block
From
To

There are no matching entries

1 Internal Transaction and > 10 Token Transfers found.

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block From To
220200882025-06-25 11:28:07218 days ago1750850887  Contract Creation0 FRAX

Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Block Oracle

Compiler Version
vyper:0.4.3

Optimization Enabled:
Yes

Other Settings:
paris EvmVersion, None license

Contract Source Code (Vyper Json-Input format)

File 1 of 3 : BlockOracle.vy
# pragma version 0.4.3
# pragma optimize gas

"""
@title Block Oracle

@notice Decentralized block hash oracle with multi-committer consensus
Uses a threshold-based commitment system where trusted committers can submit and validate block hashes
Notable features are:
    - Committers can submit block hashes and optionally trigger validation
    - Each block requires threshold number of matching commitments to be confirmed
    - Committers can update their votes before confirmation
    - Once confirmed, block hashes are immutable
    - Owner can manage committers and adjust threshold

@license Copyright (c) Curve.Fi, 2025 - all rights reserved

@author curve.fi

@custom:security [email protected]
"""

################################################################
#                            MODULES                           #
################################################################

# Import ownership management
from snekmate.auth import ownable

initializes: ownable
exports: (
    ownable.owner,
    ownable.transfer_ownership,
    ownable.renounce_ownership,
)

# Import RLP Block Header Decoder
from modules import BlockHeaderRLPDecoder as bh_rlp

################################################################
#                            EVENTS                            #
################################################################

event CommitBlock:
    committer: indexed(address)
    block_number: indexed(uint256)
    block_hash: bytes32


event ApplyBlock:
    block_number: indexed(uint256)
    block_hash: bytes32


event SubmitBlockHeader:
    block_number: indexed(uint256)
    block_hash: bytes32


event AddCommitter:
    committer: indexed(address)


event RemoveCommitter:
    committer: indexed(address)


event SetThreshold:
    new_threshold: indexed(uint256)


event SetHeaderVerifier:
    old_verifier: indexed(address)
    new_verifier: indexed(address)


################################################################
#                            CONSTANTS                          #
################################################################

MAX_COMMITTERS: constant(uint256) = 32


################################################################
#                            STORAGE                           #
################################################################

block_hash: HashMap[uint256, bytes32]  # block_number => hash
last_confirmed_block_number: public(uint256)  # number of the last confirmed block hash
header_verifier: public(address)  # address of the header verifier

block_header: public(HashMap[uint256, bh_rlp.BlockHeader])  # block_number => header
last_confirmed_header: public(bh_rlp.BlockHeader)  # last confirmed header

committers: public(DynArray[address, MAX_COMMITTERS])  # List of all committers
is_committer: public(HashMap[address, bool])
commitment_count: public(
    HashMap[uint256, HashMap[bytes32, uint256]]
)  # block_number => hash => count
committer_votes: public(
    HashMap[address, HashMap[uint256, bytes32]]
)  # committer => block_number => committed_hash
threshold: public(uint256)


################################################################
#                         CONSTRUCTOR                          #
################################################################

@deploy
def __init__():
    """
    @notice Initialize the contract with the owner
    """

    # Initialize ownable
    ownable.__init__()
    # tx.origin in case of proxy deployment
    ownable._transfer_ownership(tx.origin)


################################################################
#                      OWNER FUNCTIONS                         #
################################################################

@external
def set_header_verifier(_verifier: address):
    """
    @notice Set the block header verifier
    @dev Emits SetHeaderVerifier event
    @param _verifier Address of the block header verifier
    """

    ownable._check_owner()
    old_verifier: address = self.header_verifier
    self.header_verifier = _verifier
    log SetHeaderVerifier(old_verifier=old_verifier, new_verifier=_verifier)


@external
def add_committer(_committer: address, _bump_threshold: bool = False):
    """
    @notice Set trusted address that can commit block data
    @param _committer Address of trusted committer
    @param _bump_threshold If True, bump threshold to 1 more (useful for initial setup)
    """

    ownable._check_owner()
    if not self.is_committer[_committer]:
        assert len(self.committers) < MAX_COMMITTERS, "Max committers reached"
        self.is_committer[_committer] = True
        self.committers.append(_committer)
        log  AddCommitter(committer=_committer)

        if _bump_threshold:
            self.threshold += 1


@external
def remove_committer(_committer: address):
    """
    @notice Remove trusted address that can commit block data
    @param _committer Address of trusted committer
    """

    ownable._check_owner()
    if self.is_committer[_committer]:
        self.is_committer[_committer] = False

        # Rebuild committers array excluding the removed committer
        new_committers: DynArray[address, MAX_COMMITTERS] = []
        for committer: address in self.committers:
            if committer != _committer:
                new_committers.append(committer)
        self.committers = new_committers

        log  RemoveCommitter(committer=_committer)


@external
def set_threshold(_new_threshold: uint256):
    """
    @notice Update threshold for block application
    @param _new_threshold New threshold value
    """

    ownable._check_owner()
    assert _new_threshold <= len(
        self.committers
    ), "Threshold cannot be greater than number of committers"
    self.threshold = _new_threshold

    log  SetThreshold(new_threshold=_new_threshold)


@external
def admin_apply_block(_block_number: uint256, _block_hash: bytes32):
    """
    @notice Apply a block hash with admin rights
    @param _block_number The block number to apply
    @param _block_hash The hash to apply
    @dev Only callable by owner
    """

    ownable._check_owner()
    self._apply_block(_block_number, _block_hash)


################################################################
#                     INTERNAL FUNCTIONS                       #
################################################################

@internal
def _apply_block(_block_number: uint256, _block_hash: bytes32):
    """
    @notice Confirm a block hash and apply it
    @dev All security checks must be performed outside!
    @param _block_number The block number to confirm
    @param _block_hash The hash to confirm
    """

    self.block_hash[_block_number] = _block_hash
    if self.last_confirmed_block_number < _block_number:
        self.last_confirmed_block_number = _block_number
    log  ApplyBlock(block_number=_block_number, block_hash=_block_hash)


################################################################
#                  PERMISSIONED FUNCTIONS                      #
################################################################

@external
def commit_block(_block_number: uint256, _block_hash: bytes32, _apply: bool = True) -> bool:
    """
    @notice Commit a block hash and optionally attempt to apply it
    @param _block_number The block number to commit
    @param _block_hash The hash to commit
    @param _apply If True, checks if threshold is met and applies block
    @return True if block was applied
    """

    assert self.is_committer[msg.sender], "Not authorized"
    assert self.block_hash[_block_number] == empty(bytes32), "Already applied"
    assert _block_hash != empty(bytes32), "Invalid block hash"

    previous_commitment: bytes32 = self.committer_votes[msg.sender][_block_number]

    # Remove previous vote if exists, to avoid duplicate commitments
    if previous_commitment != empty(bytes32):
        self.commitment_count[_block_number][previous_commitment] -= 1

    self.committer_votes[msg.sender][_block_number] = _block_hash
    self.commitment_count[_block_number][_block_hash] += 1
    log  CommitBlock(committer=msg.sender, block_number=_block_number, block_hash=_block_hash)

    # Optional attempt to apply block
    if _apply and self.commitment_count[_block_number][_block_hash] >= self.threshold:
        self._apply_block(_block_number, _block_hash)
        return True
    return False


################################################################
#                 PERMISSIONLESS FUNCTIONS                     #
################################################################

@external
def apply_block(_block_number: uint256, _block_hash: bytes32):
    """
    @notice Apply a block hash if it has sufficient commitments
    @param _block_number The block number to apply
    @param _block_hash The block hash to apply
    """

    assert self.block_hash[_block_number] == empty(bytes32), "Already applied"
    assert (
        self.commitment_count[_block_number][_block_hash] >= self.threshold
    ), "Insufficient commitments"
    self._apply_block(_block_number, _block_hash)


@external
def submit_block_header(_header_data: bh_rlp.BlockHeader):
    """
    @notice Submit block header. Available only to whitelisted verifier contract.
    @param _header_data The block header to submit
    """
    assert msg.sender == self.header_verifier, "Not authorized"

    # Safety checks
    assert _header_data.block_hash != empty(bytes32), "Invalid block hash"
    assert self.block_hash[_header_data.block_number] != empty(bytes32), "Blockhash not applied"
    assert _header_data.block_hash == self.block_hash[_header_data.block_number], "Blockhash does not match"
    assert self.block_header[_header_data.block_number].block_hash == empty(bytes32), "Header already submitted"

    # Store decoded header
    self.block_header[_header_data.block_number] = _header_data

    # Update last confirmed header if new
    if _header_data.block_number > self.last_confirmed_header.block_number:
        self.last_confirmed_header = _header_data

    log  SubmitBlockHeader(
        block_number=_header_data.block_number,
        block_hash=_header_data.block_hash,
    )


################################################################
#                         VIEW FUNCTIONS                       #
################################################################

@view
@external
def get_all_committers() -> DynArray[address, MAX_COMMITTERS]:
    """
    @notice Utility viewer that returns list of all committers
    @return Array of all registered committer addresses
    """
    return self.committers


@view
@external
def get_block_hash(_block_number: uint256) -> bytes32:
    """
    @notice Get the confirmed block hash for a given block number
    @param _block_number The block number to query
    @return The confirmed block hash, or empty bytes32 if not confirmed
    """
    return self.block_hash[_block_number]


@view
@external
def get_state_root(_block_number: uint256) -> bytes32:
    """
    @notice Get the state root for a given block number
    @param _block_number The block number to query
    @return The state root from the block header, or empty bytes32 if header not submitted
    """
    return self.block_header[_block_number].state_root

File 2 of 3 : ownable.vy
# pragma version ~=0.4.3
# pragma nonreentrancy off
"""
@title Owner-Based Access Control Functions
@custom:contract-name ownable
@license GNU Affero General Public License v3.0 only
@author pcaversaccio
@notice These functions can be used to implement a basic access
        control mechanism, where there is an account (an owner)
        that can be granted exclusive access to specific functions.
        By default, the owner account will be the one that deploys
        the contract. This can later be changed with `transfer_ownership`.
        An exemplary integration can be found in the ERC-20 implementation here:
        https://github.com/pcaversaccio/snekmate/blob/main/src/snekmate/tokens/erc20.vy.
        The implementation is inspired by OpenZeppelin's implementation here:
        https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol.
"""


# @dev Returns the address of the current owner.
# @notice If you declare a variable as `public`,
# Vyper automatically generates an `external`
# getter function for the variable.
owner: public(address)


# @dev Emitted when the ownership is transferred
# from `previous_owner` to `new_owner`.
event OwnershipTransferred:
    previous_owner: indexed(address)
    new_owner: indexed(address)


@deploy
@payable
def __init__():
    """
    @dev To omit the opcodes for checking the `msg.value`
         in the creation-time EVM bytecode, the constructor
         is declared as `payable`.
    @notice The `owner` role will be assigned to
            the `msg.sender`.
    """
    self._transfer_ownership(msg.sender)


@external
def transfer_ownership(new_owner: address):
    """
    @dev Transfers the ownership of the contract
         to a new account `new_owner`.
    @notice Note that this function can only be
            called by the current `owner`. Also,
            the `new_owner` cannot be the zero address.
    @param new_owner The 20-byte address of the new owner.
    """
    self._check_owner()
    assert new_owner != empty(address), "ownable: new owner is the zero address"
    self._transfer_ownership(new_owner)


@external
def renounce_ownership():
    """
    @dev Leaves the contract without an owner.
    @notice Renouncing ownership will leave the
            contract without an owner, thereby
            removing any functionality that is
            only available to the owner.
    """
    self._check_owner()
    self._transfer_ownership(empty(address))


@internal
def _check_owner():
    """
    @dev Throws if the sender is not the owner.
    """
    assert msg.sender == self.owner, "ownable: caller is not the owner"


@internal
def _transfer_ownership(new_owner: address):
    """
    @dev Transfers the ownership of the contract
         to a new account `new_owner`.
    @notice This is an `internal` function without
            access restriction.
    @param new_owner The 20-byte address of the new owner.
    """
    old_owner: address = self.owner
    self.owner = new_owner
    log OwnershipTransferred(previous_owner=old_owner, new_owner=new_owner)

File 3 of 3 : BlockHeaderRLPDecoder.vy
# pragma version 0.4.3

"""
@title Block Header RLP Decoder Vyper Module
@author curve.fi
@license Copyright (c) Curve.Fi, 2025 - all rights reserved
@notice Decodes RLP-encoded Ethereum block header and stores key fields
@dev Extracts block number from RLP and uses it as storage key
"""

################################################################
#                           CONSTANTS                          #
################################################################
# Block header size upper limit
BLOCK_HEADER_SIZE: constant(uint256) = 1024

# RLP decoding constants
RLP_SHORT_START: constant(uint256) = 128  # 0x80
RLP_LONG_START: constant(uint256) = 183  # 0xb7
RLP_LIST_SHORT_START: constant(uint256) = 192  # 0xc0
RLP_LIST_LONG_START: constant(uint256) = 247  # 0xf7


################################################################
#                           STRUCTS                            #
################################################################

struct BlockHeader:
    block_hash: bytes32
    parent_hash: bytes32
    state_root: bytes32
    receipt_root: bytes32
    block_number: uint256
    timestamp: uint256

################################################################
#                         CONSTRUCTOR                          #
################################################################

@deploy
def __init__():
    pass


################################################################
#                      EXTERNAL FUNCTIONS                      #
################################################################
# can be exposed optionally, or used in testing
@pure
@external
def calculate_block_hash(encoded_header: Bytes[BLOCK_HEADER_SIZE]) -> bytes32:
    """
    @notice Calculates block hash from RLP encoded header
    @param encoded_header RLP encoded header data
    @return Block hash
    """
    return keccak256(encoded_header)


@pure
@external
def decode_block_header(encoded_header: Bytes[BLOCK_HEADER_SIZE]) -> BlockHeader:
    """
    @notice Decodes RLP encoded block header into BlockHeader struct
    @param encoded_header RLP encoded header data
    @return BlockHeader struct containing decoded block data
    """
    return self._decode_block_header(encoded_header)


################################################################
#                      CORE FUNCTIONS                          #
################################################################

@pure
@internal
def _decode_block_header(encoded_header: Bytes[BLOCK_HEADER_SIZE]) -> BlockHeader:
    """
    @notice Decodes key fields from RLP-encoded Ethereum block header
    @dev RLP encoding rules:
         - Single byte values (< 0x80) are encoded as themselves
         - Short strings (length < 56) start with 0x80 + length
         - Long strings (length >= 56) start with 0xb7 + length_of_length, followed by length
         - Lists follow similar rules but with 0xc0 and 0xf7 as starting points
         Makes use of utility functions to parse the RLP encoded header,
         and passes entire header to them which is not optimal in terms of gas, but
         makes code more readable.
    @param encoded_header RLP encoded block header
    @return BlockHeader(block_hash, parent_hash, state_root, block_number, timestamp)
    """

    # Placeholder variables
    tmp_int: uint256 = 0
    tmp_bytes: bytes32 = empty(bytes32)

    # Current position in the encoded header
    current_pos: uint256 = 0

    # 1. Skip RLP list length
    current_pos = self._skip_rlp_list_header(encoded_header, current_pos)

    # 2. Extract hashes
    parent_hash: bytes32 = empty(bytes32)
    parent_hash, current_pos = self._read_hash32(encoded_header, current_pos)  # parent hash
    tmp_bytes, current_pos = self._read_hash32(encoded_header, current_pos)  # skip uncle hash

    # 3. Skip miner address (20 bytes + 0x94)
    assert convert(slice(encoded_header, current_pos, 1), bytes1) == 0x94
    current_pos += 21

    # 4. Read state root
    state_root: bytes32 = empty(bytes32)
    state_root, current_pos = self._read_hash32(encoded_header, current_pos)

    # 5. Skip transaction root
    tmp_bytes, current_pos = self._read_hash32(encoded_header, current_pos)  # skip tx root

    # 6. Read receipt root
    receipt_root: bytes32 = empty(bytes32)
    receipt_root, current_pos = self._read_hash32(encoded_header, current_pos)

    # 7. Skip logs bloom
    current_pos = self._skip_rlp_string(encoded_header, current_pos)

    # 8. Skip difficulty
    tmp_int, current_pos = self._read_rlp_number(encoded_header, current_pos)

    # 9. Read block number
    block_number: uint256 = 0
    block_number, current_pos = self._read_rlp_number(encoded_header, current_pos)

    # 10. Skip gas fields
    tmp_int, current_pos = self._read_rlp_number(encoded_header, current_pos)  # skip gas limit
    tmp_int, current_pos = self._read_rlp_number(encoded_header, current_pos)  # skip gas used

    # 11. Read timestamp
    timestamp: uint256 = 0
    timestamp, current_pos = self._read_rlp_number(encoded_header, current_pos)

    return BlockHeader(
        block_hash=keccak256(encoded_header),
        parent_hash=parent_hash,
        state_root=state_root,
        receipt_root=receipt_root,
        block_number=block_number,
        timestamp=timestamp,
    )


################################################################
#                      UTILITY FUNCTIONS                       #
################################################################

@pure
@internal
def _skip_rlp_list_header(encoded: Bytes[BLOCK_HEADER_SIZE], pos: uint256) -> uint256:
    """@dev Returns position after list header"""
    first_byte: uint256 = convert(slice(encoded, 0, 1), uint256)
    assert first_byte >= RLP_LIST_SHORT_START, "Not a list"
    if first_byte <= RLP_LIST_LONG_START:
        return pos + 1
    else:
        return pos + 1 + (first_byte - RLP_LIST_LONG_START)


@pure
@internal
def _skip_rlp_string(encoded: Bytes[BLOCK_HEADER_SIZE], pos: uint256) -> uint256:
    """@dev Skip RLP string field, returns next_pos"""
    prefix: uint256 = convert(slice(encoded, pos, 1), uint256)
    if prefix < RLP_SHORT_START:
        return pos + 1
    elif prefix <= RLP_LONG_START:
        return pos + 1 + (prefix - RLP_SHORT_START)
    else:
        # Sanity check: ensure this is a string, not a list
        assert prefix < RLP_LIST_SHORT_START, "Expected string, found list prefix"

        len_of_len: uint256 = prefix - RLP_LONG_START
        data_length: uint256 = convert(
            abi_decode(abi_encode(slice(encoded, pos + 1, len_of_len)), (Bytes[32])), uint256
        )
        return pos + 1 + len_of_len + data_length


@pure
@internal
def _read_hash32(encoded: Bytes[BLOCK_HEADER_SIZE], pos: uint256) -> (bytes32, uint256):
    """@dev Read 32-byte hash field, returns (hash, next_pos)"""
    assert convert(slice(encoded, pos, 1), uint256) == 160  # RLP_SHORT_START + 32
    return extract32(encoded, pos + 1), pos + 33


@pure
@internal
def _read_rlp_number(encoded: Bytes[BLOCK_HEADER_SIZE], pos: uint256) -> (uint256, uint256):
    """@dev Read RLP-encoded number, returns (value, next_pos)"""
    prefix: uint256 = convert(slice(encoded, pos, 1), uint256)
    if prefix < RLP_SHORT_START:
        return prefix, pos + 1

    # Sanity check: ensure this is a short string (not a long string or list)
    assert prefix <= RLP_LONG_START, "Invalid RLP number encoding"

    length: uint256 = prefix - RLP_SHORT_START
    value: uint256 = convert(
        abi_decode(abi_encode(slice(encoded, pos + 1, length)), (Bytes[32])), uint256
    )
    # abi_decode(abi_encode(bytesA), bytesB) is needed to unsafe cast bytesA to bytesB
    return value, pos + 1 + length

Settings
{
  "outputSelection": {
    "0/1/contracts/BlockOracle.vy": [
      "evm.bytecode",
      "evm.deployedBytecode",
      "abi"
    ]
  },
  "search_paths": [
    "0/1/contracts",
    "0/1",
    "0/1/.venv/lib/python3.12/site-packages",
    "."
  ],
  "evmVersion": "paris"
}

Contract Security Audit

Contract ABI

API
[{"anonymous":false,"inputs":[{"indexed":true,"name":"committer","type":"address"},{"indexed":true,"name":"block_number","type":"uint256"},{"indexed":false,"name":"block_hash","type":"bytes32"}],"name":"CommitBlock","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"block_number","type":"uint256"},{"indexed":false,"name":"block_hash","type":"bytes32"}],"name":"ApplyBlock","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"block_number","type":"uint256"},{"indexed":false,"name":"block_hash","type":"bytes32"}],"name":"SubmitBlockHeader","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"committer","type":"address"}],"name":"AddCommitter","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"committer","type":"address"}],"name":"RemoveCommitter","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"new_threshold","type":"uint256"}],"name":"SetThreshold","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"old_verifier","type":"address"},{"indexed":true,"name":"new_verifier","type":"address"}],"name":"SetHeaderVerifier","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previous_owner","type":"address"},{"indexed":true,"name":"new_owner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"new_owner","type":"address"}],"name":"transfer_ownership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounce_ownership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_verifier","type":"address"}],"name":"set_header_verifier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_committer","type":"address"}],"name":"add_committer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_committer","type":"address"},{"name":"_bump_threshold","type":"bool"}],"name":"add_committer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_committer","type":"address"}],"name":"remove_committer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_new_threshold","type":"uint256"}],"name":"set_threshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_block_number","type":"uint256"},{"name":"_block_hash","type":"bytes32"}],"name":"admin_apply_block","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_block_number","type":"uint256"},{"name":"_block_hash","type":"bytes32"}],"name":"commit_block","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_block_number","type":"uint256"},{"name":"_block_hash","type":"bytes32"},{"name":"_apply","type":"bool"}],"name":"commit_block","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_block_number","type":"uint256"},{"name":"_block_hash","type":"bytes32"}],"name":"apply_block","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"name":"block_hash","type":"bytes32"},{"name":"parent_hash","type":"bytes32"},{"name":"state_root","type":"bytes32"},{"name":"receipt_root","type":"bytes32"},{"name":"block_number","type":"uint256"},{"name":"timestamp","type":"uint256"}],"name":"_header_data","type":"tuple"}],"name":"submit_block_header","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"get_all_committers","outputs":[{"name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"_block_number","type":"uint256"}],"name":"get_block_hash","outputs":[{"name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"_block_number","type":"uint256"}],"name":"get_state_root","outputs":[{"name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"last_confirmed_block_number","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"header_verifier","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"arg0","type":"uint256"}],"name":"block_header","outputs":[{"components":[{"name":"block_hash","type":"bytes32"},{"name":"parent_hash","type":"bytes32"},{"name":"state_root","type":"bytes32"},{"name":"receipt_root","type":"bytes32"},{"name":"block_number","type":"uint256"},{"name":"timestamp","type":"uint256"}],"name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"last_confirmed_header","outputs":[{"components":[{"name":"block_hash","type":"bytes32"},{"name":"parent_hash","type":"bytes32"},{"name":"state_root","type":"bytes32"},{"name":"receipt_root","type":"bytes32"},{"name":"block_number","type":"uint256"},{"name":"timestamp","type":"uint256"}],"name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"arg0","type":"uint256"}],"name":"committers","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"arg0","type":"address"}],"name":"is_committer","outputs":[{"name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"arg0","type":"uint256"},{"name":"arg1","type":"bytes32"}],"name":"commitment_count","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"arg0","type":"address"},{"name":"arg1","type":"uint256"}],"name":"committer_votes","outputs":[{"name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"threshold","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"outputs":[],"stateMutability":"nonpayable","type":"constructor"}]

346100725761000c610064565b3260405261001861002a565b61119361007761000039611193610000f35b6001546060526040516001556040516060517f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060006080a3565b3360405261007061002a565b565b600080fd60003560e01c60026015820660011b61116901601e39600051565b638da5cb5b811861104557346111645760015460405260206040f35b63f0350c04811861104557602436103417611164576004358060a01c611164576101005261006261104b565b61010051610112576020806101a0526026610120527f6f776e61626c653a206e6577206f776e657220697320746865207a65726f2061610140527f646472657373000000000000000000000000000000000000000000000000000061016052610120816101a00160468160468460045afa15611164578051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610180528060040161019cfd5b610100516040526101216110d2565b005b63b15e13ee811861014a57346111645761013b61104b565b60006040526101486110d2565b005b63873566f7811861104557606436103417611164576044358060011c6111645760a0525b602d336020526000526040600020546102005760208061012052600e60c0527f4e6f7420617574686f72697a656400000000000000000000000000000000000060e05260c0816101200181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610100528060040161011cfd5b6002600435602052600052604060002054156102955760208061012052600f60c0527f416c7265616479206170706c696564000000000000000000000000000000000060e05260c0816101200181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610100528060040161011cfd5b60243561031b5760208061012052601260c0527f496e76616c696420626c6f636b2068617368000000000000000000000000000060e05260c0816101200181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610100528060040161011cfd5b602f33602052600052604060002080600435602052600052604060002090505460c05260c0511561037a57602e60043560205260005260406000208060c051602052600052604060002090508054600181038181116111645790508155505b602435602f336020526000526040600020806004356020526000526040600020905055602e60043560205260005260406000208060243560205260005260406000209050805460018101818110611164579050815550600435337f11fe4427f3a01f8ddd0e563f79ec13468efef4738ce49084b2f00abe2897ef0360243560e052602060e0a360a05161040e576000610436565b603054602e600435602052600052604060002080602435602052600052604060002090505410155b15610458576040600460403761044a61110c565b600160e052602060e0610462565b600060e052602060e05bf35b6385c452df81186104cf57602436103417611164576004358060a01c611164576101005261049061104b565b600454610120526101005160045561010051610120517f38d8b25c8f6269edd1ad7220353bc38084ce8437843d8dfaaecbd358881ab0e96000610140a3005b631dd3e374811861050957346111645760065460405260075460605260085460805260095460a052600a5460c052600b5460e05260c06040f35b6342b2fbd981186110455760443610341761116457602e600435602052600052604060002080602435602052600052604060002090505460405260206040f35b6385ff2e9d8118611045576024361034176111645760006101205261058e565b636e63afe181186106c257604436103417611164576024358060011c61116457610120525b6004358060a01c61116457610100526105a561104b565b602d610100516020526000526040600020546106c057601f600c541115610648576020806101a0526016610140527f4d617820636f6d6d69747465727320726561636865640000000000000000000061016052610140816101a00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610180528060040161019cfd5b6001602d61010051602052600052604060002055600c54601f8111611164576101005181600d015560018101600c5550610100517fc871dc6554951ceeadd9fa74a35411fd9083fa2cbbe44e9b0ebbc0b4bca0a7ca6000610140a261012051156106c057603054600181018181106111645790506030555b005b630dfe681081186110455760243610341761116457600560043560205260005260406000206002810190505460405260206040f35b6339652ba4811861081e57602436103417611164576004358060a01c611164576101005261072361104b565b602d610100516020526000526040600020541561081c576000602d610100516020526000526040600020556000610120526000600c54602081116111645780156107ad57905b80600d0154610540526101005161054051146107a25761012051601f811161116457610540518160051b61014001526001810161012052505b600101818118610769575b50506101205160208160051b01600081601f0160051c602181116111645780156107ec57905b8060051b610120015181600c01556001018181186107d3575b50505050610100517f7e10e432298311a6e8b3ac2db903c9d8e89a137ea670aee0b38094e1c45a8b426000610540a25b005b6322e7257e8118611045576024361034176111645760056004356020526000526040600020805460405260018101546060526002810154608052600381015460a052600481015460c052600581015460e0525060c06040f35b634c8f8206811861097a576024361034176111645761089461104b565b600c54600435111561094857602080610180526035610100527f5468726573686f6c642063616e6e6f742062652067726561746572207468616e610120527f206e756d626572206f6620636f6d6d697474657273000000000000000000000061014052610100816101800160558160558460045afa15611164578051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610160528060040161017cfd5b6004356030556004357f46e8115bf463f9c29a9424fe152addef1bfaf2b43180d19bb7c2c78cc0ff1ebf6000610100a2005b63db895f63811861104557346111645760045460405260206040f35b63b6268d3181186109c457604436103417611164576109b361104b565b604060046040376109c261110c565b005b6342cde4e8811861104557346111645760305460405260206040f35b63939074b181186109ff5760443610341761116457600160a05261016e565b639724283f81186110455760243610341761116457600260043560205260005260406000205460405260206040f35b633b71f23481186110455760443610341761116457600260043560205260005260406000205415610ad65760208061010052600f60a0527f416c7265616479206170706c696564000000000000000000000000000000000060c05260a0816101000181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a060e0528060040160fcfd5b603054602e60043560205260005260406000208060243560205260005260406000209050541015610b7e5760208061010052601860a0527f496e73756666696369656e7420636f6d6d69746d656e7473000000000000000060c05260a0816101000181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a060e0528060040160fcfd5b60406004604037610b8d61110c565b005b636afd036581186110455760c43610341761116457600454331815610c295760208060a052600e6040527f4e6f7420617574686f72697a656400000000000000000000000000000000000060605260408160a00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a060805280600401609cfd5b600435610cab5760208060a05260126040527f496e76616c696420626c6f636b2068617368000000000000000000000000000060605260408160a00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a060805280600401609cfd5b6002608435602052600052604060002054610d3b5760208060a05260156040527f426c6f636b68617368206e6f74206170706c696564000000000000000000000060605260408160a00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a060805280600401609cfd5b60026084356020526000526040600020546004351815610dd05760208060a05260186040527f426c6f636b6861736820646f6573206e6f74206d61746368000000000000000060605260408160a00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a060805280600401609cfd5b600560843560205260005260406000205415610e615760208060a05260186040527f48656164657220616c7265616479207375626d6974746564000000000000000060605260408160a00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a060805280600401609cfd5b60c060046040376005608435602052600052604060002060405181556060516001820155608051600282015560a051600382015560c051600482015560e051600582015550600a546084351115610ed757600435600655602435600755604435600855606435600955608435600a5560a435600b555b6084357f43f0c452acfe4c2dc1b2d20ea502adfa6088bd930153c00ac0282dad886155da60043560405260206040a2005b63fd2dc64e8118610f6f573461116457602080604052806040016000600c548083528060051b60008260208111611164578015610f5b57905b80600d01548160051b602088010152600101818118610f41575b505082016020019150509050810190506040f35b63539f58bb811861104557604436103417611164576004358060a01c61116457604052602f604051602052600052604060002080602435602052600052604060002090505460605260206060f35b63017a494d8118610fd957346111645760035460405260206040f35b6324fe3c7c81186110455760243610341761116457600435600c5481101561116457600d015460405260206040f35b63bf8d5f31811861104557602436103417611164576004358060a01c61116457604052602d60405160205260005260406000205460605260206060f35b60006000fd5b6001543318156110d05760208060a05260206040527f6f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260605260408160a00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a060805280600401609cfd5b565b6001546060526040516001556040516060517f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060006080a3565b60605160026040516020526000526040600020556040516003541015611133576040516003555b6040517fb078a94dce502a3eb8987308759913d3d974a4ad431c3cfc174cec33b631b40b60605160805260206080a2565b600080fd01231045104510450b8f09e0003610451045001a0a2e10450fbd087706f705690f080996054904641008855820699cf8acededd39e6a8e9388734872bb55a3d8444c76a6db3bc8a786b62a2f4d19119381182a00a1657679706572830004030037

Deployed Bytecode

0x60003560e01c60026015820660011b61116901601e39600051565b638da5cb5b811861104557346111645760015460405260206040f35b63f0350c04811861104557602436103417611164576004358060a01c611164576101005261006261104b565b61010051610112576020806101a0526026610120527f6f776e61626c653a206e6577206f776e657220697320746865207a65726f2061610140527f646472657373000000000000000000000000000000000000000000000000000061016052610120816101a00160468160468460045afa15611164578051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610180528060040161019cfd5b610100516040526101216110d2565b005b63b15e13ee811861014a57346111645761013b61104b565b60006040526101486110d2565b005b63873566f7811861104557606436103417611164576044358060011c6111645760a0525b602d336020526000526040600020546102005760208061012052600e60c0527f4e6f7420617574686f72697a656400000000000000000000000000000000000060e05260c0816101200181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610100528060040161011cfd5b6002600435602052600052604060002054156102955760208061012052600f60c0527f416c7265616479206170706c696564000000000000000000000000000000000060e05260c0816101200181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610100528060040161011cfd5b60243561031b5760208061012052601260c0527f496e76616c696420626c6f636b2068617368000000000000000000000000000060e05260c0816101200181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610100528060040161011cfd5b602f33602052600052604060002080600435602052600052604060002090505460c05260c0511561037a57602e60043560205260005260406000208060c051602052600052604060002090508054600181038181116111645790508155505b602435602f336020526000526040600020806004356020526000526040600020905055602e60043560205260005260406000208060243560205260005260406000209050805460018101818110611164579050815550600435337f11fe4427f3a01f8ddd0e563f79ec13468efef4738ce49084b2f00abe2897ef0360243560e052602060e0a360a05161040e576000610436565b603054602e600435602052600052604060002080602435602052600052604060002090505410155b15610458576040600460403761044a61110c565b600160e052602060e0610462565b600060e052602060e05bf35b6385c452df81186104cf57602436103417611164576004358060a01c611164576101005261049061104b565b600454610120526101005160045561010051610120517f38d8b25c8f6269edd1ad7220353bc38084ce8437843d8dfaaecbd358881ab0e96000610140a3005b631dd3e374811861050957346111645760065460405260075460605260085460805260095460a052600a5460c052600b5460e05260c06040f35b6342b2fbd981186110455760443610341761116457602e600435602052600052604060002080602435602052600052604060002090505460405260206040f35b6385ff2e9d8118611045576024361034176111645760006101205261058e565b636e63afe181186106c257604436103417611164576024358060011c61116457610120525b6004358060a01c61116457610100526105a561104b565b602d610100516020526000526040600020546106c057601f600c541115610648576020806101a0526016610140527f4d617820636f6d6d69747465727320726561636865640000000000000000000061016052610140816101a00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610180528060040161019cfd5b6001602d61010051602052600052604060002055600c54601f8111611164576101005181600d015560018101600c5550610100517fc871dc6554951ceeadd9fa74a35411fd9083fa2cbbe44e9b0ebbc0b4bca0a7ca6000610140a261012051156106c057603054600181018181106111645790506030555b005b630dfe681081186110455760243610341761116457600560043560205260005260406000206002810190505460405260206040f35b6339652ba4811861081e57602436103417611164576004358060a01c611164576101005261072361104b565b602d610100516020526000526040600020541561081c576000602d610100516020526000526040600020556000610120526000600c54602081116111645780156107ad57905b80600d0154610540526101005161054051146107a25761012051601f811161116457610540518160051b61014001526001810161012052505b600101818118610769575b50506101205160208160051b01600081601f0160051c602181116111645780156107ec57905b8060051b610120015181600c01556001018181186107d3575b50505050610100517f7e10e432298311a6e8b3ac2db903c9d8e89a137ea670aee0b38094e1c45a8b426000610540a25b005b6322e7257e8118611045576024361034176111645760056004356020526000526040600020805460405260018101546060526002810154608052600381015460a052600481015460c052600581015460e0525060c06040f35b634c8f8206811861097a576024361034176111645761089461104b565b600c54600435111561094857602080610180526035610100527f5468726573686f6c642063616e6e6f742062652067726561746572207468616e610120527f206e756d626572206f6620636f6d6d697474657273000000000000000000000061014052610100816101800160558160558460045afa15611164578051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a0610160528060040161017cfd5b6004356030556004357f46e8115bf463f9c29a9424fe152addef1bfaf2b43180d19bb7c2c78cc0ff1ebf6000610100a2005b63db895f63811861104557346111645760045460405260206040f35b63b6268d3181186109c457604436103417611164576109b361104b565b604060046040376109c261110c565b005b6342cde4e8811861104557346111645760305460405260206040f35b63939074b181186109ff5760443610341761116457600160a05261016e565b639724283f81186110455760243610341761116457600260043560205260005260406000205460405260206040f35b633b71f23481186110455760443610341761116457600260043560205260005260406000205415610ad65760208061010052600f60a0527f416c7265616479206170706c696564000000000000000000000000000000000060c05260a0816101000181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a060e0528060040160fcfd5b603054602e60043560205260005260406000208060243560205260005260406000209050541015610b7e5760208061010052601860a0527f496e73756666696369656e7420636f6d6d69746d656e7473000000000000000060c05260a0816101000181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a060e0528060040160fcfd5b60406004604037610b8d61110c565b005b636afd036581186110455760c43610341761116457600454331815610c295760208060a052600e6040527f4e6f7420617574686f72697a656400000000000000000000000000000000000060605260408160a00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a060805280600401609cfd5b600435610cab5760208060a05260126040527f496e76616c696420626c6f636b2068617368000000000000000000000000000060605260408160a00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a060805280600401609cfd5b6002608435602052600052604060002054610d3b5760208060a05260156040527f426c6f636b68617368206e6f74206170706c696564000000000000000000000060605260408160a00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a060805280600401609cfd5b60026084356020526000526040600020546004351815610dd05760208060a05260186040527f426c6f636b6861736820646f6573206e6f74206d61746368000000000000000060605260408160a00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a060805280600401609cfd5b600560843560205260005260406000205415610e615760208060a05260186040527f48656164657220616c7265616479207375626d6974746564000000000000000060605260408160a00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a060805280600401609cfd5b60c060046040376005608435602052600052604060002060405181556060516001820155608051600282015560a051600382015560c051600482015560e051600582015550600a546084351115610ed757600435600655602435600755604435600855606435600955608435600a5560a435600b555b6084357f43f0c452acfe4c2dc1b2d20ea502adfa6088bd930153c00ac0282dad886155da60043560405260206040a2005b63fd2dc64e8118610f6f573461116457602080604052806040016000600c548083528060051b60008260208111611164578015610f5b57905b80600d01548160051b602088010152600101818118610f41575b505082016020019150509050810190506040f35b63539f58bb811861104557604436103417611164576004358060a01c61116457604052602f604051602052600052604060002080602435602052600052604060002090505460605260206060f35b63017a494d8118610fd957346111645760035460405260206040f35b6324fe3c7c81186110455760243610341761116457600435600c5481101561116457600d015460405260206040f35b63bf8d5f31811861104557602436103417611164576004358060a01c61116457604052602d60405160205260005260406000205460605260206060f35b60006000fd5b6001543318156110d05760208060a05260206040527f6f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260605260408160a00181518152602082015160208201528051806020830101601f82600003163682375050601f19601f8251602001011690509050810190506308c379a060805280600401609cfd5b565b6001546060526040516001556040516060517f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060006080a3565b60605160026040516020526000526040600020556040516003541015611133576040516003555b6040517fb078a94dce502a3eb8987308759913d3d974a4ad431c3cfc174cec33b631b40b60605160805260206080a2565b600080fd01231045104510450b8f09e0003610451045001a0a2e10450fbd087706f705690f080996054904641008

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ 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.