Address Contract Partially Verified
Address
0x4CEA3E866e7c57fD75CB0CA3E9F5f1151D4Ead3F
Balance
0 ETH
Nonce
1
Code Size
2613 bytes
Creator
0x0A47CeC6...C310 at tx 0x45cf33d8...a82409
Indexed Transactions
0 (1 on-chain, 1.3% indexed)
Contract Bytecode
2613 bytes
0x608060405234801561000f575f80fd5b50600436106100a6575f3560e01c80638da5cb5b1161006e5780638da5cb5b146101375780639551230614610147578063bd98b2b01461015a578063c7065b6a14610194578063cc780aa1146101ce578063f2fde38b146101e1575f80fd5b806322a262c9146100aa57806328aee03f146100bf5780632c09a848146100ef5780635027ad2e14610102578063715018a61461012f575b5f80fd5b6100bd6100b8366004610798565b6101f4565b005b6100d26100cd366004610814565b610269565b6040516001600160a01b0390911681526020015b60405180910390f35b6100bd6100fd366004610834565b610342565b610121610110366004610889565b5f9081526001602052604090205490565b6040519081526020016100e6565b6100bd6103b4565b5f546001600160a01b03166100d2565b6100bd6101553660046108bb565b6103c7565b61016d610168366004610814565b610578565b604080516001600160401b0390931683526001600160a01b039091166020830152016100e6565b61016d6101a2366004610889565b60026020525f90815260409020546001600160401b03811690600160401b90046001600160a01b031682565b6100bd6101dc366004610901565b6105bd565b6100bd6101ef36600461094f565b61062e565b5f6101ff8787610269565b604051637bf41d7760e11b81529091506001600160a01b0382169063f7e83aee90610234908890889088908890600401610997565b5f6040518083038186803b15801561024a575f80fd5b505afa15801561025c573d5f803e3d5ffd5b5050505050505050505050565b5f8281526002602090815260408083208151808301909252546001600160401b038116808352600160401b9091046001600160a01b03169282019290925290831015610337575f84815260016020526040902054805b8015610334575f86815260016020526040902080545f1983019081106102e7576102e76109c8565b5f918252602091829020604080518082019091529101546001600160401b038116808352600160401b9091046001600160a01b0316928201929092529350851015610334575f19016102bf565b50505b602001519392505050565b5f61034d8686610269565b604051636b40634160e01b81529091506001600160a01b03821690636b40634190610380908790879087906004016109dc565b5f6040518083038186803b158015610396575f80fd5b505afa1580156103a8573d5f803e3d5ffd5b50505050505050505050565b6103bc6106ac565b6103c55f610705565b565b6103cf6106ac565b5f838152600260209081526040918290208251808401909352546001600160401b03808216808552600160401b9092046001600160a01b031692840192909252908416101561043157604051632c3631c160e21b815260040160405180910390fd5b6001600160a01b0382166104585760405163a7f9319d60e01b815260040160405180910390fd5b80516001600160401b03808516911610156104e45760208101516001600160a01b0316156104d7575f848152600160208181526040832080549283018155835291829020835191018054928401516001600160a01b0316600160401b026001600160e01b03199093166001600160401b03909216919091179190911790555b6001600160401b03831681525b6001600160a01b0382811660208381018281525f88815260028352604090819020865181549351909616600160401b026001600160e01b03199093166001600160401b0396871617929092179091558051888152938716918401919091528201527f7a98750a395b9ee50a2644ffda039e31f1d5d06de45510275f972bb20b229b309060600160405180910390a150505050565b6001602052815f5260405f208181548110610591575f80fd5b5f918252602090912001546001600160401b0381169250600160401b90046001600160a01b0316905082565b5f6105c85f86610269565b604051636b40634160e01b81529091506001600160a01b03821690636b406341906105fb908790879087906004016109dc565b5f6040518083038186803b158015610611575f80fd5b505afa158015610623573d5f803e3d5ffd5b505050505050505050565b6106366106ac565b6001600160a01b0381166106a05760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b6106a981610705565b50565b5f546001600160a01b031633146103c55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610697565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f8083601f840112610764575f80fd5b5081356001600160401b0381111561077a575f80fd5b602083019150836020828501011115610791575f80fd5b9250929050565b5f805f805f80608087890312156107ad575f80fd5b863595506020870135945060408701356001600160401b03808211156107d1575f80fd5b6107dd8a838b01610754565b909650945060608901359150808211156107f5575f80fd5b5061080289828a01610754565b979a9699509497509295939492505050565b5f8060408385031215610825575f80fd5b50508035926020909101359150565b5f805f805f60808688031215610848575f80fd5b853594506020860135935060408601356001600160401b0381111561086b575f80fd5b61087788828901610754565b96999598509660600135949350505050565b5f60208284031215610899575f80fd5b5035919050565b80356001600160a01b03811681146108b6575f80fd5b919050565b5f805f606084860312156108cd575f80fd5b8335925060208401356001600160401b03811681146108ea575f80fd5b91506108f8604085016108a0565b90509250925092565b5f805f8060608587031215610914575f80fd5b8435935060208501356001600160401b03811115610930575f80fd5b61093c87828801610754565b9598909750949560400135949350505050565b5f6020828403121561095f575f80fd5b610968826108a0565b9392505050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b604081525f6109aa60408301868861096f565b82810360208401526109bd81858761096f565b979650505050505050565b634e487b7160e01b5f52603260045260245ffd5b604081525f6109ef60408301858761096f565b905082602083015294935050505056fea26469706673582212203c5ffe1c0349d16ee19666d69ad4d28dfae1a7bb0906692725186070f9ceb2fd64736f6c63430008180033
Verified Source Code Partial Match
Compiler: v0.8.24+commit.e11b9ed9
EVM: cancun
Optimization: Yes (200 runs)
Context.sol 24 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
IZkEvmVerifier.sol 17 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
interface IZkEvmVerifierV1 {
/// @notice Verify aggregate zk proof.
/// @param aggrProof The aggregated proof.
/// @param publicInputHash The public input hash.
function verify(bytes calldata aggrProof, bytes32 publicInputHash) external view;
}
interface IZkEvmVerifierV2 {
/// @notice Verify bundle zk proof.
/// @param bundleProof The bundle recursion proof.
/// @param publicInput The public input.
function verify(bytes calldata bundleProof, bytes calldata publicInput) external view;
}
Ownable.sol 83 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides 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 {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
IRollupVerifier.sol 41 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/// @title IRollupVerifier
/// @notice The interface for rollup verifier.
interface IRollupVerifier {
/// @notice Verify aggregate zk proof.
/// @param batchIndex The batch index to verify.
/// @param aggrProof The aggregated proof.
/// @param publicInputHash The public input hash.
function verifyAggregateProof(
uint256 batchIndex,
bytes calldata aggrProof,
bytes32 publicInputHash
) external view;
/// @notice Verify aggregate zk proof.
/// @param version The version of verifier to use.
/// @param batchIndex The batch index to verify.
/// @param aggrProof The aggregated proof.
/// @param publicInputHash The public input hash.
function verifyAggregateProof(
uint256 version,
uint256 batchIndex,
bytes calldata aggrProof,
bytes32 publicInputHash
) external view;
/// @notice Verify bundle zk proof.
/// @param version The version of verifier to use.
/// @param batchIndex The batch index used to select verifier.
/// @param bundleProof The aggregated proof.
/// @param publicInput The public input.
function verifyBundleProof(
uint256 version,
uint256 batchIndex,
bytes calldata bundleProof,
bytes calldata publicInput
) external view;
}
MultipleVersionRollupVerifier.sol 177 lines
// SPDX-License-Identifier: MIT
pragma solidity =0.8.24;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {IRollupVerifier} from "../../libraries/verifier/IRollupVerifier.sol";
import {IZkEvmVerifierV1, IZkEvmVerifierV2} from "../../libraries/verifier/IZkEvmVerifier.sol";
/// @title MultipleVersionRollupVerifier
/// @notice Verifies aggregate zk proofs using the appropriate verifier.
contract MultipleVersionRollupVerifier is IRollupVerifier, Ownable {
/**********
* Events *
**********/
/// @notice Emitted when the address of verifier is updated.
/// @param version The version of the verifier.
/// @param startBatchIndex The start batch index when the verifier will be used.
/// @param verifier The address of new verifier.
event UpdateVerifier(uint256 version, uint256 startBatchIndex, address verifier);
/**********
* Errors *
**********/
/// @dev Thrown when the given address is `address(0)`.
error ErrorZeroAddress();
/// @dev Thrown when the given start batch index is smaller than `latestVerifier.startBatchIndex`.
error ErrorStartBatchIndexTooSmall();
/***********
* Structs *
***********/
struct Verifier {
// The start batch index for the verifier.
uint64 startBatchIndex;
// The address of zkevm verifier.
address verifier;
}
/*************
* Variables *
*************/
/// @notice Mapping from verifier version to the list of legacy zkevm verifiers.
/// The verifiers are sorted by batchIndex in increasing order.
mapping(uint256 => Verifier[]) public legacyVerifiers;
/// @notice Mapping from verifier version to the latest used zkevm verifier.
mapping(uint256 => Verifier) public latestVerifier;
/***************
* Constructor *
***************/
constructor(uint256[] memory _versions, address[] memory _verifiers) {
for (uint256 i = 0; i < _versions.length; i++) {
if (_verifiers[i] == address(0)) revert ErrorZeroAddress();
latestVerifier[_versions[i]].verifier = _verifiers[i];
emit UpdateVerifier(_versions[i], 0, _verifiers[i]);
}
}
/*************************
* Public View Functions *
*************************/
/// @notice Return the number of legacy verifiers.
/// @param _version The version of legacy verifiers.
/// @return The number of legacy verifiers.
function legacyVerifiersLength(uint256 _version) external view returns (uint256) {
return legacyVerifiers[_version].length;
}
/// @notice Compute the verifier should be used for specific batch.
/// @param _version The version of verifier to query.
/// @param _batchIndex The batch index to query.
/// @return The address of verifier.
function getVerifier(uint256 _version, uint256 _batchIndex) public view returns (address) {
// Normally, we will use the latest verifier.
Verifier memory _verifier = latestVerifier[_version];
if (_verifier.startBatchIndex > _batchIndex) {
uint256 _length = legacyVerifiers[_version].length;
// In most case, only last few verifier will be used by `ScrollChain`.
// So, we use linear search instead of binary search.
unchecked {
for (uint256 i = _length; i > 0; --i) {
_verifier = legacyVerifiers[_version][i - 1];
if (_verifier.startBatchIndex <= _batchIndex) break;
}
}
}
return _verifier.verifier;
}
/*****************************
* Public Mutating Functions *
*****************************/
/// @inheritdoc IRollupVerifier
function verifyAggregateProof(
uint256 _batchIndex,
bytes calldata _aggrProof,
bytes32 _publicInputHash
) external view override {
address _verifier = getVerifier(0, _batchIndex);
IZkEvmVerifierV1(_verifier).verify(_aggrProof, _publicInputHash);
}
/// @inheritdoc IRollupVerifier
function verifyAggregateProof(
uint256 _version,
uint256 _batchIndex,
bytes calldata _aggrProof,
bytes32 _publicInputHash
) external view override {
address _verifier = getVerifier(_version, _batchIndex);
IZkEvmVerifierV1(_verifier).verify(_aggrProof, _publicInputHash);
}
/// @inheritdoc IRollupVerifier
function verifyBundleProof(
uint256 _version,
uint256 _batchIndex,
bytes calldata _bundleProof,
bytes calldata _publicInput
) external view override {
address _verifier = getVerifier(_version, _batchIndex);
IZkEvmVerifierV2(_verifier).verify(_bundleProof, _publicInput);
}
/************************
* Restricted Functions *
************************/
/// @notice Update the address of zkevm verifier.
/// @param _version The version of the verifier.
/// @param _startBatchIndex The start batch index when the verifier will be used.
/// @param _verifier The address of new verifier.
function updateVerifier(
uint256 _version,
uint64 _startBatchIndex,
address _verifier
) external onlyOwner {
// We are using version to decide the verifier to use and also this function is
// controlled by 7 days TimeLock. It is hard to predict `lastFinalizedBatchIndex` after 7 days.
// So we decide to remove this check to make verifier updating more easier.
// if (_startBatchIndex <= IScrollChain(scrollChain).lastFinalizedBatchIndex())
// revert ErrorStartBatchIndexFinalized();
Verifier memory _latestVerifier = latestVerifier[_version];
if (_startBatchIndex < _latestVerifier.startBatchIndex) revert ErrorStartBatchIndexTooSmall();
if (_verifier == address(0)) revert ErrorZeroAddress();
if (_latestVerifier.startBatchIndex < _startBatchIndex) {
// don't push when it is the first update of the version.
if (_latestVerifier.verifier != address(0)) {
legacyVerifiers[_version].push(_latestVerifier);
}
_latestVerifier.startBatchIndex = _startBatchIndex;
}
_latestVerifier.verifier = _verifier;
latestVerifier[_version] = _latestVerifier;
emit UpdateVerifier(_version, _startBatchIndex, _verifier);
}
}
Read Contract
getVerifier 0x28aee03f → address
latestVerifier 0xc7065b6a → uint64, address
legacyVerifiers 0xbd98b2b0 → uint64, address
legacyVerifiersLength 0x5027ad2e → uint256
owner 0x8da5cb5b → address
verifyAggregateProof 0x2c09a848
verifyAggregateProof 0xcc780aa1
verifyBundleProof 0x22a262c9
Write Contract 3 functions
These functions modify contract state and require a wallet transaction to execute.
renounceOwnership 0x715018a6
No parameters
transferOwnership 0xf2fde38b
address newOwner
updateVerifier 0x95512306
uint256 _version
uint64 _startBatchIndex
address _verifier
Recent Transactions
This address has 1 on-chain transactions, but only 1.3% of the chain is indexed. Transactions will appear as indexing progresses. View on Etherscan →