ETH Price: $2,592.00 (-1.84%)
Gas: 4 Gwei

Contract

0x2A34E6cae749876FB8952aD7d2fA486b00F0683F
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Set Executor183731712023-10-17 22:48:11296 days ago1697582891IN
0x2A34E6ca...b00F0683F
0 ETH0.0004504910.21990129
0x60e06040183731692023-10-17 22:47:47296 days ago1697582867IN
 Create: MessageDispatcherOptimism
0 ETH0.008887610.88882709

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
MessageDispatcherOptimism

Compiler Version
v0.8.16+commit.07a7930e

Optimization Enabled:
Yes with 200 runs

Other Settings:
london EvmVersion
File 1 of 7 : EthereumToOptimismDispatcher.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.16;

import { ICrossDomainMessenger } from "../vendor/optimism/ICrossDomainMessenger.sol";

import { IMessageExecutor } from "../interfaces/IMessageExecutor.sol";
import { IMessageDispatcher, ISingleMessageDispatcher } from "../interfaces/ISingleMessageDispatcher.sol";
import { IBatchedMessageDispatcher } from "../interfaces/IBatchedMessageDispatcher.sol";

import { MessageLib } from "../libraries/MessageLib.sol";

/**
 * @title MessageDispatcherOptimism contract
 * @notice The MessageDispatcherOptimism contract allows a user or contract to send messages from Ethereum to Optimism.
 *         It lives on the Ethereum chain and communicates with the `MessageExecutorOptimism` contract on the Optimism chain.
 */
contract MessageDispatcherOptimism is ISingleMessageDispatcher, IBatchedMessageDispatcher {
  /* ============ Variables ============ */

  /// @notice Address of the Optimism cross domain messenger on the Ethereum chain.
  ICrossDomainMessenger public immutable crossDomainMessenger;

  /// @notice Address of the executor contract on the Optimism chain.
  IMessageExecutor internal executor;

  /// @notice Nonce used to compute unique `messageId`s.
  uint256 internal nonce;

  /// @notice ID of the chain receiving the dispatched messages. i.e.: 10 for Mainnet, 420 for Goerli.
  uint256 internal immutable toChainId;

  /// @notice Gas limit at which the transaction is executed on L2 when calling `dispatchMessage`.
  uint32 internal immutable gasLimit;

  /* ============ Constructor ============ */

  /**
   * @notice MessageDispatcherOptimism constructor.
   * @param _crossDomainMessenger Address of the Optimism cross domain messenger
   * @param _toChainId ID of the chain receiving the dispatched messages
   * @param _gasLimit Gas limit at which the transaction is executed on L2 when calling `dispatchMessage`
   */
  constructor(ICrossDomainMessenger _crossDomainMessenger, uint256 _toChainId, uint32 _gasLimit) {
    require(address(_crossDomainMessenger) != address(0), "Dispatcher/CDM-not-zero-address");
    require(_toChainId != 0, "Dispatcher/chainId-not-zero");

    crossDomainMessenger = _crossDomainMessenger;
    toChainId = _toChainId;
    gasLimit = _gasLimit;
  }

  /* ============ External Functions ============ */

  /// @inheritdoc ISingleMessageDispatcher
  function dispatchMessage(
    uint256 _toChainId,
    address _to,
    bytes calldata _data
  ) external returns (bytes32) {
    return _dispatchMessage(_toChainId, _to, _data, gasLimit);
  }

  /**
   * @notice Dispatch and process a message to the receiving chain.
   * @dev Must compute and return an ID uniquely identifying the message.
   * @dev Must emit the `MessageDispatched` event when successfully dispatched.
   * @param _toChainId ID of the receiving chain
   * @param _to Address on the receiving chain that will receive `data`
   * @param _data Data dispatched to the receiving chain
   * @param _gasLimit Gas limit at which the message will be executed on Optimism
   * @return bytes32 ID uniquely identifying the message
   */
  function dispatchMessageWithGasLimit(
    uint256 _toChainId,
    address _to,
    bytes calldata _data,
    uint32 _gasLimit
  ) external returns (bytes32) {
    return _dispatchMessage(_toChainId, _to, _data, _gasLimit);
  }

  /// @inheritdoc IBatchedMessageDispatcher
  function dispatchMessageBatch(
    uint256 _toChainId,
    MessageLib.Message[] calldata _messages
  ) external returns (bytes32) {
    return _dispatchMessageBatch(_toChainId, _messages, gasLimit);
  }

  /**
   * @notice Dispatch and process `messages` to the receiving chain.
   * @dev Must compute and return an ID uniquely identifying the `messages`.
   * @dev Must emit the `MessageBatchDispatched` event when successfully dispatched.
   * @param _toChainId ID of the receiving chain
   * @param _messages Array of Message dispatched
   * @param _gasLimit Gas limit at which the message will be executed on Optimism
   * @return bytes32 ID uniquely identifying the `messages`
   */
  function dispatchMessageWithGasLimitBatch(
    uint256 _toChainId,
    MessageLib.Message[] calldata _messages,
    uint32 _gasLimit
  ) external returns (bytes32) {
    return _dispatchMessageBatch(_toChainId, _messages, _gasLimit);
  }

  /// @inheritdoc IMessageDispatcher
  function getMessageExecutorAddress(uint256 _toChainId) external view returns (address) {
    return _getMessageExecutorAddress(_toChainId);
  }

  /**
   * @notice Set executor contract address.
   * @dev Will revert if it has already been set.
   * @param _executor Address of the executor contract on the Optimism chain
   */
  function setExecutor(IMessageExecutor _executor) external {
    require(address(executor) == address(0), "Dispatcher/executor-already-set");
    executor = _executor;
  }

  /* ============ Internal Functions ============ */

  /* ============ Require Functions ============ */

  /**
   * @notice Check toChainId to ensure messages can be dispatched to this chain.
   * @dev Will revert if `_toChainId` is not supported.
   * @param _toChainId ID of the chain receiving the message
   */
  function _checkToChainId(uint256 _toChainId) internal view {
    require(_toChainId == toChainId, "Dispatcher/chainId-not-supported");
  }

  /**
   * @notice Check dispatch parameters to ensure messages can be dispatched.
   * @dev Will revert if `executor` is not set.
   * @param _executor Address of the executor contract on the Optimism chain
   */
  function _checkExecutor(address _executor) internal pure {
    require(_executor != address(0), "Dispatcher/executor-not-set");
  }

  /* ============ Getter Functions ============ */

  /**
   * @notice Retrieves address of the MessageExecutor contract on the receiving chain.
   * @dev Will revert if `_toChainId` is not supported.
   * @param _toChainId ID of the chain with which MessageDispatcher is communicating
   * @return address MessageExecutor contract address
   */
  function _getMessageExecutorAddress(uint256 _toChainId) internal view returns (address) {
    _checkToChainId(_toChainId);
    return address(executor);
  }

  /* ============ State Functions ============ */

  /**
   * @notice Helper to increment nonce.
   * @return uint256 Incremented nonce
   */
  function _incrementNonce() internal returns (uint256) {
    unchecked {
      nonce++;
    }

    return nonce;
  }

  /* ============ Dispatch Functions ============ */

  /**
   * @notice Dispatch a message to the receiving chain.
   * @dev Must compute and return an ID uniquely identifying the message.
   * @dev Must emit the `MessageDispatched` event when successfully dispatched.
   * @param _toChainId ID of the receiving chain
   * @param _to Address on the receiving chain that will receive `data`
   * @param _data Data dispatched to the receiving chain
   * @param _gasLimit Gas limit at which the message will be executed on Optimism
   * @return bytes32 ID uniquely identifying the message
   */
  function _dispatchMessage(
    uint256 _toChainId,
    address _to,
    bytes calldata _data,
    uint32 _gasLimit
  ) internal returns (bytes32) {
    address _executorAddress = _getMessageExecutorAddress(_toChainId);
    _checkExecutor(_executorAddress);

    uint256 _nonce = _incrementNonce();
    bytes32 _messageId = MessageLib.computeMessageId(_nonce, msg.sender, _to, _data);

    _sendMessage(
      _executorAddress,
      MessageLib.encodeMessage(_to, _data, _messageId, block.chainid, msg.sender),
      _gasLimit
    );

    emit MessageDispatched(_messageId, msg.sender, _toChainId, _to, _data);

    return _messageId;
  }

  /**
   * @notice Dispatch `messages` to the receiving chain.
   * @dev Must compute and return an ID uniquely identifying the `messages`.
   * @dev Must emit the `MessageBatchDispatched` event when successfully dispatched.
   * @param _toChainId ID of the receiving chain
   * @param _messages Array of Message dispatched
   * @param _gasLimit Gas limit at which the messages will be executed on Optimism
   * @return bytes32 ID uniquely identifying the `messages`
   */
  function _dispatchMessageBatch(
    uint256 _toChainId,
    MessageLib.Message[] calldata _messages,
    uint32 _gasLimit
  ) internal returns (bytes32) {
    address _executorAddress = _getMessageExecutorAddress(_toChainId);
    _checkExecutor(_executorAddress);

    uint256 _nonce = _incrementNonce();
    bytes32 _messageId = MessageLib.computeMessageBatchId(_nonce, msg.sender, _messages);

    _sendMessage(
      _executorAddress,
      MessageLib.encodeMessageBatch(_messages, _messageId, block.chainid, msg.sender),
      _gasLimit
    );

    emit MessageBatchDispatched(_messageId, msg.sender, _toChainId, _messages);

    return _messageId;
  }

  /**
   * @notice Dispatch message to Optimism chain.
   * @param _executor Address of the executor contract on the Optimism chain
   * @param _message Message dispatched
   * @param _gasLimit Gas limit at which the message will be executed on Optimism
   */
  function _sendMessage(address _executor, bytes memory _message, uint32 _gasLimit) internal {
    crossDomainMessenger.sendMessage(_executor, _message, _gasLimit);
  }
}

File 2 of 7 : ICrossDomainMessenger.sol
pragma solidity ^0.8.16;

// Right now this is copy/pasted from the contracts package. We need to do this because we don't
// currently copy the contracts into the root of the contracts package in the correct way until
// we bundle the contracts package for publication. As a result, we can't properly use the
// package the way we want to from inside the monorepo (yet). Needs to be fixed as part of a
// separate pull request.

interface ICrossDomainMessenger {
  /**********
   * Events *
   **********/

  event SentMessage(
    address indexed target,
    address sender,
    bytes message,
    uint256 messageNonce,
    uint256 gasLimit
  );
  event RelayedMessage(bytes32 indexed msgHash);
  event FailedRelayedMessage(bytes32 indexed msgHash);

  /*************
   * Variables *
   *************/

  function xDomainMessageSender() external view returns (address);

  function messageNonce() external view returns (uint256);

  /********************
   * Public Functions *
   ********************/

  /**
   * Sends a cross domain message to the target messenger.
   * @param _target Target contract address.
   * @param _message Message to send to the target.
   * @param _gasLimit Gas limit for the provided message.
   */
  function sendMessage(address _target, bytes calldata _message, uint32 _gasLimit) external;

  /// @notice Relays a message that was sent by the other CrossDomainMessenger contract. Can only
  ///         be executed via cross-chain call from the other messenger OR if the message was
  ///         already received once and is currently being replayed.
  /// @param _nonce       Nonce of the message being relayed.
  /// @param _sender      Address of the user who sent the message.
  /// @param _target      Address that the message is targeted at.
  /// @param _value       ETH value to send with the message.
  /// @param _minGasLimit Minimum amount of gas that the message can be executed with.
  /// @param _message     Message to send to the target.
  function relayMessage(
    uint256 _nonce,
    address _sender,
    address _target,
    uint256 _value,
    uint256 _minGasLimit,
    bytes calldata _message
  ) external payable;
}

File 3 of 7 : IMessageExecutor.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.16;

import { MessageLib } from "../libraries/MessageLib.sol";

/**
 * @title MessageExecutor interface
 * @notice MessageExecutor interface of the ERC-5164 standard as defined in the EIP.
 */
interface IMessageExecutor {
  /**
   * @notice Emitted when a message has successfully been executed.
   * @param fromChainId ID of the chain that dispatched the message
   * @param messageId ID uniquely identifying the message that was executed
   */
  event MessageIdExecuted(uint256 indexed fromChainId, bytes32 indexed messageId);

  /**
   * @notice Execute message from the origin chain.
   * @dev Should authenticate that the call has been performed by the bridge transport layer.
   * @dev Must revert if the message fails.
   * @dev Must emit the `MessageIdExecuted` event once the message has been executed.
   * @param to Address that will receive `data`
   * @param data Data forwarded to address `to`
   * @param messageId ID uniquely identifying the message
   * @param fromChainId ID of the chain that dispatched the message
   * @param from Address of the sender on the origin chain
   */
  function executeMessage(
    address to,
    bytes calldata data,
    bytes32 messageId,
    uint256 fromChainId,
    address from
  ) external;

  /**
   * @notice Execute a batch messages from the origin chain.
   * @dev Should authenticate that the call has been performed by the bridge transport layer.
   * @dev Must revert if one of the messages fails.
   * @dev Must emit the `MessageIdExecuted` event once messages have been executed.
   * @param messages Array of messages being executed
   * @param messageId ID uniquely identifying the messages
   * @param fromChainId ID of the chain that dispatched the messages
   * @param from Address of the sender on the origin chain
   */
  function executeMessageBatch(
    MessageLib.Message[] calldata messages,
    bytes32 messageId,
    uint256 fromChainId,
    address from
  ) external;
}

File 4 of 7 : ISingleMessageDispatcher.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.16;

import { IMessageDispatcher } from "./IMessageDispatcher.sol";

/**
 * @title ERC-5164: Cross-Chain Execution Standard, optional SingleMessageDispatcher extension
 * @dev See https://eips.ethereum.org/EIPS/eip-5164
 */
interface ISingleMessageDispatcher is IMessageDispatcher {
  /**
   * @notice Dispatch a message to the receiving chain.
   * @dev Must compute and return an ID uniquely identifying the message.
   * @dev Must emit the `MessageDispatched` event when successfully dispatched.
   * @param toChainId ID of the receiving chain
   * @param to Address on the receiving chain that will receive `data`
   * @param data Data dispatched to the receiving chain
   * @return bytes32 ID uniquely identifying the message
   */
  function dispatchMessage(
    uint256 toChainId,
    address to,
    bytes calldata data
  ) external returns (bytes32);
}

File 5 of 7 : IBatchedMessageDispatcher.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.16;

import { IMessageDispatcher } from "./IMessageDispatcher.sol";
import { MessageLib } from "../../src/libraries/MessageLib.sol";

/**
 * @title ERC-5164: Cross-Chain Execution Standard, optional BatchMessageDispatcher extension
 * @dev See https://eips.ethereum.org/EIPS/eip-5164
 */
interface IBatchedMessageDispatcher is IMessageDispatcher {
  /**
   * @notice Dispatch `messages` to the receiving chain.
   * @dev Must compute and return an ID uniquely identifying the `messages`.
   * @dev Must emit the `MessageBatchDispatched` event when successfully dispatched.
   * @param toChainId ID of the receiving chain
   * @param messages Array of Message dispatched
   * @return bytes32 ID uniquely identifying the `messages`
   */
  function dispatchMessageBatch(
    uint256 toChainId,
    MessageLib.Message[] calldata messages
  ) external returns (bytes32);
}

File 6 of 7 : MessageLib.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.16;

import { IMessageExecutor } from "../interfaces/IMessageExecutor.sol";

/**
 * @title MessageLib
 * @notice Library to declare and manipulate Message(s).
 */
library MessageLib {
  /* ============ Structs ============ */

  /**
   * @notice Message data structure
   * @param to Address that will be dispatched on the receiving chain
   * @param data Data that will be sent to the `to` address
   */
  struct Message {
    address to;
    bytes data;
  }

  /* ============ Events ============ */

  /* ============ Custom Errors ============ */

  /**
   * @notice Emitted when a messageId has already been executed.
   * @param messageId ID uniquely identifying the message or message batch that were re-executed
   */
  error MessageIdAlreadyExecuted(bytes32 messageId);

  /**
   * @notice Emitted if a call to a contract fails.
   * @param messageId ID uniquely identifying the message
   * @param errorData Error data returned by the call
   */
  error MessageFailure(bytes32 messageId, bytes errorData);

  /**
   * @notice Emitted if a call to a contract fails inside a batch of messages.
   * @param messageId ID uniquely identifying the batch of messages
   * @param messageIndex Index of the message
   * @param errorData Error data returned by the call
   */
  error MessageBatchFailure(bytes32 messageId, uint256 messageIndex, bytes errorData);

  /* ============ Internal Functions ============ */

  /**
   * @notice Helper to compute messageId.
   * @param nonce Monotonically increased nonce to ensure uniqueness
   * @param from Address that dispatched the message
   * @param to Address that will receive the message
   * @param data Data that was dispatched
   * @return bytes32 ID uniquely identifying the message that was dispatched
   */
  function computeMessageId(
    uint256 nonce,
    address from,
    address to,
    bytes memory data
  ) internal pure returns (bytes32) {
    return keccak256(abi.encode(nonce, from, to, data));
  }

  /**
   * @notice Helper to compute messageId for a batch of messages.
   * @param nonce Monotonically increased nonce to ensure uniqueness
   * @param from Address that dispatched the messages
   * @param messages Array of Message dispatched
   * @return bytes32 ID uniquely identifying the message that was dispatched
   */
  function computeMessageBatchId(
    uint256 nonce,
    address from,
    Message[] memory messages
  ) internal pure returns (bytes32) {
    return keccak256(abi.encode(nonce, from, messages));
  }

  /**
   * @notice Helper to encode message for execution by the MessageExecutor.
   * @param to Address that will receive the message
   * @param data Data that will be dispatched
   * @param messageId ID uniquely identifying the message being dispatched
   * @param fromChainId ID of the chain that dispatched the message
   * @param from Address that dispatched the message
   */
  function encodeMessage(
    address to,
    bytes memory data,
    bytes32 messageId,
    uint256 fromChainId,
    address from
  ) internal pure returns (bytes memory) {
    return
      abi.encodeCall(IMessageExecutor.executeMessage, (to, data, messageId, fromChainId, from));
  }

  /**
   * @notice Helper to encode a batch of messages for execution by the MessageExecutor.
   * @param messages Array of Message that will be dispatched
   * @param messageId ID uniquely identifying the batch of messages being dispatched
   * @param fromChainId ID of the chain that dispatched the batch of messages
   * @param from Address that dispatched the batch of messages
   */
  function encodeMessageBatch(
    Message[] memory messages,
    bytes32 messageId,
    uint256 fromChainId,
    address from
  ) internal pure returns (bytes memory) {
    return
      abi.encodeCall(
        IMessageExecutor.executeMessageBatch,
        (messages, messageId, fromChainId, from)
      );
  }

  /**
   * @notice Execute message from the origin chain.
   * @dev Will revert if `message` has already been executed.
   * @param to Address that will receive the message
   * @param data Data that was dispatched
   * @param messageId ID uniquely identifying message
   * @param fromChainId ID of the chain that dispatched the `message`
   * @param from Address of the sender on the origin chain
   * @param executedMessageId Whether `message` has already been executed or not
   */
  function executeMessage(
    address to,
    bytes memory data,
    bytes32 messageId,
    uint256 fromChainId,
    address from,
    bool executedMessageId
  ) internal {
    if (executedMessageId) {
      revert MessageIdAlreadyExecuted(messageId);
    }

    _requireContract(to);

    (bool _success, bytes memory _returnData) = to.call(
      abi.encodePacked(data, messageId, fromChainId, from)
    );

    if (!_success) {
      revert MessageFailure(messageId, _returnData);
    }
  }

  /**
   * @notice Execute messages from the origin chain.
   * @dev Will revert if `messages` have already been executed.
   * @param messages Array of messages being executed
   * @param messageId Nonce to uniquely identify the messages
   * @param from Address of the sender on the origin chain
   * @param fromChainId ID of the chain that dispatched the `messages`
   * @param executedMessageId Whether `messages` have already been executed or not
   */
  function executeMessageBatch(
    Message[] memory messages,
    bytes32 messageId,
    uint256 fromChainId,
    address from,
    bool executedMessageId
  ) internal {
    if (executedMessageId) {
      revert MessageIdAlreadyExecuted(messageId);
    }

    uint256 _messagesLength = messages.length;

    for (uint256 _messageIndex; _messageIndex < _messagesLength; ) {
      Message memory _message = messages[_messageIndex];
      _requireContract(_message.to);

      (bool _success, bytes memory _returnData) = _message.to.call(
        abi.encodePacked(_message.data, messageId, fromChainId, from)
      );

      if (!_success) {
        revert MessageBatchFailure(messageId, _messageIndex, _returnData);
      }

      unchecked {
        _messageIndex++;
      }
    }
  }

  /**
   * @notice Check that the call is being made to a contract.
   * @param to Address to check
   */
  function _requireContract(address to) internal view {
    require(to.code.length > 0, "MessageLib/no-contract-at-to");
  }
}

File 7 of 7 : IMessageDispatcher.sol
// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.16;

import { MessageLib } from "../libraries/MessageLib.sol";

/**
 * @title ERC-5164: Cross-Chain Execution Standard
 * @dev See https://eips.ethereum.org/EIPS/eip-5164
 */
interface IMessageDispatcher {
  /**
   * @notice Emitted when a message has successfully been dispatched to the executor chain.
   * @param messageId ID uniquely identifying the message
   * @param from Address that dispatched the message
   * @param toChainId ID of the chain receiving the message
   * @param to Address that will receive the message
   * @param data Data that was dispatched
   */
  event MessageDispatched(
    bytes32 indexed messageId,
    address indexed from,
    uint256 indexed toChainId,
    address to,
    bytes data
  );

  /**
   * @notice Emitted when a batch of messages has successfully been dispatched to the executor chain.
   * @param messageId ID uniquely identifying the messages
   * @param from Address that dispatched the messages
   * @param toChainId ID of the chain receiving the messages
   * @param messages Array of Message that was dispatched
   */
  event MessageBatchDispatched(
    bytes32 indexed messageId,
    address indexed from,
    uint256 indexed toChainId,
    MessageLib.Message[] messages
  );

  /**
   * @notice Retrieves address of the MessageExecutor contract on the receiving chain.
   * @dev Must revert if `toChainId` is not supported.
   * @param toChainId ID of the chain with which MessageDispatcher is communicating
   * @return address MessageExecutor contract address
   */
  function getMessageExecutorAddress(uint256 toChainId) external returns (address);
}

Settings
{
  "remappings": [
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/",
    "solidity-stringutils/=lib/solidity-stringutils/src/",
    "@maticnetwork/fx-portal/=lib/contracts/",
    "@arbitrum/nitro-contracts/=lib/nitro/contracts/",
    "@handlers/=lib/contracts/test/handlers/",
    "@mock/=lib/contracts/test/mock/",
    "@openzeppelin/=lib/contracts/lib/openzeppelin-contracts/",
    "@utils/=lib/contracts/test/utils/",
    "contracts/=lib/contracts/contracts/",
    "nitro/=lib/nitro/",
    "openzeppelin-contracts/=lib/contracts/lib/openzeppelin-contracts/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "london",
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract ICrossDomainMessenger","name":"_crossDomainMessenger","type":"address"},{"internalType":"uint256","name":"_toChainId","type":"uint256"},{"internalType":"uint32","name":"_gasLimit","type":"uint32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"messageId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"uint256","name":"toChainId","type":"uint256"},{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"indexed":false,"internalType":"struct MessageLib.Message[]","name":"messages","type":"tuple[]"}],"name":"MessageBatchDispatched","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"messageId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"uint256","name":"toChainId","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"MessageDispatched","type":"event"},{"inputs":[],"name":"crossDomainMessenger","outputs":[{"internalType":"contract ICrossDomainMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_toChainId","type":"uint256"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"dispatchMessage","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_toChainId","type":"uint256"},{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct MessageLib.Message[]","name":"_messages","type":"tuple[]"}],"name":"dispatchMessageBatch","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_toChainId","type":"uint256"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"uint32","name":"_gasLimit","type":"uint32"}],"name":"dispatchMessageWithGasLimit","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_toChainId","type":"uint256"},{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct MessageLib.Message[]","name":"_messages","type":"tuple[]"},{"internalType":"uint32","name":"_gasLimit","type":"uint32"}],"name":"dispatchMessageWithGasLimitBatch","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_toChainId","type":"uint256"}],"name":"getMessageExecutorAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IMessageExecutor","name":"_executor","type":"address"}],"name":"setExecutor","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60e060405234801561001057600080fd5b50604051610f45380380610f4583398101604081905261002f916100f9565b6001600160a01b03831661008a5760405162461bcd60e51b815260206004820152601f60248201527f446973706174636865722f43444d2d6e6f742d7a65726f2d616464726573730060448201526064015b60405180910390fd5b816000036100da5760405162461bcd60e51b815260206004820152601b60248201527f446973706174636865722f636861696e49642d6e6f742d7a65726f00000000006044820152606401610081565b6001600160a01b0390921660805260a05263ffffffff1660c052610151565b60008060006060848603121561010e57600080fd5b83516001600160a01b038116811461012557600080fd5b60208501516040860151919450925063ffffffff8116811461014657600080fd5b809150509250925092565b60805160a05160c051610db761018e60003960008181610163015261024a0152600061044b01526000818161011301526105aa0152610db76000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c806372dc93a81161005b57806372dc93a8146100e857806391b8cb56146100fb578063f43b36131461010e578063fe39827b1461013557600080fd5b806303481d921461008257806318d9f08c146100b25780631c3c0ea8146100d3575b600080fd5b6100956100903660046106a3565b610148565b6040516001600160a01b0390911681526020015b60405180910390f35b6100c56100c0366004610708565b610159565b6040519081526020016100a9565b6100e66100e1366004610769565b61018f565b005b6100c56100f63660046107e8565b61020f565b6100c5610109366004610859565b610228565b6100957f000000000000000000000000000000000000000000000000000000000000000081565b6100c56101433660046108b7565b61023f565b60006101538261026e565b92915050565b60006101878484847f000000000000000000000000000000000000000000000000000000000000000061028a565b949350505050565b6000546001600160a01b0316156101ed5760405162461bcd60e51b815260206004820152601f60248201527f446973706174636865722f6578656375746f722d616c72656164792d7365740060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b600061021e868686868661033c565b9695505050505050565b60006102368585858561028a565b95945050505050565b6000610236858585857f000000000000000000000000000000000000000000000000000000000000000061033c565b600061027982610449565b50506000546001600160a01b031690565b6000806102968661026e565b90506102a1816104bb565b60006102b36001805481019081905590565b905060006102cb82336102c6898b610983565b610511565b90506102ec836102e66102de898b610983565b844633610547565b87610593565b87336001600160a01b0316827f3e3e2584727d15a9c4d210e85682b829bdbe8c083632dbe0d61b59ad0c5b4ff18a8a604051610329929190610ac3565b60405180910390a4979650505050505050565b6000806103488761026e565b9050610353816104bb565b60006103656001805481019081905590565b905060006103ab82338a8a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061061a92505050565b90506103f6836102e68a8a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250469150339050610653565b88336001600160a01b0316827fe2f8f20ddbedfce5eb59a8b930077e7f4906a01300b9318db5f90d1c96c7b6d48b8b8b60405161043593929190610b95565b60405180910390a498975050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081146104b85760405162461bcd60e51b815260206004820181905260248201527f446973706174636865722f636861696e49642d6e6f742d737570706f7274656460448201526064016101e4565b50565b6001600160a01b0381166104b85760405162461bcd60e51b815260206004820152601b60248201527f446973706174636865722f6578656375746f722d6e6f742d736574000000000060448201526064016101e4565b600083838360405160200161052893929190610c72565b6040516020818303038152906040528051906020012090509392505050565b6060848484846040516024016105609493929190610c9c565b60408051601f198184030181529190526020810180516001600160e01b03166262e1bd60e91b1790529050949350505050565b604051633dbb202b60e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690633dbb202b906105e390869086908690600401610cd4565b600060405180830381600087803b1580156105fd57600080fd5b505af1158015610611573d6000803e3d6000fd5b50505050505050565b6000848484846040516020016106339493929190610d0e565b604051602081830303815290604052805190602001209050949350505050565b6060858585858560405160240161066e959493929190610d40565b60408051601f198184030181529190526020810180516001600160e01b03166390fe4cff60e01b179052905095945050505050565b6000602082840312156106b557600080fd5b5035919050565b60008083601f8401126106ce57600080fd5b50813567ffffffffffffffff8111156106e657600080fd5b6020830191508360208260051b850101111561070157600080fd5b9250929050565b60008060006040848603121561071d57600080fd5b83359250602084013567ffffffffffffffff81111561073b57600080fd5b610747868287016106bc565b9497909650939450505050565b6001600160a01b03811681146104b857600080fd5b60006020828403121561077b57600080fd5b813561078681610754565b9392505050565b60008083601f84011261079f57600080fd5b50813567ffffffffffffffff8111156107b757600080fd5b60208301915083602082850101111561070157600080fd5b803563ffffffff811681146107e357600080fd5b919050565b60008060008060006080868803121561080057600080fd5b85359450602086013561081281610754565b9350604086013567ffffffffffffffff81111561082e57600080fd5b61083a8882890161078d565b909450925061084d9050606087016107cf565b90509295509295909350565b6000806000806060858703121561086f57600080fd5b84359350602085013567ffffffffffffffff81111561088d57600080fd5b610899878288016106bc565b90945092506108ac9050604086016107cf565b905092959194509250565b600080600080606085870312156108cd57600080fd5b8435935060208501356108df81610754565b9250604085013567ffffffffffffffff8111156108fb57600080fd5b6109078782880161078d565b95989497509550505050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561094c5761094c610913565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561097b5761097b610913565b604052919050565b600067ffffffffffffffff8084111561099e5761099e610913565b8360051b60206109af818301610952565b8681529185019181810190368411156109c757600080fd5b865b84811015610a8e578035868111156109e15760008081fd5b880160403682900312156109f55760008081fd5b6109fd610929565b8135610a0881610754565b81528186013588811115610a1c5760008081fd5b9190910190601f3681840112610a325760008081fd5b823589811115610a4457610a44610913565b610a55818301601f19168901610952565b91508082523688828601011115610a6c5760008081fd5b80888501898401376000908201880152818701528452509183019183016109c9565b50979650505050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60208082528181018390526000906040808401600586901b8501820187855b88811015610b8757878303603f190184528135368b9003603e19018112610b0857600080fd5b8a018035610b1581610754565b6001600160a01b031684528087013536829003601e19018112610b3757600080fd5b01868101903567ffffffffffffffff811115610b5257600080fd5b803603821315610b6157600080fd5b8688860152610b738786018284610a9a565b958801959450505090850190600101610ae2565b509098975050505050505050565b6001600160a01b03841681526040602082018190526000906102369083018486610a9a565b6000815180845260005b81811015610be057602081850181015186830182015201610bc4565b506000602082860101526020601f19601f83011685010191505092915050565b600081518084526020808501808196508360051b8101915082860160005b85811015610c65578284038952815180516001600160a01b031685528501516040868601819052610c5181870183610bba565b9a87019a9550505090840190600101610c1e565b5091979650505050505050565b8381526001600160a01b038316602082015260606040820181905260009061023690830184610c00565b608081526000610caf6080830187610c00565b60208301959095525060408101929092526001600160a01b0316606090910152919050565b6001600160a01b0384168152606060208201819052600090610cf890830185610bba565b905063ffffffff83166040830152949350505050565b8481526001600160a01b0384811660208301528316604082015260806060820181905260009061021e90830184610bba565b600060018060a01b03808816835260a06020840152610d6260a0840188610bba565b604084019690965260608301949094525091166080909101529291505056fea26469706673582212200b8e16d5fcb1026e3a55b896202941da0382da1d6aa865dd1f5987400f5db83e64736f6c6343000810003300000000000000000000000025ace71c97b33cc4729cf772ae268934f7ab5fa1000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000001d4c00

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061007d5760003560e01c806372dc93a81161005b57806372dc93a8146100e857806391b8cb56146100fb578063f43b36131461010e578063fe39827b1461013557600080fd5b806303481d921461008257806318d9f08c146100b25780631c3c0ea8146100d3575b600080fd5b6100956100903660046106a3565b610148565b6040516001600160a01b0390911681526020015b60405180910390f35b6100c56100c0366004610708565b610159565b6040519081526020016100a9565b6100e66100e1366004610769565b61018f565b005b6100c56100f63660046107e8565b61020f565b6100c5610109366004610859565b610228565b6100957f00000000000000000000000025ace71c97b33cc4729cf772ae268934f7ab5fa181565b6100c56101433660046108b7565b61023f565b60006101538261026e565b92915050565b60006101878484847f00000000000000000000000000000000000000000000000000000000001d4c0061028a565b949350505050565b6000546001600160a01b0316156101ed5760405162461bcd60e51b815260206004820152601f60248201527f446973706174636865722f6578656375746f722d616c72656164792d7365740060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b600061021e868686868661033c565b9695505050505050565b60006102368585858561028a565b95945050505050565b6000610236858585857f00000000000000000000000000000000000000000000000000000000001d4c0061033c565b600061027982610449565b50506000546001600160a01b031690565b6000806102968661026e565b90506102a1816104bb565b60006102b36001805481019081905590565b905060006102cb82336102c6898b610983565b610511565b90506102ec836102e66102de898b610983565b844633610547565b87610593565b87336001600160a01b0316827f3e3e2584727d15a9c4d210e85682b829bdbe8c083632dbe0d61b59ad0c5b4ff18a8a604051610329929190610ac3565b60405180910390a4979650505050505050565b6000806103488761026e565b9050610353816104bb565b60006103656001805481019081905590565b905060006103ab82338a8a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061061a92505050565b90506103f6836102e68a8a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250469150339050610653565b88336001600160a01b0316827fe2f8f20ddbedfce5eb59a8b930077e7f4906a01300b9318db5f90d1c96c7b6d48b8b8b60405161043593929190610b95565b60405180910390a498975050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000a81146104b85760405162461bcd60e51b815260206004820181905260248201527f446973706174636865722f636861696e49642d6e6f742d737570706f7274656460448201526064016101e4565b50565b6001600160a01b0381166104b85760405162461bcd60e51b815260206004820152601b60248201527f446973706174636865722f6578656375746f722d6e6f742d736574000000000060448201526064016101e4565b600083838360405160200161052893929190610c72565b6040516020818303038152906040528051906020012090509392505050565b6060848484846040516024016105609493929190610c9c565b60408051601f198184030181529190526020810180516001600160e01b03166262e1bd60e91b1790529050949350505050565b604051633dbb202b60e01b81526001600160a01b037f00000000000000000000000025ace71c97b33cc4729cf772ae268934f7ab5fa11690633dbb202b906105e390869086908690600401610cd4565b600060405180830381600087803b1580156105fd57600080fd5b505af1158015610611573d6000803e3d6000fd5b50505050505050565b6000848484846040516020016106339493929190610d0e565b604051602081830303815290604052805190602001209050949350505050565b6060858585858560405160240161066e959493929190610d40565b60408051601f198184030181529190526020810180516001600160e01b03166390fe4cff60e01b179052905095945050505050565b6000602082840312156106b557600080fd5b5035919050565b60008083601f8401126106ce57600080fd5b50813567ffffffffffffffff8111156106e657600080fd5b6020830191508360208260051b850101111561070157600080fd5b9250929050565b60008060006040848603121561071d57600080fd5b83359250602084013567ffffffffffffffff81111561073b57600080fd5b610747868287016106bc565b9497909650939450505050565b6001600160a01b03811681146104b857600080fd5b60006020828403121561077b57600080fd5b813561078681610754565b9392505050565b60008083601f84011261079f57600080fd5b50813567ffffffffffffffff8111156107b757600080fd5b60208301915083602082850101111561070157600080fd5b803563ffffffff811681146107e357600080fd5b919050565b60008060008060006080868803121561080057600080fd5b85359450602086013561081281610754565b9350604086013567ffffffffffffffff81111561082e57600080fd5b61083a8882890161078d565b909450925061084d9050606087016107cf565b90509295509295909350565b6000806000806060858703121561086f57600080fd5b84359350602085013567ffffffffffffffff81111561088d57600080fd5b610899878288016106bc565b90945092506108ac9050604086016107cf565b905092959194509250565b600080600080606085870312156108cd57600080fd5b8435935060208501356108df81610754565b9250604085013567ffffffffffffffff8111156108fb57600080fd5b6109078782880161078d565b95989497509550505050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561094c5761094c610913565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561097b5761097b610913565b604052919050565b600067ffffffffffffffff8084111561099e5761099e610913565b8360051b60206109af818301610952565b8681529185019181810190368411156109c757600080fd5b865b84811015610a8e578035868111156109e15760008081fd5b880160403682900312156109f55760008081fd5b6109fd610929565b8135610a0881610754565b81528186013588811115610a1c5760008081fd5b9190910190601f3681840112610a325760008081fd5b823589811115610a4457610a44610913565b610a55818301601f19168901610952565b91508082523688828601011115610a6c5760008081fd5b80888501898401376000908201880152818701528452509183019183016109c9565b50979650505050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60208082528181018390526000906040808401600586901b8501820187855b88811015610b8757878303603f190184528135368b9003603e19018112610b0857600080fd5b8a018035610b1581610754565b6001600160a01b031684528087013536829003601e19018112610b3757600080fd5b01868101903567ffffffffffffffff811115610b5257600080fd5b803603821315610b6157600080fd5b8688860152610b738786018284610a9a565b958801959450505090850190600101610ae2565b509098975050505050505050565b6001600160a01b03841681526040602082018190526000906102369083018486610a9a565b6000815180845260005b81811015610be057602081850181015186830182015201610bc4565b506000602082860101526020601f19601f83011685010191505092915050565b600081518084526020808501808196508360051b8101915082860160005b85811015610c65578284038952815180516001600160a01b031685528501516040868601819052610c5181870183610bba565b9a87019a9550505090840190600101610c1e565b5091979650505050505050565b8381526001600160a01b038316602082015260606040820181905260009061023690830184610c00565b608081526000610caf6080830187610c00565b60208301959095525060408101929092526001600160a01b0316606090910152919050565b6001600160a01b0384168152606060208201819052600090610cf890830185610bba565b905063ffffffff83166040830152949350505050565b8481526001600160a01b0384811660208301528316604082015260806060820181905260009061021e90830184610bba565b600060018060a01b03808816835260a06020840152610d6260a0840188610bba565b604084019690965260608301949094525091166080909101529291505056fea26469706673582212200b8e16d5fcb1026e3a55b896202941da0382da1d6aa865dd1f5987400f5db83e64736f6c63430008100033

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

00000000000000000000000025ace71c97b33cc4729cf772ae268934f7ab5fa1000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000001d4c00

-----Decoded View---------------
Arg [0] : _crossDomainMessenger (address): 0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1
Arg [1] : _toChainId (uint256): 10
Arg [2] : _gasLimit (uint32): 1920000

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 00000000000000000000000025ace71c97b33cc4729cf772ae268934f7ab5fa1
Arg [1] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [2] : 00000000000000000000000000000000000000000000000000000000001d4c00


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
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.