ETH Price: $2,331.64 (-0.90%)

Contract

0x6fC0BBa2F81C3652E48BD9bD0B2bF0ac6cFE7E9C
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Renounce Ownersh...163856722023-01-11 19:32:471161 days ago1673465567IN
0x6fC0BBa2...c6cFE7E9C
0 ETH0.000787933.58228322
Batch Add Chunke...154309312022-08-29 0:21:251296 days ago1661732485IN
0x6fC0BBa2...c6cFE7E9C
0 ETH0.0081993612.21007765
Batch Add Chunke...154309312022-08-29 0:21:251296 days ago1661732485IN
0x6fC0BBa2...c6cFE7E9C
0 ETH0.0086368712.21007765
Batch Add Chunke...154309312022-08-29 0:21:251296 days ago1661732485IN
0x6fC0BBa2...c6cFE7E9C
0 ETH0.0088720612.21007765
Batch Add Chunke...154309312022-08-29 0:21:251296 days ago1661732485IN
0x6fC0BBa2...c6cFE7E9C
0 ETH0.0127254512.21007765
Batch Add Chunke...154309312022-08-29 0:21:251296 days ago1661732485IN
0x6fC0BBa2...c6cFE7E9C
0 ETH0.0125140212.21007765
Batch Add Chunke...154309312022-08-29 0:21:251296 days ago1661732485IN
0x6fC0BBa2...c6cFE7E9C
0 ETH0.0100654111.66897834
Batch Add Chunke...154309312022-08-29 0:21:251296 days ago1661732485IN
0x6fC0BBa2...c6cFE7E9C
0 ETH0.0094242811.66897834
Batch Add Chunke...154309312022-08-29 0:21:251296 days ago1661732485IN
0x6fC0BBa2...c6cFE7E9C
0 ETH0.0101419111.66897834
Batch Add Chunke...154309312022-08-29 0:21:251296 days ago1661732485IN
0x6fC0BBa2...c6cFE7E9C
0 ETH0.0117212611.66897834
Batch Add Chunke...154309232022-08-29 0:19:331296 days ago1661732373IN
0x6fC0BBa2...c6cFE7E9C
0 ETH0.0091661910.7199335
Batch Add Chunke...154309232022-08-29 0:19:331296 days ago1661732373IN
0x6fC0BBa2...c6cFE7E9C
0 ETH0.0105879210.37387999
Batch Add Chunke...154309232022-08-29 0:19:331296 days ago1661732373IN
0x6fC0BBa2...c6cFE7E9C
0 ETH0.010304510.37387999
Batch Add Chunke...154309232022-08-29 0:19:331296 days ago1661732373IN
0x6fC0BBa2...c6cFE7E9C
0 ETH0.0136426110.37387999
Batch Add Chunke...154309222022-08-29 0:19:131296 days ago1661732353IN
0x6fC0BBa2...c6cFE7E9C
0 ETH0.008825159.69664592
Batch Add Chunke...154309222022-08-29 0:19:131296 days ago1661732353IN
0x6fC0BBa2...c6cFE7E9C
0 ETH0.008774439.69664592
Batch Add Chunke...154309222022-08-29 0:19:131296 days ago1661732353IN
0x6fC0BBa2...c6cFE7E9C
0 ETH0.010138129.69664592
Batch Add Chunke...154309222022-08-29 0:19:131296 days ago1661732353IN
0x6fC0BBa2...c6cFE7E9C
0 ETH0.056363629.69664592

Latest 17 internal transactions

Advanced mode:
Parent Transaction Hash Method Block
From
To
0x67363d3d154309312022-08-29 0:21:251296 days ago1661732485
0x6fC0BBa2...c6cFE7E9C
 Contract Creation0 ETH
0x67363d3d154309312022-08-29 0:21:251296 days ago1661732485
0x6fC0BBa2...c6cFE7E9C
 Contract Creation0 ETH
0x67363d3d154309312022-08-29 0:21:251296 days ago1661732485
0x6fC0BBa2...c6cFE7E9C
 Contract Creation0 ETH
0x67363d3d154309312022-08-29 0:21:251296 days ago1661732485
0x6fC0BBa2...c6cFE7E9C
 Contract Creation0 ETH
0x67363d3d154309312022-08-29 0:21:251296 days ago1661732485
0x6fC0BBa2...c6cFE7E9C
 Contract Creation0 ETH
0x67363d3d154309312022-08-29 0:21:251296 days ago1661732485
0x6fC0BBa2...c6cFE7E9C
 Contract Creation0 ETH
0x67363d3d154309312022-08-29 0:21:251296 days ago1661732485
0x6fC0BBa2...c6cFE7E9C
 Contract Creation0 ETH
0x67363d3d154309312022-08-29 0:21:251296 days ago1661732485
0x6fC0BBa2...c6cFE7E9C
 Contract Creation0 ETH
0x67363d3d154309312022-08-29 0:21:251296 days ago1661732485
0x6fC0BBa2...c6cFE7E9C
 Contract Creation0 ETH
0x67363d3d154309232022-08-29 0:19:331296 days ago1661732373
0x6fC0BBa2...c6cFE7E9C
 Contract Creation0 ETH
0x67363d3d154309232022-08-29 0:19:331296 days ago1661732373
0x6fC0BBa2...c6cFE7E9C
 Contract Creation0 ETH
0x67363d3d154309232022-08-29 0:19:331296 days ago1661732373
0x6fC0BBa2...c6cFE7E9C
 Contract Creation0 ETH
0x67363d3d154309232022-08-29 0:19:331296 days ago1661732373
0x6fC0BBa2...c6cFE7E9C
 Contract Creation0 ETH
0x67363d3d154309222022-08-29 0:19:131296 days ago1661732353
0x6fC0BBa2...c6cFE7E9C
 Contract Creation0 ETH
0x67363d3d154309222022-08-29 0:19:131296 days ago1661732353
0x6fC0BBa2...c6cFE7E9C
 Contract Creation0 ETH
0x67363d3d154309222022-08-29 0:19:131296 days ago1661732353
0x6fC0BBa2...c6cFE7E9C
 Contract Creation0 ETH
0x67363d3d154309222022-08-29 0:19:131296 days ago1661732353
0x6fC0BBa2...c6cFE7E9C
 Contract Creation0 ETH
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ChunkedDataStorage

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.4;
import './libraries/SSTORE2Map.sol';

import '@openzeppelin/contracts/utils/Strings.sol';
import '@openzeppelin/contracts/utils/Base64.sol';
import '@openzeppelin/contracts/access/Ownable.sol';
import '@abf-monorepo/protocol/contracts/libraries/BytesUtils.sol';

contract ChunkedDataStorage is Ownable {
  uint256 public constant MAX_UINT_16 = 0xFFFF;

  mapping(uint256 => uint256) public numLayerDataInChunk;

  uint256 public currentMaxChunksIndex = 0;

  constructor() {}

  function batchAddChunkedData(bytes[] calldata data) public onlyOwner {
    numLayerDataInChunk[currentMaxChunksIndex] = data.length;

    bytes memory chunkedLayerData = '';

    for (uint256 i = 0; i < data.length; ++i) {
      require(
        data[i].length <= MAX_UINT_16,
        'ChunkedDataStorage: data exceeds size of 0xFFFF'
      );
      chunkedLayerData = abi.encodePacked(
        chunkedLayerData,
        uint16(data[i].length),
        data[i]
      );
    }
    SSTORE2Map.write(bytes32(currentMaxChunksIndex), chunkedLayerData);
    currentMaxChunksIndex++;
  }

  function indexToData(uint256 index) public view returns (bytes memory) {
    uint256 currentChunkIndex = 0;
    uint256 currentIndex = 0;
    do {
      currentIndex += numLayerDataInChunk[currentChunkIndex];
      currentChunkIndex++;
      if (numLayerDataInChunk[currentChunkIndex] == 0) {
        break;
      }
    } while (currentIndex <= index);
    currentChunkIndex--;
    currentIndex -= numLayerDataInChunk[currentChunkIndex];
    uint256 localChunkIndex = index - currentIndex;
    bytes memory chunkedData = SSTORE2Map.read(bytes32(currentChunkIndex));
    uint256 localChunkIndexPointer = 0;
    for (uint256 i = 0; i < chunkedData.length; i += 0) {
      if (localChunkIndexPointer == localChunkIndex) {
        return
          BytesUtils.slice(
            chunkedData,
            i + 2,
            BytesUtils.toUint16(chunkedData, i)
          );
      }
      i += BytesUtils.toUint16(chunkedData, i) + 2;
      localChunkIndexPointer++;
    }

    return '';
  }
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import './Create3.sol';

import './Bytecode.sol';

/**
  @title A write-once key-value storage for storing chunks of data with a lower write & read cost.
  @author Agustin Aguilar <aa@horizon.io>
  Readme: https://github.com/0xsequence/sstore2#readme
*/
library SSTORE2Map {
  error WriteError();

  //                                         keccak256(bytes('@0xSequence.SSTORE2Map.slot'))
  bytes32 private constant SLOT_KEY_PREFIX =
    0xd351a9253491dfef66f53115e9e3afda3b5fdef08a1de6937da91188ec553be5;

  function internalKey(bytes32 _key) internal pure returns (bytes32) {
    // Mutate the key so it doesn't collide
    // if the contract is also using CREATE3 for other things
    return keccak256(abi.encode(SLOT_KEY_PREFIX, _key));
  }

  /**
    @notice Stores `_data` and returns `pointer` as key for later retrieval
    @dev The pointer is a contract address with `_data` as code
    @param _data To be written
    @param _key unique string key for accessing the written data (can only be used once)
    @return pointer Pointer to the written `_data`
  */
  function write(string memory _key, bytes memory _data)
    internal
    returns (address pointer)
  {
    return write(keccak256(bytes(_key)), _data);
  }

  /**
    @notice Stores `_data` and returns `pointer` as key for later retrieval
    @dev The pointer is a contract address with `_data` as code
    @param _data to be written
    @param _key unique bytes32 key for accessing the written data (can only be used once)
    @return pointer Pointer to the written `_data`
  */
  function write(bytes32 _key, bytes memory _data)
    internal
    returns (address pointer)
  {
    // Append 00 to _data so contract can't be called
    // Build init code
    bytes memory code = Bytecode.creationCodeFor(
      abi.encodePacked(hex'00', _data)
    );

    // Deploy contract using create3
    pointer = Create3.create3(internalKey(_key), code);
  }

  /**
    @notice Reads the contents for a given `_key`, it maps to a contract code as data, skips the first byte
    @dev The function is intended for reading pointers first written by `write`
    @param _key string key that constains the data
    @return data read from contract associated with `_key`
  */
  function read(string memory _key) internal view returns (bytes memory) {
    return read(keccak256(bytes(_key)));
  }

  /**
    @notice Reads the contents for a given `_key`, it maps to a contract code as data, skips the first byte
    @dev The function is intended for reading pointers first written by `write`
    @param _key string key that constains the data
    @param _start number of bytes to skip
    @return data read from contract associated with `_key`
  */
  function read(string memory _key, uint256 _start)
    internal
    view
    returns (bytes memory)
  {
    return read(keccak256(bytes(_key)), _start);
  }

  /**
    @notice Reads the contents for a given `_key`, it maps to a contract code as data, skips the first byte
    @dev The function is intended for reading pointers first written by `write`
    @param _key string key that constains the data
    @param _start number of bytes to skip
    @param _end index before which to end extraction
    @return data read from contract associated with `_key`
  */
  function read(
    string memory _key,
    uint256 _start,
    uint256 _end
  ) internal view returns (bytes memory) {
    return read(keccak256(bytes(_key)), _start, _end);
  }

  /**
    @notice Reads the contents for a given `_key`, it maps to a contract code as data, skips the first byte
    @dev The function is intended for reading pointers first written by `write`
    @param _key bytes32 key that constains the data
    @return data read from contract associated with `_key`
  */
  function read(bytes32 _key) internal view returns (bytes memory) {
    return
      Bytecode.codeAt(
        Create3.addressOf(internalKey(_key)),
        1,
        type(uint256).max
      );
  }

  /**
    @notice Reads the contents for a given `_key`, it maps to a contract code as data, skips the first byte
    @dev The function is intended for reading pointers first written by `write`
    @param _key bytes32 key that constains the data
    @param _start number of bytes to skip
    @return data read from contract associated with `_key`
  */
  function read(bytes32 _key, uint256 _start)
    internal
    view
    returns (bytes memory)
  {
    return
      Bytecode.codeAt(
        Create3.addressOf(internalKey(_key)),
        _start + 1,
        type(uint256).max
      );
  }

  /**
    @notice Reads the contents for a given `_key`, it maps to a contract code as data, skips the first byte
    @dev The function is intended for reading pointers first written by `write`
    @param _key bytes32 key that constains the data
    @param _start number of bytes to skip
    @param _end index before which to end extraction
    @return data read from contract associated with `_key`
  */
  function read(
    bytes32 _key,
    uint256 _start,
    uint256 _end
  ) internal view returns (bytes memory) {
    return
      Bytecode.codeAt(
        Create3.addressOf(internalKey(_key)),
        _start + 1,
        _end + 1
      );
  }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides a set of functions to operate with Base64 strings.
 *
 * _Available since v4.5._
 */
library Base64 {
    /**
     * @dev Base64 Encoding/Decoding Table
     */
    string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    /**
     * @dev Converts a `bytes` to its Bytes64 `string` representation.
     */
    function encode(bytes memory data) internal pure returns (string memory) {
        /**
         * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence
         * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol
         */
        if (data.length == 0) return "";

        // Loads the table into memory
        string memory table = _TABLE;

        // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter
        // and split into 4 numbers of 6 bits.
        // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up
        // - `data.length + 2`  -> Round up
        // - `/ 3`              -> Number of 3-bytes chunks
        // - `4 *`              -> 4 characters for each chunk
        string memory result = new string(4 * ((data.length + 2) / 3));

        /// @solidity memory-safe-assembly
        assembly {
            // Prepare the lookup table (skip the first "length" byte)
            let tablePtr := add(table, 1)

            // Prepare result pointer, jump over length
            let resultPtr := add(result, 32)

            // Run over the input, 3 bytes at a time
            for {
                let dataPtr := data
                let endPtr := add(data, mload(data))
            } lt(dataPtr, endPtr) {

            } {
                // Advance 3 bytes
                dataPtr := add(dataPtr, 3)
                let input := mload(dataPtr)

                // To write each character, shift the 3 bytes (18 bits) chunk
                // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)
                // and apply logical AND with 0x3F which is the number of
                // the previous character in the ASCII table prior to the Base64 Table
                // The result is then added to the table to get the character to write,
                // and finally write it in the result pointer but with a left shift
                // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits

                mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance
            }

            // When data `bytes` is not exactly 3 bytes long
            // it is padded with `=` characters at the end
            switch mod(mload(data), 3)
            case 1 {
                mstore8(sub(resultPtr, 1), 0x3d)
                mstore8(sub(resultPtr, 2), 0x3d)
            }
            case 2 {
                mstore8(sub(resultPtr, 1), 0x3d)
            }
        }

        return result;
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// SPDX-License-Identifier: MIT
/*
 * @title Solidity Bytes Arrays Utils
 * @author Gonçalo Sá <goncalo.sa@consensys.net>
 *
 * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.
 *      The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.
 */
pragma solidity ^0.8.4;

library BytesUtils {
    function concat(
        bytes memory _preBytes,
        bytes memory _postBytes
    )
        internal
        pure
        returns (bytes memory)
    {
        bytes memory tempBytes;

        assembly {
            // Get a location of some free memory and store it in tempBytes as
            // Solidity does for memory variables.
            tempBytes := mload(0x40)

            // Store the length of the first bytes array at the beginning of
            // the memory for tempBytes.
            let length := mload(_preBytes)
            mstore(tempBytes, length)

            // Maintain a memory counter for the current write location in the
            // temp bytes array by adding the 32 bytes for the array length to
            // the starting location.
            let mc := add(tempBytes, 0x20)
            // Stop copying when the memory counter reaches the length of the
            // first bytes array.
            let end := add(mc, length)

            for {
                // Initialize a copy counter to the start of the _preBytes data,
                // 32 bytes into its memory.
                let cc := add(_preBytes, 0x20)
            } lt(mc, end) {
                // Increase both counters by 32 bytes each iteration.
                mc := add(mc, 0x20)
                cc := add(cc, 0x20)
            } {
                // Write the _preBytes data into the tempBytes memory 32 bytes
                // at a time.
                mstore(mc, mload(cc))
            }

            // Add the length of _postBytes to the current length of tempBytes
            // and store it as the new length in the first 32 bytes of the
            // tempBytes memory.
            length := mload(_postBytes)
            mstore(tempBytes, add(length, mload(tempBytes)))

            // Move the memory counter back from a multiple of 0x20 to the
            // actual end of the _preBytes data.
            mc := end
            // Stop copying when the memory counter reaches the new combined
            // length of the arrays.
            end := add(mc, length)

            for {
                let cc := add(_postBytes, 0x20)
            } lt(mc, end) {
                mc := add(mc, 0x20)
                cc := add(cc, 0x20)
            } {
                mstore(mc, mload(cc))
            }

            // Update the free-memory pointer by padding our last write location
            // to 32 bytes: add 31 bytes to the end of tempBytes to move to the
            // next 32 byte block, then round down to the nearest multiple of
            // 32. If the sum of the length of the two arrays is zero then add
            // one before rounding down to leave a blank 32 bytes (the length block with 0).
            mstore(0x40, and(
              add(add(end, iszero(add(length, mload(_preBytes)))), 31),
              not(31) // Round down to the nearest 32 bytes.
            ))
        }

        return tempBytes;
    }

    function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {
        assembly {
            // Read the first 32 bytes of _preBytes storage, which is the length
            // of the array. (We don't need to use the offset into the slot
            // because arrays use the entire slot.)
            let fslot := sload(_preBytes.slot)
            // Arrays of 31 bytes or less have an even value in their slot,
            // while longer arrays have an odd value. The actual length is
            // the slot divided by two for odd values, and the lowest order
            // byte divided by two for even values.
            // If the slot is even, bitwise and the slot with 255 and divide by
            // two to get the length. If the slot is odd, bitwise and the slot
            // with -1 and divide by two.
            let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
            let mlength := mload(_postBytes)
            let newlength := add(slength, mlength)
            // slength can contain both the length and contents of the array
            // if length < 32 bytes so let's prepare for that
            // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
            switch add(lt(slength, 32), lt(newlength, 32))
            case 2 {
                // Since the new array still fits in the slot, we just need to
                // update the contents of the slot.
                // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length
                sstore(
                    _preBytes.slot,
                    // all the modifications to the slot are inside this
                    // next block
                    add(
                        // we can just add to the slot contents because the
                        // bytes we want to change are the LSBs
                        fslot,
                        add(
                            mul(
                                div(
                                    // load the bytes from memory
                                    mload(add(_postBytes, 0x20)),
                                    // zero all bytes to the right
                                    exp(0x100, sub(32, mlength))
                                ),
                                // and now shift left the number of bytes to
                                // leave space for the length in the slot
                                exp(0x100, sub(32, newlength))
                            ),
                            // increase length by the double of the memory
                            // bytes length
                            mul(mlength, 2)
                        )
                    )
                )
            }
            case 1 {
                // The stored value fits in the slot, but the combined value
                // will exceed it.
                // get the keccak hash to get the contents of the array
                mstore(0x0, _preBytes.slot)
                let sc := add(keccak256(0x0, 0x20), div(slength, 32))

                // save new length
                sstore(_preBytes.slot, add(mul(newlength, 2), 1))

                // The contents of the _postBytes array start 32 bytes into
                // the structure. Our first read should obtain the `submod`
                // bytes that can fit into the unused space in the last word
                // of the stored array. To get this, we read 32 bytes starting
                // from `submod`, so the data we read overlaps with the array
                // contents by `submod` bytes. Masking the lowest-order
                // `submod` bytes allows us to add that value directly to the
                // stored value.

                let submod := sub(32, slength)
                let mc := add(_postBytes, submod)
                let end := add(_postBytes, mlength)
                let mask := sub(exp(0x100, submod), 1)

                sstore(
                    sc,
                    add(
                        and(
                            fslot,
                            0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
                        ),
                        and(mload(mc), mask)
                    )
                )

                for {
                    mc := add(mc, 0x20)
                    sc := add(sc, 1)
                } lt(mc, end) {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } {
                    sstore(sc, mload(mc))
                }

                mask := exp(0x100, sub(mc, end))

                sstore(sc, mul(div(mload(mc), mask), mask))
            }
            default {
                // get the keccak hash to get the contents of the array
                mstore(0x0, _preBytes.slot)
                // Start copying to the last used word of the stored array.
                let sc := add(keccak256(0x0, 0x20), div(slength, 32))

                // save new length
                sstore(_preBytes.slot, add(mul(newlength, 2), 1))

                // Copy over the first `submod` bytes of the new data as in
                // case 1 above.
                let slengthmod := mod(slength, 32)
                let mlengthmod := mod(mlength, 32)
                let submod := sub(32, slengthmod)
                let mc := add(_postBytes, submod)
                let end := add(_postBytes, mlength)
                let mask := sub(exp(0x100, submod), 1)

                sstore(sc, add(sload(sc), and(mload(mc), mask)))

                for {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } lt(mc, end) {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } {
                    sstore(sc, mload(mc))
                }

                mask := exp(0x100, sub(mc, end))

                sstore(sc, mul(div(mload(mc), mask), mask))
            }
        }
    }

    function slice(
        bytes memory _bytes,
        uint256 _start,
        uint256 _length
    )
        internal
        pure
        returns (bytes memory)
    {
        require(_length + 31 >= _length, "slice_overflow");
        require(_bytes.length >= _start + _length, "slice_outOfBounds");

        bytes memory tempBytes;

        assembly {
            switch iszero(_length)
            case 0 {
                // Get a location of some free memory and store it in tempBytes as
                // Solidity does for memory variables.
                tempBytes := mload(0x40)

                // The first word of the slice result is potentially a partial
                // word read from the original array. To read it, we calculate
                // the length of that partial word and start copying that many
                // bytes into the array. The first word we copy will start with
                // data we don't care about, but the last `lengthmod` bytes will
                // land at the beginning of the contents of the new array. When
                // we're done copying, we overwrite the full first word with
                // the actual length of the slice.
                let lengthmod := and(_length, 31)

                // The multiplication in the next line is necessary
                // because when slicing multiples of 32 bytes (lengthmod == 0)
                // the following copy loop was copying the origin's length
                // and then ending prematurely not copying everything it should.
                let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
                let end := add(mc, _length)

                for {
                    // The multiplication in the next line has the same exact purpose
                    // as the one above.
                    let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
                } lt(mc, end) {
                    mc := add(mc, 0x20)
                    cc := add(cc, 0x20)
                } {
                    mstore(mc, mload(cc))
                }

                mstore(tempBytes, _length)

                //update free-memory pointer
                //allocating the array padded to 32 bytes like the compiler does now
                mstore(0x40, and(add(mc, 31), not(31)))
            }
            //if we want a zero-length slice let's just return a zero-length array
            default {
                tempBytes := mload(0x40)
                //zero out the 32 bytes slice we are about to return
                //we need to do it because Solidity does not garbage collect
                mstore(tempBytes, 0)

                mstore(0x40, add(tempBytes, 0x20))
            }
        }

        return tempBytes;
    }

    function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {
        require(_bytes.length >= _start + 20, "toAddress_outOfBounds");
        address tempAddress;

        assembly {
            tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)
        }

        return tempAddress;
    }

    function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {
        require(_bytes.length >= _start + 1 , "toUint8_outOfBounds");
        uint8 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x1), _start))
        }

        return tempUint;
    }

    function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {
        require(_bytes.length >= _start + 2, "toUint16_outOfBounds");
        uint16 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x2), _start))
        }

        return tempUint;
    }

    function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {
        require(_bytes.length >= _start + 4, "toUint32_outOfBounds");
        uint32 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x4), _start))
        }

        return tempUint;
    }

    function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {
        require(_bytes.length >= _start + 8, "toUint64_outOfBounds");
        uint64 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x8), _start))
        }

        return tempUint;
    }

    function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {
        require(_bytes.length >= _start + 12, "toUint96_outOfBounds");
        uint96 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0xc), _start))
        }

        return tempUint;
    }

    function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {
        require(_bytes.length >= _start + 16, "toUint128_outOfBounds");
        uint128 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x10), _start))
        }

        return tempUint;
    }

    function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {
        require(_bytes.length >= _start + 32, "toUint256_outOfBounds");
        uint256 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x20), _start))
        }

        return tempUint;
    }

    function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {
        require(_bytes.length >= _start + 32, "toBytes32_outOfBounds");
        bytes32 tempBytes32;

        assembly {
            tempBytes32 := mload(add(add(_bytes, 0x20), _start))
        }

        return tempBytes32;
    }

    function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {
        bool success = true;

        assembly {
            let length := mload(_preBytes)

            // if lengths don't match the arrays are not equal
            switch eq(length, mload(_postBytes))
            case 1 {
                // cb is a circuit breaker in the for loop since there's
                //  no said feature for inline assembly loops
                // cb = 1 - don't breaker
                // cb = 0 - break
                let cb := 1

                let mc := add(_preBytes, 0x20)
                let end := add(mc, length)

                for {
                    let cc := add(_postBytes, 0x20)
                // the next line is the loop condition:
                // while(uint256(mc < end) + cb == 2)
                } eq(add(lt(mc, end), cb), 2) {
                    mc := add(mc, 0x20)
                    cc := add(cc, 0x20)
                } {
                    // if any of these checks fails then arrays are not equal
                    if iszero(eq(mload(mc), mload(cc))) {
                        // unsuccess:
                        success := 0
                        cb := 0
                    }
                }
            }
            default {
                // unsuccess:
                success := 0
            }
        }

        return success;
    }

    function equalStorage(
        bytes storage _preBytes,
        bytes memory _postBytes
    )
        internal
        view
        returns (bool)
    {
        bool success = true;

        assembly {
            // we know _preBytes_offset is 0
            let fslot := sload(_preBytes.slot)
            // Decode the length of the stored array like in concatStorage().
            let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
            let mlength := mload(_postBytes)

            // if lengths don't match the arrays are not equal
            switch eq(slength, mlength)
            case 1 {
                // slength can contain both the length and contents of the array
                // if length < 32 bytes so let's prepare for that
                // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
                if iszero(iszero(slength)) {
                    switch lt(slength, 32)
                    case 1 {
                        // blank the last byte which is the length
                        fslot := mul(div(fslot, 0x100), 0x100)

                        if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {
                            // unsuccess:
                            success := 0
                        }
                    }
                    default {
                        // cb is a circuit breaker in the for loop since there's
                        //  no said feature for inline assembly loops
                        // cb = 1 - don't breaker
                        // cb = 0 - break
                        let cb := 1

                        // get the keccak hash to get the contents of the array
                        mstore(0x0, _preBytes.slot)
                        let sc := keccak256(0x0, 0x20)

                        let mc := add(_postBytes, 0x20)
                        let end := add(mc, mlength)

                        // the next line is the loop condition:
                        // while(uint256(mc < end) + cb == 2)
                        for {} eq(add(lt(mc, end), cb), 2) {
                            sc := add(sc, 1)
                            mc := add(mc, 0x20)
                        } {
                            if iszero(eq(sload(sc), mload(mc))) {
                                // unsuccess:
                                success := 0
                                cb := 0
                            }
                        }
                    }
                }
            }
            default {
                // unsuccess:
                success := 0
            }
        }

        return success;
    }
}

//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.4;

/**
  @title A library for deploying contracts EIP-3171 style.
  @author Agustin Aguilar <aa@horizon.io>
*/
library Create3 {
  error ErrorCreatingProxy();
  error ErrorCreatingContract();
  error TargetAlreadyExists();

  /**
    @notice The bytecode for a contract that proxies the creation of another contract
    @dev If this code is deployed using CREATE2 it can be used to decouple `creationCode` from the child contract address
  0x67363d3d37363d34f03d5260086018f3:
      0x00  0x67  0x67XXXXXXXXXXXXXXXX  PUSH8 bytecode  0x363d3d37363d34f0
      0x01  0x3d  0x3d                  RETURNDATASIZE  0 0x363d3d37363d34f0
      0x02  0x52  0x52                  MSTORE
      0x03  0x60  0x6008                PUSH1 08        8
      0x04  0x60  0x6018                PUSH1 18        24 8
      0x05  0xf3  0xf3                  RETURN
  0x363d3d37363d34f0:
      0x00  0x36  0x36                  CALLDATASIZE    cds
      0x01  0x3d  0x3d                  RETURNDATASIZE  0 cds
      0x02  0x3d  0x3d                  RETURNDATASIZE  0 0 cds
      0x03  0x37  0x37                  CALLDATACOPY
      0x04  0x36  0x36                  CALLDATASIZE    cds
      0x05  0x3d  0x3d                  RETURNDATASIZE  0 cds
      0x06  0x34  0x34                  CALLVALUE       val 0 cds
      0x07  0xf0  0xf0                  CREATE          addr
  */

  bytes internal constant PROXY_CHILD_BYTECODE =
    hex'67_36_3d_3d_37_36_3d_34_f0_3d_52_60_08_60_18_f3';

  //                        KECCAK256_PROXY_CHILD_BYTECODE = keccak256(PROXY_CHILD_BYTECODE);
  bytes32 internal constant KECCAK256_PROXY_CHILD_BYTECODE =
    0x21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f;

  /**
    @notice Returns the size of the code on a given address
    @param _addr Address that may or may not contain code
    @return size of the code on the given `_addr`
  */
  function codeSize(address _addr) internal view returns (uint256 size) {
    assembly {
      size := extcodesize(_addr)
    }
  }

  /**
    @notice Creates a new contract with given `_creationCode` and `_salt`
    @param _salt Salt of the contract creation, resulting address will be derivated from this value only
    @param _creationCode Creation code (constructor) of the contract to be deployed, this value doesn't affect the resulting address
    @return addr of the deployed contract, reverts on error
  */
  function create3(bytes32 _salt, bytes memory _creationCode)
    internal
    returns (address addr)
  {
    return create3(_salt, _creationCode, 0);
  }

  /**
    @notice Creates a new contract with given `_creationCode` and `_salt`
    @param _salt Salt of the contract creation, resulting address will be derivated from this value only
    @param _creationCode Creation code (constructor) of the contract to be deployed, this value doesn't affect the resulting address
    @param _value In WEI of ETH to be forwarded to child contract
    @return addr of the deployed contract, reverts on error
  */
  function create3(
    bytes32 _salt,
    bytes memory _creationCode,
    uint256 _value
  ) internal returns (address addr) {
    // Creation code
    bytes memory creationCode = PROXY_CHILD_BYTECODE;

    // Get target final address
    addr = addressOf(_salt);
    if (codeSize(addr) != 0) revert TargetAlreadyExists();

    // Create CREATE2 proxy
    address proxy;
    assembly {
      proxy := create2(0, add(creationCode, 32), mload(creationCode), _salt)
    }
    if (proxy == address(0)) revert ErrorCreatingProxy();

    // Call proxy with final init code
    (bool success, ) = proxy.call{value: _value}(_creationCode);
    if (!success || codeSize(addr) == 0) revert ErrorCreatingContract();
  }

  /**
    @notice Computes the resulting address of a contract deployed using address(this) and the given `_salt`
    @param _salt Salt of the contract creation, resulting address will be derivated from this value only
    @return addr of the deployed contract, reverts on error
    @dev The address creation formula is: keccak256(rlp([keccak256(0xff ++ address(this) ++ _salt ++ keccak256(childBytecode))[12:], 0x01]))
  */
  function addressOf(bytes32 _salt) internal view returns (address) {
    address proxy = address(
      uint160(
        uint256(
          keccak256(
            abi.encodePacked(
              hex'ff',
              address(this),
              _salt,
              KECCAK256_PROXY_CHILD_BYTECODE
            )
          )
        )
      )
    );

    return
      address(
        uint160(
          uint256(keccak256(abi.encodePacked(hex'd6_94', proxy, hex'01')))
        )
      );
  }
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

library Bytecode {
  error InvalidCodeAtRange(uint256 _size, uint256 _start, uint256 _end);

  /**
    @notice Generate a creation code that results on a contract with `_code` as bytecode
    @param _code The returning value of the resulting `creationCode`
    @return creationCode (constructor) for new contract
  */
  function creationCodeFor(bytes memory _code)
    internal
    pure
    returns (bytes memory)
  {
    /*
      0x00    0x63         0x63XXXXXX  PUSH4 _code.length  size
      0x01    0x80         0x80        DUP1                size size
      0x02    0x60         0x600e      PUSH1 14            14 size size
      0x03    0x60         0x6000      PUSH1 00            0 14 size size
      0x04    0x39         0x39        CODECOPY            size
      0x05    0x60         0x6000      PUSH1 00            0 size
      0x06    0xf3         0xf3        RETURN
      <CODE>
    */

    return
      abi.encodePacked(
        hex'63',
        uint32(_code.length),
        hex'80_60_0E_60_00_39_60_00_F3',
        _code
      );
  }

  /**
    @notice Returns the size of the code on a given address
    @param _addr Address that may or may not contain code
    @return size of the code on the given `_addr`
  */
  function codeSize(address _addr) internal view returns (uint256 size) {
    assembly {
      size := extcodesize(_addr)
    }
  }

  /**
    @notice Returns the code of a given address
    @dev It will fail if `_end < _start`
    @param _addr Address that may or may not contain code
    @param _start number of bytes of code to skip on read
    @param _end index before which to end extraction
    @return oCode read from `_addr` deployed bytecode
    Forked from: https://gist.github.com/KardanovIR/fe98661df9338c842b4a30306d507fbd
  */
  function codeAt(
    address _addr,
    uint256 _start,
    uint256 _end
  ) internal view returns (bytes memory oCode) {
    uint256 csize = codeSize(_addr);
    if (csize == 0) return bytes('');

    if (_start > csize) return bytes('');
    if (_end < _start) revert InvalidCodeAtRange(csize, _start, _end);

    unchecked {
      uint256 reqSize = _end - _start;
      uint256 maxSize = csize - _start;

      uint256 size = maxSize < reqSize ? maxSize : reqSize;

      assembly {
        // allocate output byte array - this could also be done without assembly
        // by using o_code = new bytes(size)
        oCode := mload(0x40)
        // new "memory end" including padding
        mstore(0x40, add(oCode, and(add(add(size, 0x20), 0x1f), not(0x1f))))
        // store length in memory
        mstore(oCode, size)
        // actually retrieve the code, this needs assembly
        extcodecopy(_addr, add(oCode, 0x20), _start, size)
      }
    }
  }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

Settings
{
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ErrorCreatingContract","type":"error"},{"inputs":[],"name":"ErrorCreatingProxy","type":"error"},{"inputs":[{"internalType":"uint256","name":"_size","type":"uint256"},{"internalType":"uint256","name":"_start","type":"uint256"},{"internalType":"uint256","name":"_end","type":"uint256"}],"name":"InvalidCodeAtRange","type":"error"},{"inputs":[],"name":"TargetAlreadyExists","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"MAX_UINT_16","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"batchAddChunkedData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentMaxChunksIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"indexToData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"numLayerDataInChunk","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6080604052600060025534801561001557600080fd5b5061003261002761003760201b60201c565b61003f60201b60201c565b610103565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6118f2806101126000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063715018a61161005b578063715018a6146101275780638da5cb5b14610131578063a34da3181461014f578063f2fde38b1461016d57610088565b806318ed981a1461008d578063315dbf93146100bd5780635046f071146100d957806357700d33146100f7575b600080fd5b6100a760048036038101906100a29190610ca3565b610189565b6040516100b49190610d69565b60405180910390f35b6100d760048036038101906100d29190610df0565b6102e4565b005b6100e1610446565b6040516100ee9190610e4c565b60405180910390f35b610111600480360381019061010c9190610ca3565b61044c565b60405161011e9190610e4c565b60405180910390f35b61012f610464565b005b610139610478565b6040516101469190610ea8565b60405180910390f35b6101576104a1565b6040516101649190610e4c565b60405180910390f35b61018760048036038101906101829190610eef565b6104a7565b005b60606000805b6001600083815260200190815260200160002054816101ae9190610f4b565b905081806101bb90610fa1565b9250506000600160008481526020019081526020016000205414156101df576101e8565b8381111561018f575b81806101f390610fea565b9250506001600083815260200190815260200160002054816102159190611014565b9050600081856102259190611014565b905060006102358460001b61052b565b90506000805b82518110156102c6578382141561027d576102708360028361025d9190610f4b565b6102678685610570565b61ffff166105d7565b96505050505050506102df565b60026102898483610570565b6102939190611056565b61ffff16816102a29190610f4b565b905081806102af90610fa1565b9250506000816102bf9190610f4b565b905061023b565b5060405180602001604052806000815250955050505050505b919050565b6102ec6106f5565b8181905060016000600254815260200190815260200160002081905550600060405180602001604052806000815250905060005b838390508110156104185761ffff8484838181106103415761034061108e565b5b905060200281019061035391906110cc565b90501115610396576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161038d906111b2565b60405180910390fd5b818484838181106103aa576103a961108e565b5b90506020028101906103bc91906110cc565b90508585848181106103d1576103d061108e565b5b90506020028101906103e391906110cc565b6040516020016103f69493929190611278565b60405160208183030381529060405291508061041190610fa1565b9050610320565b5061042860025460001b82610773565b506002600081548092919061043c90610fa1565b9190505550505050565b60025481565b60016020528060005260406000206000915090505481565b61046c6106f5565b61047660006107bb565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61ffff81565b6104af6106f5565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561051f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161051690611321565b60405180910390fd5b610528816107bb565b50565b606061056961054161053c8461087f565b6108d4565b60017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61095c565b9050919050565b600060028261057f9190610f4b565b835110156105c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b99061138d565b60405180910390fd5b60008260028501015190508091505092915050565b606081601f836105e79190610f4b565b1015610628576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161061f906113f9565b60405180910390fd5b81836106349190610f4b565b84511015610677576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066e90611465565b60405180910390fd5b606082156000811461069857604051915060008252602082016040526106e9565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156106d657805183526020830192506020810190506106b9565b50868552601f19601f8301166040525050505b50809150509392505050565b6106fd610a42565b73ffffffffffffffffffffffffffffffffffffffff1661071b610478565b73ffffffffffffffffffffffffffffffffffffffff1614610771576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610768906114d1565b60405180910390fd5b565b60008061079e8360405160200161078a9190611528565b604051602081830303815290604052610a4a565b90506107b26107ac8561087f565b82610a76565b91505092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60007fd351a9253491dfef66f53115e9e3afda3b5fdef08a1de6937da91188ec553be560001b826040516020016108b7929190611563565b604051602081830303815290604052805190602001209050919050565b60008030837f21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f60001b60405160200161090f93929190611641565b6040516020818303038152906040528051906020012060001c90508060405160200161093b9190611721565b6040516020818303038152906040528051906020012060001c915050919050565b6060600061096985610a8c565b9050600081141561098c5760405180602001604052806000815250915050610a3b565b808411156109ac5760405180602001604052806000815250915050610a3b565b838310156109f5578084846040517f2c4a89fa0000000000000000000000000000000000000000000000000000000081526004016109ec93929190611752565b60405180910390fd5b60008484039050600085830390506000828210610a125782610a14565b815b90506040519450601f19601f60208301011685016040528085528087602087018a3c505050505b9392505050565b600033905090565b6060815182604051602001610a60929190611867565b6040516020818303038152906040529050919050565b6000610a8483836000610a97565b905092915050565b6000813b9050919050565b6000806040518060400160405280601081526020017f67363d3d37363d34f03d5260086018f3000000000000000000000000000000008152509050610adb856108d4565b91506000610ae883610c58565b14610b1f576040517fcd43efa100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000858251602084016000f59050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610b94576040517fbbd2fe8700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff168587604051610bbc91906118a5565b60006040518083038185875af1925050503d8060008114610bf9576040519150601f19603f3d011682016040523d82523d6000602084013e610bfe565b606091505b50509050801580610c1757506000610c1585610c58565b145b15610c4e576040517f53de54b900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050509392505050565b6000813b9050919050565b600080fd5b600080fd5b6000819050919050565b610c8081610c6d565b8114610c8b57600080fd5b50565b600081359050610c9d81610c77565b92915050565b600060208284031215610cb957610cb8610c63565b5b6000610cc784828501610c8e565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610d0a578082015181840152602081019050610cef565b83811115610d19576000848401525b50505050565b6000601f19601f8301169050919050565b6000610d3b82610cd0565b610d458185610cdb565b9350610d55818560208601610cec565b610d5e81610d1f565b840191505092915050565b60006020820190508181036000830152610d838184610d30565b905092915050565b600080fd5b600080fd5b600080fd5b60008083601f840112610db057610daf610d8b565b5b8235905067ffffffffffffffff811115610dcd57610dcc610d90565b5b602083019150836020820283011115610de957610de8610d95565b5b9250929050565b60008060208385031215610e0757610e06610c63565b5b600083013567ffffffffffffffff811115610e2557610e24610c68565b5b610e3185828601610d9a565b92509250509250929050565b610e4681610c6d565b82525050565b6000602082019050610e616000830184610e3d565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610e9282610e67565b9050919050565b610ea281610e87565b82525050565b6000602082019050610ebd6000830184610e99565b92915050565b610ecc81610e87565b8114610ed757600080fd5b50565b600081359050610ee981610ec3565b92915050565b600060208284031215610f0557610f04610c63565b5b6000610f1384828501610eda565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610f5682610c6d565b9150610f6183610c6d565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115610f9657610f95610f1c565b5b828201905092915050565b6000610fac82610c6d565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415610fdf57610fde610f1c565b5b600182019050919050565b6000610ff582610c6d565b9150600082141561100957611008610f1c565b5b600182039050919050565b600061101f82610c6d565b915061102a83610c6d565b92508282101561103d5761103c610f1c565b5b828203905092915050565b600061ffff82169050919050565b600061106182611048565b915061106c83611048565b92508261ffff0382111561108357611082610f1c565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080fd5b600080fd5b600080fd5b600080833560016020038436030381126110e9576110e86110bd565b5b80840192508235915067ffffffffffffffff82111561110b5761110a6110c2565b5b602083019250600182023603831315611127576111266110c7565b5b509250929050565b600082825260208201905092915050565b7f4368756e6b65644461746153746f726167653a2064617461206578636565647360008201527f2073697a65206f66203078464646460000000000000000000000000000000000602082015250565b600061119c602f8361112f565b91506111a782611140565b604082019050919050565b600060208201905081810360008301526111cb8161118f565b9050919050565b600081905092915050565b60006111e882610cd0565b6111f281856111d2565b9350611202818560208601610cec565b80840191505092915050565b60008160f01b9050919050565b60006112268261120e565b9050919050565b61123e61123982611048565b61121b565b82525050565b82818337600083830152505050565b600061125f83856111d2565b935061126c838584611244565b82840190509392505050565b600061128482876111dd565b9150611290828661122d565b6002820191506112a1828486611253565b915081905095945050505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061130b60268361112f565b9150611316826112af565b604082019050919050565b6000602082019050818103600083015261133a816112fe565b9050919050565b7f746f55696e7431365f6f75744f66426f756e6473000000000000000000000000600082015250565b600061137760148361112f565b915061138282611341565b602082019050919050565b600060208201905081810360008301526113a68161136a565b9050919050565b7f736c6963655f6f766572666c6f77000000000000000000000000000000000000600082015250565b60006113e3600e8361112f565b91506113ee826113ad565b602082019050919050565b60006020820190508181036000830152611412816113d6565b9050919050565b7f736c6963655f6f75744f66426f756e6473000000000000000000000000000000600082015250565b600061144f60118361112f565b915061145a82611419565b602082019050919050565b6000602082019050818103600083015261147e81611442565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006114bb60208361112f565b91506114c682611485565b602082019050919050565b600060208201905081810360008301526114ea816114ae565b9050919050565b600081905092915050565b60008082015250565b60006115126001836114f1565b915061151d826114fc565b600182019050919050565b600061153382611505565b915061153f82846111dd565b915081905092915050565b6000819050919050565b61155d8161154a565b82525050565b60006040820190506115786000830185611554565b6115856020830184611554565b9392505050565b7fff00000000000000000000000000000000000000000000000000000000000000600082015250565b60006115c26001836114f1565b91506115cd8261158c565b600182019050919050565b60008160601b9050919050565b60006115f0826115d8565b9050919050565b6000611602826115e5565b9050919050565b61161a61161582610e87565b6115f7565b82525050565b6000819050919050565b61163b6116368261154a565b611620565b82525050565b600061164c826115b5565b91506116588286611609565b601482019150611668828561162a565b602082019150611678828461162a565b602082019150819050949350505050565b7fd694000000000000000000000000000000000000000000000000000000000000600082015250565b60006116bf6002836114f1565b91506116ca82611689565b600282019050919050565b7f0100000000000000000000000000000000000000000000000000000000000000600082015250565b600061170b6001836114f1565b9150611716826116d5565b600182019050919050565b600061172c826116b2565b91506117388284611609565b601482019150611747826116fe565b915081905092915050565b60006060820190506117676000830186610e3d565b6117746020830185610e3d565b6117816040830184610e3d565b949350505050565b7f6300000000000000000000000000000000000000000000000000000000000000600082015250565b60006117bf6001836114f1565b91506117ca82611789565b600182019050919050565b600063ffffffff82169050919050565b60008160e01b9050919050565b60006117fd826117e5565b9050919050565b611815611810826117d5565b6117f2565b82525050565b7f80600e6000396000f30000000000000000000000000000000000000000000000600082015250565b60006118516009836114f1565b915061185c8261181b565b600982019050919050565b6000611872826117b2565b915061187e8285611804565b60048201915061188d82611844565b915061189982846111dd565b91508190509392505050565b60006118b182846111dd565b91508190509291505056fea26469706673582212208855e78b97cc37d969ab98f96df1a9abaa3e5288af5d329f5389e58a9f70de2764736f6c63430008090033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100885760003560e01c8063715018a61161005b578063715018a6146101275780638da5cb5b14610131578063a34da3181461014f578063f2fde38b1461016d57610088565b806318ed981a1461008d578063315dbf93146100bd5780635046f071146100d957806357700d33146100f7575b600080fd5b6100a760048036038101906100a29190610ca3565b610189565b6040516100b49190610d69565b60405180910390f35b6100d760048036038101906100d29190610df0565b6102e4565b005b6100e1610446565b6040516100ee9190610e4c565b60405180910390f35b610111600480360381019061010c9190610ca3565b61044c565b60405161011e9190610e4c565b60405180910390f35b61012f610464565b005b610139610478565b6040516101469190610ea8565b60405180910390f35b6101576104a1565b6040516101649190610e4c565b60405180910390f35b61018760048036038101906101829190610eef565b6104a7565b005b60606000805b6001600083815260200190815260200160002054816101ae9190610f4b565b905081806101bb90610fa1565b9250506000600160008481526020019081526020016000205414156101df576101e8565b8381111561018f575b81806101f390610fea565b9250506001600083815260200190815260200160002054816102159190611014565b9050600081856102259190611014565b905060006102358460001b61052b565b90506000805b82518110156102c6578382141561027d576102708360028361025d9190610f4b565b6102678685610570565b61ffff166105d7565b96505050505050506102df565b60026102898483610570565b6102939190611056565b61ffff16816102a29190610f4b565b905081806102af90610fa1565b9250506000816102bf9190610f4b565b905061023b565b5060405180602001604052806000815250955050505050505b919050565b6102ec6106f5565b8181905060016000600254815260200190815260200160002081905550600060405180602001604052806000815250905060005b838390508110156104185761ffff8484838181106103415761034061108e565b5b905060200281019061035391906110cc565b90501115610396576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161038d906111b2565b60405180910390fd5b818484838181106103aa576103a961108e565b5b90506020028101906103bc91906110cc565b90508585848181106103d1576103d061108e565b5b90506020028101906103e391906110cc565b6040516020016103f69493929190611278565b60405160208183030381529060405291508061041190610fa1565b9050610320565b5061042860025460001b82610773565b506002600081548092919061043c90610fa1565b9190505550505050565b60025481565b60016020528060005260406000206000915090505481565b61046c6106f5565b61047660006107bb565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61ffff81565b6104af6106f5565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561051f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161051690611321565b60405180910390fd5b610528816107bb565b50565b606061056961054161053c8461087f565b6108d4565b60017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61095c565b9050919050565b600060028261057f9190610f4b565b835110156105c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b99061138d565b60405180910390fd5b60008260028501015190508091505092915050565b606081601f836105e79190610f4b565b1015610628576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161061f906113f9565b60405180910390fd5b81836106349190610f4b565b84511015610677576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066e90611465565b60405180910390fd5b606082156000811461069857604051915060008252602082016040526106e9565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156106d657805183526020830192506020810190506106b9565b50868552601f19601f8301166040525050505b50809150509392505050565b6106fd610a42565b73ffffffffffffffffffffffffffffffffffffffff1661071b610478565b73ffffffffffffffffffffffffffffffffffffffff1614610771576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610768906114d1565b60405180910390fd5b565b60008061079e8360405160200161078a9190611528565b604051602081830303815290604052610a4a565b90506107b26107ac8561087f565b82610a76565b91505092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60007fd351a9253491dfef66f53115e9e3afda3b5fdef08a1de6937da91188ec553be560001b826040516020016108b7929190611563565b604051602081830303815290604052805190602001209050919050565b60008030837f21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f60001b60405160200161090f93929190611641565b6040516020818303038152906040528051906020012060001c90508060405160200161093b9190611721565b6040516020818303038152906040528051906020012060001c915050919050565b6060600061096985610a8c565b9050600081141561098c5760405180602001604052806000815250915050610a3b565b808411156109ac5760405180602001604052806000815250915050610a3b565b838310156109f5578084846040517f2c4a89fa0000000000000000000000000000000000000000000000000000000081526004016109ec93929190611752565b60405180910390fd5b60008484039050600085830390506000828210610a125782610a14565b815b90506040519450601f19601f60208301011685016040528085528087602087018a3c505050505b9392505050565b600033905090565b6060815182604051602001610a60929190611867565b6040516020818303038152906040529050919050565b6000610a8483836000610a97565b905092915050565b6000813b9050919050565b6000806040518060400160405280601081526020017f67363d3d37363d34f03d5260086018f3000000000000000000000000000000008152509050610adb856108d4565b91506000610ae883610c58565b14610b1f576040517fcd43efa100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000858251602084016000f59050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610b94576040517fbbd2fe8700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff168587604051610bbc91906118a5565b60006040518083038185875af1925050503d8060008114610bf9576040519150601f19603f3d011682016040523d82523d6000602084013e610bfe565b606091505b50509050801580610c1757506000610c1585610c58565b145b15610c4e576040517f53de54b900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050509392505050565b6000813b9050919050565b600080fd5b600080fd5b6000819050919050565b610c8081610c6d565b8114610c8b57600080fd5b50565b600081359050610c9d81610c77565b92915050565b600060208284031215610cb957610cb8610c63565b5b6000610cc784828501610c8e565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610d0a578082015181840152602081019050610cef565b83811115610d19576000848401525b50505050565b6000601f19601f8301169050919050565b6000610d3b82610cd0565b610d458185610cdb565b9350610d55818560208601610cec565b610d5e81610d1f565b840191505092915050565b60006020820190508181036000830152610d838184610d30565b905092915050565b600080fd5b600080fd5b600080fd5b60008083601f840112610db057610daf610d8b565b5b8235905067ffffffffffffffff811115610dcd57610dcc610d90565b5b602083019150836020820283011115610de957610de8610d95565b5b9250929050565b60008060208385031215610e0757610e06610c63565b5b600083013567ffffffffffffffff811115610e2557610e24610c68565b5b610e3185828601610d9a565b92509250509250929050565b610e4681610c6d565b82525050565b6000602082019050610e616000830184610e3d565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610e9282610e67565b9050919050565b610ea281610e87565b82525050565b6000602082019050610ebd6000830184610e99565b92915050565b610ecc81610e87565b8114610ed757600080fd5b50565b600081359050610ee981610ec3565b92915050565b600060208284031215610f0557610f04610c63565b5b6000610f1384828501610eda565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610f5682610c6d565b9150610f6183610c6d565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115610f9657610f95610f1c565b5b828201905092915050565b6000610fac82610c6d565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415610fdf57610fde610f1c565b5b600182019050919050565b6000610ff582610c6d565b9150600082141561100957611008610f1c565b5b600182039050919050565b600061101f82610c6d565b915061102a83610c6d565b92508282101561103d5761103c610f1c565b5b828203905092915050565b600061ffff82169050919050565b600061106182611048565b915061106c83611048565b92508261ffff0382111561108357611082610f1c565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080fd5b600080fd5b600080fd5b600080833560016020038436030381126110e9576110e86110bd565b5b80840192508235915067ffffffffffffffff82111561110b5761110a6110c2565b5b602083019250600182023603831315611127576111266110c7565b5b509250929050565b600082825260208201905092915050565b7f4368756e6b65644461746153746f726167653a2064617461206578636565647360008201527f2073697a65206f66203078464646460000000000000000000000000000000000602082015250565b600061119c602f8361112f565b91506111a782611140565b604082019050919050565b600060208201905081810360008301526111cb8161118f565b9050919050565b600081905092915050565b60006111e882610cd0565b6111f281856111d2565b9350611202818560208601610cec565b80840191505092915050565b60008160f01b9050919050565b60006112268261120e565b9050919050565b61123e61123982611048565b61121b565b82525050565b82818337600083830152505050565b600061125f83856111d2565b935061126c838584611244565b82840190509392505050565b600061128482876111dd565b9150611290828661122d565b6002820191506112a1828486611253565b915081905095945050505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061130b60268361112f565b9150611316826112af565b604082019050919050565b6000602082019050818103600083015261133a816112fe565b9050919050565b7f746f55696e7431365f6f75744f66426f756e6473000000000000000000000000600082015250565b600061137760148361112f565b915061138282611341565b602082019050919050565b600060208201905081810360008301526113a68161136a565b9050919050565b7f736c6963655f6f766572666c6f77000000000000000000000000000000000000600082015250565b60006113e3600e8361112f565b91506113ee826113ad565b602082019050919050565b60006020820190508181036000830152611412816113d6565b9050919050565b7f736c6963655f6f75744f66426f756e6473000000000000000000000000000000600082015250565b600061144f60118361112f565b915061145a82611419565b602082019050919050565b6000602082019050818103600083015261147e81611442565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006114bb60208361112f565b91506114c682611485565b602082019050919050565b600060208201905081810360008301526114ea816114ae565b9050919050565b600081905092915050565b60008082015250565b60006115126001836114f1565b915061151d826114fc565b600182019050919050565b600061153382611505565b915061153f82846111dd565b915081905092915050565b6000819050919050565b61155d8161154a565b82525050565b60006040820190506115786000830185611554565b6115856020830184611554565b9392505050565b7fff00000000000000000000000000000000000000000000000000000000000000600082015250565b60006115c26001836114f1565b91506115cd8261158c565b600182019050919050565b60008160601b9050919050565b60006115f0826115d8565b9050919050565b6000611602826115e5565b9050919050565b61161a61161582610e87565b6115f7565b82525050565b6000819050919050565b61163b6116368261154a565b611620565b82525050565b600061164c826115b5565b91506116588286611609565b601482019150611668828561162a565b602082019150611678828461162a565b602082019150819050949350505050565b7fd694000000000000000000000000000000000000000000000000000000000000600082015250565b60006116bf6002836114f1565b91506116ca82611689565b600282019050919050565b7f0100000000000000000000000000000000000000000000000000000000000000600082015250565b600061170b6001836114f1565b9150611716826116d5565b600182019050919050565b600061172c826116b2565b91506117388284611609565b601482019150611747826116fe565b915081905092915050565b60006060820190506117676000830186610e3d565b6117746020830185610e3d565b6117816040830184610e3d565b949350505050565b7f6300000000000000000000000000000000000000000000000000000000000000600082015250565b60006117bf6001836114f1565b91506117ca82611789565b600182019050919050565b600063ffffffff82169050919050565b60008160e01b9050919050565b60006117fd826117e5565b9050919050565b611815611810826117d5565b6117f2565b82525050565b7f80600e6000396000f30000000000000000000000000000000000000000000000600082015250565b60006118516009836114f1565b915061185c8261181b565b600982019050919050565b6000611872826117b2565b915061187e8285611804565b60048201915061188d82611844565b915061189982846111dd565b91508190509392505050565b60006118b182846111dd565b91508190509291505056fea26469706673582212208855e78b97cc37d969ab98f96df1a9abaa3e5288af5d329f5389e58a9f70de2764736f6c63430008090033

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.