BlockOracle
The BlockOracle contract is a decentralized block hash oracle which implements a threshold-based, multi-committer consensus mechanism for block hash commitments. Trusted committers submit and validate block hashes; once a threshold of matching commitments is reached, the block hash is confirmed and becomes immutable. The contract supports secure, permissionless block hash storage, committers management, threshold configuration, and integration with external header verifiers for cross-chain and state proof use cases.
BlockOracle.vyThe source code for the BlockOracle.vy contract can be found on GitHub. The contract is written using Vyper version 0.4.3.
The contract is deployed on all supported chains at 0xb10cface69821Ff7b245Cf5f28f3e714fDbd86b8.
{ }Contract ABI▼
[{"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"}]
Committers
Committers are tracked on-chain and are required for consensus operations. Only the contract owner can modify the committer set; all users can query committer status.
Managing Committers
Owner-only functions for adding or removing committers, as well as retrieving the current committer list. These operations directly affect consensus security, as only committers can submit or update block hash commitments. Exceeding the maximum committer count (32) is prevented at the contract level.
add_committer
BlockOracle.add_committer(_committer: address, _bump_threshold: bool = False)This contract makes use of a Snekmate module to manage roles and permissions. This specific function can only be called by the current owner of the contract.
Function to add a committer.
Emits: AddCommitter
| Input | Type | Description |
|---|---|---|
_committer | address | Address of the committer to add |
_bump_threshold | bool | If true, automatically increase threshold by 1 |
<>Source code▼
event AddCommitter:
committer: indexed(address)
MAX_COMMITTERS: constant(uint256) = 32
committers: public(DynArray[address, MAX_COMMITTERS]) # List of all committers
is_committer: public(HashMap[address, bool])
threshold: public(uint256)
@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
▶Example▼
>>> BlockOracle.add_committer('0x1234567890123456789012345678901234567890', False)
remove_committer
BlockOracle.remove_committer(_committer: address)This contract makes use of a Snekmate module to manage roles and permissions. This specific function can only be called by the current owner of the contract.
Function to remove a committer.
Emits: RemoveCommitter
| Input | Type | Description |
|---|---|---|
_committer | address | Address of the committer to remove |
<>Source code▼
event RemoveCommitter:
committer: indexed(address)
MAX_COMMITTERS: constant(uint256) = 32
committers: public(DynArray[address, MAX_COMMITTERS]) # List of all committers
is_committer: public(HashMap[address, bool])
@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)
▶Example▼
>>> BlockOracle.remove_committer('0x1234567890123456789012345678901234567890')
get_all_committers
BlockOracle.get_all_committers() -> DynArray[address, MAX_COMMITTERS]: viewGetter which returns all registered committers.
Returns: array of all committers (DynArray[address, MAX_COMMITTERS]).
<>Source code▼
MAX_COMMITTERS: constant(uint256) = 32
committers: public(DynArray[address, MAX_COMMITTERS]) # List of all committers
@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
▶Example▼
>>> BlockOracle.get_all_committers()
['0xFacEFeeD696BFC0ebe7EaD3FFBb9a56290d31752']
committers
BlockOracle.committers(arg0: uint256) -> address: viewGetter for the committers at a specific index.
Returns: address of the committer at the specified index (address).
| Input | Type | Description |
|---|---|---|
arg0 | uint256 | Index of the committer |
<>Source code▼
MAX_COMMITTERS: constant(uint256) = 32
committers: public(DynArray[address, MAX_COMMITTERS]) # List of all committers
▶Example▼
This example returns the committer at index 0.
>>> BlockOracle.committers(0)
'0xFacEFeeD696BFC0ebe7EaD3FFBb9a56290d31752'
is_committer
BlockOracle.is_committer(arg0: address) -> bool: viewGetter to check if a certain address is a committer.
Returns: true if the address is a committer, false otherwise (bool).
| Input | Type | Description |
|---|---|---|
arg0 | address | Address to check |
<>Source code▼
is_committer: public(HashMap[address, bool])
▶Example▼
>>> BlockOracle.is_committer('0xFacEFeeD696BFC0ebe7EaD3FFBb9a56290d31752')
True
Threshold Management
Owner-only functions for setting and querying the threshold parameter, which defines the minimum number of matching committer votes required to confirm a block hash. The threshold cannot exceed the number of registered committers.
set_threshold
BlockOracle.set_threshold(_new_threshold: uint256)This contract makes use of a Snekmate module to manage roles and permissions. This specific function can only be called by the current owner of the contract.
Function to update the threshold for block applications.
Emits: SetThreshold
| Input | Type | Description |
|---|---|---|
_new_threshold | uint256 | New threshold value |
<>Source code▼
event SetThreshold:
new_threshold: indexed(uint256)
threshold: public(uint256)
@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)
▶Example▼
>>> BlockOracle.set_threshold(2)
threshold
BlockOracle.threshold() -> uint256: viewGetter for the threshold of how many matching commitments required to confirm a block.
Returns: number of commitments required (uint256).
<>Source code▼
threshold: public(uint256)
▶Example▼
>>> BlockOracle.threshold()
1
Committing Block Hashes
Only registered committers may call commit functions. The contract maintains a mapping of committer votes and a count of votes per block hash. Commitments are mutable until a block is confirmed; after confirmation, the block hash is immutable.
commit_block
BlockOracle.commit_block(_block_number: uint256, _block_hash: bytes32, _apply: bool = True) -> boolFunction to commit a block hash and optionally attempt to apply it.
Returns: true if the block was applied (bool).
Emits: CommitBlock
| Input | Type | Description |
|---|---|---|
_block_number | uint256 | Block number to commit |
_block_hash | bytes32 | The hash to commit |
_apply | bool | true -> check if threshold is met and applies the block. |
<>Source code▼
@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
▶Example▼
>>> BlockOracle.commit_block(22788903, 0xc215221221dd6673ae7ed2e50f47f6d020034657bb4a08010b5677a1f9d06d6d, True)
True
committer_votes
BlockOracle.committer_votes(arg0: address, arg1: uint256) -> bytes32: viewGetter for the committed hash by a specific committer for a specific block number.
Returns: committed hash for the committer and block number, or empty bytes32 if no commitment (bytes32).
| Input | Type | Description |
|---|---|---|
arg0 | address | Address of the committer |
arg1 | uint256 | Block number |
<>Source code▼
committer_votes: public(
HashMap[address, HashMap[uint256, bytes32]]
) # committer => block_number => committed_hash
▶Example▼
>>> BlockOracle.committer_votes('0xFacEFeeD696BFC0ebe7EaD3FFBb9a56290d31752', 22788903)
'0xc215221221dd6673ae7ed2e50f47f6d020034657bb4a08010b5677a1f9d06d6d'
commitment_count
BlockOracle.commitment_count(arg0: uint256, arg1: bytes32) -> uint256: viewGetter for the number of commitments for a specific hash at a specific block number.
Returns: number of commitments for the hash at the block number (uint256).
| Input | Type | Description |
|---|---|---|
arg0 | uint256 | Block number |
arg1 | bytes32 | Hash to get count for |
<>Source code▼
commitment_count: public(
HashMap[uint256, HashMap[bytes32, uint256]]
) # block_number => hash => count
▶Example▼
>>> BlockOracle.commitment_count(22788903, 0xc215221221dd6673ae7ed2e50f47f6d020034657bb4a08010b5677a1f9d06d6d)
1
Block Application
Block application includes both permissionless (anyone can call) and owner-only (admin) application. Also provides views for querying confirmed block hashes and the most recent confirmed block number. Once applied, block hashes are immutable and serve as the canonical record for the oracle.
apply_block
BlockOracle.apply_block(_block_number: uint256, _block_hash: bytes32)Function to apply a block hash if it has sufficient commitments.
Emits: ApplyBlock
| Input | Type | Description |
|---|---|---|
_block_number | uint256 | Block number to apply |
_block_hash | bytes32 | The block hash to apply |
<>Source code▼
event ApplyBlock:
block_number: indexed(uint256)
block_hash: bytes32
block_hash: HashMap[uint256, bytes32] # block_number => hash
last_confirmed_block_number: public(uint256) # number of the last confirmed block hash
@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)
@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)
▶Example▼
>>> BlockOracle.apply_block(22788903, 0xc215221221dd6673ae7ed2e50f47f6d020034657bb4a08010b5677a1f9d06d6d)
admin_apply_block
BlockOracle.admin_apply_block(_block_number: uint256, _block_hash: bytes32)This contract makes use of a Snekmate module to manage roles and permissions. This specific function can only be called by the current owner of the contract.
Function to apply a block hash with admin rights.
Emits: ApplyBlock
| Input | Type | Description |
|---|---|---|
_block_number | uint256 | Block number to apply |
_block_hash | bytes32 | Hash to apply |
<>Source code▼
@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)
▶Example▼
>>> BlockOracle.admin_apply_block(22788903, 0xc215221221dd6673ae7ed2e50f47f6d020034657bb4a08010b5677a1f9d06d6d)
get_block_hash
BlockOracle.get_block_hash(_block_number: uint256) -> bytes32: viewGetter for the confirmed block hash for a given block number.
Returns: confirmed block hash or empty bytes32 if not confirmed (bytes32).
| Input | Type | Description |
|---|---|---|
_block_number | uint256 | Block number |
<>Source code▼
block_hash: HashMap[uint256, bytes32] # block_number => hash
@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]
▶Example▼
>>> BlockOracle.get_block_hash(22788903)
'0xc215221221dd6673ae7ed2e50f47f6d020034657bb4a08010b5677a1f9d06d6d'
last_confirmed_block_number
BlockOracle.last_confirmed_block_number() -> uint256: viewGetter for the last confirmed block number.
Returns: most recently confirmed block number (uint256).
<>Source code▼
last_confirmed_block_number: public(uint256) # number of the last confirmed block hash
▶Example▼
>>> BlockOracle.last_confirmed_block_number()
22788903
Block Headers
Functions for submitting and retrieving full block headers. Only the designated verifier contract may submit headers, which must match a previously confirmed block hash. Includes views for retrieving the state root, full header data, and the most recently confirmed header. These features enable advanced use cases such as state proofs and cross-chain verification.
submit_block_header
BlockOracle.submit_block_header(_header_data: bh_rlp.BlockHeader)This function can only be called by the designated header_verifier contract.
Function to submit a block header.
Emits: SubmitBlockHeader
| Input | Type | Description |
|---|---|---|
_header_data | bh_rlp.BlockHeader | Block header to submit |
<>Source code▼
# Import RLP Block Header Decoder
from modules import BlockHeaderRLPDecoder as bh_rlp
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
@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,
)
▶Example▼
>>> BlockOracle.submit_block_header(header_data)
get_state_root
BlockOracle.get_state_root(_block_number: uint256) -> bytes32: viewGetter for the state root for a given block number.
Returns: state root from the block header, or empty bytes32 if the header is not submitted (bytes32).
| Input | Type | Description |
|---|---|---|
_block_number | uint256 | Block number |
<>Source code▼
@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
▶Example▼
>>> BlockOracle.get_state_root(22788903)
'0x1338f27ed74ec2766875e2db65ca08b79fd2ce67a4f800acac4fa264e99a1984'
block_header
BlockOracle.block_header(arg0: uint256) -> tuple: viewGetter for the block header for a specific block number.
Returns: block header tuple containing (block_hash, parent_hash, state_root, receipt_root, block_number, timestamp) (tuple).
| Input | Type | Description |
|---|---|---|
arg0 | uint256 | Block number |
<>Source code▼
block_header: public(HashMap[uint256, bh_rlp.BlockHeader]) # block_number => header
▶Example▼
>>> BlockOracle.block_header(22788903)
0xc215221221dd6673ae7ed2e50f47f6d020034657bb4a08010b5677a1f9d06d6d, 0x1338f27ed74ec2766875e2db65ca08b79fd2ce67a4f800acac4fa264e99a1984, 0x168986623a9cca07db8e17253b119dc1e93d68c2838e59c8cb5a10a88f5ad7a7, 0x46a8b05c582e75b876b106621e02542c6a9b3608d10d3e1973f3bf5aae9639a1,22788903,1750944347
last_confirmed_header
BlockOracle.last_confirmed_header() -> tuple: viewGetter for the last confirmed header.
Returns: block header tuple of the most recently confirmed header (tuple).
<>Source code▼
last_confirmed_header: public(bh_rlp.BlockHeader) # last confirmed header
▶Example▼
>>> BlockOracle.last_confirmed_header()
0xc215221221dd6673ae7ed2e50f47f6d020034657bb4a08010b5677a1f9d06d6d, 0x1338f27ed74ec2766875e2db65ca08b79fd2ce67a4f800acac4fa264e99a1984, 0x168986623a9cca07db8e17253b119dc1e93d68c2838e59c8cb5a10a88f5ad7a7, 0x46a8b05c582e75b876b106621e02542c6a9b3608d10d3e1973f3bf5aae9639a1,22788903,1750944347
Verifier
Owner-only functions for setting and querying the verifier contract address. The verifier is responsible for submitting RLP-encoded block headers. Proper verifier management is essential for the integrity of header submissions and downstream state proof operations.
set_header_verifier
BlockOracle.set_header_verifier(_verifier: address)This contract makes use of a Snekmate module to manage roles and permissions. This specific function can only be called by the current owner of the contract.
Function to set the block header verifier.
Emits: SetHeaderVerifier
| Input | Type | Description |
|---|---|---|
_verifier | address | Block verifier address |
<>Source code▼
event SetHeaderVerifier:
old_verifier: indexed(address)
new_verifier: indexed(address)
header_verifier: public(address) # address of the header verifier
@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)
▶Example▼
>>> BlockOracle.set_header_verifier('0x1234567890123456789012345678901234567890')
header_verifier
BlockOracle.header_verifier() -> address: viewGetter for the block header verifier.
Returns: verifier (address).
<>Source code▼
header_verifier: public(address) # address of the header verifier
▶Example▼
>>> BlockOracle.header_verifier()
'0xB10CDEC0DE69c88a47c280a97A5AEcA8b0b83385'
Ownership
Standard Ownable interface for querying the current owner and transferring or renouncing ownership. Ownership controls all privileged operations, including committer management, threshold updates, and verifier assignment. Owner of the contract is the DAO.