Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 181 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Add Chunk To Con... | 21096625 | 47 days ago | IN | 0 ETH | 0.0058957 | ||||
Create Content | 21096624 | 47 days ago | IN | 0 ETH | 0.00033204 | ||||
Add Chunk To Con... | 21095116 | 48 days ago | IN | 0 ETH | 0.00773555 | ||||
Create Content | 21095115 | 48 days ago | IN | 0 ETH | 0.00046741 | ||||
Add Chunk To Con... | 20859519 | 80 days ago | IN | 0 ETH | 0.00864675 | ||||
Add Chunk To Con... | 20859518 | 80 days ago | IN | 0 ETH | 0.03826692 | ||||
Create Content | 20859517 | 80 days ago | IN | 0 ETH | 0.00045836 | ||||
Add Chunk To Con... | 20716218 | 100 days ago | IN | 0 ETH | 0.00502612 | ||||
Create Content | 20716217 | 100 days ago | IN | 0 ETH | 0.00026744 | ||||
Add Chunk To Con... | 20716206 | 100 days ago | IN | 0 ETH | 0.01130963 | ||||
Add Chunk To Con... | 20716205 | 100 days ago | IN | 0 ETH | 0.01387891 | ||||
Add Chunk To Con... | 20716204 | 100 days ago | IN | 0 ETH | 0.01325366 | ||||
Add Chunk To Con... | 20716203 | 100 days ago | IN | 0 ETH | 0.01369232 | ||||
Create Content | 20716202 | 100 days ago | IN | 0 ETH | 0.00018361 | ||||
Add Chunk To Con... | 20053490 | 193 days ago | IN | 0 ETH | 0.00573512 | ||||
Add Chunk To Con... | 20053489 | 193 days ago | IN | 0 ETH | 0.02453039 | ||||
Create Content | 20053488 | 193 days ago | IN | 0 ETH | 0.00038009 | ||||
Add Chunk To Con... | 19957379 | 206 days ago | IN | 0 ETH | 0.00405419 | ||||
Create Content | 19957378 | 206 days ago | IN | 0 ETH | 0.00027209 | ||||
Add Chunk To Con... | 19856504 | 221 days ago | IN | 0 ETH | 0.01333636 | ||||
Add Chunk To Con... | 19856503 | 221 days ago | IN | 0 ETH | 0.01977357 | ||||
Add Chunk To Con... | 19856502 | 221 days ago | IN | 0 ETH | 0.01944067 | ||||
Add Chunk To Con... | 19856501 | 221 days ago | IN | 0 ETH | 0.01930083 | ||||
Create Content | 19856500 | 221 days ago | IN | 0 ETH | 0.00026607 | ||||
Add Chunk To Con... | 19856498 | 221 days ago | IN | 0 ETH | 0.00560225 |
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
19123055 | 323 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Name:
ScriptyStorageV2
Compiler Version
v0.8.22+commit.4fc1097e
Optimization Enabled:
Yes with 500 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// 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; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // 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; } }
// 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) } }
// 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)))) } }
// 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); }
// 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); }
// 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; }
// 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)))) } } } }
// 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) } } }
{ "optimizer": { "enabled": true, "runs": 500 }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"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"}]
Contract Creation Code
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
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.