ETH Price: $2,166.78 (+1.09%)

Transaction Decoder

Block:
21436923 at Dec-19-2024 01:40:11 PM +UTC
Transaction Fee:
0.0018811977044662 ETH $4.08
Gas Used:
142,312 Gas / 13.218826975 Gwei

Account State Difference:

  Address   Before After State Difference Code
0x11b0E7Be...4584B1161
1.500147095785743204 Eth
Nonce: 232
1.498265898081277004 Eth
Nonce: 233
0.0018811977044662
(Fee Recipient: 0x48c6...876)
0.874408924477493648 Eth0.874409817280364368 Eth0.00000089280287072
0xb1703AD0...E689C5df9

Execution Trace

0x9a59b249b6ea7aad4a51dca08406ce0a1d6f3b01.fab13a30( )
  • StateOracle.STATICCALL( )
  • 0xbcba1f21ca212f63f71536128d9e574dc3ae28d9.4d8d3d8c( )
    • Null: 0x000...001.6a22be02( )
    • Null: 0x000...001.6a22be02( )
    • Null: 0x000...001.6a22be02( )
    • Null: 0x000...001.6a22be02( )
    • Null: 0x000...001.6a22be02( )
    • Null: 0x000...001.6a22be02( )
    • Null: 0x000...001.6a22be02( )
    • StateOracle.update( blockNum=698600, stateRoot=4E5973406C1ECB2761D26D5BC113F7F2E292E46C04A4C72D785DC7D274E21A02 )
    • 0xbcba1f21ca212f63f71536128d9e574dc3ae28d9.87bdb56d( )
    • 0xbcba1f21ca212f63f71536128d9e574dc3ae28d9.87bdb56d( )
      // SPDX-License-Identifier: MIT
      // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
      pragma solidity ^0.8.20;
      import {Context} from "../utils/Context.sol";
      /**
       * @dev Contract module which provides a basic access control mechanism, where
       * there is an account (an owner) that can be granted exclusive access to
       * specific functions.
       *
       * The initial owner is set to the address provided by the deployer. This can
       * later be changed with {transferOwnership}.
       *
       * This module is used through inheritance. It will make available the modifier
       * `onlyOwner`, which can be applied to your functions to restrict their use to
       * the owner.
       */
      abstract contract Ownable is Context {
          address private _owner;
          /**
           * @dev The caller account is not authorized to perform an operation.
           */
          error OwnableUnauthorizedAccount(address account);
          /**
           * @dev The owner is not a valid owner account. (eg. `address(0)`)
           */
          error OwnableInvalidOwner(address owner);
          event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
          /**
           * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
           */
          constructor(address initialOwner) {
              if (initialOwner == address(0)) {
                  revert OwnableInvalidOwner(address(0));
              }
              _transferOwnership(initialOwner);
          }
          /**
           * @dev Throws if called by any account other than the owner.
           */
          modifier onlyOwner() {
              _checkOwner();
              _;
          }
          /**
           * @dev Returns the address of the current owner.
           */
          function owner() public view virtual returns (address) {
              return _owner;
          }
          /**
           * @dev Throws if the sender is not the owner.
           */
          function _checkOwner() internal view virtual {
              if (owner() != _msgSender()) {
                  revert OwnableUnauthorizedAccount(_msgSender());
              }
          }
          /**
           * @dev Leaves the contract without owner. It will not be possible to call
           * `onlyOwner` functions. Can only be called by the current owner.
           *
           * NOTE: Renouncing ownership will leave the contract without an owner,
           * thereby disabling any functionality that is only available to the owner.
           */
          function renounceOwnership() public virtual onlyOwner {
              _transferOwnership(address(0));
          }
          /**
           * @dev Transfers ownership of the contract to a new account (`newOwner`).
           * Can only be called by the current owner.
           */
          function transferOwnership(address newOwner) public virtual onlyOwner {
              if (newOwner == address(0)) {
                  revert OwnableInvalidOwner(address(0));
              }
              _transferOwnership(newOwner);
          }
          /**
           * @dev Transfers ownership of the contract to a new account (`newOwner`).
           * Internal function without access restriction.
           */
          function _transferOwnership(address newOwner) internal virtual {
              address oldOwner = _owner;
              _owner = newOwner;
              emit OwnershipTransferred(oldOwner, newOwner);
          }
      }
      // SPDX-License-Identifier: MIT
      // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
      pragma solidity ^0.8.20;
      /**
       * @dev Provides information about the current execution context, including the
       * sender of the transaction and its data. While these are generally available
       * via msg.sender and msg.data, they should not be accessed in such a direct
       * manner, since when dealing with meta-transactions the account sending and
       * paying for execution may not be the actual sender (as far as an application
       * is concerned).
       *
       * This contract is only required for intermediate, library-like contracts.
       */
      abstract contract Context {
          function _msgSender() internal view virtual returns (address) {
              return msg.sender;
          }
          function _msgData() internal view virtual returns (bytes calldata) {
              return msg.data;
          }
          function _contextSuffixLength() internal view virtual returns (uint256) {
              return 0;
          }
      }
      // SPDX-License-Identifier: UNLICENSED
      pragma solidity 0.8.27;
      /// State oracle provides the hash of a different chain state.
      interface IStateOracle {
          function lastState() external view returns (bytes32);
          function lastBlockNum() external view returns (uint256);
          function lastUpdateTime() external view returns (uint256);
          function chainId() external view returns (uint256);
          function update(uint256 blockNum, bytes32 stateRoot) external;
      }
      // SPDX-License-Identifier: UNLICENSED
      pragma solidity 0.8.27;
      import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
      import {IStateOracle} from "./interfaces/IStateOracle.sol";
      /// Oracle providing the state hash of a monitored chain.
      /// To be owned and updated by UpdateManager contract.
      /// @custom:security-contact security@fantom.foundation
      contract StateOracle is IStateOracle, Ownable {
          bytes32 public lastState;
          uint256 public lastBlockNum;
          uint256 public lastUpdateTime;
          uint256 public immutable chainId; // of the monitored chain
          constructor(address _ownedBy, uint256 _chainId) Ownable(_ownedBy) {
              require(_chainId != 0, "Chain id not set");
              chainId = _chainId;
          }
          /// Update the state. Callable by UpdateManager.
          function update(uint256 blockNum, bytes32 stateRoot) external onlyOwner {
              require(blockNum > lastBlockNum, "Unable to revert to older state");
              lastState = stateRoot;
              lastBlockNum = blockNum;
              lastUpdateTime = block.timestamp;
          }
      }