ETH Price: $2,375.56 (-2.66%)

Contract

0x9E0f2864C6f125bBf599dF6Ca6e6c3774c5B2E04
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Create File186882172023-12-01 1:14:11313 days ago1701393251IN
0x9E0f2864...74c5B2E04
0 ETH0.0111599733.15826383
Create File186882142023-12-01 1:13:35313 days ago1701393215IN
0x9E0f2864...74c5B2E04
0 ETH0.0136295632.8687781

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block From To
186881562023-12-01 1:01:47313 days ago1701392507  Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
FileSystem

Compiler Version
v0.8.23+commit.f704f362

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion
File 1 of 7 : FileSystem.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import {SSTORE2} from "sstore2/SSTORE2.sol";

import {IContentStore} from "ethfs/packages/contracts/src/IContentStore.sol";
import {IFileSystem, Directory, File, Inode, InodeType} from "src/interfaces/IFileSystem.sol";

import "src/utils/Constants.sol";

/**
 * @title FileSystem
 * @author fx(hash)
 * @notice See the documentation in {IFileSystem}
 */
contract FileSystem is IFileSystem {
    /*//////////////////////////////////////////////////////////////////////////
                                    STORAGE
    //////////////////////////////////////////////////////////////////////////*/

    address internal constant GOERLI_CONTENT_STORE = 0x7c1730B7bE9424D0b983B84aEb254e3a2a105d91;
    address internal constant MAINNET_CONTENT_STORE = 0xC6806fd75745bB5F5B32ADa19963898155f9DB91;

    /**
     * @inheritdoc IFileSystem
     */
    address public immutable CONTENT_STORE;

    /**
     * @inheritdoc IFileSystem
     */
    mapping(bytes32 checksum => Inode inode) public inodes;

    /*//////////////////////////////////////////////////////////////////////////
                                  CONSTRUCTOR
    //////////////////////////////////////////////////////////////////////////*/

    /**
     * @dev Initializes the ContentStore contract
     */
    constructor() {
        CONTENT_STORE = block.chainid == 1 ? MAINNET_CONTENT_STORE : GOERLI_CONTENT_STORE;
    }

    /*//////////////////////////////////////////////////////////////////////////
                                  EXTERNAL FUNCTIONS
    //////////////////////////////////////////////////////////////////////////*/

    /**
     * @inheritdoc IFileSystem
     */
    function createDirectory(
        string[] calldata _fileNames,
        bytes32[] calldata _inodeChecksums
    ) external returns (bytes32 directoryChecksum) {
        if (_fileNames.length != _inodeChecksums.length) revert LengthMismatch();
        bytes memory concatenatedFiles = concatenateFiles(_fileNames, _inodeChecksums);

        for (uint256 i; i < _inodeChecksums.length; i++) {
            if (!inodeExists(_inodeChecksums[i])) revert InodeNotFound();
        }
        directoryChecksum = keccak256(bytes.concat(bytes1(uint8(InodeType.Directory)), concatenatedFiles));
        if (inodeExists(directoryChecksum)) return directoryChecksum;
        inodes[directoryChecksum].directory = Directory(_fileNames, _inodeChecksums);
        emit DirectoryCreated(directoryChecksum, _fileNames, _inodeChecksums);
    }

    /**
     * @inheritdoc IFileSystem
     */
    function createFile(
        bytes calldata _metadata,
        bytes32[] calldata _chunkPointers
    ) external returns (bytes32 fileChecksum) {
        for (uint256 i; i < _chunkPointers.length; i++) {
            if (!IContentStore(CONTENT_STORE).checksumExists(_chunkPointers[i])) revert ChunkNotFound();
        }
        fileChecksum = keccak256(
            bytes.concat(
                bytes1(uint8(InodeType.File)),
                keccak256(abi.encodePacked(_chunkPointers)),
                keccak256(_metadata)
            )
        );
        if (inodeExists(fileChecksum)) return fileChecksum;
        inodes[fileChecksum].inodeType = InodeType.File;
        inodes[fileChecksum].file = File(_metadata, _chunkPointers);
        emit FileCreated(fileChecksum, _metadata, _chunkPointers);
    }

    /**
     * @inheritdoc IFileSystem
     */
    function readDirectory(bytes32 _checksum) external view returns (string[] memory, bytes32[] memory) {
        if (!inodeExists(_checksum)) revert InodeNotFound();
        Inode memory inode = inodes[_checksum];
        if (inode.inodeType != InodeType.Directory) revert DirectoryNotFound();
        return (inode.directory.filenames, inode.directory.fileChecksums);
    }

    /**
     * @inheritdoc IFileSystem
     */
    function readFile(bytes32 _checksum) external view returns (bytes memory) {
        if (!inodeExists(_checksum)) revert InodeNotFound();
        Inode memory inode = inodes[_checksum];
        if (inode.inodeType != InodeType.File) revert FileNotFound();
        return concatenateChunks(inode.file.chunkChecksums);
    }

    /*//////////////////////////////////////////////////////////////////////////
                                  PUBLIC FUNCTIONS
    //////////////////////////////////////////////////////////////////////////*/

    /**
     * @inheritdoc IFileSystem
     */
    function concatenateChunks(bytes32[] memory _pointers) public view returns (bytes memory fileContent) {
        address pointer;
        bytes memory chunkContent;
        for (uint256 i; i < _pointers.length; i++) {
            pointer = IContentStore(CONTENT_STORE).getPointer(_pointers[i]);
            chunkContent = SSTORE2.read(pointer);
            fileContent = abi.encodePacked(fileContent, chunkContent);
        }
    }

    /**
     * @inheritdoc IFileSystem
     */
    function concatenateFiles(
        string[] calldata _fileNames,
        bytes32[] calldata _filePointers
    ) public pure returns (bytes memory concatenatedFiles) {
        uint256 length = _fileNames.length;
        bytes memory filename;
        for (uint256 i; i < length; i++) {
            filename = bytes(_fileNames[i]);
            if (filename.length == 0) revert InvalidFileName();
            if (_containsForbiddenChars(filename)) revert InvalidCharacter();
            concatenatedFiles = abi.encodePacked(_filePointers[i], keccak256(filename), concatenatedFiles);
        }
    }

    /**
     * @inheritdoc IFileSystem
     */
    function inodeExists(bytes32 _checksum) public view returns (bool) {
        Inode memory inode = inodes[_checksum];
        if (inode.inodeType == InodeType.File) {
            return inode.file.metadata.length != 0 || inode.file.chunkChecksums.length != 0;
        } else {
            return inode.directory.filenames.length != 0 || inode.directory.fileChecksums.length != 0;
        }
    }

    /*//////////////////////////////////////////////////////////////////////////
                                  PRIVATE FUNCTIONS
    //////////////////////////////////////////////////////////////////////////*/

    /**
     * @dev Checks if the given string contains any forbidden characters
     */
    function _containsForbiddenChars(bytes memory _string) private pure returns (bool) {
        uint256 length = _string.length;
        for (uint256 i; i < length; i++) {
            for (uint256 j; j < FORBIDDEN_CHARS.length; j++) {
                if (_string[i] == FORBIDDEN_CHARS[j]) {
                    return true;
                }
            }
        }
        return false;
    }

    function getInodeAt(
        bytes32 _inodeChecksum,
        string[] memory _pathSegments
    ) public view returns (bytes32, Inode memory) {
        if (!inodeExists(_inodeChecksum)) revert InodeNotFound();

        Inode memory inode = inodes[_inodeChecksum];
        bytes32 inodeChecksum = _inodeChecksum;

        uint256 length = _pathSegments.length;
        Directory memory directory;
        string[] memory filenames;
        bool found;
        for (uint256 i; i < length; i++) {
            if (inode.inodeType != InodeType.Directory) revert InodeNotFound();
            directory = inode.directory;
            filenames = inode.directory.filenames;
            found = false;
            for (uint256 j; j < filenames.length; j++) {
                if (keccak256(bytes(filenames[j])) == keccak256(bytes(_pathSegments[i]))) {
                    found = true;
                    inodeChecksum = directory.fileChecksums[j];
                    inode = inodes[inodeChecksum];
                    break;
                }
            }
            if (!found) revert InodeNotFound();
        }
        return (inodeChecksum, inode);
    }
}

File 2 of 7 : SSTORE2.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./utils/Bytecode.sol";

/**
  @title A key-value storage with auto-generated keys for storing chunks of data with a lower write & read cost.
  @author Agustin Aguilar <[email protected]>

  Readme: https://github.com/0xsequence/sstore2#readme
*/
library SSTORE2 {
  error WriteError();

  /**
    @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
    @return pointer Pointer to the written `_data`
  */
  function write(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 create
    assembly { pointer := create(0, add(code, 32), mload(code)) }

    // Address MUST be non-zero
    if (pointer == address(0)) revert WriteError();
  }

  /**
    @notice Reads the contents of the `_pointer` code as data, skips the first byte 
    @dev The function is intended for reading pointers generated by `write`
    @param _pointer to be read
    @return data read from `_pointer` contract
  */
  function read(address _pointer) internal view returns (bytes memory) {
    return Bytecode.codeAt(_pointer, 1, type(uint256).max);
  }

  /**
    @notice Reads the contents of the `_pointer` code as data, skips the first byte 
    @dev The function is intended for reading pointers generated by `write`
    @param _pointer to be read
    @param _start number of bytes to skip
    @return data read from `_pointer` contract
  */
  function read(address _pointer, uint256 _start) internal view returns (bytes memory) {
    return Bytecode.codeAt(_pointer, _start + 1, type(uint256).max);
  }

  /**
    @notice Reads the contents of the `_pointer` code as data, skips the first byte 
    @dev The function is intended for reading pointers generated by `write`
    @param _pointer to be read
    @param _start number of bytes to skip
    @param _end index before which to end extraction
    @return data read from `_pointer` contract
  */
  function read(address _pointer, uint256 _start, uint256 _end) internal view returns (bytes memory) {
    return Bytecode.codeAt(_pointer, _start + 1, _end + 1);
  }
}

File 3 of 7 : IContentStore.sol
// SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.13;

interface IContentStore {
    event NewChecksum(bytes32 indexed checksum, uint256 contentSize);

    error ChecksumExists(bytes32 checksum);
    error ChecksumNotFound(bytes32 checksum);

    function pointers(bytes32 checksum)
        external
        view
        returns (address pointer);

    function checksumExists(bytes32 checksum) external view returns (bool);

    function contentLength(bytes32 checksum)
        external
        view
        returns (uint256 size);

    function addPointer(address pointer) external returns (bytes32 checksum);

    function addContent(bytes memory content)
        external
        returns (bytes32 checksum, address pointer);

    function getPointer(bytes32 checksum)
        external
        view
        returns (address pointer);
}

File 4 of 7 : IFileSystem.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import {Directory, File, Inode, InodeType} from "src/lib/Structs.sol";

/**
 * @title IFileSystem
 * @author fx(hash)
 * @notice System for storing and retrieving files onchain
 */
interface IFileSystem {
    /*//////////////////////////////////////////////////////////////////////////
                                  Events
    //////////////////////////////////////////////////////////////////////////*/

    /**
     * @notice Event emitted when creating a new file inode
     */
    event FileCreated(bytes32 indexed _checksum, bytes metadata, bytes32[] _chunkPointers);

    /**
     * @notice Event emitted when creating a new directory inode
     */
    event DirectoryCreated(bytes32 indexed _checksum, string[] _names, bytes32[] _inodeChecksums);

    /*//////////////////////////////////////////////////////////////////////////
                                  ERRORS
    //////////////////////////////////////////////////////////////////////////*/

    /**
     * @notice Error thrown when attempting to read chunk that does not exist
     */
    error ChunkNotFound();
    /**
     * @notice Error thrown when reading a directory that does not exist
     */
    error DirectoryNotFound();

    /**
     * @notice Error thrown when attempting to read a file that does not exist
     */
    error FileNotFound();

    /**
     * @notice Error thrown when attempting to read an inode that does not exist
     */
    error InodeNotFound();

    /**
     * @notice Error thrown when file name is empty
     */
    error InvalidFileName();

    /**
     * @notice Error thrown when a forbidden character is present
     */
    error InvalidCharacter();

    /**
     * @notice Error thrown when array lengths do not match
     */
    error LengthMismatch();

    /*//////////////////////////////////////////////////////////////////////////
                                  FUNCTIONS
    //////////////////////////////////////////////////////////////////////////*/

    /**
     * @notice Concatenates the content of file chunks from the given pointers
     * @param _chunkChecksums Checksums for the file chunks
     * @return Concatenated content of the file chunks
     */
    function concatenateChunks(bytes32[] memory _chunkChecksums) external view returns (bytes memory);

    /**
     * @notice Returns the address of the ContentStore contract
     */
    function CONTENT_STORE() external view returns (address);

    /**
     * @notice Creates a new directory with the given names and file inode pointers
     * @param _fileNames The names of the files in the directory
     * @param _fileChecksums Pointers to the file inodes in the directory
     */
    function createDirectory(
        string[] calldata _fileNames,
        bytes32[] calldata _fileChecksums
    ) external returns (bytes32 directoryChecksum);

    /**
     * @notice Creates a new file with the given metadata and chunk pointers
     * @param _metadata Metadata of the file
     * @param _chunkChecksums Checksums for chunks of the file
     */
    function createFile(
        bytes calldata _metadata,
        bytes32[] calldata _chunkChecksums
    ) external returns (bytes32 fileChecksum);

    function getInodeAt(
        bytes32 _inodeChecksum,
        string[] memory _pathSegments
    ) external view returns (bytes32, Inode memory);

    /**
     * @notice Hashes a list of file names in the directory
     * @param _fileNames List of file names
     * @param _inodeChecksums List of checksums for the inodes
     * @return The concatenated files
     */
    function concatenateFiles(
        string[] calldata _fileNames,
        bytes32[] calldata _inodeChecksums
    ) external view returns (bytes memory);

    /**
     * @notice Mapping of checksum pointer to Inode struct
     */
    function inodes(bytes32 _checksum) external view returns (InodeType, File memory, Directory memory);

    /**
     * @notice Checks if an inode with the given checksum exists
     * @param _checksum Checksum of the inode
     * @return Status of inode existence
     */
    function inodeExists(bytes32 _checksum) external view returns (bool);

    /**
     * @notice Reads the content of a directory with the given checksum
     * @param _checksum Checksum of the directory
     * @return Names and file inode pointers in the directory
     */
    function readDirectory(bytes32 _checksum) external view returns (string[] memory, bytes32[] memory);

    /**
     * @notice Reads the content of a file with the given checksum
     * @param _checksum Checksum of the file
     * @return Content of the file
     */
    function readFile(bytes32 _checksum) external view returns (bytes memory);
}

File 5 of 7 : Constants.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

/*//////////////////////////////////////////////////////////////////////////
                                CONSTANTS
//////////////////////////////////////////////////////////////////////////*/

bytes constant FORBIDDEN_CHARS = ":/?#[]@!$&'()*+,;=";

File 6 of 7 : Bytecode.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;


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)
      }
    }
  }
}

File 7 of 7 : Structs.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

/*//////////////////////////////////////////////////////////////////////////
                                STRUCTS
//////////////////////////////////////////////////////////////////////////*/

enum InodeType {
    Directory,
    File
}

struct Directory {
    string[] filenames;
    bytes32[] fileChecksums;
}

struct File {
    bytes metadata;
    bytes32[] chunkChecksums;
}

struct Inode {
    InodeType inodeType;
    File file;
    Directory directory;
}

Settings
{
  "remappings": [
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "ethfs/=lib/ethfs/",
    "ethier/=lib/ethfs/packages/contracts/lib/ethier/",
    "forge-std/=lib/forge-std/src/",
    "openzeppelin-contracts/=lib/ethfs/packages/contracts/lib/openzeppelin-contracts/",
    "openzeppelin/=lib/ethfs/packages/contracts/lib/openzeppelin-contracts/contracts/",
    "solady/=lib/ethfs/packages/contracts/lib/solady/src/",
    "solmate/=lib/ethfs/packages/contracts/lib/solady/lib/solmate/src/",
    "sstore2/=lib/sstore2/contracts/"
  ],
  "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

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ChunkNotFound","type":"error"},{"inputs":[],"name":"DirectoryNotFound","type":"error"},{"inputs":[],"name":"FileNotFound","type":"error"},{"inputs":[],"name":"InodeNotFound","type":"error"},{"inputs":[],"name":"InvalidCharacter","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":"InvalidFileName","type":"error"},{"inputs":[],"name":"LengthMismatch","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_checksum","type":"bytes32"},{"indexed":false,"internalType":"string[]","name":"_names","type":"string[]"},{"indexed":false,"internalType":"bytes32[]","name":"_inodeChecksums","type":"bytes32[]"}],"name":"DirectoryCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_checksum","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"metadata","type":"bytes"},{"indexed":false,"internalType":"bytes32[]","name":"_chunkPointers","type":"bytes32[]"}],"name":"FileCreated","type":"event"},{"inputs":[],"name":"CONTENT_STORE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_pointers","type":"bytes32[]"}],"name":"concatenateChunks","outputs":[{"internalType":"bytes","name":"fileContent","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string[]","name":"_fileNames","type":"string[]"},{"internalType":"bytes32[]","name":"_filePointers","type":"bytes32[]"}],"name":"concatenateFiles","outputs":[{"internalType":"bytes","name":"concatenatedFiles","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"string[]","name":"_fileNames","type":"string[]"},{"internalType":"bytes32[]","name":"_inodeChecksums","type":"bytes32[]"}],"name":"createDirectory","outputs":[{"internalType":"bytes32","name":"directoryChecksum","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_metadata","type":"bytes"},{"internalType":"bytes32[]","name":"_chunkPointers","type":"bytes32[]"}],"name":"createFile","outputs":[{"internalType":"bytes32","name":"fileChecksum","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_inodeChecksum","type":"bytes32"},{"internalType":"string[]","name":"_pathSegments","type":"string[]"}],"name":"getInodeAt","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"components":[{"internalType":"enum InodeType","name":"inodeType","type":"uint8"},{"components":[{"internalType":"bytes","name":"metadata","type":"bytes"},{"internalType":"bytes32[]","name":"chunkChecksums","type":"bytes32[]"}],"internalType":"struct File","name":"file","type":"tuple"},{"components":[{"internalType":"string[]","name":"filenames","type":"string[]"},{"internalType":"bytes32[]","name":"fileChecksums","type":"bytes32[]"}],"internalType":"struct Directory","name":"directory","type":"tuple"}],"internalType":"struct Inode","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_checksum","type":"bytes32"}],"name":"inodeExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"checksum","type":"bytes32"}],"name":"inodes","outputs":[{"internalType":"enum InodeType","name":"inodeType","type":"uint8"},{"components":[{"internalType":"bytes","name":"metadata","type":"bytes"},{"internalType":"bytes32[]","name":"chunkChecksums","type":"bytes32[]"}],"internalType":"struct File","name":"file","type":"tuple"},{"components":[{"internalType":"string[]","name":"filenames","type":"string[]"},{"internalType":"bytes32[]","name":"fileChecksums","type":"bytes32[]"}],"internalType":"struct Directory","name":"directory","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_checksum","type":"bytes32"}],"name":"readDirectory","outputs":[{"internalType":"string[]","name":"","type":"string[]"},{"internalType":"bytes32[]","name":"","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_checksum","type":"bytes32"}],"name":"readFile","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"}]

60a060405234801561001057600080fd5b504660011461003357737c1730b7be9424d0b983b84aeb254e3a2a105d91610049565b73c6806fd75745bb5f5b32ada19963898155f9db915b6001600160a01b031660805260805161270361007e60003960008181610145015281816107e80152610d7501526127036000f3fe608060405234801561001057600080fd5b506004361061009e5760003560e01c80636bdd12cf116100665780636bdd12cf14610140578063793bbd011461017f5780637ea664a4146101925780638d0c7318146101b4578063eb1e3d06146101d557600080fd5b806331c11f6b146100a35780633430ce6e146100cb5780633487ae16146100ec5780633a72a9c41461010c5780635e7e639a1461011f575b600080fd5b6100b66100b1366004611cc9565b6101e8565b60405190151581526020015b60405180910390f35b6100de6100d9366004611cc9565b6104d8565b6040516100c2929190611d32565b6100ff6100fa366004611e38565b6107d4565b6040516100c29190611ece565b6100ff61011a366004611cc9565b6108d0565b61013261012d366004611f26565b610bc6565b6040519081526020016100c2565b6101677f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016100c2565b61013261018d366004611f92565b610d67565b6101a56101a0366004611cc9565b610fe2565b6040516100c293929190612132565b6101c76101c236600461223a565b611236565b6040516100c2929190612295565b6100ff6101e3366004611f26565b6118a7565b600081815260208190526040808220815160608101909252805483929190829060ff16600181111561021c5761021c612010565b600181111561022d5761022d612010565b815260200160018201604051806040016040529081600082018054610251906122e4565b80601f016020809104026020016040519081016040528092919081815260200182805461027d906122e4565b80156102ca5780601f1061029f576101008083540402835291602001916102ca565b820191906000526020600020905b8154815290600101906020018083116102ad57829003601f168201915b505050505081526020016001820180548060200260200160405190810160405280929190818152602001828054801561032257602002820191906000526020600020905b81548152602001906001019080831161030e575b50505050508152505081526020016003820160405180604001604052908160008201805480602002602001604051908101604052809291908181526020016000905b82821015610410578382906000526020600020018054610383906122e4565b80601f01602080910402602001604051908101604052809291908181526020018280546103af906122e4565b80156103fc5780601f106103d1576101008083540402835291602001916103fc565b820191906000526020600020905b8154815290600101906020018083116103df57829003601f168201915b505050505081526020019060010190610364565b5050505081526020016001820180548060200260200160405190810160405280929190818152602001828054801561046757602002820191906000526020600020905b815481526020019060010190808311610453575b50505091909252505050905250905060018151600181111561048b5761048b612010565b036104b257602081015151511515806104ab575060208082015101515115155b9392505050565b604081015151511515806104ab5750604001516020015151151592915050565b50919050565b6060806104e4836101e8565b610501576040516329566a1160e21b815260040160405180910390fd5b6000838152602081905260408082208151606081019092528054829060ff16600181111561053157610531612010565b600181111561054257610542612010565b815260200160018201604051806040016040529081600082018054610566906122e4565b80601f0160208091040260200160405190810160405280929190818152602001828054610592906122e4565b80156105df5780601f106105b4576101008083540402835291602001916105df565b820191906000526020600020905b8154815290600101906020018083116105c257829003601f168201915b505050505081526020016001820180548060200260200160405190810160405280929190818152602001828054801561063757602002820191906000526020600020905b815481526020019060010190808311610623575b50505050508152505081526020016003820160405180604001604052908160008201805480602002602001604051908101604052809291908181526020016000905b82821015610725578382906000526020600020018054610698906122e4565b80601f01602080910402602001604051908101604052809291908181526020018280546106c4906122e4565b80156107115780601f106106e657610100808354040283529160200191610711565b820191906000526020600020905b8154815290600101906020018083116106f457829003601f168201915b505050505081526020019060010190610679565b5050505081526020016001820180548060200260200160405190810160405280929190818152602001828054801561077c57602002820191906000526020600020905b815481526020019060010190808311610768575b5050509190925250505090525090506000815160018111156107a0576107a0612010565b146107be57604051630d3f149360e01b815260040160405180910390fd5b6040015180516020909101519094909350915050565b60606000606060005b84518110156108c8577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634641dce686838151811061082757610827612318565b60200260200101516040518263ffffffff1660e01b815260040161084d91815260200190565b602060405180830381865afa15801561086a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088e919061232e565b9250610899836119b5565b915083826040516020016108ae929190612357565b60408051601f1981840301815291905293506001016107dd565b505050919050565b60606108db826101e8565b6108f8576040516329566a1160e21b815260040160405180910390fd5b6000828152602081905260408082208151606081019092528054829060ff16600181111561092857610928612010565b600181111561093957610939612010565b81526020016001820160405180604001604052908160008201805461095d906122e4565b80601f0160208091040260200160405190810160405280929190818152602001828054610989906122e4565b80156109d65780601f106109ab576101008083540402835291602001916109d6565b820191906000526020600020905b8154815290600101906020018083116109b957829003601f168201915b5050505050815260200160018201805480602002602001604051908101604052809291908181526020018280548015610a2e57602002820191906000526020600020905b815481526020019060010190808311610a1a575b50505050508152505081526020016003820160405180604001604052908160008201805480602002602001604051908101604052809291908181526020016000905b82821015610b1c578382906000526020600020018054610a8f906122e4565b80601f0160208091040260200160405190810160405280929190818152602001828054610abb906122e4565b8015610b085780601f10610add57610100808354040283529160200191610b08565b820191906000526020600020905b815481529060010190602001808311610aeb57829003601f168201915b505050505081526020019060010190610a70565b50505050815260200160018201805480602002602001604051908101604052809291908181526020018280548015610b7357602002820191906000526020600020905b815481526020019060010190808311610b5f575b505050919092525050509052509050600181516001811115610b9757610b97612010565b14610bb557604051633b4835d960e21b815260040160405180910390fd5b6104ab8160200151602001516107d4565b6000838214610beb576040516001621398b960e31b0319815260040160405180910390fd5b6000610bf9868686866118a7565b905060005b83811015610c4c57610c27858583818110610c1b57610c1b612318565b905060200201356101e8565b610c44576040516329566a1160e21b815260040160405180910390fd5b600101610bfe565b50604051610c61906000908390602001612386565b604051602081830303815290604052805190602001209150610c82826101e8565b15610c8d5750610d5f565b6040805180820190915280610ca287896123b7565b81526020018585808060200260200160405190810160405280939291908181526020018383602002808284376000920182905250939094525050848152602081815260409091208351805160039092019350610d02928492910190611b66565b506020828101518051610d1b9260018501920190611bbc565b50905050817f9e96d07bfdc590d70d3d527a10bddffcd78e4d5304e3e5fefb03c887c4239b3c87878787604051610d55949392919061241f565b60405180910390a2505b949350505050565b6000805b82811015610e3f577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f97406f7858584818110610db457610db4612318565b905060200201356040518263ffffffff1660e01b8152600401610dd991815260200190565b602060405180830381865afa158015610df6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e1a91906124c6565b610e375760405163cd3be3d360e01b815260040160405180910390fd5b600101610d6b565b50604051600160f81b90610e5990859085906020016124e8565b604051602081830303815290604052805190602001208686604051610e7f929190612511565b6040519081900381206001600160f81b0319909316602082015260218101919091526041810191909152606101604051602081830303815290604052805190602001209050610ecd816101e8565b610d5f57600081815260208181526040918290208054600160ff1990911617905581516060601f880183900490920281018201835291820186815282918890889081908501838280828437600092019190915250505090825250604080516020868102828101820190935286825292830192909187918791829185019084908082843760009201829052509390945250508381526020819052604090208251600190910191508190610f7f9082612572565b506020828101518051610f989260018501920190611bbc565b50905050807f8d0ccab543d291cf7866a13f680a2e4c534abed9d724e9792910372e783a7a2086868686604051610fd29493929190612632565b60405180910390a2949350505050565b600060208190529081526040908190208054825180840190935260018201805460ff909216939182908290611016906122e4565b80601f0160208091040260200160405190810160405280929190818152602001828054611042906122e4565b801561108f5780601f106110645761010080835404028352916020019161108f565b820191906000526020600020905b81548152906001019060200180831161107257829003601f168201915b50505050508152602001600182018054806020026020016040519081016040528092919081815260200182805480156110e757602002820191906000526020600020905b8154815260200190600101908083116110d3575b505050505081525050908060030160405180604001604052908160008201805480602002602001604051908101604052809291908181526020016000905b828210156111d1578382906000526020600020018054611144906122e4565b80601f0160208091040260200160405190810160405280929190818152602001828054611170906122e4565b80156111bd5780601f10611192576101008083540402835291602001916111bd565b820191906000526020600020905b8154815290600101906020018083116111a057829003601f168201915b505050505081526020019060010190611125565b5050505081526020016001820180548060200260200160405190810160405280929190818152602001828054801561122857602002820191906000526020600020905b815481526020019060010190808311611214575b505050505081525050905083565b6000611240611c03565b611249846101e8565b611266576040516329566a1160e21b815260040160405180910390fd5b6000848152602081905260408082208151606081019092528054829060ff16600181111561129657611296612010565b60018111156112a7576112a7612010565b8152602001600182016040518060400160405290816000820180546112cb906122e4565b80601f01602080910402602001604051908101604052809291908181526020018280546112f7906122e4565b80156113445780601f1061131957610100808354040283529160200191611344565b820191906000526020600020905b81548152906001019060200180831161132757829003601f168201915b505050505081526020016001820180548060200260200160405190810160405280929190818152602001828054801561139c57602002820191906000526020600020905b815481526020019060010190808311611388575b50505050508152505081526020016003820160405180604001604052908160008201805480602002602001604051908101604052809291908181526020016000905b8282101561148a5783829060005260206000200180546113fd906122e4565b80601f0160208091040260200160405190810160405280929190818152602001828054611429906122e4565b80156114765780601f1061144b57610100808354040283529160200191611476565b820191906000526020600020905b81548152906001019060200180831161145957829003601f168201915b5050505050815260200190600101906113de565b505050508152602001600182018054806020026020016040519081016040528092919081815260200182805480156114e157602002820191906000526020600020905b8154815260200190600101908083116114cd575b5050509190925250505090525084516040805180820190915260608082526020820152919250869160606000805b848110156118945760008751600181111561152c5761152c612010565b1461154a576040516329566a1160e21b815260040160405180910390fd5b60408701518051909450925060009150815b835181101561186d578a828151811061157757611577612318565b60200260200101518051906020012084828151811061159857611598612318565b602002602001015180519060200120036118655760019250846020015181815181106115c6576115c6612318565b602090810291909101810151600081815291829052604091829020825160608101909352805491995090829060ff16600181111561160657611606612010565b600181111561161757611617612010565b81526020016001820160405180604001604052908160008201805461163b906122e4565b80601f0160208091040260200160405190810160405280929190818152602001828054611667906122e4565b80156116b45780601f10611689576101008083540402835291602001916116b4565b820191906000526020600020905b81548152906001019060200180831161169757829003601f168201915b505050505081526020016001820180548060200260200160405190810160405280929190818152602001828054801561170c57602002820191906000526020600020905b8154815260200190600101908083116116f8575b50505050508152505081526020016003820160405180604001604052908160008201805480602002602001604051908101604052809291908181526020016000905b828210156117fa57838290600052602060002001805461176d906122e4565b80601f0160208091040260200160405190810160405280929190818152602001828054611799906122e4565b80156117e65780601f106117bb576101008083540402835291602001916117e6565b820191906000526020600020905b8154815290600101906020018083116117c957829003601f168201915b50505050508152602001906001019061174e565b5050505081526020016001820180548060200260200160405190810160405280929190818152602001828054801561185157602002820191906000526020600020905b81548152602001906001019080831161183d575b50505050508152505081525050975061186d565b60010161155c565b508161188c576040516329566a1160e21b815260040160405180910390fd5b60010161150f565b50939650939450505050505b9250929050565b6060838160005b828110156119aa578787828181106118c8576118c8612318565b90506020028101906118da9190612659565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525084519496509390930392506119359150505760405163dcfcfa9b60e01b815260040160405180910390fd5b61193e826119cb565b1561195c576040516318954fab60e11b815260040160405180910390fd5b85858281811061196e5761196e612318565b90506020020135828051906020012085604051602001611990939291906126a0565b60408051601f1981840301815291905293506001016118ae565b505050949350505050565b60606119c5826001600019611aad565b92915050565b8051600090815b81811015611aa35760005b604051806040016040528060128152602001713a2f3f235b5d402124262728292a2b2c3b3d60701b81525051811015611a9a57604051806040016040528060128152602001713a2f3f235b5d402124262728292a2b2c3b3d60701b8152508181518110611a4c57611a4c612318565b602001015160f81c60f81b6001600160f81b031916858381518110611a7357611a73612318565b01602001516001600160f81b03191603611a9257506001949350505050565b6001016119dd565b506001016119d2565b5060009392505050565b6060833b6000819003611ad05750506040805160208101909152600081526104ab565b80841115611aee5750506040805160208101909152600081526104ab565b83831015611b245760405163162544fd60e11b815260048101829052602481018590526044810184905260640160405180910390fd5b8383038482036000828210611b395782611b3b565b815b60408051603f8301601f19168101909152818152955090508087602087018a3c505050509392505050565b828054828255906000526020600020908101928215611bac579160200282015b82811115611bac5782518290611b9c9082612572565b5091602001919060010190611b86565b50611bb8929150611c5a565b5090565b828054828255906000526020600020908101928215611bf7579160200282015b82811115611bf7578251825591602001919060010190611bdc565b50611bb8929150611c77565b60408051606081019091528060008152602001611c33604051806040016040528060608152602001606081525090565b8152602001611c55604051806040016040528060608152602001606081525090565b905290565b80821115611bb8576000611c6e8282611c8c565b50600101611c5a565b5b80821115611bb85760008155600101611c78565b508054611c98906122e4565b6000825580601f10611ca8575050565b601f016020900490600052602060002090810190611cc69190611c77565b50565b600060208284031215611cdb57600080fd5b5035919050565b60005b83811015611cfd578181015183820152602001611ce5565b50506000910152565b60008151808452611d1e816020860160208601611ce2565b601f01601f19169290920160200192915050565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b83811015611d8957605f19888703018552611d77868351611d06565b95509382019390820190600101611d5b565b50508584038187015286518085528782019482019350915060005b82811015611dc057845184529381019392810192600101611da4565b5091979650505050505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611e0c57611e0c611dcd565b604052919050565b600067ffffffffffffffff821115611e2e57611e2e611dcd565b5060051b60200190565b60006020808385031215611e4b57600080fd5b823567ffffffffffffffff811115611e6257600080fd5b8301601f81018513611e7357600080fd5b8035611e86611e8182611e14565b611de3565b81815260059190911b82018301908381019087831115611ea557600080fd5b928401925b82841015611ec357833582529284019290840190611eaa565b979650505050505050565b6020815260006104ab6020830184611d06565b60008083601f840112611ef357600080fd5b50813567ffffffffffffffff811115611f0b57600080fd5b6020830191508360208260051b85010111156118a057600080fd5b60008060008060408587031215611f3c57600080fd5b843567ffffffffffffffff80821115611f5457600080fd5b611f6088838901611ee1565b90965094506020870135915080821115611f7957600080fd5b50611f8687828801611ee1565b95989497509550505050565b60008060008060408587031215611fa857600080fd5b843567ffffffffffffffff80821115611fc057600080fd5b818701915087601f830112611fd457600080fd5b813581811115611fe357600080fd5b886020828501011115611ff557600080fd5b602092830196509450908601359080821115611f7957600080fd5b634e487b7160e01b600052602160045260246000fd5b6002811061204457634e487b7160e01b600052602160045260246000fd5b9052565b60008151808452602080850194506020840160005b838110156120795781518752958201959082019060010161205d565b509495945050505050565b60008151604084526120996040850182611d06565b9050602083015184820360208601526120b28282612048565b95945050505050565b60006040830182516040855281815180845260608701915060608160051b88010193506020808401935060005b8281101561211657605f19898703018452612104868651611d06565b955093810193928101926001016120e8565b5050505050602083015184820360208601526120b28282612048565b61213c8185612026565b6060602082015260006121526060830185612084565b828103604084015261216481856120bb565b9695505050505050565b600061217c611e8184611e14565b8381529050602080820190600585901b84018681111561219b57600080fd5b845b8181101561222f57803567ffffffffffffffff808211156121be5760008081fd5b8188019150601f8a818401126121d45760008081fd5b8235828111156121e6576121e6611dcd565b6121f7818301601f19168801611de3565b92508083528b8782860101111561221057600091508182fd5b808785018885013760009083018701525085525092820192820161219d565b505050509392505050565b6000806040838503121561224d57600080fd5b82359150602083013567ffffffffffffffff81111561226b57600080fd5b8301601f8101851361227c57600080fd5b61228b8582356020840161216e565b9150509250929050565b828152604060208201526122ad604082018351612026565b600060208301516060808401526122c760a0840182612084565b90506040840151603f1984830301608085015261216482826120bb565b600181811c908216806122f857607f821691505b6020821081036104d257634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121561234057600080fd5b81516001600160a01b03811681146104ab57600080fd5b60008351612369818460208801611ce2565b83519083019061237d818360208801611ce2565b01949350505050565b6001600160f81b03198316815281516000906123a9816001850160208701611ce2565b919091016001019392505050565b60006104ab36848461216e565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b81835260006001600160fb1b0383111561240657600080fd5b8260051b80836020870137939093016020019392505050565b6040808252810184905260006060600586901b8301810190830187835b888110156124b057858403605f190183528135368b9003601e1901811261246257600080fd5b8a01602081810191359067ffffffffffffffff82111561248157600080fd5b81360383131561249057600080fd5b61249b8783856123c4565b9650948501949390930192505060010161243c565b5050508281036020840152611ec38185876123ed565b6000602082840312156124d857600080fd5b815180151581146104ab57600080fd5b60006001600160fb1b038311156124fe57600080fd5b8260051b80858437919091019392505050565b8183823760009101908152919050565b601f82111561256d576000816000526020600020601f850160051c8101602086101561254a5750805b601f850160051c820191505b8181101561256957828155600101612556565b5050505b505050565b815167ffffffffffffffff81111561258c5761258c611dcd565b6125a08161259a84546122e4565b84612521565b602080601f8311600181146125d557600084156125bd5750858301515b600019600386901b1c1916600185901b178555612569565b600085815260208120601f198616915b82811015612604578886015182559484019460019091019084016125e5565b50858210156126225787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6040815260006126466040830186886123c4565b8281036020840152611ec38185876123ed565b6000808335601e1984360301811261267057600080fd5b83018035915067ffffffffffffffff82111561268b57600080fd5b6020019150368190038213156118a057600080fd5b838152826020820152600082516126be816040850160208701611ce2565b9190910160400194935050505056fea26469706673582212202c3e5cd05a5fbc5d3f9df6945dd49171511e8a23b2215b3a1b0dae28c31ddf2464736f6c63430008170033

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061009e5760003560e01c80636bdd12cf116100665780636bdd12cf14610140578063793bbd011461017f5780637ea664a4146101925780638d0c7318146101b4578063eb1e3d06146101d557600080fd5b806331c11f6b146100a35780633430ce6e146100cb5780633487ae16146100ec5780633a72a9c41461010c5780635e7e639a1461011f575b600080fd5b6100b66100b1366004611cc9565b6101e8565b60405190151581526020015b60405180910390f35b6100de6100d9366004611cc9565b6104d8565b6040516100c2929190611d32565b6100ff6100fa366004611e38565b6107d4565b6040516100c29190611ece565b6100ff61011a366004611cc9565b6108d0565b61013261012d366004611f26565b610bc6565b6040519081526020016100c2565b6101677f000000000000000000000000c6806fd75745bb5f5b32ada19963898155f9db9181565b6040516001600160a01b0390911681526020016100c2565b61013261018d366004611f92565b610d67565b6101a56101a0366004611cc9565b610fe2565b6040516100c293929190612132565b6101c76101c236600461223a565b611236565b6040516100c2929190612295565b6100ff6101e3366004611f26565b6118a7565b600081815260208190526040808220815160608101909252805483929190829060ff16600181111561021c5761021c612010565b600181111561022d5761022d612010565b815260200160018201604051806040016040529081600082018054610251906122e4565b80601f016020809104026020016040519081016040528092919081815260200182805461027d906122e4565b80156102ca5780601f1061029f576101008083540402835291602001916102ca565b820191906000526020600020905b8154815290600101906020018083116102ad57829003601f168201915b505050505081526020016001820180548060200260200160405190810160405280929190818152602001828054801561032257602002820191906000526020600020905b81548152602001906001019080831161030e575b50505050508152505081526020016003820160405180604001604052908160008201805480602002602001604051908101604052809291908181526020016000905b82821015610410578382906000526020600020018054610383906122e4565b80601f01602080910402602001604051908101604052809291908181526020018280546103af906122e4565b80156103fc5780601f106103d1576101008083540402835291602001916103fc565b820191906000526020600020905b8154815290600101906020018083116103df57829003601f168201915b505050505081526020019060010190610364565b5050505081526020016001820180548060200260200160405190810160405280929190818152602001828054801561046757602002820191906000526020600020905b815481526020019060010190808311610453575b50505091909252505050905250905060018151600181111561048b5761048b612010565b036104b257602081015151511515806104ab575060208082015101515115155b9392505050565b604081015151511515806104ab5750604001516020015151151592915050565b50919050565b6060806104e4836101e8565b610501576040516329566a1160e21b815260040160405180910390fd5b6000838152602081905260408082208151606081019092528054829060ff16600181111561053157610531612010565b600181111561054257610542612010565b815260200160018201604051806040016040529081600082018054610566906122e4565b80601f0160208091040260200160405190810160405280929190818152602001828054610592906122e4565b80156105df5780601f106105b4576101008083540402835291602001916105df565b820191906000526020600020905b8154815290600101906020018083116105c257829003601f168201915b505050505081526020016001820180548060200260200160405190810160405280929190818152602001828054801561063757602002820191906000526020600020905b815481526020019060010190808311610623575b50505050508152505081526020016003820160405180604001604052908160008201805480602002602001604051908101604052809291908181526020016000905b82821015610725578382906000526020600020018054610698906122e4565b80601f01602080910402602001604051908101604052809291908181526020018280546106c4906122e4565b80156107115780601f106106e657610100808354040283529160200191610711565b820191906000526020600020905b8154815290600101906020018083116106f457829003601f168201915b505050505081526020019060010190610679565b5050505081526020016001820180548060200260200160405190810160405280929190818152602001828054801561077c57602002820191906000526020600020905b815481526020019060010190808311610768575b5050509190925250505090525090506000815160018111156107a0576107a0612010565b146107be57604051630d3f149360e01b815260040160405180910390fd5b6040015180516020909101519094909350915050565b60606000606060005b84518110156108c8577f000000000000000000000000c6806fd75745bb5f5b32ada19963898155f9db916001600160a01b0316634641dce686838151811061082757610827612318565b60200260200101516040518263ffffffff1660e01b815260040161084d91815260200190565b602060405180830381865afa15801561086a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088e919061232e565b9250610899836119b5565b915083826040516020016108ae929190612357565b60408051601f1981840301815291905293506001016107dd565b505050919050565b60606108db826101e8565b6108f8576040516329566a1160e21b815260040160405180910390fd5b6000828152602081905260408082208151606081019092528054829060ff16600181111561092857610928612010565b600181111561093957610939612010565b81526020016001820160405180604001604052908160008201805461095d906122e4565b80601f0160208091040260200160405190810160405280929190818152602001828054610989906122e4565b80156109d65780601f106109ab576101008083540402835291602001916109d6565b820191906000526020600020905b8154815290600101906020018083116109b957829003601f168201915b5050505050815260200160018201805480602002602001604051908101604052809291908181526020018280548015610a2e57602002820191906000526020600020905b815481526020019060010190808311610a1a575b50505050508152505081526020016003820160405180604001604052908160008201805480602002602001604051908101604052809291908181526020016000905b82821015610b1c578382906000526020600020018054610a8f906122e4565b80601f0160208091040260200160405190810160405280929190818152602001828054610abb906122e4565b8015610b085780601f10610add57610100808354040283529160200191610b08565b820191906000526020600020905b815481529060010190602001808311610aeb57829003601f168201915b505050505081526020019060010190610a70565b50505050815260200160018201805480602002602001604051908101604052809291908181526020018280548015610b7357602002820191906000526020600020905b815481526020019060010190808311610b5f575b505050919092525050509052509050600181516001811115610b9757610b97612010565b14610bb557604051633b4835d960e21b815260040160405180910390fd5b6104ab8160200151602001516107d4565b6000838214610beb576040516001621398b960e31b0319815260040160405180910390fd5b6000610bf9868686866118a7565b905060005b83811015610c4c57610c27858583818110610c1b57610c1b612318565b905060200201356101e8565b610c44576040516329566a1160e21b815260040160405180910390fd5b600101610bfe565b50604051610c61906000908390602001612386565b604051602081830303815290604052805190602001209150610c82826101e8565b15610c8d5750610d5f565b6040805180820190915280610ca287896123b7565b81526020018585808060200260200160405190810160405280939291908181526020018383602002808284376000920182905250939094525050848152602081815260409091208351805160039092019350610d02928492910190611b66565b506020828101518051610d1b9260018501920190611bbc565b50905050817f9e96d07bfdc590d70d3d527a10bddffcd78e4d5304e3e5fefb03c887c4239b3c87878787604051610d55949392919061241f565b60405180910390a2505b949350505050565b6000805b82811015610e3f577f000000000000000000000000c6806fd75745bb5f5b32ada19963898155f9db916001600160a01b031663f97406f7858584818110610db457610db4612318565b905060200201356040518263ffffffff1660e01b8152600401610dd991815260200190565b602060405180830381865afa158015610df6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e1a91906124c6565b610e375760405163cd3be3d360e01b815260040160405180910390fd5b600101610d6b565b50604051600160f81b90610e5990859085906020016124e8565b604051602081830303815290604052805190602001208686604051610e7f929190612511565b6040519081900381206001600160f81b0319909316602082015260218101919091526041810191909152606101604051602081830303815290604052805190602001209050610ecd816101e8565b610d5f57600081815260208181526040918290208054600160ff1990911617905581516060601f880183900490920281018201835291820186815282918890889081908501838280828437600092019190915250505090825250604080516020868102828101820190935286825292830192909187918791829185019084908082843760009201829052509390945250508381526020819052604090208251600190910191508190610f7f9082612572565b506020828101518051610f989260018501920190611bbc565b50905050807f8d0ccab543d291cf7866a13f680a2e4c534abed9d724e9792910372e783a7a2086868686604051610fd29493929190612632565b60405180910390a2949350505050565b600060208190529081526040908190208054825180840190935260018201805460ff909216939182908290611016906122e4565b80601f0160208091040260200160405190810160405280929190818152602001828054611042906122e4565b801561108f5780601f106110645761010080835404028352916020019161108f565b820191906000526020600020905b81548152906001019060200180831161107257829003601f168201915b50505050508152602001600182018054806020026020016040519081016040528092919081815260200182805480156110e757602002820191906000526020600020905b8154815260200190600101908083116110d3575b505050505081525050908060030160405180604001604052908160008201805480602002602001604051908101604052809291908181526020016000905b828210156111d1578382906000526020600020018054611144906122e4565b80601f0160208091040260200160405190810160405280929190818152602001828054611170906122e4565b80156111bd5780601f10611192576101008083540402835291602001916111bd565b820191906000526020600020905b8154815290600101906020018083116111a057829003601f168201915b505050505081526020019060010190611125565b5050505081526020016001820180548060200260200160405190810160405280929190818152602001828054801561122857602002820191906000526020600020905b815481526020019060010190808311611214575b505050505081525050905083565b6000611240611c03565b611249846101e8565b611266576040516329566a1160e21b815260040160405180910390fd5b6000848152602081905260408082208151606081019092528054829060ff16600181111561129657611296612010565b60018111156112a7576112a7612010565b8152602001600182016040518060400160405290816000820180546112cb906122e4565b80601f01602080910402602001604051908101604052809291908181526020018280546112f7906122e4565b80156113445780601f1061131957610100808354040283529160200191611344565b820191906000526020600020905b81548152906001019060200180831161132757829003601f168201915b505050505081526020016001820180548060200260200160405190810160405280929190818152602001828054801561139c57602002820191906000526020600020905b815481526020019060010190808311611388575b50505050508152505081526020016003820160405180604001604052908160008201805480602002602001604051908101604052809291908181526020016000905b8282101561148a5783829060005260206000200180546113fd906122e4565b80601f0160208091040260200160405190810160405280929190818152602001828054611429906122e4565b80156114765780601f1061144b57610100808354040283529160200191611476565b820191906000526020600020905b81548152906001019060200180831161145957829003601f168201915b5050505050815260200190600101906113de565b505050508152602001600182018054806020026020016040519081016040528092919081815260200182805480156114e157602002820191906000526020600020905b8154815260200190600101908083116114cd575b5050509190925250505090525084516040805180820190915260608082526020820152919250869160606000805b848110156118945760008751600181111561152c5761152c612010565b1461154a576040516329566a1160e21b815260040160405180910390fd5b60408701518051909450925060009150815b835181101561186d578a828151811061157757611577612318565b60200260200101518051906020012084828151811061159857611598612318565b602002602001015180519060200120036118655760019250846020015181815181106115c6576115c6612318565b602090810291909101810151600081815291829052604091829020825160608101909352805491995090829060ff16600181111561160657611606612010565b600181111561161757611617612010565b81526020016001820160405180604001604052908160008201805461163b906122e4565b80601f0160208091040260200160405190810160405280929190818152602001828054611667906122e4565b80156116b45780601f10611689576101008083540402835291602001916116b4565b820191906000526020600020905b81548152906001019060200180831161169757829003601f168201915b505050505081526020016001820180548060200260200160405190810160405280929190818152602001828054801561170c57602002820191906000526020600020905b8154815260200190600101908083116116f8575b50505050508152505081526020016003820160405180604001604052908160008201805480602002602001604051908101604052809291908181526020016000905b828210156117fa57838290600052602060002001805461176d906122e4565b80601f0160208091040260200160405190810160405280929190818152602001828054611799906122e4565b80156117e65780601f106117bb576101008083540402835291602001916117e6565b820191906000526020600020905b8154815290600101906020018083116117c957829003601f168201915b50505050508152602001906001019061174e565b5050505081526020016001820180548060200260200160405190810160405280929190818152602001828054801561185157602002820191906000526020600020905b81548152602001906001019080831161183d575b50505050508152505081525050975061186d565b60010161155c565b508161188c576040516329566a1160e21b815260040160405180910390fd5b60010161150f565b50939650939450505050505b9250929050565b6060838160005b828110156119aa578787828181106118c8576118c8612318565b90506020028101906118da9190612659565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525084519496509390930392506119359150505760405163dcfcfa9b60e01b815260040160405180910390fd5b61193e826119cb565b1561195c576040516318954fab60e11b815260040160405180910390fd5b85858281811061196e5761196e612318565b90506020020135828051906020012085604051602001611990939291906126a0565b60408051601f1981840301815291905293506001016118ae565b505050949350505050565b60606119c5826001600019611aad565b92915050565b8051600090815b81811015611aa35760005b604051806040016040528060128152602001713a2f3f235b5d402124262728292a2b2c3b3d60701b81525051811015611a9a57604051806040016040528060128152602001713a2f3f235b5d402124262728292a2b2c3b3d60701b8152508181518110611a4c57611a4c612318565b602001015160f81c60f81b6001600160f81b031916858381518110611a7357611a73612318565b01602001516001600160f81b03191603611a9257506001949350505050565b6001016119dd565b506001016119d2565b5060009392505050565b6060833b6000819003611ad05750506040805160208101909152600081526104ab565b80841115611aee5750506040805160208101909152600081526104ab565b83831015611b245760405163162544fd60e11b815260048101829052602481018590526044810184905260640160405180910390fd5b8383038482036000828210611b395782611b3b565b815b60408051603f8301601f19168101909152818152955090508087602087018a3c505050509392505050565b828054828255906000526020600020908101928215611bac579160200282015b82811115611bac5782518290611b9c9082612572565b5091602001919060010190611b86565b50611bb8929150611c5a565b5090565b828054828255906000526020600020908101928215611bf7579160200282015b82811115611bf7578251825591602001919060010190611bdc565b50611bb8929150611c77565b60408051606081019091528060008152602001611c33604051806040016040528060608152602001606081525090565b8152602001611c55604051806040016040528060608152602001606081525090565b905290565b80821115611bb8576000611c6e8282611c8c565b50600101611c5a565b5b80821115611bb85760008155600101611c78565b508054611c98906122e4565b6000825580601f10611ca8575050565b601f016020900490600052602060002090810190611cc69190611c77565b50565b600060208284031215611cdb57600080fd5b5035919050565b60005b83811015611cfd578181015183820152602001611ce5565b50506000910152565b60008151808452611d1e816020860160208601611ce2565b601f01601f19169290920160200192915050565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b83811015611d8957605f19888703018552611d77868351611d06565b95509382019390820190600101611d5b565b50508584038187015286518085528782019482019350915060005b82811015611dc057845184529381019392810192600101611da4565b5091979650505050505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611e0c57611e0c611dcd565b604052919050565b600067ffffffffffffffff821115611e2e57611e2e611dcd565b5060051b60200190565b60006020808385031215611e4b57600080fd5b823567ffffffffffffffff811115611e6257600080fd5b8301601f81018513611e7357600080fd5b8035611e86611e8182611e14565b611de3565b81815260059190911b82018301908381019087831115611ea557600080fd5b928401925b82841015611ec357833582529284019290840190611eaa565b979650505050505050565b6020815260006104ab6020830184611d06565b60008083601f840112611ef357600080fd5b50813567ffffffffffffffff811115611f0b57600080fd5b6020830191508360208260051b85010111156118a057600080fd5b60008060008060408587031215611f3c57600080fd5b843567ffffffffffffffff80821115611f5457600080fd5b611f6088838901611ee1565b90965094506020870135915080821115611f7957600080fd5b50611f8687828801611ee1565b95989497509550505050565b60008060008060408587031215611fa857600080fd5b843567ffffffffffffffff80821115611fc057600080fd5b818701915087601f830112611fd457600080fd5b813581811115611fe357600080fd5b886020828501011115611ff557600080fd5b602092830196509450908601359080821115611f7957600080fd5b634e487b7160e01b600052602160045260246000fd5b6002811061204457634e487b7160e01b600052602160045260246000fd5b9052565b60008151808452602080850194506020840160005b838110156120795781518752958201959082019060010161205d565b509495945050505050565b60008151604084526120996040850182611d06565b9050602083015184820360208601526120b28282612048565b95945050505050565b60006040830182516040855281815180845260608701915060608160051b88010193506020808401935060005b8281101561211657605f19898703018452612104868651611d06565b955093810193928101926001016120e8565b5050505050602083015184820360208601526120b28282612048565b61213c8185612026565b6060602082015260006121526060830185612084565b828103604084015261216481856120bb565b9695505050505050565b600061217c611e8184611e14565b8381529050602080820190600585901b84018681111561219b57600080fd5b845b8181101561222f57803567ffffffffffffffff808211156121be5760008081fd5b8188019150601f8a818401126121d45760008081fd5b8235828111156121e6576121e6611dcd565b6121f7818301601f19168801611de3565b92508083528b8782860101111561221057600091508182fd5b808785018885013760009083018701525085525092820192820161219d565b505050509392505050565b6000806040838503121561224d57600080fd5b82359150602083013567ffffffffffffffff81111561226b57600080fd5b8301601f8101851361227c57600080fd5b61228b8582356020840161216e565b9150509250929050565b828152604060208201526122ad604082018351612026565b600060208301516060808401526122c760a0840182612084565b90506040840151603f1984830301608085015261216482826120bb565b600181811c908216806122f857607f821691505b6020821081036104d257634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121561234057600080fd5b81516001600160a01b03811681146104ab57600080fd5b60008351612369818460208801611ce2565b83519083019061237d818360208801611ce2565b01949350505050565b6001600160f81b03198316815281516000906123a9816001850160208701611ce2565b919091016001019392505050565b60006104ab36848461216e565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b81835260006001600160fb1b0383111561240657600080fd5b8260051b80836020870137939093016020019392505050565b6040808252810184905260006060600586901b8301810190830187835b888110156124b057858403605f190183528135368b9003601e1901811261246257600080fd5b8a01602081810191359067ffffffffffffffff82111561248157600080fd5b81360383131561249057600080fd5b61249b8783856123c4565b9650948501949390930192505060010161243c565b5050508281036020840152611ec38185876123ed565b6000602082840312156124d857600080fd5b815180151581146104ab57600080fd5b60006001600160fb1b038311156124fe57600080fd5b8260051b80858437919091019392505050565b8183823760009101908152919050565b601f82111561256d576000816000526020600020601f850160051c8101602086101561254a5750805b601f850160051c820191505b8181101561256957828155600101612556565b5050505b505050565b815167ffffffffffffffff81111561258c5761258c611dcd565b6125a08161259a84546122e4565b84612521565b602080601f8311600181146125d557600084156125bd5750858301515b600019600386901b1c1916600185901b178555612569565b600085815260208120601f198616915b82811015612604578886015182559484019460019091019084016125e5565b50858210156126225787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6040815260006126466040830186886123c4565b8281036020840152611ec38185876123ed565b6000808335601e1984360301811261267057600080fd5b83018035915067ffffffffffffffff82111561268b57600080fd5b6020019150368190038213156118a057600080fd5b838152826020820152600082516126be816040850160208701611ce2565b9190910160400194935050505056fea26469706673582212202c3e5cd05a5fbc5d3f9df6945dd49171511e8a23b2215b3a1b0dae28c31ddf2464736f6c63430008170033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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