ETH Price: $2,941.00 (-0.57%)

Contract

0x4c6C68E8F5206EE4a1690C808cfF5c3fD35b512F

Overview

ETH Balance

0.06994 ETH

ETH Value

$205.69 (@ $2,941.00/ETH)

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To
Recv Message3093582652025-02-24 9:15:57335 days ago1740388557IN
0x4c6C68E8...fD35b512F
0 ETH0.000005660.01
Recv Message3093477232025-02-24 8:31:58335 days ago1740385918IN
0x4c6C68E8...fD35b512F
0 ETH0.000004640.020051
Recv Message3093477222025-02-24 8:31:57335 days ago1740385917IN
0x4c6C68E8...fD35b512F
0 ETH0.00000460.020017
Recv Message3093471592025-02-24 8:29:36335 days ago1740385776IN
0x4c6C68E8...fD35b512F
0 ETH0.000005090.021203
Recv Message3093378612025-02-24 7:50:43335 days ago1740383443IN
0x4c6C68E8...fD35b512F
0 ETH0.000005850.01
Recv Message3093372862025-02-24 7:48:18335 days ago1740383298IN
0x4c6C68E8...fD35b512F
0 ETH0.000002390.01
Recv Message3093372382025-02-24 7:48:06335 days ago1740383286IN
0x4c6C68E8...fD35b512F
0 ETH0.00000240.01
Recv Message3093371902025-02-24 7:47:54335 days ago1740383274IN
0x4c6C68E8...fD35b512F
0 ETH0.000002350.01
Recv Message3093366772025-02-24 7:45:45335 days ago1740383145IN
0x4c6C68E8...fD35b512F
0 ETH0.000005840.01
Recv Message3093366172025-02-24 7:45:30335 days ago1740383130IN
0x4c6C68E8...fD35b512F
0 ETH0.00000240.01
Recv Message3093333902025-02-24 7:31:57335 days ago1740382317IN
0x4c6C68E8...fD35b512F
0 ETH0.000005890.01
Recv Message3093333782025-02-24 7:31:54335 days ago1740382314IN
0x4c6C68E8...fD35b512F
0 ETH0.000002470.01
Recv Message3093332822025-02-24 7:31:30335 days ago1740382290IN
0x4c6C68E8...fD35b512F
0 ETH0.000002420.01
Recv Message3093332232025-02-24 7:31:15335 days ago1740382275IN
0x4c6C68E8...fD35b512F
0 ETH0.000002430.01
Recv Message3093305432025-02-24 7:20:00335 days ago1740381600IN
0x4c6C68E8...fD35b512F
0 ETH0.000005870.01
Recv Message3093304842025-02-24 7:19:46335 days ago1740381586IN
0x4c6C68E8...fD35b512F
0 ETH0.000002440.01
Recv Message3092994252025-02-24 5:09:46335 days ago1740373786IN
0x4c6C68E8...fD35b512F
0 ETH0.000005820.01
Recv Message3092921492025-02-24 4:39:21335 days ago1740371961IN
0x4c6C68E8...fD35b512F
0 ETH0.000010480.043757
Recv Message3092902452025-02-24 4:31:24335 days ago1740371484IN
0x4c6C68E8...fD35b512F
0 ETH0.00001660.028787
Recv Message3092883512025-02-24 4:23:30335 days ago1740371010IN
0x4c6C68E8...fD35b512F
0 ETH0.000002460.01
Recv Message3092808342025-02-24 3:52:09335 days ago1740369129IN
0x4c6C68E8...fD35b512F
0 ETH0.000002510.01
Recv Message3092766632025-02-24 3:34:46335 days ago1740368086IN
0x4c6C68E8...fD35b512F
0 ETH0.000027420.114821
Recv Message3092733622025-02-24 3:20:54335 days ago1740367254IN
0x4c6C68E8...fD35b512F
0 ETH0.000002460.01
Recv Message3092531362025-02-24 1:56:13335 days ago1740362173IN
0x4c6C68E8...fD35b512F
0 ETH0.000005860.01
Recv Message3092415612025-02-24 1:07:39335 days ago1740359259IN
0x4c6C68E8...fD35b512F
0 ETH0.00000240.01
View all transactions

Latest 25 internal transactions (View All)

Parent Transaction Hash Block From To
3096149072025-02-25 3:07:44334 days ago1740452864
0x4c6C68E8...fD35b512F
0.00002 ETH
3093476772025-02-24 8:31:46335 days ago1740385906
0x4c6C68E8...fD35b512F
0.00002 ETH
3093475772025-02-24 8:31:21335 days ago1740385881
0x4c6C68E8...fD35b512F
0.00002 ETH
3093470492025-02-24 8:29:09335 days ago1740385749
0x4c6C68E8...fD35b512F
0.00002 ETH
3093406012025-02-24 8:02:12335 days ago1740384132
0x4c6C68E8...fD35b512F
0.00002 ETH
3093404952025-02-24 8:01:46335 days ago1740384106
0x4c6C68E8...fD35b512F
0.00002 ETH
3093403882025-02-24 8:01:20335 days ago1740384080
0x4c6C68E8...fD35b512F
0.00002 ETH
3093401702025-02-24 8:00:25335 days ago1740384025
0x4c6C68E8...fD35b512F
0.00002 ETH
3093398522025-02-24 7:59:05335 days ago1740383945
0x4c6C68E8...fD35b512F
0.00002 ETH
3093387202025-02-24 7:54:19335 days ago1740383659
0x4c6C68E8...fD35b512F
0.00002 ETH
3093383592025-02-24 7:52:48335 days ago1740383568
0x4c6C68E8...fD35b512F
0.00002 ETH
3093381402025-02-24 7:51:53335 days ago1740383513
0x4c6C68E8...fD35b512F
0.00002 ETH
3093378012025-02-24 7:50:27335 days ago1740383427
0x4c6C68E8...fD35b512F
0.00002 ETH
3093376462025-02-24 7:49:48335 days ago1740383388
0x4c6C68E8...fD35b512F
0.00002 ETH
3093373672025-02-24 7:48:39335 days ago1740383319
0x4c6C68E8...fD35b512F
0.00002 ETH
3093372372025-02-24 7:48:06335 days ago1740383286
0x4c6C68E8...fD35b512F
0.00002 ETH
3093371482025-02-24 7:47:44335 days ago1740383264
0x4c6C68E8...fD35b512F
0.00002 ETH
3093371272025-02-24 7:47:38335 days ago1740383258
0x4c6C68E8...fD35b512F
0.00002 ETH
3093365772025-02-24 7:45:20335 days ago1740383120
0x4c6C68E8...fD35b512F
0.00002 ETH
3093333462025-02-24 7:31:46335 days ago1740382306
0x4c6C68E8...fD35b512F
0.00002 ETH
3093333292025-02-24 7:31:42335 days ago1740382302
0x4c6C68E8...fD35b512F
0.00002 ETH
3093332382025-02-24 7:31:19335 days ago1740382279
0x4c6C68E8...fD35b512F
0.00002 ETH
3093331192025-02-24 7:30:49335 days ago1740382249
0x4c6C68E8...fD35b512F
0.00002 ETH
3093304962025-02-24 7:19:49335 days ago1740381589
0x4c6C68E8...fD35b512F
0.00002 ETH
3093303772025-02-24 7:19:19335 days ago1740381559
0x4c6C68E8...fD35b512F
0.00002 ETH
View All Internal Transactions

Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CentralizedConnection

Compiler Version
v0.8.21+commit.d9974bed

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion
// SPDX-License-Identifier: Apache-2.0
pragma solidity >=0.8.0;
pragma abicoder v2;

import "openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol";
import "@xcall/utils/Types.sol";
import "@xcall/contracts/xcall/interfaces/IConnection.sol";
import "@iconfoundation/xcall-solidity-library/interfaces/ICallService.sol";

contract CentralizedConnection is Initializable, IConnection {
    mapping(string => uint256) private messageFees;
    mapping(string => uint256) private responseFees;
    mapping(string => mapping(uint256 => bool)) receipts;
    address private xCall;
    address private adminAddress;
    uint256 public connSn;

    event Message(string targetNetwork, uint256 sn, bytes _msg);

    modifier onlyAdmin() {
        require(msg.sender == this.admin(), "OnlyRelayer");
        _;
    }

    function initialize(address _relayer, address _xCall) public initializer {
        xCall = _xCall;
        adminAddress = _relayer;
    }

    /**
     @notice Sets the fee to the target network
     @param networkId String Network Id of target chain
     @param messageFee Integer ( The fee needed to send a Message )
     @param responseFee Integer (The fee of the response )
     */
    function setFee(
        string calldata networkId,
        uint256 messageFee,
        uint256 responseFee
    ) external onlyAdmin {
        messageFees[networkId] = messageFee;
        responseFees[networkId] = responseFee;
    }

    /**
     @notice Gets the fee to the target network
    @param to String Network Id of target chain
    @param response Boolean ( Whether the responding fee is included )
    @return fee Integer (The fee of sending a message to a given destination network )
    */
    function getFee(
        string memory to,
        bool response
    ) external view override returns (uint256 fee) {
        uint256 messageFee = messageFees[to];
        if (response == true) {
            uint256 responseFee = responseFees[to];
            return messageFee + responseFee;
        }
        return messageFee;
    }

    /**
     @notice Sends the message to a specific network.
     @param sn : positive for two-way message, zero for one-way message, negative for response
     @param to  String ( Network Id of destination network )
     @param svc String ( name of the service )
     @param sn  Integer ( serial number of the xcall message )
     @param _msg Bytes ( serialized bytes of Service Message )
     */
    function sendMessage(
        string calldata to,
        string calldata svc,
        int256 sn,
        bytes calldata _msg
    ) external payable override {
        require(msg.sender == xCall, "Only Xcall can call sendMessage");
        uint256 fee;
        if (sn > 0) {
            fee = this.getFee(to, true);
        } else if (sn == 0) {
            fee = this.getFee(to, false);
        }
        require(msg.value >= fee, "Fee is not Sufficient");
        connSn++;
        emit Message(to, connSn, _msg);
    }

    /**
     @notice Sends the message to a xCall.
     @param srcNetwork  String ( Network Id )
     @param _connSn Integer ( connection message sn )
     @param _msg Bytes ( serialized bytes of Service Message )
     */
    function recvMessage(
        string memory srcNetwork,
        uint256 _connSn,
        bytes calldata _msg
    ) public onlyAdmin {
        require(!receipts[srcNetwork][_connSn], "Duplicate Message");
        receipts[srcNetwork][_connSn] = true;
        ICallService(xCall).handleMessage(srcNetwork, _msg);
    }

    /**
     @notice Sends the balance of the contract to the owner(relayer)

    */
    function claimFees() public onlyAdmin {
        payable(adminAddress).transfer(address(this).balance);
    }

    /**
     @notice Revert a messages, used in special cases where message can't just be dropped
     @param sn  Integer ( serial number of the  xcall message )
     */
    function revertMessage(uint256 sn) public onlyAdmin {
        ICallService(xCall).handleError(sn);
    }

    /**
     @notice Gets a message receipt
     @param srcNetwork String ( Network Id )
     @param _connSn Integer ( connection message sn )
     @return boolean if is has been recived or not
     */
    function getReceipt(
        string memory srcNetwork,
        uint256 _connSn
    ) public view returns (bool) {
        return receipts[srcNetwork][_connSn];
    }

    /**
        @notice Set the address of the admin.
        @param _address The address of the admin.
     */
    function setAdmin(address _address) external onlyAdmin {
        adminAddress = _address;
    }

    /**
       @notice Gets the address of admin
       @return (Address) the address of admin
    */
    function admin() external view returns (address) {
        return adminAddress;
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)

pragma solidity ^0.8.20;

/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
 *
 * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
 * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
 * case an upgrade adds a module that needs to be initialized.
 *
 * For example:
 *
 * [.hljs-theme-light.nopadding]
 * ```solidity
 * contract MyToken is ERC20Upgradeable {
 *     function initialize() initializer public {
 *         __ERC20_init("MyToken", "MTK");
 *     }
 * }
 *
 * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
 *     function initializeV2() reinitializer(2) public {
 *         __ERC20Permit_init("MyToken");
 *     }
 * }
 * ```
 *
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
 *
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 *
 * [CAUTION]
 * ====
 * Avoid leaving a contract uninitialized.
 *
 * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
 * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
 * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
 *
 * [.hljs-theme-light.nopadding]
 * ```
 * /// @custom:oz-upgrades-unsafe-allow constructor
 * constructor() {
 *     _disableInitializers();
 * }
 * ```
 * ====
 */
abstract contract Initializable {
    /**
     * @dev Storage of the initializable contract.
     *
     * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
     * when using with upgradeable contracts.
     *
     * @custom:storage-location erc7201:openzeppelin.storage.Initializable
     */
    struct InitializableStorage {
        /**
         * @dev Indicates that the contract has been initialized.
         */
        uint64 _initialized;
        /**
         * @dev Indicates that the contract is in the process of being initialized.
         */
        bool _initializing;
    }

    // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;

    /**
     * @dev The contract is already initialized.
     */
    error InvalidInitialization();

    /**
     * @dev The contract is not initializing.
     */
    error NotInitializing();

    /**
     * @dev Triggered when the contract has been initialized or reinitialized.
     */
    event Initialized(uint64 version);

    /**
     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
     * `onlyInitializing` functions can be used to initialize parent contracts.
     *
     * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
     * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
     * production.
     *
     * Emits an {Initialized} event.
     */
    modifier initializer() {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        // Cache values to avoid duplicated sloads
        bool isTopLevelCall = !$._initializing;
        uint64 initialized = $._initialized;

        // Allowed calls:
        // - initialSetup: the contract is not in the initializing state and no previous version was
        //                 initialized
        // - construction: the contract is initialized at version 1 (no reininitialization) and the
        //                 current contract is just being deployed
        bool initialSetup = initialized == 0 && isTopLevelCall;
        bool construction = initialized == 1 && address(this).code.length == 0;

        if (!initialSetup && !construction) {
            revert InvalidInitialization();
        }
        $._initialized = 1;
        if (isTopLevelCall) {
            $._initializing = true;
        }
        _;
        if (isTopLevelCall) {
            $._initializing = false;
            emit Initialized(1);
        }
    }

    /**
     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
     * used to initialize parent contracts.
     *
     * A reinitializer may be used after the original initialization step. This is essential to configure modules that
     * are added through upgrades and that require initialization.
     *
     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
     * cannot be nested. If one is invoked in the context of another, execution will revert.
     *
     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
     * a contract, executing them in the right order is up to the developer or operator.
     *
     * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
     *
     * Emits an {Initialized} event.
     */
    modifier reinitializer(uint64 version) {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        if ($._initializing || $._initialized >= version) {
            revert InvalidInitialization();
        }
        $._initialized = version;
        $._initializing = true;
        _;
        $._initializing = false;
        emit Initialized(version);
    }

    /**
     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
     * {initializer} and {reinitializer} modifiers, directly or indirectly.
     */
    modifier onlyInitializing() {
        _checkInitializing();
        _;
    }

    /**
     * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
     */
    function _checkInitializing() internal view virtual {
        if (!_isInitializing()) {
            revert NotInitializing();
        }
    }

    /**
     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called
     * through proxies.
     *
     * Emits an {Initialized} event the first time it is successfully executed.
     */
    function _disableInitializers() internal virtual {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        if ($._initializing) {
            revert InvalidInitialization();
        }
        if ($._initialized != type(uint64).max) {
            $._initialized = type(uint64).max;
            emit Initialized(type(uint64).max);
        }
    }

    /**
     * @dev Returns the highest version that has been initialized. See {reinitializer}.
     */
    function _getInitializedVersion() internal view returns (uint64) {
        return _getInitializableStorage()._initialized;
    }

    /**
     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
     */
    function _isInitializing() internal view returns (bool) {
        return _getInitializableStorage()._initializing;
    }

    /**
     * @dev Returns a pointer to the storage namespace.
     */
    // solhint-disable-next-line var-name-mixedcase
    function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
        assembly {
            $.slot := INITIALIZABLE_STORAGE
        }
    }
}

// SPDX-License-Identifier: Apache-2.0
pragma solidity >=0.8.0;
import "@xcall/utils/RLPEncodeStruct.sol";
import "@xcall/utils/RLPEncodeStruct.sol";

/**
 * @notice List of ALL Struct being used to Encode and Decode RLP Messages
 */
library Types {
    using RLPEncodeStruct for Types.CallMessageWithRollback;
    using RLPEncodeStruct for Types.XCallEnvelope;

    // The name of CallService.
    string constant NAME = "xcallM";

    int constant CS_REQUEST = 1;
    /**
     * Legacy Code, CS_RESPONSE replaced by CS_RESULT in V2
     */
    int constant CS_RESPONSE = 2;

    int constant CS_RESULT = 2;

    int constant CALL_MESSAGE_TYPE = 0;
    int constant CALL_MESSAGE_ROLLBACK_TYPE = 1;
    int constant PERSISTENT_MESSAGE_TYPE = 2;

    /**
     * Legacy Code, CallRequest replaced with RollbackData
     */
    struct CallRequest {
        address from;
        string to;
        string[] sources;
        bytes rollback;
        bool enabled; //whether wait response or received
    }

    struct RollbackData {
        address from;
        string to;
        string[] sources;
        bytes rollback;
        bool enabled; 
    }

    struct CSMessage {
        int msgType;
        bytes payload;
    }

    struct CSMessageResponse {
        uint256 sn;
        int code;
    }

    /**
     * Legacy Code, CSMessageRequest replaced with CSMessageRequestV2
     */
    struct CSMessageRequest {
        string from;
        string to;
        uint256 sn;
        bool rollback;
        bytes data;
        string[] protocols;
    }

    /**
     * Legacy Code, ProxyRequest replaced with ProxyRequestV2
     */
    struct ProxyRequest {
        string from;
        string to;
        uint256 sn;
        bool rollback;
        bytes32 hash;
        string[] protocols;
    }

    struct CSMessageRequestV2 {
        string from;
        string to;
        uint256 sn;
        int messageType;
        bytes data;
        string[] protocols;
    }

    struct ProxyRequestV2 {
        string from;
        string to;
        uint256 sn;
        int256 messageType;
        bytes32 hash;
        string[] protocols;
    }

    int constant CS_RESP_SUCCESS = 1;
    int constant CS_RESP_FAILURE = 0;

    struct CSMessageResult {
        uint256 sn;
        int code;
        bytes message;
    }

    struct PendingResponse {
        bytes msg;
        string targetNetwork;
    }

    struct XCallEnvelope {
        int messageType;
        bytes message;
        string[] sources;
        string[] destinations;
    }

    struct CallMessage {
        bytes data;
    }

    struct CallMessageWithRollback {
        bytes data;
        bytes rollback;
    }

    struct ProcessResult {
        bool needResponse;
        bytes data;
    }

    function createPersistentMessage(
        bytes memory data,
        string[] memory sources,
        string[] memory destinations
    ) internal pure returns (bytes memory) {
        return
            XCallEnvelope(PERSISTENT_MESSAGE_TYPE, data, sources, destinations).encodeXCallEnvelope();
    }

    function createCallMessage(
        bytes memory data,
        string[] memory sources,
        string[] memory destinations
    ) internal pure returns (bytes memory) {
        return XCallEnvelope(CALL_MESSAGE_TYPE, data, sources, destinations).encodeXCallEnvelope();
    }

    function createCallMessageWithRollback(
        bytes memory data,
        bytes memory rollback,
        string[] memory sources,
        string[] memory destinations
    ) internal pure returns (bytes memory) {
        Types.CallMessageWithRollback memory _msg = Types
            .CallMessageWithRollback(data, rollback);

        return
            XCallEnvelope(
                CALL_MESSAGE_ROLLBACK_TYPE,
                _msg.encodeCallMessageWithRollback(),
                sources,
                destinations
            ).encodeXCallEnvelope();
    }
}

// SPDX-License-Identifier: Apache-2.0
pragma solidity >=0.8.0;
pragma abicoder v2;

interface IConnection {

    /**
        @notice Send the message to a specific network.
        @dev Caller must be an registered BSH.
        @param _to      Network id of destination network
        @param _svc     Name of the service
        @param _sn      Serial number of the message
        @param _msg     Serialized bytes of Service Message
     */
    function sendMessage(
        string memory _to,
        string memory _svc,
        int256 _sn,
        bytes memory _msg
    ) external payable;

    /**
       @notice Gets the fee to the target network
       @dev _response should be true if it uses positive value for _sn of {@link #sendMessage}.
            If _to is not reachable, then it reverts.
            If _to does not exist in the fee table, then it returns zero.
       @param  _to       String ( Network ID of destionation chain )
       @param  _response Boolean ( Whether the responding fee is included )
       @return _fee      Integer (The fee of sending a message to a given destination network )
     */
    function getFee(
        string memory _to,
        bool _response
    ) external view returns (
        uint256 _fee
    );

    /**
     * @dev Set the address of the admin.
     * @param _address The address of the admin.
     */
    function setAdmin(address _address) external;

    /**
     * @dev Get the address of the admin.
     * @return (Address) The address of the admin.
     */
    function admin() external view returns (address);
}

// SPDX-License-Identifier: Apache-2.0
pragma solidity >=0.8.0;

interface ICallService {
    function getNetworkAddress() external view returns (string memory);

    function getNetworkId() external view returns (string memory);

    /**
       @notice Gets the fee for delivering a message to the _net.
               If the sender is going to provide rollback data, the _rollback param should set as true.
               The returned fee is the sum of the protocol fee and the relay fee.
       @param _net (String) The destination network address
       @param _rollback (Bool) Indicates whether it provides rollback data
       @return (Integer) the sum of the protocol fee and the relay fee
     */
    function getFee(
        string memory _net,
        bool _rollback
    ) external view returns (uint256);

    function getFee(
        string memory _net,
        bool _rollback,
        string[] memory _sources
    ) external view returns (uint256);

    /*======== At the source CALL_BSH ========*/
    /**
       @notice Sends a call message to the contract on the destination chain.
       @param _to The BTP address of the callee on the destination chain
       @param _data The calldata specific to the target contract
       @param _rollback (Optional) The data for restoring the caller state when an error occurred
       @return The serial number of the request
     */
    function sendCallMessage(
        string memory _to,
        bytes memory _data,
        bytes memory _rollback
    ) external payable returns (uint256);

    function sendCallMessage(
        string memory _to,
        bytes memory _data,
        bytes memory _rollback,
        string[] memory sources,
        string[] memory destinations
    ) external payable returns (uint256);

    function sendCall(
        string memory _to,
        bytes memory _data
    ) external payable returns (uint256);

    /**
       @notice Notifies that the requested call message has been sent.
       @param _from The chain-specific address of the caller
       @param _to The BTP address of the callee on the destination chain
       @param _sn The serial number of the request
     */
    event CallMessageSent(
        address indexed _from,
        string indexed _to,
        uint256 indexed _sn
    );

    /**
       @notice Notifies that a response message has arrived for the `_sn` if the request was a two-way message.
       @param _sn The serial number of the previous request
       @param _code The execution result code
                    (0: Success, -1: Unknown generic failure, >=1: User defined error code)
     */
    event ResponseMessage(uint256 indexed _sn, int _code);

    /**
       @notice Notifies the user that a rollback operation is required for the request '_sn'.
       @param _sn The serial number of the previous request
     */
    event RollbackMessage(uint256 indexed _sn);

    /**
       @notice Rollbacks the caller state of the request '_sn'.
       @param _sn The serial number of the previous request
     */
    function executeRollback(uint256 _sn) external;

    /**
       @notice Notifies that the rollback has been executed.
       @param _sn The serial number for the rollback
     */
    event RollbackExecuted(uint256 indexed _sn);

    /*======== At the destination CALL_BSH ========*/
    /**
       @notice Notifies the user that a new call message has arrived.
       @param _from The BTP address of the caller on the source chain
       @param _to A string representation of the callee address
       @param _sn The serial number of the request from the source
       @param _reqId The request id of the destination chain
       @param _data The calldata
     */
    event CallMessage(
        string indexed _from,
        string indexed _to,
        uint256 indexed _sn,
        uint256 _reqId,
        bytes _data
    );

    /**
       @notice Executes the requested call message.
       @param _reqId The request id
       @param _data The calldata
     */
    function executeCall(uint256 _reqId, bytes memory _data) external;

    /**
       @notice Notifies that the call message has been executed.
       @param _reqId The request id for the call message
       @param _code The execution result code
                    (0: Success, -1: Unknown generic failure)
       @param _msg The result message if any
     */
    event CallExecuted(uint256 indexed _reqId, int _code, string _msg);

    /**
       @notice BTP Message from other blockchain.
       @param _from    Network Address of source network
       @param _msg     Serialized bytes of ServiceMessage
   */
    function handleMessage(string calldata _from, bytes calldata _msg) external;

    /**
       @notice Handle the error on delivering the message.
       @param _sn      Serial number of the original message
   */
    function handleError(uint256 _sn) external;
}

// SPDX-License-Identifier: Apache-2.0
pragma solidity >=0.8.0;
pragma abicoder v2;

import "@iconfoundation/xcall-solidity-library/utils/RLPEncode.sol";
import "./Types.sol";

library RLPEncodeStruct {
    using RLPEncode for bytes;
    using RLPEncode for string;
    using RLPEncode for uint256;
    using RLPEncode for int256;
    using RLPEncode for address;
    using RLPEncode for bool;

    using RLPEncodeStruct for Types.CSMessage;
    using RLPEncodeStruct for Types.CSMessageRequest;
    using RLPEncodeStruct for Types.CSMessageResult;

    function encodeCSMessage(
        Types.CSMessage memory _bs
    ) internal pure returns (bytes memory) {
        bytes memory _rlp = abi.encodePacked(
            _bs.msgType.encodeInt(),
            _bs.payload.encodeBytes()
        );
        return _rlp.encodeList();
    }

    function encodeCSMessageRequest(Types.CSMessageRequest memory _bs)
        internal
        pure
        returns (bytes memory)
    {

        bytes memory _protocols;
        bytes memory temp;
        for (uint256 i = 0; i < _bs.protocols.length; i++) {
            temp = abi.encodePacked(_bs.protocols[i].encodeString());
            _protocols = abi.encodePacked(_protocols, temp);
        }
        bytes memory _rlp =
            abi.encodePacked(
                _bs.from.encodeString(),
                _bs.to.encodeString(),
                _bs.sn.encodeUint(),
                _bs.rollback.encodeBool(),
                _bs.data.encodeBytes(),
                _protocols.encodeList()

            );
        return _rlp.encodeList();
    }

    function encodeCSMessageRequestV2(
        Types.CSMessageRequestV2 memory _bs
    ) internal pure returns (bytes memory) {
        bytes memory _protocols;
        bytes memory temp;
        for (uint256 i = 0; i < _bs.protocols.length; i++) {
            temp = abi.encodePacked(_bs.protocols[i].encodeString());
            _protocols = abi.encodePacked(_protocols, temp);
        }
        bytes memory _rlp = abi.encodePacked(
            _bs.from.encodeString(),
            _bs.to.encodeString(),
            _bs.sn.encodeUint(),
            _bs.messageType.encodeInt(),
            _bs.data.encodeBytes(),
            _protocols.encodeList()
        );
        return _rlp.encodeList();
    }

    function encodeCSMessageResponse(Types.CSMessageResponse memory _bs)
        internal
        pure
        returns (bytes memory)
    {
        bytes memory _rlp =
            abi.encodePacked(
                _bs.sn.encodeUint(),
                _bs.code.encodeInt()
            );
        return _rlp.encodeList();
    }

    function encodeXCallEnvelope(
        Types.XCallEnvelope memory env
    ) internal pure returns (bytes memory) {

        bytes memory _sources;
        bytes memory temp;

        for (uint256 i = 0; i < env.sources.length; i++) {
            temp = abi.encodePacked(env.sources[i].encodeString());
            _sources = abi.encodePacked(_sources, temp);
        }

        bytes memory _dests;
        for (uint256 i = 0; i < env.destinations.length; i++) {
            temp = abi.encodePacked(env.destinations[i].encodeString());
            _dests = abi.encodePacked(_dests, temp);
        }

        bytes memory _rlp = abi.encodePacked(
            env.messageType.encodeInt(),
            env.message.encodeBytes(),
            _sources.encodeList(),
            _dests.encodeList()
        );

        return _rlp.encodeList();
    }

    function encodeCSMessageResult(
        Types.CSMessageResult memory _bs
    ) internal pure returns (bytes memory) {
        bytes memory _rlp = abi.encodePacked(
            _bs.sn.encodeUint(),
            _bs.code.encodeInt(),
            _bs.message.encodeBytes()
        );
        return _rlp.encodeList();
    }

    function encodeCallMessageWithRollback(
        Types.CallMessageWithRollback memory _bs
    ) internal pure returns (bytes memory) {
        bytes memory _rlp = abi.encodePacked(
            _bs.data.encodeBytes(),
            _bs.rollback.encodeBytes()
        );
        return _rlp.encodeList();
    }
}

// SPDX-License-Identifier: Apache-2.0
pragma solidity >=0.8.0;

/**
 * @title RLPEncode
 * @dev A simple RLP encoding library.
 * @author Bakaoh
 * The original code was modified. For more info, please check the link:
 * https://github.com/bakaoh/solidity-rlp-encode.git
 */
library RLPEncode {
    bytes internal constant NULL = hex"f800";

    /*
     * Internal functions
     */

    /**
     * @dev RLP encodes a byte string.
     * @param self The byte string to encode.
     * @return The RLP encoded string in bytes.
     */
    function encodeBytes(bytes memory self)
        internal
        pure
        returns (bytes memory)
    {
        bytes memory encoded;
        if (self.length == 1 && uint8(self[0]) < 128) {
            encoded = self;
        } else {
            encoded = abi.encodePacked(encodeLength(self.length, 128), self);
        }
        return encoded;
    }

    /**
     * @dev RLP encodes a list of RLP encoded byte byte strings.
     * @param self The list of RLP encoded byte strings.
     * @return The RLP encoded list of items in bytes.
     */
    function encodeList(bytes[] memory self)
        internal
        pure
        returns (bytes memory)
    {
        bytes memory list = flatten(self);
        return abi.encodePacked(encodeLength(list.length, 192), list);
    }

    /**
     * @dev RLP encodes a list
     * @param self concatenated bytes of RLP encoded bytes.
     * @return The RLP encoded list of items in bytes
     */
    function encodeList(bytes memory self)
        internal
        pure
        returns (bytes memory)
    {
        return abi.encodePacked(encodeLength(self.length, 192), self);
    }

    /**
     * @dev RLP encodes a string.
     * @param self The string to encode.
     * @return The RLP encoded string in bytes.
     */
    function encodeString(string memory self)
        internal
        pure
        returns (bytes memory)
    {
        return encodeBytes(bytes(self));
    }

    /**
     * @dev RLP encodes an address.
     * @param self The address to encode.
     * @return The RLP encoded address in bytes.
     */
    function encodeAddress(address self) internal pure returns (bytes memory) {
        bytes memory inputBytes;
        assembly {
            let m := mload(0x40)
            mstore(
                add(m, 20),
                xor(0x140000000000000000000000000000000000000000, self)
            )
            mstore(0x40, add(m, 52))
            inputBytes := m
        }
        return encodeBytes(inputBytes);
    }

    /**
     * @dev RLP encodes a uint.
     * @param self The uint to encode.
     * @return The RLP encoded uint in bytes.
     */
    function encodeUint(uint256 self) internal pure returns (bytes memory) {
        return encodeBytes(uintToBytes(self));
    }

    /**
     * @dev RLP encodes an int.
     * @param self The int to encode.
     * @return The RLP encoded int in bytes.
     */
    function encodeInt(int256 self) internal pure returns (bytes memory) {
        return encodeBytes(intToBytes(self));
    }

    /**
     * @dev RLP encodes a bool.
     * @param self The bool to encode.
     * @return The RLP encoded bool in bytes.
     */
    function encodeBool(bool self) internal pure returns (bytes memory) {
        bytes memory encoded = new bytes(1);
        encoded[0] = (self ? bytes1(0x01) : bytes1(0x00));
        return encoded;
    }

    /**
     * @dev RLP encodes null.
     * @return bytes for null
     */
    function encodeNull() internal pure returns (bytes memory) {
        return NULL;
    }

    /*
     * Private functions
     */

    /**
     * @dev Encode the first byte, followed by the `len` in binary form if `length` is more than 55.
     * @param len The length of the string or the payload.
     * @param offset 128 if item is string, 192 if item is list.
     * @return RLP encoded bytes.
     */
    function encodeLength(uint256 len, uint256 offset)
        private
        pure
        returns (bytes memory)
    {
        bytes memory encoded;
        if (len < 56) {
            encoded = new bytes(1);
            encoded[0] = bytes32(len + offset)[31];
        } else {
            uint256 lenLen;
            uint256 i = 1;
            while (len / i != 0) {
                lenLen++;
                i *= 256;
            }

            encoded = new bytes(lenLen + 1);
            encoded[0] = bytes32(lenLen + offset + 55)[31];
            for (i = 1; i <= lenLen; i++) {
                encoded[i] = bytes32((len / (256**(lenLen - i))) % 256)[31];
            }
        }
        return encoded;
    }

    function lastBytesOf(int256 value, uint256 size) internal pure returns  (bytes memory){
        bytes memory buffer = new bytes(size);
        assembly {
            let dst := add(buffer, 32)
            for { let idx := sub(32,size) } lt(idx,32) { idx := add(idx, 1) } {
                mstore8(dst, byte(idx, value))
                dst := add(dst, 1)
            }
        }
        return buffer;
    }

    function intToBytes(int256 x) internal pure returns (bytes memory) {
        if (x == 0) {
            return new bytes(1);
        }
        int256 right = 0x80;
        int256 left = -0x81;
        for (uint i = 1 ; i<32 ; i++) {
            if ((x<right) && (x>left)) {
                return lastBytesOf(x, i);
            }
            right <<= 8;
            left <<= 8;
        }
        return abi.encodePacked(x);
    }

    function uintToBytes(uint256 x) internal pure returns (bytes memory) {
        if (x == 0) {
            return new bytes(1);
        }
        uint256 right = 0x80;
        for (uint i = 1 ; i<32 ; i++) {
            if (x<right) {
                return lastBytesOf(int256(x), i);
            }
            right <<= 8;
        }
        if (x<right) {
            return abi.encodePacked(x);
        } else {
            return abi.encodePacked(bytes1(0), x);
        }
    }

    /**
     * @dev Flattens a list of byte strings into one byte string.
     * @notice From: https://github.com/sammayo/solidity-rlp-encoder/blob/master/RLPEncode.sol.
     * @param _list List of byte strings to flatten.
     * @return The flattened byte string.
     */
    function flatten(bytes[] memory _list) private pure returns (bytes memory) {
        if (_list.length == 0) {
            return new bytes(0);
        }

        uint256 len;
        uint256 i;
        for (i = 0; i < _list.length; i++) {
            len += _list[i].length;
        }

        bytes memory flattened = new bytes(len);
        uint256 flattenedPtr;
        assembly {
            flattenedPtr := add(flattened, 0x20)
        }

        for (i = 0; i < _list.length; i++) {
            bytes memory item = _list[i];

            uint256 listPtr;
            assembly {
                listPtr := add(item, 0x20)
            }

            memcpy(flattenedPtr, listPtr, item.length);
            flattenedPtr += _list[i].length;
        }

        return flattened;
    }

    /**
     * @dev Copies a piece of memory to another location.
     * @notice From: https://github.com/Arachnid/solidity-stringutils/blob/master/src/strings.sol.
     * @param dest Destination location.
     * @param src Source location.
     * @param len Length of memory to copy.
     */
    function memcpy(uint dest, uint src, uint len) private pure {
        // Copy word-length chunks while possible
        for(; len >= 32; len -= 32) {
            assembly {
                mstore(dest, mload(src))
            }
            dest += 32;
            src += 32;
        }

        // Copy remaining bytes
        uint mask = type(uint).max;
        if (len > 0) {
            mask = 256 ** (32 - len) - 1;
            assembly {
                let srcpart := and(mload(src), not(mask))
                let destpart := and(mload(dest), mask)
                mstore(dest, or(destpart, srcpart))
            }
        }
    }
}

Settings
{
  "remappings": [
    "@xcall/contracts/=contracts/",
    "@iconfoundation/xcall-solidity-library/=library/xcall/",
    "@xcall/utils/=library/utils/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
    "forge-std/=lib/forge-std/src/",
    "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/",
    "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "openzeppelin/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "wormhole-solidity-sdk/=lib/wormhole-solidity-sdk/src/",
    "@lz-contracts/=lib/solidity-examples/contracts/lzApp/",
    "@lz-contracts/utils/=lib/solidity-examples/contracts/libraries/",
    "openzeppelin-foundry-upgrades/=lib/openzeppelin-foundry-upgrades/src/",
    "solidity-examples/=lib/solidity-examples/contracts/",
    "solidity-stringutils/=lib/openzeppelin-foundry-upgrades/lib/solidity-stringutils/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"targetNetwork","type":"string"},{"indexed":false,"internalType":"uint256","name":"sn","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_msg","type":"bytes"}],"name":"Message","type":"event"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"connSn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"to","type":"string"},{"internalType":"bool","name":"response","type":"bool"}],"name":"getFee","outputs":[{"internalType":"uint256","name":"fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"srcNetwork","type":"string"},{"internalType":"uint256","name":"_connSn","type":"uint256"}],"name":"getReceipt","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_relayer","type":"address"},{"internalType":"address","name":"_xCall","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"srcNetwork","type":"string"},{"internalType":"uint256","name":"_connSn","type":"uint256"},{"internalType":"bytes","name":"_msg","type":"bytes"}],"name":"recvMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"sn","type":"uint256"}],"name":"revertMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"to","type":"string"},{"internalType":"string","name":"svc","type":"string"},{"internalType":"int256","name":"sn","type":"int256"},{"internalType":"bytes","name":"_msg","type":"bytes"}],"name":"sendMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"networkId","type":"string"},{"internalType":"uint256","name":"messageFee","type":"uint256"},{"internalType":"uint256","name":"responseFee","type":"uint256"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b5061103a806100206000396000f3fe60806040526004361061009c5760003560e01c80637d4c4f4a116100645780637d4c4f4a146101365780639664da0e1461016957806399f1fca714610199578063b58b4cec146101af578063d294f093146101cf578063f851a440146101e457600080fd5b80632d3fb823146100a157806343f08a89146100c3578063485cc955146100e3578063522a901e14610103578063704b6c0214610116575b600080fd5b3480156100ad57600080fd5b506100c16100bc366004610add565b61020c565b005b3480156100cf57600080fd5b506100c16100de366004610b3f565b610308565b3480156100ef57600080fd5b506100c16100fe366004610ba5565b6103e8565b6100c1610111366004610bde565b610520565b34801561012257600080fd5b506100c1610131366004610c82565b610710565b34801561014257600080fd5b50610156610151366004610d42565b6107c4565b6040519081526020015b60405180910390f35b34801561017557600080fd5b50610189610184366004610d8e565b610833565b6040519015158152602001610160565b3480156101a557600080fd5b5061015660055481565b3480156101bb57600080fd5b506100c16101ca366004610dd3565b61086b565b3480156101db57600080fd5b506100c1610a0f565b3480156101f057600080fd5b506004546040516001600160a01b039091168152602001610160565b306001600160a01b031663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa15801561024a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061026e9190610e43565b6001600160a01b0316336001600160a01b0316146102a75760405162461bcd60e51b815260040161029e90610e60565b60405180910390fd5b60035460405163b070f9e560e01b8152600481018390526001600160a01b039091169063b070f9e590602401600060405180830381600087803b1580156102ed57600080fd5b505af1158015610301573d6000803e3d6000fd5b5050505050565b306001600160a01b031663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa158015610346573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061036a9190610e43565b6001600160a01b0316336001600160a01b03161461039a5760405162461bcd60e51b815260040161029e90610e60565b81600085856040516103ad929190610e85565b90815260200160405180910390208190555080600185856040516103d2929190610e85565b9081526040519081900360200190205550505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff16159067ffffffffffffffff1660008115801561042e5750825b905060008267ffffffffffffffff16600114801561044b5750303b155b905081158015610459575080155b156104775760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156104a157845460ff60401b1916600160401b1785555b600380546001600160a01b038089166001600160a01b03199283161790925560048054928a1692909116919091179055831561051757845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b6003546001600160a01b0316331461057a5760405162461bcd60e51b815260206004820152601f60248201527f4f6e6c79205863616c6c2063616e2063616c6c2073656e644d65737361676500604482015260640161029e565b6000808413156105f457604051633ea627a560e11b81523090637d4c4f4a906105ac908b908b90600190600401610ebe565b602060405180830381865afa1580156105c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ed9190610ee4565b9050610668565b8360000361066857604051633ea627a560e11b81523090637d4c4f4a90610624908b908b90600090600401610ebe565b602060405180830381865afa158015610641573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106659190610ee4565b90505b803410156106b05760405162461bcd60e51b8152602060048201526015602482015274119959481a5cc81b9bdd0814dd59999a58da595b9d605a1b604482015260640161029e565b600580549060006106c083610f13565b91905055507f37be353f216cf7e33639101fd610c542e6a0c0109173fa1c1d8b04d34edb7c1b888860055486866040516106fe959493929190610f2c565b60405180910390a15050505050505050565b306001600160a01b031663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa15801561074e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107729190610e43565b6001600160a01b0316336001600160a01b0316146107a25760405162461bcd60e51b815260040161029e90610e60565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6000806000846040516107d79190610f89565b90815260405190819003602001902054905082151560010361082a5760006001856040516108059190610f89565b9081526040519081900360200190205490506108218183610fa5565b9250505061082d565b90505b92915050565b60006002836040516108459190610f89565b908152604080516020928190038301902060009485529091529091205460ff1692915050565b306001600160a01b031663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108cd9190610e43565b6001600160a01b0316336001600160a01b0316146108fd5760405162461bcd60e51b815260040161029e90610e60565b60028460405161090d9190610f89565b90815260408051602092819003830190206000868152925290205460ff161561096c5760405162461bcd60e51b81526020600482015260116024820152704475706c6963617465204d65737361676560781b604482015260640161029e565b600160028560405161097e9190610f89565b9081526040805160209281900383018120600088815293529120805460ff19169215159290921790915560035463bbc22efd60e01b82526001600160a01b03169063bbc22efd906109d790879086908690600401610fb8565b600060405180830381600087803b1580156109f157600080fd5b505af1158015610a05573d6000803e3d6000fd5b5050505050505050565b306001600160a01b031663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a719190610e43565b6001600160a01b0316336001600160a01b031614610aa15760405162461bcd60e51b815260040161029e90610e60565b6004546040516001600160a01b03909116904780156108fc02916000818181858888f19350505050158015610ada573d6000803e3d6000fd5b50565b600060208284031215610aef57600080fd5b5035919050565b60008083601f840112610b0857600080fd5b50813567ffffffffffffffff811115610b2057600080fd5b602083019150836020828501011115610b3857600080fd5b9250929050565b60008060008060608587031215610b5557600080fd5b843567ffffffffffffffff811115610b6c57600080fd5b610b7887828801610af6565b90989097506020870135966040013595509350505050565b6001600160a01b0381168114610ada57600080fd5b60008060408385031215610bb857600080fd5b8235610bc381610b90565b91506020830135610bd381610b90565b809150509250929050565b60008060008060008060006080888a031215610bf957600080fd5b873567ffffffffffffffff80821115610c1157600080fd5b610c1d8b838c01610af6565b909950975060208a0135915080821115610c3657600080fd5b610c428b838c01610af6565b909750955060408a0135945060608a0135915080821115610c6257600080fd5b50610c6f8a828b01610af6565b989b979a50959850939692959293505050565b600060208284031215610c9457600080fd5b813561082a81610b90565b634e487b7160e01b600052604160045260246000fd5b600082601f830112610cc657600080fd5b813567ffffffffffffffff80821115610ce157610ce1610c9f565b604051601f8301601f19908116603f01168101908282118183101715610d0957610d09610c9f565b81604052838152866020858801011115610d2257600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215610d5557600080fd5b823567ffffffffffffffff811115610d6c57600080fd5b610d7885828601610cb5565b92505060208301358015158114610bd357600080fd5b60008060408385031215610da157600080fd5b823567ffffffffffffffff811115610db857600080fd5b610dc485828601610cb5565b95602094909401359450505050565b60008060008060608587031215610de957600080fd5b843567ffffffffffffffff80821115610e0157600080fd5b610e0d88838901610cb5565b9550602087013594506040870135915080821115610e2a57600080fd5b50610e3787828801610af6565b95989497509550505050565b600060208284031215610e5557600080fd5b815161082a81610b90565b6020808252600b908201526a27b7363ca932b630bcb2b960a91b604082015260600190565b8183823760009101908152919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b604081526000610ed2604083018587610e95565b90508215156020830152949350505050565b600060208284031215610ef657600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600060018201610f2557610f25610efd565b5060010190565b606081526000610f40606083018789610e95565b8560208401528281036040840152610f59818587610e95565b98975050505050505050565b60005b83811015610f80578181015183820152602001610f68565b50506000910152565b60008251610f9b818460208701610f65565b9190910192915050565b8082018082111561082d5761082d610efd565b6040815260008451806040840152610fd7816060850160208901610f65565b601f01601f1916820182810360609081016020850152610ffa9082018587610e95565b969550505050505056fea2646970667358221220988c2b72597e86ea20081e428e1996cbd1b3fc7518c0a1d394dfb2760cdedd1764736f6c63430008150033

Deployed Bytecode

0x60806040526004361061009c5760003560e01c80637d4c4f4a116100645780637d4c4f4a146101365780639664da0e1461016957806399f1fca714610199578063b58b4cec146101af578063d294f093146101cf578063f851a440146101e457600080fd5b80632d3fb823146100a157806343f08a89146100c3578063485cc955146100e3578063522a901e14610103578063704b6c0214610116575b600080fd5b3480156100ad57600080fd5b506100c16100bc366004610add565b61020c565b005b3480156100cf57600080fd5b506100c16100de366004610b3f565b610308565b3480156100ef57600080fd5b506100c16100fe366004610ba5565b6103e8565b6100c1610111366004610bde565b610520565b34801561012257600080fd5b506100c1610131366004610c82565b610710565b34801561014257600080fd5b50610156610151366004610d42565b6107c4565b6040519081526020015b60405180910390f35b34801561017557600080fd5b50610189610184366004610d8e565b610833565b6040519015158152602001610160565b3480156101a557600080fd5b5061015660055481565b3480156101bb57600080fd5b506100c16101ca366004610dd3565b61086b565b3480156101db57600080fd5b506100c1610a0f565b3480156101f057600080fd5b506004546040516001600160a01b039091168152602001610160565b306001600160a01b031663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa15801561024a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061026e9190610e43565b6001600160a01b0316336001600160a01b0316146102a75760405162461bcd60e51b815260040161029e90610e60565b60405180910390fd5b60035460405163b070f9e560e01b8152600481018390526001600160a01b039091169063b070f9e590602401600060405180830381600087803b1580156102ed57600080fd5b505af1158015610301573d6000803e3d6000fd5b5050505050565b306001600160a01b031663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa158015610346573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061036a9190610e43565b6001600160a01b0316336001600160a01b03161461039a5760405162461bcd60e51b815260040161029e90610e60565b81600085856040516103ad929190610e85565b90815260200160405180910390208190555080600185856040516103d2929190610e85565b9081526040519081900360200190205550505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff16159067ffffffffffffffff1660008115801561042e5750825b905060008267ffffffffffffffff16600114801561044b5750303b155b905081158015610459575080155b156104775760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156104a157845460ff60401b1916600160401b1785555b600380546001600160a01b038089166001600160a01b03199283161790925560048054928a1692909116919091179055831561051757845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b6003546001600160a01b0316331461057a5760405162461bcd60e51b815260206004820152601f60248201527f4f6e6c79205863616c6c2063616e2063616c6c2073656e644d65737361676500604482015260640161029e565b6000808413156105f457604051633ea627a560e11b81523090637d4c4f4a906105ac908b908b90600190600401610ebe565b602060405180830381865afa1580156105c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ed9190610ee4565b9050610668565b8360000361066857604051633ea627a560e11b81523090637d4c4f4a90610624908b908b90600090600401610ebe565b602060405180830381865afa158015610641573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106659190610ee4565b90505b803410156106b05760405162461bcd60e51b8152602060048201526015602482015274119959481a5cc81b9bdd0814dd59999a58da595b9d605a1b604482015260640161029e565b600580549060006106c083610f13565b91905055507f37be353f216cf7e33639101fd610c542e6a0c0109173fa1c1d8b04d34edb7c1b888860055486866040516106fe959493929190610f2c565b60405180910390a15050505050505050565b306001600160a01b031663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa15801561074e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107729190610e43565b6001600160a01b0316336001600160a01b0316146107a25760405162461bcd60e51b815260040161029e90610e60565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6000806000846040516107d79190610f89565b90815260405190819003602001902054905082151560010361082a5760006001856040516108059190610f89565b9081526040519081900360200190205490506108218183610fa5565b9250505061082d565b90505b92915050565b60006002836040516108459190610f89565b908152604080516020928190038301902060009485529091529091205460ff1692915050565b306001600160a01b031663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108cd9190610e43565b6001600160a01b0316336001600160a01b0316146108fd5760405162461bcd60e51b815260040161029e90610e60565b60028460405161090d9190610f89565b90815260408051602092819003830190206000868152925290205460ff161561096c5760405162461bcd60e51b81526020600482015260116024820152704475706c6963617465204d65737361676560781b604482015260640161029e565b600160028560405161097e9190610f89565b9081526040805160209281900383018120600088815293529120805460ff19169215159290921790915560035463bbc22efd60e01b82526001600160a01b03169063bbc22efd906109d790879086908690600401610fb8565b600060405180830381600087803b1580156109f157600080fd5b505af1158015610a05573d6000803e3d6000fd5b5050505050505050565b306001600160a01b031663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a719190610e43565b6001600160a01b0316336001600160a01b031614610aa15760405162461bcd60e51b815260040161029e90610e60565b6004546040516001600160a01b03909116904780156108fc02916000818181858888f19350505050158015610ada573d6000803e3d6000fd5b50565b600060208284031215610aef57600080fd5b5035919050565b60008083601f840112610b0857600080fd5b50813567ffffffffffffffff811115610b2057600080fd5b602083019150836020828501011115610b3857600080fd5b9250929050565b60008060008060608587031215610b5557600080fd5b843567ffffffffffffffff811115610b6c57600080fd5b610b7887828801610af6565b90989097506020870135966040013595509350505050565b6001600160a01b0381168114610ada57600080fd5b60008060408385031215610bb857600080fd5b8235610bc381610b90565b91506020830135610bd381610b90565b809150509250929050565b60008060008060008060006080888a031215610bf957600080fd5b873567ffffffffffffffff80821115610c1157600080fd5b610c1d8b838c01610af6565b909950975060208a0135915080821115610c3657600080fd5b610c428b838c01610af6565b909750955060408a0135945060608a0135915080821115610c6257600080fd5b50610c6f8a828b01610af6565b989b979a50959850939692959293505050565b600060208284031215610c9457600080fd5b813561082a81610b90565b634e487b7160e01b600052604160045260246000fd5b600082601f830112610cc657600080fd5b813567ffffffffffffffff80821115610ce157610ce1610c9f565b604051601f8301601f19908116603f01168101908282118183101715610d0957610d09610c9f565b81604052838152866020858801011115610d2257600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215610d5557600080fd5b823567ffffffffffffffff811115610d6c57600080fd5b610d7885828601610cb5565b92505060208301358015158114610bd357600080fd5b60008060408385031215610da157600080fd5b823567ffffffffffffffff811115610db857600080fd5b610dc485828601610cb5565b95602094909401359450505050565b60008060008060608587031215610de957600080fd5b843567ffffffffffffffff80821115610e0157600080fd5b610e0d88838901610cb5565b9550602087013594506040870135915080821115610e2a57600080fd5b50610e3787828801610af6565b95989497509550505050565b600060208284031215610e5557600080fd5b815161082a81610b90565b6020808252600b908201526a27b7363ca932b630bcb2b960a91b604082015260600190565b8183823760009101908152919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b604081526000610ed2604083018587610e95565b90508215156020830152949350505050565b600060208284031215610ef657600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600060018201610f2557610f25610efd565b5060010190565b606081526000610f40606083018789610e95565b8560208401528281036040840152610f59818587610e95565b98975050505050505050565b60005b83811015610f80578181015183820152602001610f68565b50506000910152565b60008251610f9b818460208701610f65565b9190910192915050565b8082018082111561082d5761082d610efd565b6040815260008451806040840152610fd7816060850160208901610f65565b601f01601f1916820182810360609081016020850152610ffa9082018587610e95565b969550505050505056fea2646970667358221220988c2b72597e86ea20081e428e1996cbd1b3fc7518c0a1d394dfb2760cdedd1764736f6c63430008150033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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