ETH Price: $3,417.48 (-7.40%)

Contract

0xbD11994aABB55Da86DC246EBB17C1Be0af5b7699
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Add Chunk To Con...210966252024-11-02 1:17:4747 days ago1730510267IN
0xbD11994a...0af5b7699
0 ETH0.00589574.7373234
Create Content210966242024-11-02 1:17:3547 days ago1730510255IN
0xbD11994a...0af5b7699
0 ETH0.000332044.39196206
Add Chunk To Con...210951162024-11-01 20:14:1148 days ago1730492051IN
0xbD11994a...0af5b7699
0 ETH0.007735556.23776533
Create Content210951152024-11-01 20:13:5948 days ago1730492039IN
0xbD11994a...0af5b7699
0 ETH0.000467416.18254446
Add Chunk To Con...208595192024-09-29 23:15:4780 days ago1727651747IN
0xbD11994a...0af5b7699
0 ETH0.008646756.72532865
Add Chunk To Con...208595182024-09-29 23:15:3580 days ago1727651735IN
0xbD11994a...0af5b7699
0 ETH0.038266926.77132232
Create Content208595172024-09-29 23:15:2380 days ago1727651723IN
0xbD11994a...0af5b7699
0 ETH0.000458366.07827508
Add Chunk To Con...207162182024-09-09 23:03:59100 days ago1725923039IN
0xbD11994a...0af5b7699
0 ETH0.005026123.45028327
Create Content207162172024-09-09 23:03:47100 days ago1725923027IN
0xbD11994a...0af5b7699
0 ETH0.000267443.54423546
Add Chunk To Con...207162062024-09-09 23:01:35100 days ago1725922895IN
0xbD11994a...0af5b7699
0 ETH0.011309632.71452133
Add Chunk To Con...207162052024-09-09 23:01:23100 days ago1725922883IN
0xbD11994a...0af5b7699
0 ETH0.013878912.47082358
Add Chunk To Con...207162042024-09-09 23:01:11100 days ago1725922871IN
0xbD11994a...0af5b7699
0 ETH0.013253662.35951178
Add Chunk To Con...207162032024-09-09 23:00:59100 days ago1725922859IN
0xbD11994a...0af5b7699
0 ETH0.013692322.42285376
Create Content207162022024-09-09 23:00:47100 days ago1725922847IN
0xbD11994a...0af5b7699
0 ETH0.000183612.43485453
Add Chunk To Con...200534902024-06-09 9:51:59193 days ago1717926719IN
0xbD11994a...0af5b7699
0 ETH0.005735124.62529095
Add Chunk To Con...200534892024-06-09 9:51:47193 days ago1717926707IN
0xbD11994a...0af5b7699
0 ETH0.024530394.34064689
Create Content200534882024-06-09 9:51:35193 days ago1717926695IN
0xbD11994a...0af5b7699
0 ETH0.000380095.04026245
Add Chunk To Con...199573792024-05-26 23:37:47206 days ago1716766667IN
0xbD11994a...0af5b7699
0 ETH0.004054193.73011194
Create Content199573782024-05-26 23:37:35206 days ago1716766655IN
0xbD11994a...0af5b7699
0 ETH0.000272093.60126506
Add Chunk To Con...198565042024-05-12 21:04:23221 days ago1715547863IN
0xbD11994a...0af5b7699
0 ETH0.013336363.53362621
Add Chunk To Con...198565032024-05-12 21:04:11221 days ago1715547851IN
0xbD11994a...0af5b7699
0 ETH0.019773573.52023285
Add Chunk To Con...198565022024-05-12 21:03:59221 days ago1715547839IN
0xbD11994a...0af5b7699
0 ETH0.019440673.46096718
Add Chunk To Con...198565012024-05-12 21:03:47221 days ago1715547827IN
0xbD11994a...0af5b7699
0 ETH0.019300833.41527814
Create Content198565002024-05-12 21:03:35221 days ago1715547815IN
0xbD11994a...0af5b7699
0 ETH0.000266073.52836455
Add Chunk To Con...198564982024-05-12 21:03:11221 days ago1715547791IN
0xbD11994a...0af5b7699
0 ETH0.005602253.92298065
View all transactions

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block
From
To
191230552024-01-31 0:59:11323 days ago1706662751  Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ScriptyStorageV2

Compiler Version
v0.8.22+commit.4fc1097e

Optimization Enabled:
Yes with 500 runs

Other Settings:
paris EvmVersion
File 1 of 10 : ScriptyStorageV2.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

///////////////////////////////////////////////////////////
// ░██████╗░█████╗░██████╗░██╗██████╗░████████╗██╗░░░██╗ //
// ██╔════╝██╔══██╗██╔══██╗██║██╔══██╗╚══██╔══╝╚██╗░██╔╝ //
// ╚█████╗░██║░░╚═╝██████╔╝██║██████╔╝░░░██║░░░░╚████╔╝░ //
// ░╚═══██╗██║░░██╗██╔══██╗██║██╔═══╝░░░░██║░░░░░╚██╔╝░░ //
// ██████╔╝╚█████╔╝██║░░██║██║██║░░░░░░░░██║░░░░░░██║░░░ //
// ╚═════╝░░╚════╝░╚═╝░░╚═╝╚═╝╚═╝░░░░░░░░╚═╝░░░░░░╚═╝░░░ //
///////////////////////////////////////////////////////////
//░░░░░░░░░░░░░░░░░░░░    STORAGE    ░░░░░░░░░░░░░░░░░░░░//
///////////////////////////////////////////////////////////

/**
  @title A generic data storage contract
  @author @xtremetom
  @author @0xthedude

  Built on top of FileStore from EthFS V2. Chunk pointers
  are deterministic and using the EthFS's salt.

  Special thanks to @frolic, @cxkoda and @dhof.
*/

import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {IFileStore} from "./dependencies/ethfs/IFileStore.sol";
import "./dependencies/ethfs/common.sol";
import {AddressChunks} from "./utils/AddressChunks.sol";

import {IScriptyStorage} from "./interfaces/IScriptyStorage.sol";
import {IScriptyContractStorage} from "./interfaces/IScriptyContractStorage.sol";

contract ScriptyStorageV2 is Ownable, IScriptyStorage, IScriptyContractStorage {
    IFileStore public immutable ethfsFileStore;
    mapping(string => Content) public contents;

    constructor(IFileStore ethfsFileStore_) {
        ethfsFileStore = IFileStore(ethfsFileStore_);
    }

    // =============================================================
    //                           MODIFIERS
    // =============================================================

    /**
     * @notice Check if the msg.sender is the owner of the content
     * @param name - Name given to the content. Eg: threejs.min.js_r148
     */
    modifier isContentOwner(string calldata name) {
        if (msg.sender != contents[name].owner) revert NotContentOwner();
        _;
    }

    /**
     * @notice Check if a content can be created by checking if it already exists
     * @param name - Name given to the content. Eg: threejs.min.js_r148
     */
    modifier canCreate(string calldata name) {
        if (contents[name].owner != address(0)) revert ContentExists();
        _;
    }

    /**
     * @notice Check if a content is frozen
     * @param name - Name given to the content. Eg: threejs.min.js_r148
     */
    modifier isFrozen(string calldata name) {
        if (contents[name].isFrozen) revert ContentIsFrozen(name);
        _;
    }

    // =============================================================
    //                      MANAGEMENT OPERATIONS
    // =============================================================

    /**
     * @notice Create a new content
     * @param name - Name given to the content. Eg: threejs.min.js_r148
     * @param details - Any details the owner wishes to store about the content
     *
     * Emits an {ContentCreated} event.
     */
    function createContent(
        string calldata name,
        bytes calldata details
    ) public canCreate(name) {
        contents[name] = Content(
            false,
            msg.sender,
            0,
            details,
            new address[](0)
        );
        emit ContentCreated(name, details);
    }

    /**
     * @notice Add a code chunk to the content
     * @param name - Name given to the content. Eg: threejs.min.js_r148
     * @param chunk - Next sequential code chunk
     *
     * Emits an {ChunkStored} event.
     */
    function addChunkToContent(
        string calldata name,
        bytes calldata chunk
    ) public isFrozen(name) isContentOwner(name) {
        address pointer = addContent(ethfsFileStore.deployer(), chunk);
        contents[name].chunks.push(pointer);
        contents[name].size += chunk.length;
        emit ChunkStored(name, chunk.length);
    }

    /**
     * @notice Edit the content details
     * @param name - Name given to the content. Eg: threejs.min.js_r148
     * @param details - Any details the owner wishes to store about the content
     *
     * Emits an {ContentDetailsUpdated} event.
     */
    function updateDetails(
        string calldata name,
        bytes calldata details
    ) public isFrozen(name) isContentOwner(name) {
        contents[name].details = details;
        emit ContentDetailsUpdated(name, details);
    }

    /**
     * @notice Update the frozen status of the content
     * @dev [WARNING] Once a content it frozen is can no longer be edited
     * @param name - Name given to the content. Eg: threejs.min.js_r148
     *
     * Emits an {ContentFrozen} event.
     */
    function freezeContent(
        string calldata name
    ) public isFrozen(name) isContentOwner(name) {
        contents[name].isFrozen = true;
        emit ContentFrozen(name);
    }

    /**
     * @notice Submit content to EthFS V2 FileStore
     * @param name - Name given to the content. Eg: threejs.min.js_r148
     * @param metadata - metadata for EthFS V2 File
     *
     * Uses name as file name.
     * Emits an {ContentSubmittedToFileStore} event.
     */
    function submitToEthFSFileStore(
        string calldata name,
        bytes memory metadata
    ) public isContentOwner(name) {
        Content memory content = contents[name];
        ethfsFileStore.createFileFromPointers(
            name,
            content.chunks,
            metadata
        );
        contents[name].isFrozen = true;
        emit ContentSubmittedToEthFSFileStore(name, name);
    }

    /**
     * @notice Submit content to EthFS V2 FileStore
     * @param name - Name given to the content. Eg: threejs.min.js_r148
     * @param fileName - Name given to the File in FileStore
     * @param metadata - metadata for EthFS V2 File
     *
     * Emits an {ContentSubmittedToFileStore} event.
     */
    function submitToEthFSFileStoreWithFileName(
        string calldata name,
        string calldata fileName,
        bytes memory metadata
    ) public isContentOwner(name) {
        Content memory content = contents[name];
        ethfsFileStore.createFileFromPointers(
            fileName,
            content.chunks,
            metadata
        );
        contents[name].isFrozen = true;
        emit ContentSubmittedToEthFSFileStore(name, fileName);
    }

    // =============================================================
    //                            GETTERS
    // =============================================================

    /**
     * @notice Get the full content
     * @param name - Name given to the content. Eg: threejs.min.js_r148
     * @param data - Arbitrary data. Not used by this contract.
     * @return content - Full content from merged chunks
     */
    function getContent(
        string memory name,
        bytes memory data
    ) public view returns (bytes memory content) {
        return AddressChunks.mergeChunks(contents[name].chunks);
    }

    /**
     * @notice Get content's chunk pointer list
     * @param name - Name given to the content. Eg: threejs.min.js_r148
     * @return pointers - List of pointers
     */
    function getContentChunkPointers(
        string memory name
    ) public view returns (address[] memory pointers) {
        return contents[name].chunks;
    }
}

File 2 of 10 : Ownable.sol
// 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);
    }
}

File 3 of 10 : Context.sol
// 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;
    }
}

File 4 of 10 : common.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;

import {SSTORE2} from "solady/src/utils/SSTORE2.sol";

bytes32 constant SALT = bytes32("EthFS");

/**
 * @dev Error thrown when the pointer of the content added does not match the one we compute from the content, signaling something weird going on with the deployer
 * @param expectedPointer The expected address of the content
 * @param actualPointer The actual address of the content
 */
error UnexpectedPointer(address expectedPointer, address actualPointer);

/**
 * @dev Converts data into creation code for an SSTORE2 data contract
 * @param content The bytes content to be converted
 * @return creationCode The creation code for the data contract
 */
function contentToInitCode(
    bytes memory content
) pure returns (bytes memory creationCode) {
    // Use the same strategy as Solady's SSTORE2 to write a data contract, but do this via the deployer for a constant address
    // https://github.com/Vectorized/solady/blob/cb801a60f8319a148697b09d19b748d04e3d65c4/src/utils/SSTORE2.sol#L44-L59
    // TODO: convert this to assembly?
    return
        abi.encodePacked(
            bytes11(0x61000080600a3d393df300) |
                // Overlay content size (plus offset for STOP opcode) into second and third bytes
                bytes11(bytes3(uint24(content.length + 1))),
            content
        );
}

/**
 * @dev Predicts the address of a data contract based on its content
 * @param deployer The deployer's address
 * @param content The content of the data contract
 * @return pointer The predicted address of the data contract
 */
function getPointer(
    address deployer,
    bytes memory content
) pure returns (address pointer) {
    return SSTORE2.predictDeterministicAddress(content, SALT, deployer);
}

/**
 * @dev Checks if a pointer (data contract address) already exists
 * @param pointer The data contract address to check
 * @return true if the data contract exists, false otherwise
 */
function pointerExists(address pointer) view returns (bool) {
    return pointer.code.length > 0;
}

/**
 * @dev Adds content as a data contract using a deterministic deployer
 * @param deployer The deployer's address
 * @param content The content to be added as a data contract
 * @return pointer The address of the data contract
 */
function addContent(
    address deployer,
    bytes memory content
) returns (address pointer) {
    address expectedPointer = getPointer(deployer, content);
    if (pointerExists(expectedPointer)) {
        return expectedPointer;
    }

    (bool success, bytes memory data) = deployer.call(
        abi.encodePacked(SALT, contentToInitCode(content))
    );
    if (!success) revertWithBytes(data);

    pointer = address(uint160(bytes20(data)));
    if (pointer != expectedPointer) {
        revert UnexpectedPointer(expectedPointer, pointer);
    }
}

/**
 * @notice Reverts the transaction using the provided raw bytes as the revert reason
 * @dev Uses assembly to perform the revert operation with the raw bytes
 * @param reason The raw bytes revert reason
 */
function revertWithBytes(bytes memory reason) pure {
    assembly {
        // reason+32 is a pointer to the error message, mload(reason) is the length of the error message
        revert(add(reason, 0x20), mload(reason))
    }
}

/**
 * @dev Checks if the given address points to a valid SSTORE2 data contract (i.e. starts with STOP opcode)
 * @param pointer The address to be checked
 * @return isValid true if the address points to a valid contract (bytecode starts with a STOP opcode), false otherwise
 */
function isValidPointer(address pointer) view returns (bool isValid) {
    // The assembly below is equivalent to
    //
    //   pointer.code.length >= 1 && pointer.code[0] == 0x00;
    //
    // but less gas because it doesn't have to load all the pointer's bytecode

    assembly {
        // Get the size of the bytecode at pointer
        let size := extcodesize(pointer)

        // Initialize first byte with INVALID opcode
        let firstByte := 0xfe

        // If there's at least one byte of code, copy the first byte
        if gt(size, 0) {
            // Allocate memory for the first byte
            let code := mload(0x40)

            // Copy the first byte of the code
            extcodecopy(pointer, code, 0, 1)

            // Retrieve the first byte, ensuring it's a single byte
            firstByte := and(mload(sub(code, 31)), 0xff)
        }

        // Check if the first byte is 0x00 (STOP opcode)
        isValid := eq(firstByte, 0x00)
    }
}

File 5 of 10 : File.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;

/**
 * @title EthFS File
 * @notice A representation of an onchain file, composed of slices of contract bytecode and utilities to construct the file contents from those slices.
 * @dev For best gas efficiency, it's recommended using `File.read()` as close to the output returned by the contract call as possible. Lots of gas is consumed every time a large data blob is passed between functions.
 */

/**
 * @dev Represents a reference to a slice of bytecode in a contract
 */
struct BytecodeSlice {
    address pointer;
    uint32 start;
    uint32 end;
}

/**
 * @dev Represents a file composed of one or more bytecode slices
 */
struct File {
    // Total length of file contents (sum of all slice sizes). Useful when you want to use DynamicBuffer to build the file contents from the slices.
    uint256 size;
    BytecodeSlice[] slices;
}
// extend File struct with read functions
using {read} for File global;
using {readUnchecked} for File global;

/**
 * @dev Error thrown when a slice is out of the bounds of the contract's bytecode
 */
error SliceOutOfBounds(
    address pointer,
    uint32 codeSize,
    uint32 sliceStart,
    uint32 sliceEnd
);

/**
 * @notice Reads the contents of a file by concatenating its slices
 * @param file The file to read
 * @return contents The concatenated contents of the file
 */
function read(File memory file) view returns (string memory contents) {
    BytecodeSlice[] memory slices = file.slices;
    bytes4 sliceOutOfBoundsSelector = SliceOutOfBounds.selector;

    assembly {
        let len := mload(slices)
        let size := 0x20
        contents := mload(0x40)
        let slice
        let pointer
        let start
        let end
        let codeSize

        for {
            let i := 0
        } lt(i, len) {
            i := add(i, 1)
        } {
            slice := mload(add(slices, add(0x20, mul(i, 0x20))))
            pointer := mload(slice)
            start := mload(add(slice, 0x20))
            end := mload(add(slice, 0x40))

            codeSize := extcodesize(pointer)
            if gt(end, codeSize) {
                mstore(0x00, sliceOutOfBoundsSelector)
                mstore(0x04, pointer)
                mstore(0x24, codeSize)
                mstore(0x44, start)
                mstore(0x64, end)
                revert(0x00, 0x84)
            }

            extcodecopy(pointer, add(contents, size), start, sub(end, start))
            size := add(size, sub(end, start))
        }

        // update contents size
        mstore(contents, sub(size, 0x20))
        // store contents
        mstore(0x40, add(contents, and(add(size, 0x1f), not(0x1f))))
    }
}

/**
 * @notice Reads the contents of a file without reverting on unreadable/invalid slices. Skips any slices that are out of bounds or invalid. Useful if you are composing contract bytecode where a contract can still selfdestruct (which would result in an invalid slice) and want to avoid reverts but still output potentially "corrupted" file contents (due to missing data).
 * @param file The file to read
 * @return contents The concatenated contents of the file, skipping invalid slices
 */
function readUnchecked(File memory file) view returns (string memory contents) {
    BytecodeSlice[] memory slices = file.slices;

    assembly {
        let len := mload(slices)
        let size := 0x20
        contents := mload(0x40)
        let slice
        let pointer
        let start
        let end
        let codeSize

        for {
            let i := 0
        } lt(i, len) {
            i := add(i, 1)
        } {
            slice := mload(add(slices, add(0x20, mul(i, 0x20))))
            pointer := mload(slice)
            start := mload(add(slice, 0x20))
            end := mload(add(slice, 0x40))

            codeSize := extcodesize(pointer)
            if lt(end, codeSize) {
                extcodecopy(
                    pointer,
                    add(contents, size),
                    start,
                    sub(end, start)
                )
                size := add(size, sub(end, start))
            }
        }

        // update contents size
        mstore(contents, sub(size, 0x20))
        // store contents
        mstore(0x40, add(contents, and(add(size, 0x1f), not(0x1f))))
    }
}

File 6 of 10 : IFileStore.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;

import {File, BytecodeSlice} from "./File.sol";

/// @title EthFS FileStore interface
/// @notice Specifies a content-addressable onchain file store
interface IFileStore {
    event Deployed();

    /**
     * @dev Emitted when a new file is created
     * @param indexedFilename The indexed filename for easier finding by filename in logs
     * @param pointer The pointer address of the file
     * @param filename The name of the file
     * @param size The total size of the file
     * @param metadata Additional metadata of the file, only emitted for use in offchain indexers
     */
    event FileCreated(
        string indexed indexedFilename,
        address indexed pointer,
        string filename,
        uint256 size,
        bytes metadata
    );

    /**
     * @dev Error thrown when a requested file is not found
     * @param filename The name of the file requested
     */
    error FileNotFound(string filename);

    /**
     * @dev Error thrown when a filename already exists
     * @param filename The name of the file attempted to be created
     */
    error FilenameExists(string filename);

    /**
     * @dev Error thrown when attempting to create an empty file
     */
    error FileEmpty();

    /**
     * @dev Error thrown when a provided slice for a file is empty
     * @param pointer The contract address where the bytecode lives
     * @param start The byte offset to start the slice (inclusive)
     * @param end The byte offset to end the slice (exclusive)
     */
    error SliceEmpty(address pointer, uint32 start, uint32 end);

    /**
     * @dev Error thrown when the provided pointer's bytecode does not have the expected STOP opcode prefix from SSTORE2
     * @param pointer The SSTORE2 pointer address
     */
    error InvalidPointer(address pointer);

    /**
     * @notice Returns the address of the CREATE2 deterministic deployer used by this FileStore
     * @return The address of the CREATE2 deterministic deployer
     */
    function deployer() external view returns (address);

    /**
     * @notice Retrieves the pointer address of a file by its filename
     * @param filename The name of the file
     * @return pointer The pointer address of the file
     */
    function files(
        string memory filename
    ) external view returns (address pointer);

    /**
     * @notice Checks if a file exists for a given filename
     * @param filename The name of the file to check
     * @return True if the file exists, false otherwise
     */
    function fileExists(string memory filename) external view returns (bool);

    /**
     * @notice Retrieves the pointer address for a given filename
     * @param filename The name of the file
     * @return pointer The pointer address of the file
     */
    function getPointer(
        string memory filename
    ) external view returns (address pointer);

    /**
     * @notice Retrieves a file by its filename
     * @param filename The name of the file
     * @return file The file associated with the filename
     */
    function getFile(
        string memory filename
    ) external view returns (File memory file);

    /**
     * @notice Creates a new file with the provided file contents
     * @dev This is a convenience method to simplify small file uploads. It's recommended to use `createFileFromPointers` or `createFileFromSlices` for larger files. This particular method splits `contents` into 24575-byte chunks before storing them via SSTORE2.
     * @param filename The name of the new file
     * @param contents The contents of the file
     * @return pointer The pointer address of the new file
     * @return file The newly created file
     */
    function createFile(
        string memory filename,
        string memory contents
    ) external returns (address pointer, File memory file);

    /**
     * @notice Creates a new file with the provided file contents and file metadata
     * @dev This is a convenience method to simplify small file uploads. It's recommended to use `createFileFromPointers` or `createFileFromSlices` for larger files. This particular method splits `contents` into 24575-byte chunks before storing them via SSTORE2.
     * @param filename The name of the new file
     * @param contents The contents of the file
     * @param metadata Additional file metadata, usually a JSON-encoded string, for offchain indexers
     * @return pointer The pointer address of the new file
     * @return file The newly created file
     */
    function createFile(
        string memory filename,
        string memory contents,
        bytes memory metadata
    ) external returns (address pointer, File memory file);

    /**
     * @notice Creates a new file where its content is composed of the provided string chunks
     * @dev This is a convenience method to simplify small and nuanced file uploads. It's recommended to use `createFileFromPointers` or `createFileFromSlices` for larger files. This particular will store each chunk separately via SSTORE2. For best gas efficiency, each chunk should be as large as possible (up to the contract size limit) and at least 32 bytes.
     * @param filename The name of the new file
     * @param chunks The string chunks composing the file
     * @return pointer The pointer address of the new file
     * @return file The newly created file
     */
    function createFileFromChunks(
        string memory filename,
        string[] memory chunks
    ) external returns (address pointer, File memory file);

    /**
     * @notice Creates a new file with the provided string chunks and file metadata
     * @dev This is a convenience method to simplify small and nuanced file uploads. It's recommended to use `createFileFromPointers` or `createFileFromSlices` for larger files. This particular will store each chunk separately via SSTORE2. For best gas efficiency, each chunk should be as large as possible (up to the contract size limit) and at least 32 bytes.
     * @param filename The name of the new file
     * @param chunks The string chunks composing the file
     * @param metadata Additional file metadata, usually a JSON-encoded string, for offchain indexers
     * @return pointer The pointer address of the new file
     * @return file The newly created file
     */
    function createFileFromChunks(
        string memory filename,
        string[] memory chunks,
        bytes memory metadata
    ) external returns (address pointer, File memory file);

    /**
     * @notice Creates a new file where its content is composed of the provided SSTORE2 pointers
     * @param filename The name of the new file
     * @param pointers The SSTORE2 pointers composing the file
     * @return pointer The pointer address of the new file
     * @return file The newly created file
     */
    function createFileFromPointers(
        string memory filename,
        address[] memory pointers
    ) external returns (address pointer, File memory file);

    /**
     * @notice Creates a new file with the provided SSTORE2 pointers and file metadata
     * @param filename The name of the new file
     * @param pointers The SSTORE2 pointers composing the file
     * @param metadata Additional file metadata, usually a JSON-encoded string, for offchain indexers
     * @return pointer The pointer address of the new file
     * @return file The newly created file
     */
    function createFileFromPointers(
        string memory filename,
        address[] memory pointers,
        bytes memory metadata
    ) external returns (address pointer, File memory file);

    /**
     * @notice Creates a new file where its content is composed of the provided bytecode slices
     * @param filename The name of the new file
     * @param slices The bytecode slices composing the file
     * @return pointer The pointer address of the new file
     * @return file The newly created file
     */
    function createFileFromSlices(
        string memory filename,
        BytecodeSlice[] memory slices
    ) external returns (address pointer, File memory file);

    /**
     * @notice Creates a new file with the provided bytecode slices and file metadata
     * @param filename The name of the new file
     * @param slices The bytecode slices composing the file
     * @param metadata Additional file metadata, usually a JSON-encoded string, for offchain indexers
     * @return pointer The pointer address of the new file
     * @return file The newly created file
     */
    function createFileFromSlices(
        string memory filename,
        BytecodeSlice[] memory slices,
        bytes memory metadata
    ) external returns (address pointer, File memory file);
}

File 7 of 10 : IScriptyContractStorage.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;

///////////////////////////////////////////////////////////
// ░██████╗░█████╗░██████╗░██╗██████╗░████████╗██╗░░░██╗ //
// ██╔════╝██╔══██╗██╔══██╗██║██╔══██╗╚══██╔══╝╚██╗░██╔╝ //
// ╚█████╗░██║░░╚═╝██████╔╝██║██████╔╝░░░██║░░░░╚████╔╝░ //
// ░╚═══██╗██║░░██╗██╔══██╗██║██╔═══╝░░░░██║░░░░░╚██╔╝░░ //
// ██████╔╝╚█████╔╝██║░░██║██║██║░░░░░░░░██║░░░░░░██║░░░ //
// ╚═════╝░░╚════╝░╚═╝░░╚═╝╚═╝╚═╝░░░░░░░░╚═╝░░░░░░╚═╝░░░ //
///////////////////////////////////////////////////////////

interface IScriptyContractStorage {
    // =============================================================
    //                            GETTERS
    // =============================================================

    /**
     * @notice Get the full content
     * @param name - Name given to the script. Eg: threejs.min.js_r148
     * @param data - Arbitrary data to be passed to storage
     * @return script - Full script from merged chunks
     */
    function getContent(string calldata name, bytes memory data)
        external
        view
        returns (bytes memory script);
}

File 8 of 10 : IScriptyStorage.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

///////////////////////////////////////////////////////////
// ░██████╗░█████╗░██████╗░██╗██████╗░████████╗██╗░░░██╗ //
// ██╔════╝██╔══██╗██╔══██╗██║██╔══██╗╚══██╔══╝╚██╗░██╔╝ //
// ╚█████╗░██║░░╚═╝██████╔╝██║██████╔╝░░░██║░░░░╚████╔╝░ //
// ░╚═══██╗██║░░██╗██╔══██╗██║██╔═══╝░░░░██║░░░░░╚██╔╝░░ //
// ██████╔╝╚█████╔╝██║░░██║██║██║░░░░░░░░██║░░░░░░██║░░░ //
// ╚═════╝░░╚════╝░╚═╝░░╚═╝╚═╝╚═╝░░░░░░░░╚═╝░░░░░░╚═╝░░░ //
///////////////////////////////////////////////////////////

interface IScriptyStorage {
    // =============================================================
    //                            STRUCTS
    // =============================================================

    struct Content {
        bool isFrozen;
        address owner;
        uint256 size;
        bytes details;
        address[] chunks;
    }

    // =============================================================
    //                            ERRORS
    // =============================================================

    /**
     * @notice Error for, The content you are trying to create already exists
     */
    error ContentExists();

    /**
     * @notice Error for, You dont have permissions to perform this action
     */
    error NotContentOwner();

    /**
     * @notice Error for, The content you are trying to edit is frozen
     */
    error ContentIsFrozen(string name);

    // =============================================================
    //                            EVENTS
    // =============================================================

    /**
     * @notice Event for, Successful freezing of a content
     * @param name - Name given to the content. Eg: threejs.min.js_r148
     */
    event ContentFrozen(string indexed name);

    /**
     * @notice Event for, Successful creation of a content
     * @param name - Name given to the content. Eg: threejs.min.js_r148
     * @param details - Custom details of the content
     */
    event ContentCreated(string indexed name, bytes details);

    /**
     * @notice Event for, Successful addition of content chunk
     * @param name - Name given to the content. Eg: threejs.min.js_r148
     * @param size - Bytes size of the chunk
     */
    event ChunkStored(string indexed name, uint256 size);

    /**
     * @notice Event for, Successful update of custom details
     * @param name - Name given to the content. Eg: threejs.min.js_r148
     * @param details - Custom details of the content
     */
    event ContentDetailsUpdated(string indexed name, bytes details);

    /**
     * @notice Event for, submitting content to EthFS FileStore
     * @param name - Name given to the content. Eg: threejs.min.js_r148
     * @param fileName - Name given to the file in File Store.
     */
    event ContentSubmittedToEthFSFileStore(string indexed name, string indexed fileName);

    // =============================================================
    //                      MANAGEMENT OPERATIONS
    // =============================================================

    /**
     * @notice Create a new content
     * @param name - Name given to the content. Eg: threejs.min.js_r148
     * @param details - Any details the owner wishes to store about the content
     *
     * Emits an {ContentCreated} event.
     */
    function createContent(
        string calldata name,
        bytes calldata details
    ) external;

    /**
     * @notice Add a content chunk to the content
     * @param name - Name given to the content. Eg: threejs.min.js_r148
     * @param chunk - Next sequential content chunk
     *
     * Emits an {ChunkStored} event.
     */
    function addChunkToContent(
        string calldata name,
        bytes calldata chunk
    ) external;

    /**
     * @notice Submit content to EthFS V2 FileStore
     * @param name - Name given to the content. Eg: threejs.min.js_r148
     * @param metadata - metadata for EthFS V2 File
     *
     * Uses name as file name.
     * Emits an {ContentSubmittedToFileStore} event.
     */
    function submitToEthFSFileStore(
        string calldata name,
        bytes memory metadata
    ) external;

    /**
     * @notice Submit content to EthFS V2 FileStore
     * @param name - Name given to the content. Eg: threejs.min.js_r148
     * @param fileName - Name given to the File in FileStore
     * @param metadata - metadata for EthFS V2 File
     *
     * Emits an {ContentSubmittedToFileStore} event.
     */
    function submitToEthFSFileStoreWithFileName(
        string calldata name,
        string calldata fileName,
        bytes memory metadata
    ) external;
}

File 9 of 10 : AddressChunks.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;

/**
 * @title AddressChunks
 * @author @xtremetom
 * @notice Reads chunk pointers and merges their values
 */
library AddressChunks {
    function mergeChunks(address[] memory chunks)
        internal
        view
        returns (bytes memory o_code)
    {
        unchecked {
            assembly {
                let len := mload(chunks)
                let totalSize := 0x20
                let size := 0
                o_code := mload(0x40)

                // loop through all chunk addresses
                // - get address
                // - get data size
                // - get code and add to o_code
                // - update total size
                let targetChunk := 0
                for {
                    let i := 0
                } lt(i, len) {
                    i := add(i, 1)
                } {
                    targetChunk := mload(add(chunks, add(0x20, mul(i, 0x20))))
                    size := sub(extcodesize(targetChunk), 1)
                    extcodecopy(targetChunk, add(o_code, totalSize), 1, size)
                    totalSize := add(totalSize, size)
                }

                // update o_code size
                mstore(o_code, sub(totalSize, 0x20))
                // store o_code
                mstore(0x40, add(o_code, and(add(totalSize, 0x1f), not(0x1f))))
            }
        }
    }
}

File 10 of 10 : SSTORE2.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Read and write to persistent storage at a fraction of the cost.
/// @author Solady (https://github.com/vectorized/solmady/blob/main/src/utils/SSTORE2.sol)
/// @author Saw-mon-and-Natalie (https://github.com/Saw-mon-and-Natalie)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SSTORE2.sol)
/// @author Modified from 0xSequence (https://github.com/0xSequence/sstore2/blob/master/contracts/SSTORE2.sol)
library SSTORE2 {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         CONSTANTS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev We skip the first byte as it's a STOP opcode,
    /// which ensures the contract can't be called.
    uint256 internal constant DATA_OFFSET = 1;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                        CUSTOM ERRORS                       */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Unable to deploy the storage contract.
    error DeploymentFailed();

    /// @dev The storage contract address is invalid.
    error InvalidPointer();

    /// @dev Attempt to read outside of the storage contract's bytecode bounds.
    error ReadOutOfBounds();

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         WRITE LOGIC                        */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Writes `data` into the bytecode of a storage contract and returns its address.
    function write(bytes memory data) internal returns (address pointer) {
        /// @solidity memory-safe-assembly
        assembly {
            let originalDataLength := mload(data)

            // Add 1 to data size since we are prefixing it with a STOP opcode.
            let dataSize := add(originalDataLength, DATA_OFFSET)

            /**
             * ------------------------------------------------------------------------------+
             * Opcode      | Mnemonic        | Stack                   | Memory              |
             * ------------------------------------------------------------------------------|
             * 61 dataSize | PUSH2 dataSize  | dataSize                |                     |
             * 80          | DUP1            | dataSize dataSize       |                     |
             * 60 0xa      | PUSH1 0xa       | 0xa dataSize dataSize   |                     |
             * 3D          | RETURNDATASIZE  | 0 0xa dataSize dataSize |                     |
             * 39          | CODECOPY        | dataSize                | [0..dataSize): code |
             * 3D          | RETURNDATASIZE  | 0 dataSize              | [0..dataSize): code |
             * F3          | RETURN          |                         | [0..dataSize): code |
             * 00          | STOP            |                         |                     |
             * ------------------------------------------------------------------------------+
             * @dev Prefix the bytecode with a STOP opcode to ensure it cannot be called.
             * Also PUSH2 is used since max contract size cap is 24,576 bytes which is less than 2 ** 16.
             */
            mstore(
                // Do a out-of-gas revert if `dataSize` is more than 2 bytes.
                // The actual EVM limit may be smaller and may change over time.
                add(data, gt(dataSize, 0xffff)),
                // Left shift `dataSize` by 64 so that it lines up with the 0000 after PUSH2.
                or(0xfd61000080600a3d393df300, shl(0x40, dataSize))
            )

            // Deploy a new contract with the generated creation code.
            pointer := create(0, add(data, 0x15), add(dataSize, 0xa))

            // If `pointer` is zero, revert.
            if iszero(pointer) {
                // Store the function selector of `DeploymentFailed()`.
                mstore(0x00, 0x30116425)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }

            // Restore original length of the variable size `data`.
            mstore(data, originalDataLength)
        }
    }

    /// @dev Writes `data` into the bytecode of a storage contract with `salt`
    /// and returns its deterministic address.
    function writeDeterministic(bytes memory data, bytes32 salt)
        internal
        returns (address pointer)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let originalDataLength := mload(data)
            let dataSize := add(originalDataLength, DATA_OFFSET)

            mstore(
                // Do a out-of-gas revert if `dataSize` is more than 2 bytes.
                // The actual EVM limit may be smaller and may change over time.
                add(data, gt(dataSize, 0xffff)),
                // Left shift `dataSize` by 64 so that it lines up with the 0000 after PUSH2.
                or(0xfd61000080600a3d393df300, shl(0x40, dataSize))
            )

            // Deploy a new contract with the generated creation code.
            pointer := create2(0, add(data, 0x15), add(dataSize, 0xa), salt)

            // If `pointer` is zero, revert.
            if iszero(pointer) {
                // Store the function selector of `DeploymentFailed()`.
                mstore(0x00, 0x30116425)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }

            // Restore original length of the variable size `data`.
            mstore(data, originalDataLength)
        }
    }

    /// @dev Returns the initialization code hash of the storage contract for `data`.
    /// Used for mining vanity addresses with create2crunch.
    function initCodeHash(bytes memory data) internal pure returns (bytes32 hash) {
        /// @solidity memory-safe-assembly
        assembly {
            let originalDataLength := mload(data)
            let dataSize := add(originalDataLength, DATA_OFFSET)

            // Do a out-of-gas revert if `dataSize` is more than 2 bytes.
            // The actual EVM limit may be smaller and may change over time.
            returndatacopy(returndatasize(), returndatasize(), shr(16, dataSize))

            mstore(data, or(0x61000080600a3d393df300, shl(0x40, dataSize)))

            hash := keccak256(add(data, 0x15), add(dataSize, 0xa))

            // Restore original length of the variable size `data`.
            mstore(data, originalDataLength)
        }
    }

    /// @dev Returns the address of the storage contract for `data`
    /// deployed with `salt` by `deployer`.
    /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly.
    function predictDeterministicAddress(bytes memory data, bytes32 salt, address deployer)
        internal
        pure
        returns (address predicted)
    {
        bytes32 hash = initCodeHash(data);
        /// @solidity memory-safe-assembly
        assembly {
            // Compute and store the bytecode hash.
            mstore8(0x00, 0xff) // Write the prefix.
            mstore(0x35, hash)
            mstore(0x01, shl(96, deployer))
            mstore(0x15, salt)
            predicted := keccak256(0x00, 0x55)
            // Restore the part of the free memory pointer that has been overwritten.
            mstore(0x35, 0)
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         READ LOGIC                         */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns all the `data` from the bytecode of the storage contract at `pointer`.
    function read(address pointer) internal view returns (bytes memory data) {
        /// @solidity memory-safe-assembly
        assembly {
            let pointerCodesize := extcodesize(pointer)
            if iszero(pointerCodesize) {
                // Store the function selector of `InvalidPointer()`.
                mstore(0x00, 0x11052bb4)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }
            // Offset all indices by 1 to skip the STOP opcode.
            let size := sub(pointerCodesize, DATA_OFFSET)

            // Get the pointer to the free memory and allocate
            // enough 32-byte words for the data and the length of the data,
            // then copy the code to the allocated memory.
            // Masking with 0xffe0 will suffice, since contract size is less than 16 bits.
            data := mload(0x40)
            mstore(0x40, add(data, and(add(size, 0x3f), 0xffe0)))
            mstore(data, size)
            mstore(add(add(data, 0x20), size), 0) // Zeroize the last slot.
            extcodecopy(pointer, add(data, 0x20), DATA_OFFSET, size)
        }
    }

    /// @dev Returns the `data` from the bytecode of the storage contract at `pointer`,
    /// from the byte at `start`, to the end of the data stored.
    function read(address pointer, uint256 start) internal view returns (bytes memory data) {
        /// @solidity memory-safe-assembly
        assembly {
            let pointerCodesize := extcodesize(pointer)
            if iszero(pointerCodesize) {
                // Store the function selector of `InvalidPointer()`.
                mstore(0x00, 0x11052bb4)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }

            // If `!(pointer.code.size > start)`, reverts.
            // This also handles the case where `start + DATA_OFFSET` overflows.
            if iszero(gt(pointerCodesize, start)) {
                // Store the function selector of `ReadOutOfBounds()`.
                mstore(0x00, 0x84eb0dd1)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }
            let size := sub(pointerCodesize, add(start, DATA_OFFSET))

            // Get the pointer to the free memory and allocate
            // enough 32-byte words for the data and the length of the data,
            // then copy the code to the allocated memory.
            // Masking with 0xffe0 will suffice, since contract size is less than 16 bits.
            data := mload(0x40)
            mstore(0x40, add(data, and(add(size, 0x3f), 0xffe0)))
            mstore(data, size)
            mstore(add(add(data, 0x20), size), 0) // Zeroize the last slot.
            extcodecopy(pointer, add(data, 0x20), add(start, DATA_OFFSET), size)
        }
    }

    /// @dev Returns the `data` from the bytecode of the storage contract at `pointer`,
    /// from the byte at `start`, to the byte at `end` (exclusive) of the data stored.
    function read(address pointer, uint256 start, uint256 end)
        internal
        view
        returns (bytes memory data)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let pointerCodesize := extcodesize(pointer)
            if iszero(pointerCodesize) {
                // Store the function selector of `InvalidPointer()`.
                mstore(0x00, 0x11052bb4)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }

            // If `!(pointer.code.size > end) || (start > end)`, revert.
            // This also handles the cases where
            // `end + DATA_OFFSET` or `start + DATA_OFFSET` overflows.
            if iszero(
                and(
                    gt(pointerCodesize, end), // Within bounds.
                    iszero(gt(start, end)) // Valid range.
                )
            ) {
                // Store the function selector of `ReadOutOfBounds()`.
                mstore(0x00, 0x84eb0dd1)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }
            let size := sub(end, start)

            // Get the pointer to the free memory and allocate
            // enough 32-byte words for the data and the length of the data,
            // then copy the code to the allocated memory.
            // Masking with 0xffe0 will suffice, since contract size is less than 16 bits.
            data := mload(0x40)
            mstore(0x40, add(data, and(add(size, 0x3f), 0xffe0)))
            mstore(data, size)
            mstore(add(add(data, 0x20), size), 0) // Zeroize the last slot.
            extcodecopy(pointer, add(data, 0x20), add(start, DATA_OFFSET), size)
        }
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 500
  },
  "evmVersion": "paris",
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract IFileStore","name":"ethfsFileStore_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ContentExists","type":"error"},{"inputs":[{"internalType":"string","name":"name","type":"string"}],"name":"ContentIsFrozen","type":"error"},{"inputs":[],"name":"NotContentOwner","type":"error"},{"inputs":[{"internalType":"address","name":"expectedPointer","type":"address"},{"internalType":"address","name":"actualPointer","type":"address"}],"name":"UnexpectedPointer","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"uint256","name":"size","type":"uint256"}],"name":"ChunkStored","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"bytes","name":"details","type":"bytes"}],"name":"ContentCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"bytes","name":"details","type":"bytes"}],"name":"ContentDetailsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"name","type":"string"}],"name":"ContentFrozen","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"name","type":"string"},{"indexed":true,"internalType":"string","name":"fileName","type":"string"}],"name":"ContentSubmittedToEthFSFileStore","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"bytes","name":"chunk","type":"bytes"}],"name":"addChunkToContent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"contents","outputs":[{"internalType":"bool","name":"isFrozen","type":"bool"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"size","type":"uint256"},{"internalType":"bytes","name":"details","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"bytes","name":"details","type":"bytes"}],"name":"createContent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"ethfsFileStore","outputs":[{"internalType":"contract IFileStore","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"}],"name":"freezeContent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"getContent","outputs":[{"internalType":"bytes","name":"content","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"}],"name":"getContentChunkPointers","outputs":[{"internalType":"address[]","name":"pointers","type":"address[]"}],"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":"string","name":"name","type":"string"},{"internalType":"bytes","name":"metadata","type":"bytes"}],"name":"submitToEthFSFileStore","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"fileName","type":"string"},{"internalType":"bytes","name":"metadata","type":"bytes"}],"name":"submitToEthFSFileStoreWithFileName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"bytes","name":"details","type":"bytes"}],"name":"updateDetails","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a06040523480156200001157600080fd5b5060405162001f1038038062001f108339810160408190526200003491620000a1565b6200003f3362000051565b6001600160a01b0316608052620000d3565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600060208284031215620000b457600080fd5b81516001600160a01b0381168114620000cc57600080fd5b9392505050565b608051611e0c62000104600039600081816101a0015281816103f0015281816106c80152610af00152611e0c6000f3fe608060405234801561001057600080fd5b50600436106100df5760003560e01c80637a2c57011161008c578063a6acce3511610066578063a6acce35146101c2578063c3766aff146101e5578063f2fde38b146101f8578063f71e55c61461020b57600080fd5b80637a2c5701146101635780638da5cb5b1461017657806397228f671461019b57600080fd5b80634f1165ce116100bd5780634f1165ce146101355780635fe5069914610148578063715018a61461015b57600080fd5b80631a4165e4146100e457806324fcb5b0146100f95780632647c23d1461010c575b600080fd5b6100f76100f2366004611570565b61022b565b005b6100f76101073660046115d9565b610503565b61011f61011a36600461166d565b6107dd565b60405161012c9190611721565b60405180910390f35b6100f7610143366004611734565b610864565b6100f7610156366004611734565b610a43565b6100f7610c89565b6100f76101713660046117a0565b610c9d565b6000546001600160a01b03165b6040516001600160a01b03909116815260200161012c565b6101837f000000000000000000000000000000000000000000000000000000000000000081565b6101d56101d03660046117e2565b610db3565b60405161012c949392919061181f565b6100f76101f3366004611734565b610e80565b6100f761020636600461186e565b610fab565b61021e6102193660046117e2565b611024565b60405161012c91906118d7565b82826001828260405161023f9291906118ea565b9081526040516020918190039190910190205461010090046001600160a01b0316331461027f5760405163796d3af960e11b815260040160405180910390fd5b6000600186866040516102939291906118ea565b90815260408051918290036020908101832060a084018352805460ff8116151585526001600160a01b0361010090910416918401919091526001810154918301919091526002810180546060840191906102ec906118fa565b80601f0160208091040260200160405190810160405280929190818152602001828054610318906118fa565b80156103655780601f1061033a57610100808354040283529160200191610365565b820191906000526020600020905b81548152906001019060200180831161034857829003601f168201915b50505050508152602001600382018054806020026020016040519081016040528092919081815260200182805480156103c757602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116103a9575b505050919092525050506080810151604051633b08e58160e11b81529192506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691637611cb0291610429918a918a918a9060040161195d565b6000604051808303816000875af1158015610448573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261047091908101906119bb565b505060018087876040516104859291906118ea565b908152604051908190036020018120805492151560ff19909316929092179091556104b390879087906118ea565b604051809103902086866040516104cb9291906118ea565b604051908190038120907f45b4f2dc04ba811e9f0eb4779ac0016db21bdc2f7bd725e733fe2f82a454aec390600090a3505050505050565b8484600182826040516105179291906118ea565b9081526040516020918190039190910190205461010090046001600160a01b031633146105575760405163796d3af960e11b815260040160405180910390fd5b60006001888860405161056b9291906118ea565b90815260408051918290036020908101832060a084018352805460ff8116151585526001600160a01b0361010090910416918401919091526001810154918301919091526002810180546060840191906105c4906118fa565b80601f01602080910402602001604051908101604052809291908181526020018280546105f0906118fa565b801561063d5780601f106106125761010080835404028352916020019161063d565b820191906000526020600020905b81548152906001019060200180831161062057829003601f168201915b505050505081526020016003820180548060200260200160405190810160405280929190818152602001828054801561069f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610681575b505050919092525050506080810151604051633b08e58160e11b81529192506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691637611cb0291610701918a918a918a9060040161195d565b6000604051808303816000875af1158015610720573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261074891908101906119bb565b5050600180898960405161075d9291906118ea565b908152604051908190036020018120805492151560ff199093169290921790915561078b90879087906118ea565b604051809103902088886040516107a39291906118ea565b604051908190038120907f45b4f2dc04ba811e9f0eb4779ac0016db21bdc2f7bd725e733fe2f82a454aec390600090a35050505050505050565b606061085b6001846040516107f29190611af5565b908152604080519182900360209081018320600301805480830285018301909352828452919083018282801561085157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610833575b50505050506110a1565b90505b92915050565b838360006001600160a01b0316600183836040516108839291906118ea565b908152604051908190036020019020546001600160a01b0361010090910416146108c057604051637568bc3560e01b815260040160405180910390fd5b6040518060a00160405280600015158152602001336001600160a01b031681526020016000815260200185858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509385525050604080519283526020808401825290930191909152505160019061094890899089906118ea565b9081526040805160209281900383019020835181549385015174ffffffffffffffffffffffffffffffffffffffffff1990941690151574ffffffffffffffffffffffffffffffffffffffff001916176101006001600160a01b03909416939093029290921782558201516001820155606082015160028201906109cb9082611b62565b50608082015180516109e79160038401916020909101906113aa565b50506040516109fa9150879087906118ea565b60405180910390207fdef375f83e0f3b86cf8ca9fc60e75073470e0e38705f1e215206737edb2a564a8585604051610a33929190611c22565b60405180910390a2505050505050565b838360018282604051610a579291906118ea565b9081526040519081900360200190205460ff1615610a9557818160405163096ef08360e01b8152600401610a8c929190611c22565b60405180910390fd5b858560018282604051610aa99291906118ea565b9081526040516020918190039190910190205461010090046001600160a01b03163314610ae95760405163796d3af960e11b815260040160405180910390fd5b6000610bac7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d5f394886040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b709190611c36565b88888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506110f992505050565b905060018989604051610bc09291906118ea565b908152604051602091819003820181206003018054600180820183556000928352939091200180546001600160a01b0319166001600160a01b038516179055879190610c0f908c908c906118ea565b90815260200160405180910390206001016000828254610c2f9190611c53565b9091555050604051610c44908a908a906118ea565b604051908190038120878252907f4c4439fb488c666dfac05b75b1eaa33ddec20e80ade108bbfbf9a346101a17fa9060200160405180910390a2505050505050505050565b610c91611211565b610c9b600061126b565b565b818160018282604051610cb19291906118ea565b9081526040519081900360200190205460ff1615610ce657818160405163096ef08360e01b8152600401610a8c929190611c22565b838360018282604051610cfa9291906118ea565b9081526040516020918190039190910190205461010090046001600160a01b03163314610d3a5760405163796d3af960e11b815260040160405180910390fd5b6001808787604051610d4d9291906118ea565b908152604051908190036020018120805492151560ff1990931692909217909155610d7b90879087906118ea565b604051908190038120907f97add12139614f08415043a75d4c656150251bc30d807d1bf5fe2eda77c539f690600090a2505050505050565b80516020818301810180516001808352938301929094019190912092905281549082015460028301805460ff8416946101009094046001600160a01b0316939190610dfd906118fa565b80601f0160208091040260200160405190810160405280929190818152602001828054610e29906118fa565b8015610e765780601f10610e4b57610100808354040283529160200191610e76565b820191906000526020600020905b815481529060010190602001808311610e5957829003601f168201915b5050505050905084565b838360018282604051610e949291906118ea565b9081526040519081900360200190205460ff1615610ec957818160405163096ef08360e01b8152600401610a8c929190611c22565b858560018282604051610edd9291906118ea565b9081526040516020918190039190910190205461010090046001600160a01b03163314610f1d5760405163796d3af960e11b815260040160405180910390fd5b858560018a8a604051610f319291906118ea565b90815260200160405180910390206002019182610f4f929190611c74565b508787604051610f609291906118ea565b60405180910390207f841de8cd90147293506b2d92fd0b437d946450a4a4a4f399dccc9d76473d72a78787604051610f99929190611c22565b60405180910390a25050505050505050565b610fb3611211565b6001600160a01b0381166110185760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a8c565b6110218161126b565b50565b60606001826040516110369190611af5565b908152604080519182900360209081018320600301805480830285018301909352828452919083018282801561109557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611077575b50505050509050919050565b8051604051906020600080805b848110156110dd576020810260200187015191506001823b039250826001858801843c928201926001016110ae565b505050601f198082018452601f90910116820160405250919050565b60008061110684846112bb565b90506001600160a01b0381163b1561111f57905061085e565b600080856001600160a01b031664457468465360d81b61113e876112d0565b60405160200161114f929190611d35565b60408051601f198184030181529082905261116991611af5565b6000604051808303816000865af19150503d80600081146111a6576040519150601f19603f3d011682016040523d82523d6000602084013e6111ab565b606091505b5091509150816111be576111be8161133b565b6111c781611d5b565b60601c93506001600160a01b038316841461120857604051636509115d60e01b81526001600160a01b03808516600483015285166024820152604401610a8c565b50505092915050565b6000546001600160a01b03163314610c9b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a8c565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600061085b8264457468465360d81b85611343565b6060815160016112e09190611c53565b60e81b7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166a61000080600a3d393df30060a81b1782604051602001611325929190611d97565b6040516020818303038152906040529050919050565b805160208201fd5b60008061134f85611379565b905060ff600053806035528260601b60015283601552605560002091506000603552509392505050565b60008151600181018060101c3d3d3e6a61000080600a3d393df300604082901b178452600a01601584012092525090565b8280548282559060005260206000209081019282156113ff579160200282015b828111156113ff57825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906113ca565b5061140b92915061140f565b5090565b5b8082111561140b5760008155600101611410565b60008083601f84011261143657600080fd5b50813567ffffffffffffffff81111561144e57600080fd5b60208301915083602082850101111561146657600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156114a6576114a661146d565b60405290565b6040516060810167ffffffffffffffff811182821017156114a6576114a661146d565b604051601f8201601f1916810167ffffffffffffffff811182821017156114f8576114f861146d565b604052919050565b600082601f83011261151157600080fd5b813567ffffffffffffffff81111561152b5761152b61146d565b61153e601f8201601f19166020016114cf565b81815284602083860101111561155357600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006040848603121561158557600080fd5b833567ffffffffffffffff8082111561159d57600080fd5b6115a987838801611424565b909550935060208601359150808211156115c257600080fd5b506115cf86828701611500565b9150509250925092565b6000806000806000606086880312156115f157600080fd5b853567ffffffffffffffff8082111561160957600080fd5b61161589838a01611424565b9097509550602088013591508082111561162e57600080fd5b61163a89838a01611424565b9095509350604088013591508082111561165357600080fd5b5061166088828901611500565b9150509295509295909350565b6000806040838503121561168057600080fd5b823567ffffffffffffffff8082111561169857600080fd5b6116a486838701611500565b935060208501359150808211156116ba57600080fd5b506116c785828601611500565b9150509250929050565b60005b838110156116ec5781810151838201526020016116d4565b50506000910152565b6000815180845261170d8160208601602086016116d1565b601f01601f19169290920160200192915050565b60208152600061085b60208301846116f5565b6000806000806040858703121561174a57600080fd5b843567ffffffffffffffff8082111561176257600080fd5b61176e88838901611424565b9096509450602087013591508082111561178757600080fd5b5061179487828801611424565b95989497509550505050565b600080602083850312156117b357600080fd5b823567ffffffffffffffff8111156117ca57600080fd5b6117d685828601611424565b90969095509350505050565b6000602082840312156117f457600080fd5b813567ffffffffffffffff81111561180b57600080fd5b61181784828501611500565b949350505050565b84151581526001600160a01b038416602082015282604082015260806060820152600061184f60808301846116f5565b9695505050505050565b6001600160a01b038116811461102157600080fd5b60006020828403121561188057600080fd5b813561188b81611859565b9392505050565b60008151808452602080850194506020840160005b838110156118cc5781516001600160a01b0316875295820195908201906001016118a7565b509495945050505050565b60208152600061085b6020830184611892565b8183823760009101908152919050565b600181811c9082168061190e57607f821691505b60208210810361192e57634e487b7160e01b600052602260045260246000fd5b50919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b606081526000611971606083018688611934565b82810360208401526119838186611892565b9050828103604084015261199781856116f5565b979650505050505050565b805163ffffffff811681146119b657600080fd5b919050565b60008060408084860312156119cf57600080fd5b83516119da81611859565b8093505060208085015167ffffffffffffffff808211156119fa57600080fd5b9086019060408289031215611a0e57600080fd5b611a16611483565b825181528383015182811115611a2b57600080fd5b80840193505088601f840112611a4057600080fd5b825182811115611a5257611a5261146d565b611a60858260051b016114cf565b8181528581019350606091820285018601918b831115611a7f57600080fd5b948601945b82861015611ade5780868d031215611a9c5760008081fd5b611aa46114ac565b8651611aaf81611859565b8152611abc8789016119a2565b88820152611acb8988016119a2565b818a015285529485019493860193611a84565b508086840152505080955050505050509250929050565b60008251611b078184602087016116d1565b9190910192915050565b601f821115611b5d576000816000526020600020601f850160051c81016020861015611b3a5750805b601f850160051c820191505b81811015611b5957828155600101611b46565b5050505b505050565b815167ffffffffffffffff811115611b7c57611b7c61146d565b611b9081611b8a84546118fa565b84611b11565b602080601f831160018114611bc55760008415611bad5750858301515b600019600386901b1c1916600185901b178555611b59565b600085815260208120601f198616915b82811015611bf457888601518255948401946001909101908401611bd5565b5085821015611c125787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602081526000611817602083018486611934565b600060208284031215611c4857600080fd5b815161188b81611859565b8082018082111561085e57634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff831115611c8c57611c8c61146d565b611ca083611c9a83546118fa565b83611b11565b6000601f841160018114611cd45760008515611cbc5750838201355b600019600387901b1c1916600186901b178355611d2e565b600083815260209020601f19861690835b82811015611d055786850135825560209485019460019092019101611ce5565b5086821015611d225760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b82815260008251611d4d8160208501602087016116d1565b919091016020019392505050565b805160208201516bffffffffffffffffffffffff198082169291906014831015611d8f5780818460140360031b1b83161693505b505050919050565b74ffffffffffffffffffffffffffffffffffffffffff19831681528151600090611dc881600b8501602087016116d1565b91909101600b01939250505056fea264697066735822122000d7937b0bcb0d4efc37cda494e12a71f317e959f93bb3c6a2c6309ae38509a564736f6c63430008160033000000000000000000000000fe1411d6864592549ade050215482e4385dfa0fb

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100df5760003560e01c80637a2c57011161008c578063a6acce3511610066578063a6acce35146101c2578063c3766aff146101e5578063f2fde38b146101f8578063f71e55c61461020b57600080fd5b80637a2c5701146101635780638da5cb5b1461017657806397228f671461019b57600080fd5b80634f1165ce116100bd5780634f1165ce146101355780635fe5069914610148578063715018a61461015b57600080fd5b80631a4165e4146100e457806324fcb5b0146100f95780632647c23d1461010c575b600080fd5b6100f76100f2366004611570565b61022b565b005b6100f76101073660046115d9565b610503565b61011f61011a36600461166d565b6107dd565b60405161012c9190611721565b60405180910390f35b6100f7610143366004611734565b610864565b6100f7610156366004611734565b610a43565b6100f7610c89565b6100f76101713660046117a0565b610c9d565b6000546001600160a01b03165b6040516001600160a01b03909116815260200161012c565b6101837f000000000000000000000000fe1411d6864592549ade050215482e4385dfa0fb81565b6101d56101d03660046117e2565b610db3565b60405161012c949392919061181f565b6100f76101f3366004611734565b610e80565b6100f761020636600461186e565b610fab565b61021e6102193660046117e2565b611024565b60405161012c91906118d7565b82826001828260405161023f9291906118ea565b9081526040516020918190039190910190205461010090046001600160a01b0316331461027f5760405163796d3af960e11b815260040160405180910390fd5b6000600186866040516102939291906118ea565b90815260408051918290036020908101832060a084018352805460ff8116151585526001600160a01b0361010090910416918401919091526001810154918301919091526002810180546060840191906102ec906118fa565b80601f0160208091040260200160405190810160405280929190818152602001828054610318906118fa565b80156103655780601f1061033a57610100808354040283529160200191610365565b820191906000526020600020905b81548152906001019060200180831161034857829003601f168201915b50505050508152602001600382018054806020026020016040519081016040528092919081815260200182805480156103c757602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116103a9575b505050919092525050506080810151604051633b08e58160e11b81529192506001600160a01b037f000000000000000000000000fe1411d6864592549ade050215482e4385dfa0fb1691637611cb0291610429918a918a918a9060040161195d565b6000604051808303816000875af1158015610448573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261047091908101906119bb565b505060018087876040516104859291906118ea565b908152604051908190036020018120805492151560ff19909316929092179091556104b390879087906118ea565b604051809103902086866040516104cb9291906118ea565b604051908190038120907f45b4f2dc04ba811e9f0eb4779ac0016db21bdc2f7bd725e733fe2f82a454aec390600090a3505050505050565b8484600182826040516105179291906118ea565b9081526040516020918190039190910190205461010090046001600160a01b031633146105575760405163796d3af960e11b815260040160405180910390fd5b60006001888860405161056b9291906118ea565b90815260408051918290036020908101832060a084018352805460ff8116151585526001600160a01b0361010090910416918401919091526001810154918301919091526002810180546060840191906105c4906118fa565b80601f01602080910402602001604051908101604052809291908181526020018280546105f0906118fa565b801561063d5780601f106106125761010080835404028352916020019161063d565b820191906000526020600020905b81548152906001019060200180831161062057829003601f168201915b505050505081526020016003820180548060200260200160405190810160405280929190818152602001828054801561069f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610681575b505050919092525050506080810151604051633b08e58160e11b81529192506001600160a01b037f000000000000000000000000fe1411d6864592549ade050215482e4385dfa0fb1691637611cb0291610701918a918a918a9060040161195d565b6000604051808303816000875af1158015610720573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261074891908101906119bb565b5050600180898960405161075d9291906118ea565b908152604051908190036020018120805492151560ff199093169290921790915561078b90879087906118ea565b604051809103902088886040516107a39291906118ea565b604051908190038120907f45b4f2dc04ba811e9f0eb4779ac0016db21bdc2f7bd725e733fe2f82a454aec390600090a35050505050505050565b606061085b6001846040516107f29190611af5565b908152604080519182900360209081018320600301805480830285018301909352828452919083018282801561085157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610833575b50505050506110a1565b90505b92915050565b838360006001600160a01b0316600183836040516108839291906118ea565b908152604051908190036020019020546001600160a01b0361010090910416146108c057604051637568bc3560e01b815260040160405180910390fd5b6040518060a00160405280600015158152602001336001600160a01b031681526020016000815260200185858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509385525050604080519283526020808401825290930191909152505160019061094890899089906118ea565b9081526040805160209281900383019020835181549385015174ffffffffffffffffffffffffffffffffffffffffff1990941690151574ffffffffffffffffffffffffffffffffffffffff001916176101006001600160a01b03909416939093029290921782558201516001820155606082015160028201906109cb9082611b62565b50608082015180516109e79160038401916020909101906113aa565b50506040516109fa9150879087906118ea565b60405180910390207fdef375f83e0f3b86cf8ca9fc60e75073470e0e38705f1e215206737edb2a564a8585604051610a33929190611c22565b60405180910390a2505050505050565b838360018282604051610a579291906118ea565b9081526040519081900360200190205460ff1615610a9557818160405163096ef08360e01b8152600401610a8c929190611c22565b60405180910390fd5b858560018282604051610aa99291906118ea565b9081526040516020918190039190910190205461010090046001600160a01b03163314610ae95760405163796d3af960e11b815260040160405180910390fd5b6000610bac7f000000000000000000000000fe1411d6864592549ade050215482e4385dfa0fb6001600160a01b031663d5f394886040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b709190611c36565b88888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506110f992505050565b905060018989604051610bc09291906118ea565b908152604051602091819003820181206003018054600180820183556000928352939091200180546001600160a01b0319166001600160a01b038516179055879190610c0f908c908c906118ea565b90815260200160405180910390206001016000828254610c2f9190611c53565b9091555050604051610c44908a908a906118ea565b604051908190038120878252907f4c4439fb488c666dfac05b75b1eaa33ddec20e80ade108bbfbf9a346101a17fa9060200160405180910390a2505050505050505050565b610c91611211565b610c9b600061126b565b565b818160018282604051610cb19291906118ea565b9081526040519081900360200190205460ff1615610ce657818160405163096ef08360e01b8152600401610a8c929190611c22565b838360018282604051610cfa9291906118ea565b9081526040516020918190039190910190205461010090046001600160a01b03163314610d3a5760405163796d3af960e11b815260040160405180910390fd5b6001808787604051610d4d9291906118ea565b908152604051908190036020018120805492151560ff1990931692909217909155610d7b90879087906118ea565b604051908190038120907f97add12139614f08415043a75d4c656150251bc30d807d1bf5fe2eda77c539f690600090a2505050505050565b80516020818301810180516001808352938301929094019190912092905281549082015460028301805460ff8416946101009094046001600160a01b0316939190610dfd906118fa565b80601f0160208091040260200160405190810160405280929190818152602001828054610e29906118fa565b8015610e765780601f10610e4b57610100808354040283529160200191610e76565b820191906000526020600020905b815481529060010190602001808311610e5957829003601f168201915b5050505050905084565b838360018282604051610e949291906118ea565b9081526040519081900360200190205460ff1615610ec957818160405163096ef08360e01b8152600401610a8c929190611c22565b858560018282604051610edd9291906118ea565b9081526040516020918190039190910190205461010090046001600160a01b03163314610f1d5760405163796d3af960e11b815260040160405180910390fd5b858560018a8a604051610f319291906118ea565b90815260200160405180910390206002019182610f4f929190611c74565b508787604051610f609291906118ea565b60405180910390207f841de8cd90147293506b2d92fd0b437d946450a4a4a4f399dccc9d76473d72a78787604051610f99929190611c22565b60405180910390a25050505050505050565b610fb3611211565b6001600160a01b0381166110185760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a8c565b6110218161126b565b50565b60606001826040516110369190611af5565b908152604080519182900360209081018320600301805480830285018301909352828452919083018282801561109557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611077575b50505050509050919050565b8051604051906020600080805b848110156110dd576020810260200187015191506001823b039250826001858801843c928201926001016110ae565b505050601f198082018452601f90910116820160405250919050565b60008061110684846112bb565b90506001600160a01b0381163b1561111f57905061085e565b600080856001600160a01b031664457468465360d81b61113e876112d0565b60405160200161114f929190611d35565b60408051601f198184030181529082905261116991611af5565b6000604051808303816000865af19150503d80600081146111a6576040519150601f19603f3d011682016040523d82523d6000602084013e6111ab565b606091505b5091509150816111be576111be8161133b565b6111c781611d5b565b60601c93506001600160a01b038316841461120857604051636509115d60e01b81526001600160a01b03808516600483015285166024820152604401610a8c565b50505092915050565b6000546001600160a01b03163314610c9b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a8c565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600061085b8264457468465360d81b85611343565b6060815160016112e09190611c53565b60e81b7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166a61000080600a3d393df30060a81b1782604051602001611325929190611d97565b6040516020818303038152906040529050919050565b805160208201fd5b60008061134f85611379565b905060ff600053806035528260601b60015283601552605560002091506000603552509392505050565b60008151600181018060101c3d3d3e6a61000080600a3d393df300604082901b178452600a01601584012092525090565b8280548282559060005260206000209081019282156113ff579160200282015b828111156113ff57825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906113ca565b5061140b92915061140f565b5090565b5b8082111561140b5760008155600101611410565b60008083601f84011261143657600080fd5b50813567ffffffffffffffff81111561144e57600080fd5b60208301915083602082850101111561146657600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156114a6576114a661146d565b60405290565b6040516060810167ffffffffffffffff811182821017156114a6576114a661146d565b604051601f8201601f1916810167ffffffffffffffff811182821017156114f8576114f861146d565b604052919050565b600082601f83011261151157600080fd5b813567ffffffffffffffff81111561152b5761152b61146d565b61153e601f8201601f19166020016114cf565b81815284602083860101111561155357600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006040848603121561158557600080fd5b833567ffffffffffffffff8082111561159d57600080fd5b6115a987838801611424565b909550935060208601359150808211156115c257600080fd5b506115cf86828701611500565b9150509250925092565b6000806000806000606086880312156115f157600080fd5b853567ffffffffffffffff8082111561160957600080fd5b61161589838a01611424565b9097509550602088013591508082111561162e57600080fd5b61163a89838a01611424565b9095509350604088013591508082111561165357600080fd5b5061166088828901611500565b9150509295509295909350565b6000806040838503121561168057600080fd5b823567ffffffffffffffff8082111561169857600080fd5b6116a486838701611500565b935060208501359150808211156116ba57600080fd5b506116c785828601611500565b9150509250929050565b60005b838110156116ec5781810151838201526020016116d4565b50506000910152565b6000815180845261170d8160208601602086016116d1565b601f01601f19169290920160200192915050565b60208152600061085b60208301846116f5565b6000806000806040858703121561174a57600080fd5b843567ffffffffffffffff8082111561176257600080fd5b61176e88838901611424565b9096509450602087013591508082111561178757600080fd5b5061179487828801611424565b95989497509550505050565b600080602083850312156117b357600080fd5b823567ffffffffffffffff8111156117ca57600080fd5b6117d685828601611424565b90969095509350505050565b6000602082840312156117f457600080fd5b813567ffffffffffffffff81111561180b57600080fd5b61181784828501611500565b949350505050565b84151581526001600160a01b038416602082015282604082015260806060820152600061184f60808301846116f5565b9695505050505050565b6001600160a01b038116811461102157600080fd5b60006020828403121561188057600080fd5b813561188b81611859565b9392505050565b60008151808452602080850194506020840160005b838110156118cc5781516001600160a01b0316875295820195908201906001016118a7565b509495945050505050565b60208152600061085b6020830184611892565b8183823760009101908152919050565b600181811c9082168061190e57607f821691505b60208210810361192e57634e487b7160e01b600052602260045260246000fd5b50919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b606081526000611971606083018688611934565b82810360208401526119838186611892565b9050828103604084015261199781856116f5565b979650505050505050565b805163ffffffff811681146119b657600080fd5b919050565b60008060408084860312156119cf57600080fd5b83516119da81611859565b8093505060208085015167ffffffffffffffff808211156119fa57600080fd5b9086019060408289031215611a0e57600080fd5b611a16611483565b825181528383015182811115611a2b57600080fd5b80840193505088601f840112611a4057600080fd5b825182811115611a5257611a5261146d565b611a60858260051b016114cf565b8181528581019350606091820285018601918b831115611a7f57600080fd5b948601945b82861015611ade5780868d031215611a9c5760008081fd5b611aa46114ac565b8651611aaf81611859565b8152611abc8789016119a2565b88820152611acb8988016119a2565b818a015285529485019493860193611a84565b508086840152505080955050505050509250929050565b60008251611b078184602087016116d1565b9190910192915050565b601f821115611b5d576000816000526020600020601f850160051c81016020861015611b3a5750805b601f850160051c820191505b81811015611b5957828155600101611b46565b5050505b505050565b815167ffffffffffffffff811115611b7c57611b7c61146d565b611b9081611b8a84546118fa565b84611b11565b602080601f831160018114611bc55760008415611bad5750858301515b600019600386901b1c1916600185901b178555611b59565b600085815260208120601f198616915b82811015611bf457888601518255948401946001909101908401611bd5565b5085821015611c125787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602081526000611817602083018486611934565b600060208284031215611c4857600080fd5b815161188b81611859565b8082018082111561085e57634e487b7160e01b600052601160045260246000fd5b67ffffffffffffffff831115611c8c57611c8c61146d565b611ca083611c9a83546118fa565b83611b11565b6000601f841160018114611cd45760008515611cbc5750838201355b600019600387901b1c1916600186901b178355611d2e565b600083815260209020601f19861690835b82811015611d055786850135825560209485019460019092019101611ce5565b5086821015611d225760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b82815260008251611d4d8160208501602087016116d1565b919091016020019392505050565b805160208201516bffffffffffffffffffffffff198082169291906014831015611d8f5780818460140360031b1b83161693505b505050919050565b74ffffffffffffffffffffffffffffffffffffffffff19831681528151600090611dc881600b8501602087016116d1565b91909101600b01939250505056fea264697066735822122000d7937b0bcb0d4efc37cda494e12a71f317e959f93bb3c6a2c6309ae38509a564736f6c63430008160033

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

000000000000000000000000fe1411d6864592549ade050215482e4385dfa0fb

-----Decoded View---------------
Arg [0] : ethfsFileStore_ (address): 0xFe1411d6864592549AdE050215482e4385dFa0FB

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000fe1411d6864592549ade050215482e4385dfa0fb


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.