Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
GENESIS at txn GENESIS_5300000000000000000000000000000000000000
Multichain Info
N/A
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
6885276 | 11 mins ago | 0 ETH | ||||
6885276 | 11 mins ago | 0 ETH | ||||
6884298 | 2 hrs ago | 0 ETH | ||||
6884298 | 2 hrs ago | 0 ETH | ||||
6884037 | 2 hrs ago | 0 ETH | ||||
6884037 | 2 hrs ago | 0 ETH | ||||
6883963 | 2 hrs ago | 0 ETH | ||||
6883963 | 2 hrs ago | 0 ETH | ||||
6883224 | 4 hrs ago | 0 ETH | ||||
6883224 | 4 hrs ago | 0 ETH | ||||
6883154 | 4 hrs ago | 0 ETH | ||||
6883154 | 4 hrs ago | 0 ETH | ||||
6883011 | 4 hrs ago | 0 ETH | ||||
6883011 | 4 hrs ago | 0 ETH | ||||
6882899 | 4 hrs ago | 0 ETH | ||||
6882899 | 4 hrs ago | 0 ETH | ||||
6882765 | 4 hrs ago | 0 ETH | ||||
6882765 | 4 hrs ago | 0 ETH | ||||
6882713 | 4 hrs ago | 0 ETH | ||||
6882713 | 4 hrs ago | 0 ETH | ||||
6882472 | 5 hrs ago | 0 ETH | ||||
6882472 | 5 hrs ago | 0 ETH | ||||
6882205 | 5 hrs ago | 0 ETH | ||||
6882205 | 5 hrs ago | 0 ETH | ||||
6881397 | 7 hrs ago | 0 ETH |
Loading...
Loading
Contract Name:
L2MessageQueue
Compiler Version
v0.8.16+commit.07a7930e
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity =0.8.16; import {AppendOnlyMerkleTree} from "../../libraries/common/AppendOnlyMerkleTree.sol"; import {OwnableBase} from "../../libraries/common/OwnableBase.sol"; /// @title L2MessageQueue /// @notice The original idea is from Optimism, see [OVM_L2ToL1MessagePasser](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/predeploys/OVM_L2ToL1MessagePasser.sol). /// The L2 to L1 Message Passer is a utility contract which facilitate an L1 proof of the /// of a message on L2. The L1 Cross Domain Messenger performs this proof in its /// _verifyStorageProof function, which verifies the existence of the transaction hash in this /// contract's `sentMessages` mapping. contract L2MessageQueue is AppendOnlyMerkleTree, OwnableBase { /********** * Events * **********/ /// @notice Emitted when a new message is added to the merkle tree. /// @param index The index of the corresponding message. /// @param messageHash The hash of the corresponding message. event AppendMessage(uint256 index, bytes32 messageHash); /************* * Variables * *************/ /// @notice The address of L2ScrollMessenger contract. address public messenger; /*************** * Constructor * ***************/ constructor(address _owner) { _transferOwnership(_owner); } /// @notice Initialize the state of `L2MessageQueue` /// @dev You are not allowed to initialize when there are some messages appended. /// @param _messenger The address of messenger to update. function initialize(address _messenger) external onlyOwner { require(nextMessageIndex == 0, "cannot initialize"); _initializeMerkleTree(); messenger = _messenger; } /***************************** * Public Mutating Functions * *****************************/ /// @notice record the message to merkle tree and compute the new root. /// @param _messageHash The hash of the new added message. function appendMessage(bytes32 _messageHash) external returns (bytes32) { require(msg.sender == messenger, "only messenger"); (uint256 _currentNonce, bytes32 _currentRoot) = _appendMessageHash(_messageHash); // We can use the event to compute the merkle tree locally. emit AppendMessage(_currentNonce, _messageHash); return _currentRoot; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; abstract contract AppendOnlyMerkleTree { /// @dev The maximum height of the withdraw merkle tree. uint256 private constant MAX_TREE_HEIGHT = 40; /// @notice The merkle root of the current merkle tree. /// @dev This is actual equal to `branches[n]`. bytes32 public messageRoot; /// @notice The next unused message index. uint256 public nextMessageIndex; /// @notice The list of zero hash in each height. bytes32[MAX_TREE_HEIGHT] private zeroHashes; /// @notice The list of minimum merkle proofs needed to compute next root. /// @dev Only first `n` elements are used, where `n` is the minimum value that `2^{n-1} >= currentMaxNonce + 1`. /// It means we only use `currentMaxNonce + 1` leaf nodes to construct the merkle tree. bytes32[MAX_TREE_HEIGHT] public branches; function _initializeMerkleTree() internal { // Compute hashes in empty sparse Merkle tree for (uint256 height = 0; height + 1 < MAX_TREE_HEIGHT; height++) { zeroHashes[height + 1] = _efficientHash(zeroHashes[height], zeroHashes[height]); } } function _appendMessageHash(bytes32 _messageHash) internal returns (uint256, bytes32) { require(zeroHashes[1] != bytes32(0), "call before initialization"); uint256 _currentMessageIndex = nextMessageIndex; bytes32 _hash = _messageHash; uint256 _height = 0; while (_currentMessageIndex != 0) { if (_currentMessageIndex % 2 == 0) { // it may be used in next round. branches[_height] = _hash; // it's a left child, the right child must be null _hash = _efficientHash(_hash, zeroHashes[_height]); } else { // it's a right child, use previously computed hash _hash = _efficientHash(branches[_height], _hash); } unchecked { _height += 1; } _currentMessageIndex >>= 1; } branches[_height] = _hash; messageRoot = _hash; _currentMessageIndex = nextMessageIndex; unchecked { nextMessageIndex = _currentMessageIndex + 1; } return (_currentMessageIndex, _hash); } function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { // solhint-disable-next-line no-inline-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; abstract contract OwnableBase { /********** * Events * **********/ /// @notice Emitted when owner is changed by current owner. /// @param _oldOwner The address of previous owner. /// @param _newOwner The address of new owner. event OwnershipTransferred(address indexed _oldOwner, address indexed _newOwner); /************* * Variables * *************/ /// @notice The address of the current owner. address public owner; /********************** * Function Modifiers * **********************/ /// @dev Throws if called by any account other than the owner. modifier onlyOwner() { require(owner == msg.sender, "caller is not the owner"); _; } /************************ * Restricted Functions * ************************/ /// @notice Leaves the contract without owner. It will not be possible to call /// `onlyOwner` functions anymore. Can only be called by the current owner. /// /// @dev Renouncing ownership will leave the contract without an owner, /// thereby removing any functionality that is only available to the owner. function renounceOwnership() public onlyOwner { _transferOwnership(address(0)); } /// @notice Transfers ownership of the contract to a new account (`newOwner`). /// Can only be called by the current owner. function transferOwnership(address _newOwner) public onlyOwner { require(_newOwner != address(0), "new owner is the zero address"); _transferOwnership(_newOwner); } /********************** * Internal Functions * **********************/ /// @dev Transfers ownership of the contract to a new account (`newOwner`). /// Internal function without access restriction. function _transferOwnership(address _newOwner) internal { address _oldOwner = owner; owner = _newOwner; emit OwnershipTransferred(_oldOwner, _newOwner); } }
{ "remappings": [ "@openzeppelin/=node_modules/@openzeppelin/", "ds-test/=lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "hardhat/=node_modules/hardhat/", "solmate/=lib/solmate/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs" }, "outputSelection": { "*": { "": [ "ast" ], "*": [ "abi", "evm.bytecode", "evm.deployedBytecode", "evm.methodIdentifiers", "metadata" ] } }, "evmVersion": "london", "libraries": {} }
[{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"messageHash","type":"bytes32"}],"name":"AppendMessage","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"_newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"bytes32","name":"_messageHash","type":"bytes32"}],"name":"appendMessage","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"branches","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_messenger","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"messageRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"messenger","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextMessageIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50600436106100935760003560e01c806383cc76601161006657806383cc7660146100fc5780638da5cb5b1461010f578063c4d66de814610122578063d4b9f4fa14610135578063f2fde38b1461013e57600080fd5b806326aad7b7146100985780633cb747bf146100b4578063600a2e77146100df578063715018a6146100f2575b600080fd5b6100a160015481565b6040519081526020015b60405180910390f35b6053546100c7906001600160a01b031681565b6040516001600160a01b0390911681526020016100ab565b6100a16100ed36600461054a565b610151565b6100fa6101f6565b005b6100a161010a36600461054a565b61022c565b6052546100c7906001600160a01b031681565b6100fa610130366004610563565b610243565b6100a160005481565b6100fa61014c366004610563565b6102db565b6053546000906001600160a01b031633146101a45760405162461bcd60e51b815260206004820152600e60248201526d37b7363c9036b2b9b9b2b733b2b960911b60448201526064015b60405180910390fd5b6000806101b084610367565b60408051838152602081018890529294509092507ffaa617c2d8ce12c62637dbce76efcc18dae60574aa95709bdcedce7e76071693910160405180910390a19392505050565b6052546001600160a01b031633146102205760405162461bcd60e51b815260040161019b90610593565b61022a6000610486565b565b602a816028811061023c57600080fd5b0154905081565b6052546001600160a01b0316331461026d5760405162461bcd60e51b815260040161019b90610593565b600154156102b15760405162461bcd60e51b815260206004820152601160248201527063616e6e6f7420696e697469616c697a6560781b604482015260640161019b565b6102b96104d8565b605380546001600160a01b0319166001600160a01b0392909216919091179055565b6052546001600160a01b031633146103055760405162461bcd60e51b815260040161019b90610593565b6001600160a01b03811661035b5760405162461bcd60e51b815260206004820152601d60248201527f6e6577206f776e657220697320746865207a65726f2061646472657373000000604482015260640161019b565b61036481610486565b50565b60035460009081906103bb5760405162461bcd60e51b815260206004820152601a60248201527f63616c6c206265666f726520696e697469616c697a6174696f6e000000000000604482015260640161019b565b6001548360005b8215610456576103d36002846105e0565b60000361041f5781602a82602881106103ee576103ee6105ca565b01556104188260028360288110610407576104076105ca565b015460009182526020526040902090565b915061044a565b610447602a8260288110610435576104356105ca565b01548360009182526020526040902090565b91505b600192831c92016103c2565b81602a826028811061046a5761046a6105ca565b0155506000819055600180548082019091559590945092505050565b605280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60005b60286104e8826001610618565b10156103645761051960028260288110610504576105046105ca565b015460028360288110610407576104076105ca565b6002610526836001610618565b60288110610536576105366105ca565b01558061054281610631565b9150506104db565b60006020828403121561055c57600080fd5b5035919050565b60006020828403121561057557600080fd5b81356001600160a01b038116811461058c57600080fd5b9392505050565b60208082526017908201527f63616c6c6572206973206e6f7420746865206f776e6572000000000000000000604082015260600190565b634e487b7160e01b600052603260045260246000fd5b6000826105fd57634e487b7160e01b600052601260045260246000fd5b500690565b634e487b7160e01b600052601160045260246000fd5b8082018082111561062b5761062b610602565b92915050565b60006001820161064357610643610602565b506001019056fea26469706673582212208fb1cb9933bb17dd0a7c17de7c890919b08d2fd7eb2bede7b41caa32709b30b564736f6c63430008100033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100935760003560e01c806383cc76601161006657806383cc7660146100fc5780638da5cb5b1461010f578063c4d66de814610122578063d4b9f4fa14610135578063f2fde38b1461013e57600080fd5b806326aad7b7146100985780633cb747bf146100b4578063600a2e77146100df578063715018a6146100f2575b600080fd5b6100a160015481565b6040519081526020015b60405180910390f35b6053546100c7906001600160a01b031681565b6040516001600160a01b0390911681526020016100ab565b6100a16100ed36600461054a565b610151565b6100fa6101f6565b005b6100a161010a36600461054a565b61022c565b6052546100c7906001600160a01b031681565b6100fa610130366004610563565b610243565b6100a160005481565b6100fa61014c366004610563565b6102db565b6053546000906001600160a01b031633146101a45760405162461bcd60e51b815260206004820152600e60248201526d37b7363c9036b2b9b9b2b733b2b960911b60448201526064015b60405180910390fd5b6000806101b084610367565b60408051838152602081018890529294509092507ffaa617c2d8ce12c62637dbce76efcc18dae60574aa95709bdcedce7e76071693910160405180910390a19392505050565b6052546001600160a01b031633146102205760405162461bcd60e51b815260040161019b90610593565b61022a6000610486565b565b602a816028811061023c57600080fd5b0154905081565b6052546001600160a01b0316331461026d5760405162461bcd60e51b815260040161019b90610593565b600154156102b15760405162461bcd60e51b815260206004820152601160248201527063616e6e6f7420696e697469616c697a6560781b604482015260640161019b565b6102b96104d8565b605380546001600160a01b0319166001600160a01b0392909216919091179055565b6052546001600160a01b031633146103055760405162461bcd60e51b815260040161019b90610593565b6001600160a01b03811661035b5760405162461bcd60e51b815260206004820152601d60248201527f6e6577206f776e657220697320746865207a65726f2061646472657373000000604482015260640161019b565b61036481610486565b50565b60035460009081906103bb5760405162461bcd60e51b815260206004820152601a60248201527f63616c6c206265666f726520696e697469616c697a6174696f6e000000000000604482015260640161019b565b6001548360005b8215610456576103d36002846105e0565b60000361041f5781602a82602881106103ee576103ee6105ca565b01556104188260028360288110610407576104076105ca565b015460009182526020526040902090565b915061044a565b610447602a8260288110610435576104356105ca565b01548360009182526020526040902090565b91505b600192831c92016103c2565b81602a826028811061046a5761046a6105ca565b0155506000819055600180548082019091559590945092505050565b605280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60005b60286104e8826001610618565b10156103645761051960028260288110610504576105046105ca565b015460028360288110610407576104076105ca565b6002610526836001610618565b60288110610536576105366105ca565b01558061054281610631565b9150506104db565b60006020828403121561055c57600080fd5b5035919050565b60006020828403121561057557600080fd5b81356001600160a01b038116811461058c57600080fd5b9392505050565b60208082526017908201527f63616c6c6572206973206e6f7420746865206f776e6572000000000000000000604082015260600190565b634e487b7160e01b600052603260045260246000fd5b6000826105fd57634e487b7160e01b600052601260045260246000fd5b500690565b634e487b7160e01b600052601160045260246000fd5b8082018082111561062b5761062b610602565b92915050565b60006001820161064357610643610602565b506001019056fea26469706673582212208fb1cb9933bb17dd0a7c17de7c890919b08d2fd7eb2bede7b41caa32709b30b564736f6c63430008100033
Loading...
Loading
Loading...
Loading
[ 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.