ERC-721
Overview
Max Total Supply
321 EP
Holders
98
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
1 EPLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
Planets
Compiler Version
v0.8.18+commit.87f61d96
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: MIT // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ pragma solidity ^0.8.18; import "./PlanetsThumbnail.sol"; import "./Utilities.sol"; import "./interfaces/IPlanets.sol"; import "./interfaces/IPlanetsRenderer.sol"; import "scripty.sol/contracts/scripty/IScriptyBuilder.sol"; import {ERC721A} from "erc721a/contracts/ERC721A.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; contract Planets is ERC721A, Ownable { uint256 public immutable deployBlock; uint256 public immutable supply; address public thumbnailAddress; address public rendererAddress; uint256 public price; bool public isOpen; bool public finalized; error MintClosed(); error SoldOut(); error InsufficientFunds(); error TokenDoesntExist(); error RefundFailed(); error Finalized(); constructor( string memory name, string memory symbol, uint256 _supply, uint256 _price, address _thumbnailAddress, address _rendererAddress ) ERC721A(name, symbol) { thumbnailAddress = _thumbnailAddress; rendererAddress = _rendererAddress; supply = _supply; price = _price; deployBlock = block.number; } /** * @notice Airdrops tokens to a list of recipients. Only callable by the contract owner. * @param _recipients List of recipients to receive the airdrop. * @param _quantity Quantity of tokens to airdrop to each recipient. */ function airdrop(address[] calldata _recipients, uint256 _quantity) external payable onlyOwner { if (totalMinted() + _recipients.length * _quantity > supply) revert SoldOut(); for (uint256 i = 0; i < _recipients.length; i++) { _mint(_recipients[i], _quantity); } } /** * @notice Mints new tokens for the caller. * @param _quantity Quantity of tokens to mint. */ function mint(uint256 _quantity) public payable { if (!isOpen) revert MintClosed(); if (totalMinted() + _quantity > supply) revert SoldOut(); if (msg.value < price * _quantity) revert InsufficientFunds(); _mint(msg.sender, _quantity); // Refund any extra ETH sent if (msg.value > price * _quantity) { (bool status, ) = payable(msg.sender).call{value: msg.value - price * _quantity}(""); if (!status) revert RefundFailed(); } } /** * @notice Withdraws the contract's balance. Only callable by the contract owner. */ function withdraw() external onlyOwner { require(payable(msg.sender).send(address(this).balance)); } /** * @notice Update the mint price. * @dev Very doubtful this gets used, but good to have * @param _price - The new price. */ function setPrice(uint256 _price) external onlyOwner { price = _price; } /** * @notice Update thumbnail contract address * @param _thumbnailAddress - Address of the thumbnail contract. */ function setThumbnailAddress(address _thumbnailAddress) external onlyOwner { if (finalized) revert Finalized(); thumbnailAddress = _thumbnailAddress; } /** * @notice Update renderer contract address * @param _rendererAddress - Address of the renderer contract. */ function setRendererAddress(address _rendererAddress) external onlyOwner { if (finalized) revert Finalized(); rendererAddress = _rendererAddress; } /** * @notice Open or close minting * @param _state - Boolean state for being open or closed. */ function setMintStatus(bool _state) external onlyOwner { isOpen = _state; } function finalize() external onlyOwner { finalized = true; } /** * @notice Minting starts at token id #1 * @return Token id to start minting at */ function _startTokenId() internal pure override returns (uint256) { return 1; } /** * @notice Retrieve how many tokens have been minted * @return Total number of minted tokens */ function totalMinted() public view returns (uint256) { return _totalMinted(); } function formatVar(bytes memory _name, uint256 _value) internal pure returns (bytes memory) { return abi.encodePacked("var ", _name, "=", utils.uint2str(_value), ";"); } /** * @notice Build all the settings into a struct * @param _tokenId - Token ID for seed value * @return settings - All settings as a struct */ function buildSettings(uint256 _tokenId) public view returns (Settings memory settings) { uint256 randomSeed = _tokenId + deployBlock; settings.seed = utils.randomRange(randomSeed, "seed", 1, 1000000); settings.vars[0] = formatVar("seed", settings.seed); settings.planetSize = utils.randomRange(randomSeed, "planetSize", 30, 100); settings.vars[1] = formatVar("planetSize", settings.planetSize); // 40% gas, 60% rock settings.planetType = utils.randomRange(randomSeed, "planetType", 0, 10) < 4 ? PlanetType.GAS : PlanetType.SOLID; settings.vars[4] = formatVar("planetType", uint256(settings.planetType)); // 30% of gaseous planets; settings.hasRings = settings.planetType == PlanetType.GAS && utils.randomRange(randomSeed, "hasRings", 0, 10) < 3; settings.vars[2] = formatVar("hasRings", settings.hasRings ? 1 : 0); { // 25% 1 moon, 12% 2 moons, 3% 3 moons uint256 observation = utils.randomRange(randomSeed, "numMoons", 0, 100); if (observation < 25) settings.numMoons = 1; else if (observation < 37) settings.numMoons = 2; else if (observation < 40) settings.numMoons = 3; else settings.numMoons = 0; settings.vars[3] = formatVar("numMoons", settings.numMoons); } settings.hue = utils.randomRange(randomSeed, "baseHue", 0, 360); settings.vars[5] = formatVar("baseHue", settings.hue); // If rocky, 30% water settings.hasWater = settings.planetType == PlanetType.SOLID && utils.randomRange(randomSeed, "hasWater", 0, 10) < 3; settings.vars[6] = formatVar("hasWater", settings.hasWater ? 1 : 0); return settings; } /** * @notice Util function to help build traits * @param _key - Trait key as string * @param _value - Trait value as string * @return trait - object as string */ function buildTraitString(string memory _key, string memory _value) internal pure returns (string memory trait) { return string.concat('{"trait_type":"', _key, '","value":"', _value, '"}'); } /** * @notice Util function to help build traits where value is continuous * @param _key - Trait key as string * @param _value - Trait value as string * @return trait - object as string */ function buildTraitNumber(string memory _key, string memory _value) internal pure returns (string memory trait) { return string.concat('{"trait_type":"', _key, '","value":', _value, "}"); } /** * @notice Build attributes for metadata * @param settings - Track settings struct * @return attr - array as a string */ function buildAttributes(Settings memory settings) public pure returns (string memory attr) { return string.concat( '"attributes": [', buildTraitNumber("Planet Size", utils.uint2str(settings.planetSize)), ",", buildTraitString("Has Rings", settings.hasRings ? "Yes" : "No"), ",", buildTraitString("Has Water", settings.hasWater ? "Yes" : "No"), ",", buildTraitString("Number of Moons", utils.uint2str(settings.numMoons)), ",", buildTraitString("Planet Type", settings.planetType == PlanetType.SOLID ? "Rock" : "Gas"), ",", buildTraitString("Planet Color", utils.getColorName(settings.hue)), "]" ); } /** * @notice Pack and base64 encode JS compatible vars * @param settings - Track settings struct * @return vars - base64 encoded JS compatible setting variables */ function buildVars(Settings memory settings) public pure returns (bytes memory vars) { return bytes( utils.encode( abi.encodePacked( settings.vars[0], settings.vars[1], settings.vars[2], settings.vars[3], settings.vars[4], settings.vars[5], settings.vars[6] ) ) ); } /** * @notice Build the metadata including the full render html for the planet * @dev This depends on * - https://ethfs.xyz/ [stores code libraries] * - https://github.com/intartnft/scripty.sol [builds rendering html and stores code libraries] * @param _tokenId - TokenId to build planet for * @return metadata - as string */ function tokenURI(uint256 _tokenId) public view virtual override(ERC721A) returns (string memory metadata) { // show nothing if token doesnt exist if (!_exists(_tokenId)) revert TokenDoesntExist(); // Generate all the settings and various objects for the metadata Settings memory settings = buildSettings(_tokenId); string memory attr = buildAttributes(settings); bytes memory vars = buildVars(settings); string memory thumbnail = utils.encode(PlanetsThumbnail(thumbnailAddress).buildThumbnail(settings)); bytes memory animationUri = IPlanetsRenderer(rendererAddress).buildAnimationURI(vars); bytes memory json = abi.encodePacked( '{"name":"', "EtherPlanet #", utils.uint2str(_tokenId), '", "description":"', "Fully on-chain, procedurally generated, 3D planets.", '","image":"data:image/svg+xml;base64,', thumbnail, '","animation_url":"', animationUri, '",', attr, "}" ); return string(abi.encodePacked("data:application/json,", json)); } }
// 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.17; enum PlanetType { GAS, SOLID } struct Settings { uint256 seed; uint256 planetSize; bool hasRings; uint256 numMoons; PlanetType planetType; uint256 hue; bool hasWater; bytes[7] vars; }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.17; import "scripty.sol/contracts/scripty/IScriptyBuilder.sol"; import "./IPlanets.sol"; interface IPlanetsRenderer { function buildAnimationURI(bytes calldata vars) external view returns (bytes memory html); }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.18; import "./interfaces/IPlanets.sol"; import "./Utilities.sol"; contract PlanetsThumbnail { uint256 private constant CANVAS_SIZE = 500; bytes private constant BACKGROUND = '<g fill="#fff"><circle cx="50" cy="100" r="2" fill="#fff"/><circle cx="200" cy="150" r="2" fill="#fff"/><circle cx="300" cy="250" r="2" fill="#fff"/><circle cx="400" cy="75" r="2" fill="#fff"/><circle cx="175" cy="200" r="2" fill="#fff"/><circle cx="450" cy="350" r="2" fill="#fff"/><circle cx="125" cy="400" r="2" fill="#fff"/><circle cx="375" cy="300" r="2" fill="#fff"/><circle cx="225" cy="375" r="2" fill="#fff"/><circle cx="75" cy="250" r="2" fill="#fff"/><circle cx="25" cy="25" r="2" fill="#fff"/></g>'; bytes private constant PLANET = '<path class="rings" stroke-width="8.686" d="M149.379 79.264c0-5.756-32.406-10.423-72.38-10.423-39.976 0-72.382 4.667-72.382 10.423"/><ellipse cx="76.713" cy="69.999" class="body" rx="50.088" ry="49.798"/><mask id="a" width="101" height="102" x="26" y="19" maskUnits="userSpaceOnUse" style="mask-type:alpha"><circle cx="76.515" cy="70" r="50" fill="#AC0000" transform="rotate(-33.909 76.515 70)"/></mask><g mask="url(#a)"><path class="water" d="M84.845 48.333c.476-2.063 2.428-8.047 6.428-15.476 3.049-1.905 10.795-3.016 14.287-3.333h14.048l15 25-8.81 24.285h-.714c-.571.572-2.143.556-2.857.477l-9.762-5.477a20.235 20.235 0 0 0-21.192-12.857c-12.952 1.143-9.682-7.936-6.428-12.619ZM34.137 66.904c-3.239-1.333-6.27 2.46-7.381 4.524l-2.858 1.429 2.143 23.095 25.477 20.953c1.587-1.826 5-6.381 5.952-10 1.19-4.524-3.333-7.858-6.905-9.286-3.571-1.429-1.905-8.572-.714-11.429 1.19-2.857-3.334-8.571-8.334-11.428-5-2.858-3.333-6.19-7.38-7.858Z"/><path class="body-sec" d="M72.5 100.5C67 93.5 80 89.5 78 84c1.334-1.167 5.2-4.4 10-8 6-4.5 19.5 0 23 4.5s-.5 11-3.5 20c-2.4 7.2-10 8-13.5 7.5-5.333-.167-17.1-1.9-21.5-7.5ZM44 70.5c0-2-2.6-8.2-13-17l-4.5-2 20-25.5c2.167 1.833 7.3 4.4 10.5 0 4-5.5 10.5.5 13 5.5S61.5 41 70 42s8 1 8 11.5S72.5 57 72.5 65s-9 11-17 11c-6.4 0-10.333-3.667-11.5-5.5Z"/></g><path class="rings" stroke-width="8.686" d="M149.379 78.106c0 5.757-32.406 10.423-72.38 10.423-39.976 0-72.382-4.666-72.382-10.423"/>'; string[3] private MOONS = [ '<circle cx="22" cy="171" r="22" fill="#BBBBBB"/>', '<circle cx="370" cy="106" r="16" fill="#BBBBBB"/>', '<circle cx="30" cy="11" r="11" fill="#BBBBBB"/>' ]; function getPlanet(uint256 planetSize) internal pure returns (string memory) { return string( abi.encodePacked( '<g transform-origin="72 60" transform="translate(-26,-20),translate(200,200),scale(', utils.uint2floatstr((planetSize * 1e3) / 40, 3), ')">', PLANET, "</g>" ) ); } function getMoons(uint256 numMoons) internal view returns (bytes memory) { bytes memory moons = '<g transform="translate(50,170)">'; for (uint256 i = 0; i < numMoons; i++) { moons = abi.encodePacked(moons, MOONS[i]); } moons = abi.encodePacked(moons, "</g>"); return moons; } /** * @notice Build the SVG thumbnail * @param _settings - Track settings struct * @return final svg as bytes */ function buildThumbnail(Settings calldata _settings) external view returns (bytes memory) { bytes memory svg = abi.encodePacked( '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ', utils.uint2str(CANVAS_SIZE), " ", utils.uint2str(CANVAS_SIZE), '" width="500" height="500" fill="none">', // "<defs><style>.rings{stroke:", // _settings.hasRings ? getHSL(_settings.hue, 100, 15) : "none", // ";}.body{fill:", // getHSL(_settings.hue, 70, 34), // ";}.water{fill:", // _settings.planetType == PlanetType.SOLID ? "#2680D9" : "none", // ";}</style></defs>", "<defs><style>", ".rings { stroke: ", _settings.hasRings ? utils.getHSL(_settings.hue, 100, 15) : "none", "; }", ".body { fill: ", utils.getHSL(_settings.hue, 60, 40), "; }", ".body-sec { fill: ", _settings.planetType == PlanetType.SOLID ? utils.getHSL((_settings.hue + 5) % 360, 45, 50) : "none", "; }", ".water { fill: ", _settings.hasWater ? "#2680D9" : "none", "; }", "</style></defs>", '<rect x="0" y="0" width="', utils.uint2str(CANVAS_SIZE), '" height="', utils.uint2str(CANVAS_SIZE), '" fill="#000000"/>', BACKGROUND, getPlanet(_settings.planetSize), getMoons(_settings.numMoons), '<g transform="translate(440,470)"><text x="13" y="0" fill="#fff" font-size="24" font-family="Helvetica">2D</text><text x="13" y="15" fill="#fff" font-size="12" font-family="Helvetica">VIEW</text></g></svg>' ); return svg; } }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.12; library utils { function getColorName(uint256 _hue) public pure returns (string memory) { string[12] memory colorNames = [ "Red", "Orange", "Yellow", "Chartreuse", "Green", "Spring", "Cyan", "Azure", "Blue", "Violet", "Magenta", "Rose" ]; require(_hue <= 360, "Hue must be between 0 and 360"); uint256 colorIndex = (_hue * 12) / 360; return colorNames[colorIndex]; } function getHSL(uint256 hue, uint256 saturation, uint256 lightness) internal pure returns (string memory) { return string.concat( "hsl(", utils.uint2str(hue), ", ", utils.uint2str(saturation), "%, ", utils.uint2str(lightness), "%)" ); } function assemblyKeccak(bytes memory _input) public pure returns (bytes32 x) { assembly { x := keccak256(add(_input, 0x20), mload(_input)) } } function random(string memory input) internal pure returns (uint256) { return uint256(assemblyKeccak(abi.encodePacked(input))); } function randomRange( uint256 tokenId, string memory keyPrefix, uint256 lower, uint256 upper ) internal pure returns (uint256) { uint256 rand = random(string(abi.encodePacked(keyPrefix, uint2str(tokenId)))); return (rand % (upper - lower + 1)) + lower; } function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } function sliceUint(bytes memory bs, uint256 start) internal pure returns (uint256) { require(bs.length >= start + 32, "slicing out of range"); uint256 x; assembly { x := mload(add(bs, add(0x20, start))) } return x; } function int2str(int256 _i) internal pure returns (string memory _uintAsString) { if (_i < 0) { return string.concat("-", uint2str(uint256(-_i))); } else { return uint2str(uint256(_i)); } } function uint2floatstr(uint256 _i_scaled, uint256 _decimals) internal pure returns (string memory) { return string.concat(uint2str(_i_scaled / (10 ** _decimals)), ".", uint2str(_i_scaled % (10 ** _decimals))); } // converts an unsigned integer to a string from Solady (https://github.com/vectorized/solady/blob/main/src) /// @dev Returns the base 10 decimal representation of `value`. function uint2str(uint256 value) internal pure returns (string memory str) { /// @solidity memory-safe-assembly assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. // We will need 1 word for the trailing zeros padding, 1 word for the length, // and 3 words for a maximum of 78 digits. str := add(mload(0x40), 0x80) // Update the free memory pointer to allocate. mstore(0x40, add(str, 0x20)) // Zeroize the slot after the string. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str let w := not(0) // Tsk. // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. for { let temp := value } 1 { } { str := add(str, w) // `sub(str, 1)`. // Write the character to the pointer. // The ASCII index of the '0' character is 48. mstore8(str, add(48, mod(temp, 10))) // Keep dividing `temp` until zero. temp := div(temp, 10) if iszero(temp) { break } } let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 0x20) // Store the length. mstore(str, length) } } /// @dev Encodes `data` using the base64 encoding described in RFC 4648. /// See: https://datatracker.ietf.org/doc/html/rfc4648 /// @param fileSafe Whether to replace '+' with '-' and '/' with '_'. /// @param noPadding Whether to strip away the padding. function encode(bytes memory data, bool fileSafe, bool noPadding) internal pure returns (string memory result) { /// @solidity memory-safe-assembly assembly { let dataLength := mload(data) if dataLength { // Multiply by 4/3 rounded up. // The `shl(2, ...)` is equivalent to multiplying by 4. let encodedLength := shl(2, div(add(dataLength, 2), 3)) // Set `result` to point to the start of the free memory. result := mload(0x40) // Store the table into the scratch space. // Offsetted by -1 byte so that the `mload` will load the character. // We will rewrite the free memory pointer at `0x40` later with // the allocated size. // The magic constant 0x0230 will translate "-_" + "+/". mstore(0x1f, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef") mstore(0x3f, sub("ghijklmnopqrstuvwxyz0123456789-_", mul(iszero(fileSafe), 0x0230))) // Skip the first slot, which stores the length. let ptr := add(result, 0x20) let end := add(ptr, encodedLength) // Run over the input, 3 bytes at a time. for { } 1 { } { data := add(data, 3) // Advance 3 bytes. let input := mload(data) // Write 4 bytes. Optimized for fewer stack operations. mstore8(0, mload(and(shr(18, input), 0x3F))) mstore8(1, mload(and(shr(12, input), 0x3F))) mstore8(2, mload(and(shr(6, input), 0x3F))) mstore8(3, mload(and(input, 0x3F))) mstore(ptr, mload(0x00)) ptr := add(ptr, 4) // Advance 4 bytes. if iszero(lt(ptr, end)) { break } } // Allocate the memory for the string. // Add 31 and mask with `not(31)` to round the // free memory pointer up the next multiple of 32. mstore(0x40, and(add(end, 31), not(31))) // Equivalent to `o = [0, 2, 1][dataLength % 3]`. let o := div(2, mod(dataLength, 3)) // Offset `ptr` and pad with '='. We can simply write over the end. mstore(sub(ptr, o), shl(240, 0x3d3d)) // Set `o` to zero if there is padding. o := mul(iszero(iszero(noPadding)), o) // Zeroize the slot after the string. mstore(sub(ptr, o), 0) // Write the length of the string. mstore(result, sub(encodedLength, o)) } } } /// @dev Encodes `data` using the base64 encoding described in RFC 4648. /// Equivalent to `encode(data, false, false)`. function encode(bytes memory data) internal pure returns (string memory result) { result = encode(data, false, false); } }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; import './IERC721A.sol'; /** * @dev Interface of ERC721 token receiver. */ interface ERC721A__IERC721Receiver { function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } /** * @title ERC721A * * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721) * Non-Fungible Token Standard, including the Metadata extension. * Optimized for lower gas during batch mints. * * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...) * starting from `_startTokenId()`. * * Assumptions: * * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256). */ contract ERC721A is IERC721A { // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364). struct TokenApprovalRef { address value; } // ============================================================= // CONSTANTS // ============================================================= // Mask of an entry in packed address data. uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1; // The bit position of `numberMinted` in packed address data. uint256 private constant _BITPOS_NUMBER_MINTED = 64; // The bit position of `numberBurned` in packed address data. uint256 private constant _BITPOS_NUMBER_BURNED = 128; // The bit position of `aux` in packed address data. uint256 private constant _BITPOS_AUX = 192; // Mask of all 256 bits in packed address data except the 64 bits for `aux`. uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1; // The bit position of `startTimestamp` in packed ownership. uint256 private constant _BITPOS_START_TIMESTAMP = 160; // The bit mask of the `burned` bit in packed ownership. uint256 private constant _BITMASK_BURNED = 1 << 224; // The bit position of the `nextInitialized` bit in packed ownership. uint256 private constant _BITPOS_NEXT_INITIALIZED = 225; // The bit mask of the `nextInitialized` bit in packed ownership. uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225; // The bit position of `extraData` in packed ownership. uint256 private constant _BITPOS_EXTRA_DATA = 232; // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`. uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1; // The mask of the lower 160 bits for addresses. uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1; // The maximum `quantity` that can be minted with {_mintERC2309}. // This limit is to prevent overflows on the address data entries. // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309} // is required to cause an overflow, which is unrealistic. uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000; // The `Transfer` event signature is given by: // `keccak256(bytes("Transfer(address,address,uint256)"))`. bytes32 private constant _TRANSFER_EVENT_SIGNATURE = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; // ============================================================= // STORAGE // ============================================================= // The next token ID to be minted. uint256 private _currentIndex; // The number of tokens burned. uint256 private _burnCounter; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to ownership details // An empty struct value does not necessarily mean the token is unowned. // See {_packedOwnershipOf} implementation for details. // // Bits Layout: // - [0..159] `addr` // - [160..223] `startTimestamp` // - [224] `burned` // - [225] `nextInitialized` // - [232..255] `extraData` mapping(uint256 => uint256) private _packedOwnerships; // Mapping owner address to address data. // // Bits Layout: // - [0..63] `balance` // - [64..127] `numberMinted` // - [128..191] `numberBurned` // - [192..255] `aux` mapping(address => uint256) private _packedAddressData; // Mapping from token ID to approved address. mapping(uint256 => TokenApprovalRef) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // ============================================================= // CONSTRUCTOR // ============================================================= constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; _currentIndex = _startTokenId(); } // ============================================================= // TOKEN COUNTING OPERATIONS // ============================================================= /** * @dev Returns the starting token ID. * To change the starting token ID, please override this function. */ function _startTokenId() internal view virtual returns (uint256) { return 0; } /** * @dev Returns the next token ID to be minted. */ function _nextTokenId() internal view virtual returns (uint256) { return _currentIndex; } /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() public view virtual override returns (uint256) { // Counter underflow is impossible as _burnCounter cannot be incremented // more than `_currentIndex - _startTokenId()` times. unchecked { return _currentIndex - _burnCounter - _startTokenId(); } } /** * @dev Returns the total amount of tokens minted in the contract. */ function _totalMinted() internal view virtual returns (uint256) { // Counter underflow is impossible as `_currentIndex` does not decrement, // and it is initialized to `_startTokenId()`. unchecked { return _currentIndex - _startTokenId(); } } /** * @dev Returns the total number of tokens burned. */ function _totalBurned() internal view virtual returns (uint256) { return _burnCounter; } // ============================================================= // ADDRESS DATA OPERATIONS // ============================================================= /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) public view virtual override returns (uint256) { if (owner == address(0)) revert BalanceQueryForZeroAddress(); return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens minted by `owner`. */ function _numberMinted(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens burned by or on behalf of `owner`. */ function _numberBurned(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). */ function _getAux(address owner) internal view returns (uint64) { return uint64(_packedAddressData[owner] >> _BITPOS_AUX); } /** * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). * If there are multiple variables, please pack them into a uint64. */ function _setAux(address owner, uint64 aux) internal virtual { uint256 packed = _packedAddressData[owner]; uint256 auxCasted; // Cast `aux` with assembly to avoid redundant masking. assembly { auxCasted := aux } packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX); _packedAddressData[owner] = packed; } // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { // The interface IDs are constants representing the first 4 bytes // of the XOR of all function selectors in the interface. // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165) // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`) return interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165. interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721. interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata. } // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the token collection symbol. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { if (!_exists(tokenId)) revert URIQueryForNonexistentToken(); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : ''; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, it can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ''; } // ============================================================= // OWNERSHIPS OPERATIONS // ============================================================= /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return address(uint160(_packedOwnershipOf(tokenId))); } /** * @dev Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around over time. */ function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnershipOf(tokenId)); } /** * @dev Returns the unpacked `TokenOwnership` struct at `index`. */ function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnerships[index]); } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal virtual { if (_packedOwnerships[index] == 0) { _packedOwnerships[index] = _packedOwnershipOf(index); } } /** * Returns the packed ownership data of `tokenId`. */ function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) { uint256 curr = tokenId; unchecked { if (_startTokenId() <= curr) if (curr < _currentIndex) { uint256 packed = _packedOwnerships[curr]; // If not burned. if (packed & _BITMASK_BURNED == 0) { // Invariant: // There will always be an initialized ownership slot // (i.e. `ownership.addr != address(0) && ownership.burned == false`) // before an unintialized ownership slot // (i.e. `ownership.addr == address(0) && ownership.burned == false`) // Hence, `curr` will not underflow. // // We can directly compare the packed value. // If the address is zero, packed will be zero. while (packed == 0) { packed = _packedOwnerships[--curr]; } return packed; } } } revert OwnerQueryForNonexistentToken(); } /** * @dev Returns the unpacked `TokenOwnership` struct from `packed`. */ function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) { ownership.addr = address(uint160(packed)); ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP); ownership.burned = packed & _BITMASK_BURNED != 0; ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA); } /** * @dev Packs ownership data into a single uint256. */ function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`. result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags)) } } /** * @dev Returns the `nextInitialized` flag set if `quantity` equals 1. */ function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) { // For branchless setting of the `nextInitialized` flag. assembly { // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`. result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1)) } } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) public payable virtual override { address owner = ownerOf(tokenId); if (_msgSenderERC721A() != owner) if (!isApprovedForAll(owner, _msgSenderERC721A())) { revert ApprovalCallerNotOwnerNorApproved(); } _tokenApprovals[tokenId].value = to; emit Approval(owner, to, tokenId); } /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken(); return _tokenApprovals[tokenId].value; } /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) public virtual override { _operatorApprovals[_msgSenderERC721A()][operator] = approved; emit ApprovalForAll(_msgSenderERC721A(), operator, approved); } /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted. See {_mint}. */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _startTokenId() <= tokenId && tokenId < _currentIndex && // If within bounds, _packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned. } /** * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`. */ function _isSenderApprovedOrOwner( address approvedAddress, address owner, address msgSender ) private pure returns (bool result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean. msgSender := and(msgSender, _BITMASK_ADDRESS) // `msgSender == owner || msgSender == approvedAddress`. result := or(eq(msgSender, owner), eq(msgSender, approvedAddress)) } } /** * @dev Returns the storage slot and value for the approved address of `tokenId`. */ function _getApprovedSlotAndAddress(uint256 tokenId) private view returns (uint256 approvedAddressSlot, address approvedAddress) { TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId]; // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`. assembly { approvedAddressSlot := tokenApproval.slot approvedAddress := sload(approvedAddressSlot) } } // ============================================================= // TRANSFER OPERATIONS // ============================================================= /** * @dev Transfers `tokenId` from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) public payable virtual override { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner(); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); if (to == address(0)) revert TransferToZeroAddress(); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // We can directly increment and decrement the balances. --_packedAddressData[from]; // Updates: `balance -= 1`. ++_packedAddressData[to]; // Updates: `balance += 1`. // Updates: // - `address` to the next owner. // - `startTimestamp` to the timestamp of transfering. // - `burned` to `false`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( to, _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, to, tokenId); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public payable virtual override { safeTransferFrom(from, to, tokenId, ''); } /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public payable virtual override { transferFrom(from, to, tokenId); if (to.code.length != 0) if (!_checkContractOnERC721Received(from, to, tokenId, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } /** * @dev Hook that is called before a set of serially-ordered token IDs * are about to be transferred. This includes minting. * And also called before burning one token. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Hook that is called after a set of serially-ordered token IDs * have been transferred. This includes minting. * And also called after one token has been burned. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been * transferred to `to`. * - When `from` is zero, `tokenId` has been minted for `to`. * - When `to` is zero, `tokenId` has been burned by `from`. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract. * * `from` - Previous owner of the given token ID. * `to` - Target address that will receive the token. * `tokenId` - Token ID to be transferred. * `_data` - Optional data to send along with the call. * * Returns whether the call correctly returned the expected magic value. */ function _checkContractOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns ( bytes4 retval ) { return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert TransferToNonERC721ReceiverImplementer(); } else { assembly { revert(add(32, reason), mload(reason)) } } } } // ============================================================= // MINT OPERATIONS // ============================================================= /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {Transfer} event for each mint. */ function _mint(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (quantity == 0) revert MintZeroQuantity(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // `balance` and `numberMinted` have a maximum limit of 2**64. // `tokenId` has a maximum limit of 2**256. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); uint256 toMasked; uint256 end = startTokenId + quantity; // Use assembly to loop and emit the `Transfer` event for gas savings. // The duplicated `log4` removes an extra check and reduces stack juggling. // The assembly, together with the surrounding Solidity code, have been // delicately arranged to nudge the compiler into producing optimized opcodes. assembly { // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. toMasked := and(to, _BITMASK_ADDRESS) // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. 0, // `address(0)`. toMasked, // `to`. startTokenId // `tokenId`. ) // The `iszero(eq(,))` check ensures that large values of `quantity` // that overflows uint256 will make the loop run out of gas. // The compiler will optimize the `iszero` away for performance. for { let tokenId := add(startTokenId, 1) } iszero(eq(tokenId, end)) { tokenId := add(tokenId, 1) } { // Emit the `Transfer` event. Similar to above. log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId) } } if (toMasked == 0) revert MintToZeroAddress(); _currentIndex = end; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * This function is intended for efficient minting only during contract creation. * * It emits only one {ConsecutiveTransfer} as defined in * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309), * instead of a sequence of {Transfer} event(s). * * Calling this function outside of contract creation WILL make your contract * non-compliant with the ERC721 standard. * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309 * {ConsecutiveTransfer} event is only permissible during contract creation. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {ConsecutiveTransfer} event. */ function _mintERC2309(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (to == address(0)) revert MintToZeroAddress(); if (quantity == 0) revert MintZeroQuantity(); if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are unrealistic due to the above check for `quantity` to be below the limit. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to); _currentIndex = startTokenId + quantity; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Safely mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called for each safe transfer. * - `quantity` must be greater than 0. * * See {_mint}. * * Emits a {Transfer} event for each mint. */ function _safeMint( address to, uint256 quantity, bytes memory _data ) internal virtual { _mint(to, quantity); unchecked { if (to.code.length != 0) { uint256 end = _currentIndex; uint256 index = end - quantity; do { if (!_checkContractOnERC721Received(address(0), to, index++, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } while (index < end); // Reentrancy protection. if (_currentIndex != end) revert(); } } } /** * @dev Equivalent to `_safeMint(to, quantity, '')`. */ function _safeMint(address to, uint256 quantity) internal virtual { _safeMint(to, quantity, ''); } // ============================================================= // BURN OPERATIONS // ============================================================= /** * @dev Equivalent to `_burn(tokenId, false)`. */ function _burn(uint256 tokenId) internal virtual { _burn(tokenId, false); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId, bool approvalCheck) internal virtual { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); address from = address(uint160(prevOwnershipPacked)); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); if (approvalCheck) { // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); } _beforeTokenTransfers(from, address(0), tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // Updates: // - `balance -= 1`. // - `numberBurned += 1`. // // We can directly decrement the balance, and increment the number burned. // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`. _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1; // Updates: // - `address` to the last owner. // - `startTimestamp` to the timestamp of burning. // - `burned` to `true`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( from, (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, address(0), tokenId); _afterTokenTransfers(from, address(0), tokenId, 1); // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times. unchecked { _burnCounter++; } } // ============================================================= // EXTRA DATA OPERATIONS // ============================================================= /** * @dev Directly sets the extra data for the ownership data `index`. */ function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual { uint256 packed = _packedOwnerships[index]; if (packed == 0) revert OwnershipNotInitializedForExtraData(); uint256 extraDataCasted; // Cast `extraData` with assembly to avoid redundant masking. assembly { extraDataCasted := extraData } packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA); _packedOwnerships[index] = packed; } /** * @dev Called during each token transfer to set the 24bit `extraData` field. * Intended to be overridden by the cosumer contract. * * `previousExtraData` - the value of `extraData` before transfer. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _extraData( address from, address to, uint24 previousExtraData ) internal view virtual returns (uint24) {} /** * @dev Returns the next extra data for the packed ownership data. * The returned result is shifted into position. */ function _nextExtraData( address from, address to, uint256 prevOwnershipPacked ) private view returns (uint256) { uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA); return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA; } // ============================================================= // OTHER OPERATIONS // ============================================================= /** * @dev Returns the message sender (defaults to `msg.sender`). * * If you are writing GSN compatible contracts, you need to override this function. */ function _msgSenderERC721A() internal view virtual returns (address) { return msg.sender; } /** * @dev Converts a uint256 to its ASCII string decimal representation. */ function _toString(uint256 value) internal pure virtual returns (string memory str) { assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. // We will need 1 word for the trailing zeros padding, 1 word for the length, // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0. let m := add(mload(0x40), 0xa0) // Update the free memory pointer to allocate. mstore(0x40, m) // Assign the `str` to the end. str := sub(m, 0x20) // Zeroize the slot after the string. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // prettier-ignore for { let temp := value } 1 {} { str := sub(str, 1) // Write the character to the pointer. // The ASCII index of the '0' character is 48. mstore8(str, add(48, mod(temp, 10))) // Keep dividing `temp` until zero. temp := div(temp, 10) // prettier-ignore if iszero(temp) { break } } let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 0x20) // Store the length. mstore(str, length) } } }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721A. */ interface IERC721A { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * The token does not exist. */ error ApprovalQueryForNonexistentToken(); /** * Cannot query the balance for the zero address. */ error BalanceQueryForZeroAddress(); /** * Cannot mint to the zero address. */ error MintToZeroAddress(); /** * The quantity of tokens minted must be more than zero. */ error MintZeroQuantity(); /** * The token does not exist. */ error OwnerQueryForNonexistentToken(); /** * The caller must own the token or be an approved operator. */ error TransferCallerNotOwnerNorApproved(); /** * The token must be owned by `from`. */ error TransferFromIncorrectOwner(); /** * Cannot safely transfer to a contract that does not implement the * ERC721Receiver interface. */ error TransferToNonERC721ReceiverImplementer(); /** * Cannot transfer to the zero address. */ error TransferToZeroAddress(); /** * The token does not exist. */ error URIQueryForNonexistentToken(); /** * The `quantity` minted with ERC2309 exceeds the safety limit. */ error MintERC2309QuantityExceedsLimit(); /** * The `extraData` cannot be set on an unintialized ownership slot. */ error OwnershipNotInitializedForExtraData(); // ============================================================= // STRUCTS // ============================================================= struct TokenOwnership { // The address of the owner. address addr; // Stores the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}. uint24 extraData; } // ============================================================= // TOKEN COUNTERS // ============================================================= /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() external view returns (uint256); // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); // ============================================================= // IERC721 // ============================================================= /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables * (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, * checking first that contract recipients are aware of the ERC721 protocol * to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move * this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external payable; /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Transfers `tokenId` from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} * whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external payable; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) external view returns (bool); // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); // ============================================================= // IERC2309 // ============================================================= /** * @dev Emitted when tokens in `fromTokenId` to `toTokenId` * (inclusive) is transferred from `from` to `to`, as defined in the * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard. * * See {_mintERC2309} for more details. */ event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; /////////////////////////////////////////////////////////// // βββββββββββββββββββββββββββββββββββββββββββββββββββββ // // βββββββββββββββββββββββββββββββββββββββββββββββββββββ // // βββββββββββββββββββββββββββββββββββββββββββββββββββββ // // βββββββββββββββββββββββββββββββββββββββββββββββββββββ // // βββββββββββββββββββββββββββββββββββββββββββββββββββββ // // βββββββββββββββββββββββββββββββββββββββββββββββββββββ // /////////////////////////////////////////////////////////// // ============================================================= // STRUCTS // ============================================================= struct WrappedScriptRequest { string name; address contractAddress; bytes contractData; uint8 wrapType; bytes wrapPrefix; bytes wrapSuffix; bytes scriptContent; } struct InlineScriptRequest { string name; address contractAddress; bytes contractData; bytes scriptContent; } interface IScriptyBuilder { // ============================================================= // ERRORS // ============================================================= /** * @notice Error for, Invalid length of requests */ error InvalidRequestsLength(); // ============================================================= // RAW HTML GETTERS // ============================================================= /** * @notice Get requested scripts housed in <body> with custom wrappers * @dev Your requested scripts are returned in the following format: * <html> * <head></head> * <body style='margin:0;'> * [wrapPrefix[0]]{request[0]}[wrapSuffix[0]] * [wrapPrefix[1]]{request[1]}[wrapSuffix[1]] * ... * [wrapPrefix[n]]{request[n]}[wrapSuffix[n]] * </body> * </html> * @param requests - Array of WrappedScriptRequests * @param bufferSize - Total buffer size of all requested scripts * @return Full html wrapped scripts */ function getHTMLWrapped( WrappedScriptRequest[] calldata requests, uint256 bufferSize ) external view returns (bytes memory); /** * @notice Get requested scripts housed in URL Safe wrappers * @dev Any wrapper type 0 scripts are converted to base64 and wrapped * with <script src="data:text/javascript;base64,[SCRIPT]"></script> * * [WARNING]: Large non-base64 libraries that need base64 encoding * carry a high risk of causing a gas out. Highly advised to use * base64 encoded scripts where possible * * Your requested scripts are returned in the following format: * <html> * <head></head> * <body style='margin:0;'> * [wrapPrefix[0]]{request[0]}[wrapSuffix[0]] * [wrapPrefix[1]]{request[1]}[wrapSuffix[1]] * ... * [wrapPrefix[n]]{request[n]}[wrapSuffix[n]] * </body> * </html> * @param requests - Array of WrappedScriptRequests * @param bufferSize - Total buffer size of all requested scripts * @return Full URL Safe wrapped scripts */ function getHTMLWrappedURLSafe( WrappedScriptRequest[] calldata requests, uint256 bufferSize ) external view returns (bytes memory); /** * @notice Get requested scripts housed in <body> all wrapped in <script></script> * @dev Your requested scripts are returned in the following format: * <html> * <head></head> * <body style='margin:0;'> * <script> * {request[0]} * {request[1]} * ... * {request[n]} * </script> * </body> * </html> * @param requests - Array of InlineScriptRequest * @param bufferSize - Total buffer size of all requested scripts * @return Full html wrapped scripts */ function getHTMLInline( InlineScriptRequest[] calldata requests, uint256 bufferSize ) external view returns (bytes memory); // ============================================================= // ENCODED HTML GETTERS // ============================================================= /** * @notice Get {getHTMLWrapped} and base64 encode it * @param requests - Array of WrappedScriptRequests * @param bufferSize - Total buffer size of all requested scripts * @return Full html wrapped scripts, base64 encoded */ function getEncodedHTMLWrapped( WrappedScriptRequest[] calldata requests, uint256 bufferSize ) external view returns (bytes memory); /** * @notice Get {getHTMLInline} and base64 encode it * @param requests - Array of InlineScriptRequests * @param bufferSize - Total buffer size of all requested scripts * @return Full html wrapped scripts, base64 encoded */ function getEncodedHTMLInline( InlineScriptRequest[] calldata requests, uint256 bufferSize ) external view returns (bytes memory); // ============================================================= // STRING UTILITIES // ============================================================= /** * @notice Convert {getHTMLWrapped} output to a string * @param requests - Array of WrappedScriptRequests * @param bufferSize - Total buffer size of all requested scripts * @return {getHTMLWrapped} as a string */ function getHTMLWrappedString( WrappedScriptRequest[] calldata requests, uint256 bufferSize ) external view returns (string memory); /** * @notice Convert {getHTMLInline} output to a string * @param requests - Array of InlineScriptRequests * @param bufferSize - Total buffer size of all requested scripts * @return {getHTMLInline} as a string */ function getHTMLInlineString( InlineScriptRequest[] calldata requests, uint256 bufferSize ) external view returns (string memory); /** * @notice Convert {getEncodedHTMLWrapped} output to a string * @param requests - Array of WrappedScriptRequests * @param bufferSize - Total buffer size of all requested scripts * before encoding. * @return {getEncodedHTMLWrapped} as a string */ function getEncodedHTMLWrappedString( WrappedScriptRequest[] calldata requests, uint256 bufferSize ) external view returns (string memory); /** * @notice Convert {getEncodedHTMLInline} output to a string * @param requests - Array of InlineScriptRequests * @param bufferSize - Total buffer size of all requested scripts * before encoding. * @return {getEncodedHTMLInline} as a string */ function getEncodedHTMLInlineString( InlineScriptRequest[] calldata requests, uint256 bufferSize ) external view returns (string memory); // ============================================================= // OFF-CHAIN UTILITIES // ============================================================= /** * @notice Get the buffer size of a single inline requested code * @param request - InlineScriptRequest data for code * @return Buffer size as an unit256 */ function getInlineScriptSize(InlineScriptRequest memory request) external view returns (uint256); /** * @notice Get the buffer size of a single wrapped requested code * @param request - WrappedScriptRequest data for code * @return Buffer size as an unit256 */ function getWrappedScriptSize(WrappedScriptRequest memory request) external view returns (uint256); /** * @notice Get the buffer size of a single wrapped requested code * @dev If the script is of wrapper type 0, we get buffer size for * base64 encoded version. * @param request - WrappedScriptRequest data for code * @return Buffer size as an unit256 */ function getURLSafeWrappedScriptSize(WrappedScriptRequest memory request) external view returns (uint256); /** * @notice Get the buffer size of an array of html wrapped inline scripts * @param requests - InlineScriptRequests data for code * @return Buffer size as an unit256 */ function getBufferSizeForHTMLInline(InlineScriptRequest[] calldata requests) external view returns (uint256); /** * @notice Get the buffer size of an array of html wrapped, wrapped scripts * @param requests - WrappedScriptRequests data for code * @return Buffer size as an unit256 */ function getBufferSizeForHTMLWrapped( WrappedScriptRequest[] calldata requests ) external view returns (uint256); /** * @notice Get the buffer size of an array of URL safe html wrapped scripts * @param requests - WrappedScriptRequests data for code * @return Buffer size as an unit256 */ function getBufferSizeForURLSafeHTMLWrapped( WrappedScriptRequest[] calldata requests ) external view returns (uint256); /** * @notice Get the buffer size for encoded HTML inline scripts * @param requests - InlineScriptRequests data for code * @return Buffer size as an unit256 */ function getBufferSizeForEncodedHTMLInline( InlineScriptRequest[] calldata requests ) external view returns (uint256); /** * @notice Get the buffer size for encoded HTML inline scripts * @param requests - InlineScriptRequests data for code * @return Buffer size as an unit256 */ function getBufferSizeForEncodedHTMLWrapped( WrappedScriptRequest[] calldata requests ) external view returns (uint256); }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": { "contracts/Utilities.sol": { "utils": "0x0e47a2b3de8c3dc9d7f11952164d73a0c1d9d5ac" } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"_supply","type":"uint256"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"address","name":"_thumbnailAddress","type":"address"},{"internalType":"address","name":"_rendererAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"Finalized","type":"error"},{"inputs":[],"name":"InsufficientFunds","type":"error"},{"inputs":[],"name":"MintClosed","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"RefundFailed","type":"error"},{"inputs":[],"name":"SoldOut","type":"error"},{"inputs":[],"name":"TokenDoesntExist","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address[]","name":"_recipients","type":"address[]"},{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"airdrop","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"seed","type":"uint256"},{"internalType":"uint256","name":"planetSize","type":"uint256"},{"internalType":"bool","name":"hasRings","type":"bool"},{"internalType":"uint256","name":"numMoons","type":"uint256"},{"internalType":"enum PlanetType","name":"planetType","type":"uint8"},{"internalType":"uint256","name":"hue","type":"uint256"},{"internalType":"bool","name":"hasWater","type":"bool"},{"internalType":"bytes[7]","name":"vars","type":"bytes[7]"}],"internalType":"struct Settings","name":"settings","type":"tuple"}],"name":"buildAttributes","outputs":[{"internalType":"string","name":"attr","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"buildSettings","outputs":[{"components":[{"internalType":"uint256","name":"seed","type":"uint256"},{"internalType":"uint256","name":"planetSize","type":"uint256"},{"internalType":"bool","name":"hasRings","type":"bool"},{"internalType":"uint256","name":"numMoons","type":"uint256"},{"internalType":"enum PlanetType","name":"planetType","type":"uint8"},{"internalType":"uint256","name":"hue","type":"uint256"},{"internalType":"bool","name":"hasWater","type":"bool"},{"internalType":"bytes[7]","name":"vars","type":"bytes[7]"}],"internalType":"struct Settings","name":"settings","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"seed","type":"uint256"},{"internalType":"uint256","name":"planetSize","type":"uint256"},{"internalType":"bool","name":"hasRings","type":"bool"},{"internalType":"uint256","name":"numMoons","type":"uint256"},{"internalType":"enum PlanetType","name":"planetType","type":"uint8"},{"internalType":"uint256","name":"hue","type":"uint256"},{"internalType":"bool","name":"hasWater","type":"bool"},{"internalType":"bytes[7]","name":"vars","type":"bytes[7]"}],"internalType":"struct Settings","name":"settings","type":"tuple"}],"name":"buildVars","outputs":[{"internalType":"bytes","name":"vars","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"deployBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"finalize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"finalized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rendererAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"setMintStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rendererAddress","type":"address"}],"name":"setRendererAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_thumbnailAddress","type":"address"}],"name":"setThumbnailAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"supply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"thumbnailAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"metadata","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60c06040523480156200001157600080fd5b506040516200515338038062005153833981810160405281019062000037919062000444565b858581600290816200004a91906200075f565b5080600390816200005c91906200075f565b506200006d6200013a60201b60201c565b600081905550505062000095620000896200014360201b60201c565b6200014b60201b60201c565b81600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508360a0818152505082600b81905550436080818152505050505050505062000846565b60006001905090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200027a826200022f565b810181811067ffffffffffffffff821117156200029c576200029b62000240565b5b80604052505050565b6000620002b162000211565b9050620002bf82826200026f565b919050565b600067ffffffffffffffff821115620002e257620002e162000240565b5b620002ed826200022f565b9050602081019050919050565b60005b838110156200031a578082015181840152602081019050620002fd565b60008484015250505050565b60006200033d6200033784620002c4565b620002a5565b9050828152602081018484840111156200035c576200035b6200022a565b5b62000369848285620002fa565b509392505050565b600082601f83011262000389576200038862000225565b5b81516200039b84826020860162000326565b91505092915050565b6000819050919050565b620003b981620003a4565b8114620003c557600080fd5b50565b600081519050620003d981620003ae565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200040c82620003df565b9050919050565b6200041e81620003ff565b81146200042a57600080fd5b50565b6000815190506200043e8162000413565b92915050565b60008060008060008060c087890312156200046457620004636200021b565b5b600087015167ffffffffffffffff81111562000485576200048462000220565b5b6200049389828a0162000371565b965050602087015167ffffffffffffffff811115620004b757620004b662000220565b5b620004c589828a0162000371565b9550506040620004d889828a01620003c8565b9450506060620004eb89828a01620003c8565b9350506080620004fe89828a016200042d565b92505060a06200051189828a016200042d565b9150509295509295509295565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200057157607f821691505b60208210810362000587576200058662000529565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620005f17fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620005b2565b620005fd8683620005b2565b95508019841693508086168417925050509392505050565b6000819050919050565b6000620006406200063a6200063484620003a4565b62000615565b620003a4565b9050919050565b6000819050919050565b6200065c836200061f565b620006746200066b8262000647565b848454620005bf565b825550505050565b600090565b6200068b6200067c565b6200069881848462000651565b505050565b5b81811015620006c057620006b460008262000681565b6001810190506200069e565b5050565b601f8211156200070f57620006d9816200058d565b620006e484620005a2565b81016020851015620006f4578190505b6200070c6200070385620005a2565b8301826200069d565b50505b505050565b600082821c905092915050565b6000620007346000198460080262000714565b1980831691505092915050565b60006200074f838362000721565b9150826002028217905092915050565b6200076a826200051e565b67ffffffffffffffff81111562000786576200078562000240565b5b62000792825462000558565b6200079f828285620006c4565b600060209050601f831160018114620007d75760008415620007c2578287015190505b620007ce858262000741565b8655506200083e565b601f198416620007e7866200058d565b60005b828110156200081157848901518255600182019150602085019450602081019050620007ea565b868310156200083157848901516200082d601f89168262000721565b8355505b6001600288020188555050505b505050505050565b60805160a0516148d262000881600039600081816108b401528181611b5f01526120510152600081816113e60152611e0b01526148d26000f3fe60806040526004361061020f5760003560e01c806391b7f5ed11610118578063afbfbaa0116100a0578063c87b56dd1161006f578063c87b56dd14610729578063d67c52eb14610766578063d949bc5f14610791578063e985e9c5146107ba578063f2fde38b146107f75761020f565b8063afbfbaa014610689578063b3f05b97146106c6578063b88d4fde146106f1578063c204642c1461070d5761020f565b8063a0712d68116100e7578063a0712d68146105c5578063a22cb465146105e1578063a2309ff81461060a578063a3ec191a14610635578063a556f60f146106605761020f565b806391b7f5ed1461051b57806395d89b411461054457806399e8fa261461056f578063a035b1fe1461059a5761020f565b806342842e0e1161019b57806366d76b2c1161016a57806366d76b2c1461042257806370a082311461045f578063715018a61461049c5780637607b6db146104b35780638da5cb5b146104f05761020f565b806342842e0e1461038757806347535d7b146103a35780634bb278f3146103ce5780636352211e146103e55761020f565b8063095ea7b3116101e2578063095ea7b3146102e457806318160ddd146103005780631f85e3ca1461032b57806323b872dd146103545780633ccfd60b146103705761020f565b806301ffc9a714610214578063047fc9aa1461025157806306fdde031461027c578063081812fc146102a7575b600080fd5b34801561022057600080fd5b5061023b60048036038101906102369190612f2e565b610820565b6040516102489190612f76565b60405180910390f35b34801561025d57600080fd5b506102666108b2565b6040516102739190612faa565b60405180910390f35b34801561028857600080fd5b506102916108d6565b60405161029e9190613055565b60405180910390f35b3480156102b357600080fd5b506102ce60048036038101906102c991906130a3565b610968565b6040516102db9190613111565b60405180910390f35b6102fe60048036038101906102f99190613158565b6109e7565b005b34801561030c57600080fd5b50610315610b2b565b6040516103229190612faa565b60405180910390f35b34801561033757600080fd5b50610352600480360381019061034d91906131c4565b610b42565b005b61036e600480360381019061036991906131f1565b610b67565b005b34801561037c57600080fd5b50610385610e89565b005b6103a1600480360381019061039c91906131f1565b610ed1565b005b3480156103af57600080fd5b506103b8610ef1565b6040516103c59190612f76565b60405180910390f35b3480156103da57600080fd5b506103e3610f04565b005b3480156103f157600080fd5b5061040c600480360381019061040791906130a3565b610f29565b6040516104199190613111565b60405180910390f35b34801561042e57600080fd5b5061044960048036038101906104449190613562565b610f3b565b6040516104569190613055565b60405180910390f35b34801561046b57600080fd5b50610486600480360381019061048191906135ab565b61130e565b6040516104939190612faa565b60405180910390f35b3480156104a857600080fd5b506104b16113c6565b005b3480156104bf57600080fd5b506104da60048036038101906104d591906130a3565b6113da565b6040516104e79190613828565b60405180910390f35b3480156104fc57600080fd5b50610505611a1d565b6040516105129190613111565b60405180910390f35b34801561052757600080fd5b50610542600480360381019061053d91906130a3565b611a47565b005b34801561055057600080fd5b50610559611a59565b6040516105669190613055565b60405180910390f35b34801561057b57600080fd5b50610584611aeb565b6040516105919190613111565b60405180910390f35b3480156105a657600080fd5b506105af611b11565b6040516105bc9190612faa565b60405180910390f35b6105df60048036038101906105da91906130a3565b611b17565b005b3480156105ed57600080fd5b506106086004803603810190610603919061384a565b611cef565b005b34801561061657600080fd5b5061061f611dfa565b60405161062c9190612faa565b60405180910390f35b34801561064157600080fd5b5061064a611e09565b6040516106579190612faa565b60405180910390f35b34801561066c57600080fd5b50610687600480360381019061068291906135ab565b611e2d565b005b34801561069557600080fd5b506106b060048036038101906106ab9190613562565b611ec0565b6040516106bd91906138d4565b60405180910390f35b3480156106d257600080fd5b506106db611fc1565b6040516106e89190612f76565b60405180910390f35b61070b600480360381019061070691906138f6565b611fd4565b005b610727600480360381019061072291906139d4565b612047565b005b34801561073557600080fd5b50610750600480360381019061074b91906130a3565b612121565b60405161075d9190613055565b60405180910390f35b34801561077257600080fd5b5061077b61233a565b6040516107889190613111565b60405180910390f35b34801561079d57600080fd5b506107b860048036038101906107b391906135ab565b612360565b005b3480156107c657600080fd5b506107e160048036038101906107dc9190613a34565b6123f3565b6040516107ee9190612f76565b60405180910390f35b34801561080357600080fd5b5061081e600480360381019061081991906135ab565b612487565b005b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061087b57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806108ab5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6060600280546108e590613aa3565b80601f016020809104026020016040519081016040528092919081815260200182805461091190613aa3565b801561095e5780601f106109335761010080835404028352916020019161095e565b820191906000526020600020905b81548152906001019060200180831161094157829003601f168201915b5050505050905090565b60006109738261250a565b6109a9576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006109f282610f29565b90508073ffffffffffffffffffffffffffffffffffffffff16610a13612569565b73ffffffffffffffffffffffffffffffffffffffff1614610a7657610a3f81610a3a612569565b6123f3565b610a75576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000610b35612571565b6001546000540303905090565b610b4a61257a565b80600c60006101000a81548160ff02191690831515021790555050565b6000610b72826125f8565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610bd9576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610be5846126c4565b91509150610bfb8187610bf6612569565b6126eb565b610c4757610c1086610c0b612569565b6123f3565b610c46576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610cad576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cba868686600161272f565b8015610cc557600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610d9385610d6f888887612735565b7c02000000000000000000000000000000000000000000000000000000001761275d565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610e195760006001850190506000600460008381526020019081526020016000205403610e17576000548114610e16578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610e818686866001612788565b505050505050565b610e9161257a565b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050610ecf57600080fd5b565b610eec83838360405180602001604052806000815250611fd4565b505050565b600c60009054906101000a900460ff1681565b610f0c61257a565b6001600c60016101000a81548160ff021916908315150217905550565b6000610f34826125f8565b9050919050565b6060610f886040518060400160405280600b81526020017f506c616e65742053697a65000000000000000000000000000000000000000000815250610f83846020015161278e565b6127df565b6110416040518060400160405280600981526020017f4861732052696e677300000000000000000000000000000000000000000000008152508460400151611005576040518060400160405280600281526020017f4e6f00000000000000000000000000000000000000000000000000000000000081525061103c565b6040518060400160405280600381526020017f59657300000000000000000000000000000000000000000000000000000000008152505b61280b565b6110fa6040518060400160405280600981526020017f48617320576174657200000000000000000000000000000000000000000000008152508560c001516110be576040518060400160405280600281526020017f4e6f0000000000000000000000000000000000000000000000000000000000008152506110f5565b6040518060400160405280600381526020017f59657300000000000000000000000000000000000000000000000000000000008152505b61280b565b6111456040518060400160405280600f81526020017f4e756d626572206f66204d6f6f6e730000000000000000000000000000000000815250611140876060015161278e565b61280b565b6112246040518060400160405280600b81526020017f506c616e65742054797065000000000000000000000000000000000000000000815250600180811115611191576111906135f6565b5b886080015160018111156111a8576111a76135f6565b5b146111e8576040518060400160405280600381526020017f476173000000000000000000000000000000000000000000000000000000000081525061121f565b6040518060400160405280600481526020017f526f636b000000000000000000000000000000000000000000000000000000008152505b61280b565b6112e36040518060400160405280600c81526020017f506c616e657420436f6c6f720000000000000000000000000000000000000000815250730e47a2b3de8c3dc9d7f11952164d73a0c1d9d5ac630d56fe878a60a001516040518263ffffffff1660e01b81526004016112989190613ae3565b600060405180830381865af41580156112b5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906112de9190613b9f565b61280b565b6040516020016112f896959493929190613c96565b6040516020818303038152906040529050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611375576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6113ce61257a565b6113d86000612837565b565b6113e2612e3a565b60007f0000000000000000000000000000000000000000000000000000000000000000836114109190613d86565b9050611457816040518060400160405280600481526020017f73656564000000000000000000000000000000000000000000000000000000008152506001620f42406128fd565b8260000181815250506114a36040518060400160405280600481526020017f7365656400000000000000000000000000000000000000000000000000000000815250836000015161296d565b8260e001516000600781106114bb576114ba613dba565b5b6020020181905250611506816040518060400160405280600a81526020017f706c616e657453697a6500000000000000000000000000000000000000000000815250601e60646128fd565b8260200181815250506115526040518060400160405280600a81526020017f706c616e657453697a6500000000000000000000000000000000000000000000815250836020015161296d565b8260e0015160016007811061156a57611569613dba565b5b602002018190525060046115b7826040518060400160405280600a81526020017f706c616e657454797065000000000000000000000000000000000000000000008152506000600a6128fd565b106115c35760016115c6565b60005b826080019060018111156115dd576115dc6135f6565b5b908160018111156115f1576115f06135f6565b5b8152505061164a6040518060400160405280600a81526020017f706c616e6574547970650000000000000000000000000000000000000000000081525083608001516001811115611645576116446135f6565b5b61296d565b8260e0015160046007811061166257611661613dba565b5b60200201819052506000600181111561167e5761167d6135f6565b5b82608001516001811115611695576116946135f6565b5b1480156116e4575060036116e2826040518060400160405280600881526020017f68617352696e67730000000000000000000000000000000000000000000000008152506000600a6128fd565b105b8260400190151590811515815250506117476040518060400160405280600881526020017f68617352696e6773000000000000000000000000000000000000000000000000815250836040015161173c57600061173f565b60015b60ff1661296d565b8260e0015160026007811061175f5761175e613dba565b5b602002018190525060006117ac826040518060400160405280600881526020017f6e756d4d6f6f6e73000000000000000000000000000000000000000000000000815250600060646128fd565b905060198110156117c7576001836060018181525050611807565b60258110156117e0576002836060018181525050611806565b60288110156117f9576003836060018181525050611805565b60008360600181815250505b5b5b61184a6040518060400160405280600881526020017f6e756d4d6f6f6e73000000000000000000000000000000000000000000000000815250846060015161296d565b8360e0015160036007811061186257611861613dba565b5b6020020181905250506118af816040518060400160405280600781526020017f626173654875650000000000000000000000000000000000000000000000000081525060006101686128fd565b8260a00181815250506118fb6040518060400160405280600781526020017f62617365487565000000000000000000000000000000000000000000000000008152508360a0015161296d565b8260e0015160056007811061191357611912613dba565b5b602002018190525060018081111561192e5761192d6135f6565b5b82608001516001811115611945576119446135f6565b5b14801561199457506003611992826040518060400160405280600881526020017f68617357617465720000000000000000000000000000000000000000000000008152506000600a6128fd565b105b8260c00190151590811515815250506119f76040518060400160405280600881526020017f68617357617465720000000000000000000000000000000000000000000000008152508360c001516119ec5760006119ef565b60015b60ff1661296d565b8260e00151600660078110611a0f57611a0e613dba565b5b602002018190525050919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b611a4f61257a565b80600b8190555050565b606060038054611a6890613aa3565b80601f0160208091040260200160405190810160405280929190818152602001828054611a9490613aa3565b8015611ae15780601f10611ab657610100808354040283529160200191611ae1565b820191906000526020600020905b815481529060010190602001808311611ac457829003601f168201915b5050505050905090565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600b5481565b600c60009054906101000a900460ff16611b5d576040517f589ed34b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000081611b87611dfa565b611b919190613d86565b1115611bc9576040517f52df9fe500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600b54611bd79190613de9565b341015611c10576040517f356680b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c1a33826129a1565b80600b54611c289190613de9565b341115611cec5760003373ffffffffffffffffffffffffffffffffffffffff1682600b54611c569190613de9565b34611c619190613e2b565b604051611c6d90613e90565b60006040518083038185875af1925050503d8060008114611caa576040519150601f19603f3d011682016040523d82523d6000602084013e611caf565b606091505b5050905080611cea576040517ff0c49d4400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b50565b8060076000611cfc612569565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611da9612569565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611dee9190612f76565b60405180910390a35050565b6000611e04612b5c565b905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b611e3561257a565b600c60019054906101000a900460ff1615611e7c576040517f6823b07300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6060611fba8260e00151600060078110611edd57611edc613dba565b5b60200201518360e00151600160078110611efa57611ef9613dba565b5b60200201518460e00151600260078110611f1757611f16613dba565b5b60200201518560e00151600360078110611f3457611f33613dba565b5b60200201518660e00151600460078110611f5157611f50613dba565b5b60200201518760e00151600560078110611f6e57611f6d613dba565b5b60200201518860e00151600660078110611f8b57611f8a613dba565b5b6020020151604051602001611fa69796959493929190613ed6565b604051602081830303815290604052612b6f565b9050919050565b600c60019054906101000a900460ff1681565b611fdf848484610b67565b60008373ffffffffffffffffffffffffffffffffffffffff163b146120415761200a84848484612b84565b612040576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b61204f61257a565b7f0000000000000000000000000000000000000000000000000000000000000000818484905061207f9190613de9565b612087611dfa565b6120919190613d86565b11156120c9576040517f52df9fe500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8383905081101561211b576121088484838181106120ed576120ec613dba565b5b905060200201602081019061210291906135ab565b836129a1565b808061211390613f3b565b9150506120cc565b50505050565b606061212c8261250a565b612162576040517feb7d192800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061216d836113da565b9050600061217a82610f3b565b9050600061218783611ec0565b90506000612234600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c7d3625b866040518263ffffffff1660e01b81526004016121e99190613828565b600060405180830381865afa158015612206573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061222f9190613ff3565b612b6f565b90506000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bf471ba7846040518263ffffffff1660e01b815260040161229391906138d4565b600060405180830381865afa1580156122b0573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906122d99190613ff3565b905060006122e68861278e565b8383876040516020016122fc94939291906142e8565b60405160208183030381529060405290508060405160200161231e91906143ca565b6040516020818303038152906040529650505050505050919050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61236861257a565b600c60019054906101000a900460ff16156123af576040517f6823b07300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61248f61257a565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036124fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124f59061445e565b60405180910390fd5b61250781612837565b50565b600081612515612571565b11158015612524575060005482105b8015612562575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b60006001905090565b612582612cd4565b73ffffffffffffffffffffffffffffffffffffffff166125a0611a1d565b73ffffffffffffffffffffffffffffffffffffffff16146125f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125ed906144ca565b60405180910390fd5b565b60008082905080612607612571565b1161268d5760005481101561268c5760006004600083815260200190815260200160002054905060007c010000000000000000000000000000000000000000000000000000000082160361268a575b60008103612680576004600083600190039350838152602001908152602001600020549050612656565b80925050506126bf565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e861274c868684612cdc565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b60606080604051019050602081016040526000815280600019835b6001156127ca578184019350600a81066030018453600a81049050806127a9575b50828203602084039350808452505050919050565b606082826040516020016127f492919061455c565b604051602081830303815290604052905092915050565b606082826040516020016128209291906145f9565b604051602081830303815290604052905092915050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000806129328561290d8861278e565b60405160200161291e92919061464a565b604051602081830303815290604052612ce5565b905083600185856129439190613e2b565b61294d9190613d86565b82612958919061469d565b6129629190613d86565b915050949350505050565b6060826129798361278e565b60405160200161298a9291906147b2565b604051602081830303815290604052905092915050565b600080549050600082036129e1576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129ee600084838561272f565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612a6583612a566000866000612735565b612a5f85612d19565b1761275d565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b818114612b0657808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050612acb565b5060008203612b41576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000819055505050612b576000848385612788565b505050565b6000612b66612571565b60005403905090565b6060612b7d82600080612d29565b9050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612baa612569565b8786866040518563ffffffff1660e01b8152600401612bcc94939291906147f7565b6020604051808303816000875af1925050508015612c0857506040513d601f19601f82011682018060405250810190612c059190614858565b60015b612c81573d8060008114612c38576040519150601f19603f3d011682016040523d82523d6000602084013e612c3d565b606091505b506000815103612c79576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b600033905090565b60009392505050565b6000612d0f82604051602001612cfb9190614885565b604051602081830303815290604052612e2a565b60001c9050919050565b60006001821460e11b9050919050565b606083518015612e22576003600282010460021b60405192507f4142434445464748494a4b4c4d4e4f505152535455565758595a616263646566601f526102308515027f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5f03603f52602083018181015b600115612def576003880197508751603f8160121c1651600053603f81600c1c1651600153603f8160061c1651600253603f8116516003536000518352600483019250818310612de95750612def565b50612d99565b601f19601f82011660405260038406600204613d3d60f01b81840352808715150290506000818403528084038652505050505b509392505050565b6000815160208301209050919050565b60405180610100016040528060008152602001600081526020016000151581526020016000815260200160006001811115612e7857612e776135f6565b5b815260200160008152602001600015158152602001612e95612e9b565b81525090565b6040518060e001604052806007905b6060815260200190600190039081612eaa5790505090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612f0b81612ed6565b8114612f1657600080fd5b50565b600081359050612f2881612f02565b92915050565b600060208284031215612f4457612f43612ecc565b5b6000612f5284828501612f19565b91505092915050565b60008115159050919050565b612f7081612f5b565b82525050565b6000602082019050612f8b6000830184612f67565b92915050565b6000819050919050565b612fa481612f91565b82525050565b6000602082019050612fbf6000830184612f9b565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612fff578082015181840152602081019050612fe4565b60008484015250505050565b6000601f19601f8301169050919050565b600061302782612fc5565b6130318185612fd0565b9350613041818560208601612fe1565b61304a8161300b565b840191505092915050565b6000602082019050818103600083015261306f818461301c565b905092915050565b61308081612f91565b811461308b57600080fd5b50565b60008135905061309d81613077565b92915050565b6000602082840312156130b9576130b8612ecc565b5b60006130c78482850161308e565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006130fb826130d0565b9050919050565b61310b816130f0565b82525050565b60006020820190506131266000830184613102565b92915050565b613135816130f0565b811461314057600080fd5b50565b6000813590506131528161312c565b92915050565b6000806040838503121561316f5761316e612ecc565b5b600061317d85828601613143565b925050602061318e8582860161308e565b9150509250929050565b6131a181612f5b565b81146131ac57600080fd5b50565b6000813590506131be81613198565b92915050565b6000602082840312156131da576131d9612ecc565b5b60006131e8848285016131af565b91505092915050565b60008060006060848603121561320a57613209612ecc565b5b600061321886828701613143565b935050602061322986828701613143565b925050604061323a8682870161308e565b9150509250925092565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6132818261300b565b810181811067ffffffffffffffff821117156132a05761329f613249565b5b80604052505050565b60006132b3612ec2565b90506132bf8282613278565b919050565b600080fd5b600281106132d657600080fd5b50565b6000813590506132e8816132c9565b92915050565b600080fd5b600067ffffffffffffffff82111561330e5761330d613249565b5b602082029050919050565b600080fd5b600080fd5b600067ffffffffffffffff82111561333e5761333d613249565b5b6133478261300b565b9050602081019050919050565b82818337600083830152505050565b600061337661337184613323565b6132a9565b9050828152602081018484840111156133925761339161331e565b5b61339d848285613354565b509392505050565b600082601f8301126133ba576133b96132ee565b5b81356133ca848260208601613363565b91505092915050565b60006133e66133e1846132f3565b6132a9565b90508060208402830185811115613400576133ff613319565b5b835b8181101561344757803567ffffffffffffffff811115613425576134246132ee565b5b80860161343289826133a5565b85526020850194505050602081019050613402565b5050509392505050565b600082601f830112613466576134656132ee565b5b60076134738482856133d3565b91505092915050565b6000610100828403121561349357613492613244565b5b61349e6101006132a9565b905060006134ae8482850161308e565b60008301525060206134c28482850161308e565b60208301525060406134d6848285016131af565b60408301525060606134ea8482850161308e565b60608301525060806134fe848285016132d9565b60808301525060a06135128482850161308e565b60a08301525060c0613526848285016131af565b60c08301525060e082013567ffffffffffffffff81111561354a576135496132c4565b5b61355684828501613451565b60e08301525092915050565b60006020828403121561357857613577612ecc565b5b600082013567ffffffffffffffff81111561359657613595612ed1565b5b6135a28482850161347c565b91505092915050565b6000602082840312156135c1576135c0612ecc565b5b60006135cf84828501613143565b91505092915050565b6135e181612f91565b82525050565b6135f081612f5b565b82525050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60028110613636576136356135f6565b5b50565b600081905061364782613625565b919050565b600061365782613639565b9050919050565b6136678161364c565b82525050565b600060079050919050565b600081905092915050565b6000819050919050565b600081519050919050565b600082825260208201905092915050565b60006136b48261368d565b6136be8185613698565b93506136ce818560208601612fe1565b6136d78161300b565b840191505092915050565b60006136ee83836136a9565b905092915050565b6000602082019050919050565b600061370e8261366d565b6137188185613678565b93508360208202850161372a85613683565b8060005b85811015613766578484038952815161374785826136e2565b9450613752836136f6565b925060208a0199505060018101905061372e565b50829750879550505050505092915050565b60006101008301600083015161379160008601826135d8565b5060208301516137a460208601826135d8565b5060408301516137b760408601826135e7565b5060608301516137ca60608601826135d8565b5060808301516137dd608086018261365e565b5060a08301516137f060a08601826135d8565b5060c083015161380360c08601826135e7565b5060e083015184820360e086015261381b8282613703565b9150508091505092915050565b600060208201905081810360008301526138428184613778565b905092915050565b6000806040838503121561386157613860612ecc565b5b600061386f85828601613143565b9250506020613880858286016131af565b9150509250929050565b600082825260208201905092915050565b60006138a68261368d565b6138b0818561388a565b93506138c0818560208601612fe1565b6138c98161300b565b840191505092915050565b600060208201905081810360008301526138ee818461389b565b905092915050565b600080600080608085870312156139105761390f612ecc565b5b600061391e87828801613143565b945050602061392f87828801613143565b93505060406139408782880161308e565b925050606085013567ffffffffffffffff81111561396157613960612ed1565b5b61396d878288016133a5565b91505092959194509250565b600080fd5b60008083601f840112613994576139936132ee565b5b8235905067ffffffffffffffff8111156139b1576139b0613979565b5b6020830191508360208202830111156139cd576139cc613319565b5b9250929050565b6000806000604084860312156139ed576139ec612ecc565b5b600084013567ffffffffffffffff811115613a0b57613a0a612ed1565b5b613a178682870161397e565b93509350506020613a2a8682870161308e565b9150509250925092565b60008060408385031215613a4b57613a4a612ecc565b5b6000613a5985828601613143565b9250506020613a6a85828601613143565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613abb57607f821691505b602082108103613ace57613acd613a74565b5b50919050565b613add81612f91565b82525050565b6000602082019050613af86000830184613ad4565b92915050565b600067ffffffffffffffff821115613b1957613b18613249565b5b613b228261300b565b9050602081019050919050565b6000613b42613b3d84613afe565b6132a9565b905082815260208101848484011115613b5e57613b5d61331e565b5b613b69848285612fe1565b509392505050565b600082601f830112613b8657613b856132ee565b5b8151613b96848260208601613b2f565b91505092915050565b600060208284031215613bb557613bb4612ecc565b5b600082015167ffffffffffffffff811115613bd357613bd2612ed1565b5b613bdf84828501613b71565b91505092915050565b7f2261747472696275746573223a205b0000000000000000000000000000000000815250565b600081905092915050565b6000613c2482612fc5565b613c2e8185613c0e565b9350613c3e818560208601612fe1565b80840191505092915050565b7f2c00000000000000000000000000000000000000000000000000000000000000815250565b7f5d00000000000000000000000000000000000000000000000000000000000000815250565b6000613ca182613be8565b600f82019150613cb18289613c19565b9150613cbc82613c4a565b600182019150613ccc8288613c19565b9150613cd782613c4a565b600182019150613ce78287613c19565b9150613cf282613c4a565b600182019150613d028286613c19565b9150613d0d82613c4a565b600182019150613d1d8285613c19565b9150613d2882613c4a565b600182019150613d388284613c19565b9150613d4382613c70565b600182019150819050979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613d9182612f91565b9150613d9c83612f91565b9250828201905080821115613db457613db3613d57565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000613df482612f91565b9150613dff83612f91565b9250828202613e0d81612f91565b91508282048414831517613e2457613e23613d57565b5b5092915050565b6000613e3682612f91565b9150613e4183612f91565b9250828203905081811115613e5957613e58613d57565b5b92915050565b600081905092915050565b50565b6000613e7a600083613e5f565b9150613e8582613e6a565b600082019050919050565b6000613e9b82613e6d565b9150819050919050565b6000613eb08261368d565b613eba8185613e5f565b9350613eca818560208601612fe1565b80840191505092915050565b6000613ee2828a613ea5565b9150613eee8289613ea5565b9150613efa8288613ea5565b9150613f068287613ea5565b9150613f128286613ea5565b9150613f1e8285613ea5565b9150613f2a8284613ea5565b915081905098975050505050505050565b6000613f4682612f91565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613f7857613f77613d57565b5b600182019050919050565b6000613f96613f9184613323565b6132a9565b905082815260208101848484011115613fb257613fb161331e565b5b613fbd848285612fe1565b509392505050565b600082601f830112613fda57613fd96132ee565b5b8151613fea848260208601613f83565b91505092915050565b60006020828403121561400957614008612ecc565b5b600082015167ffffffffffffffff81111561402757614026612ed1565b5b61403384828501613fc5565b91505092915050565b7f7b226e616d65223a220000000000000000000000000000000000000000000000600082015250565b6000614072600983613c0e565b915061407d8261403c565b600982019050919050565b7f4574686572506c616e6574202300000000000000000000000000000000000000600082015250565b60006140be600d83613c0e565b91506140c982614088565b600d82019050919050565b7f222c20226465736372697074696f6e223a220000000000000000000000000000600082015250565b600061410a601283613c0e565b9150614115826140d4565b601282019050919050565b7f46756c6c79206f6e2d636861696e2c2070726f6365647572616c6c792067656e60008201527f6572617465642c20334420706c616e6574732e00000000000000000000000000602082015250565b600061417c603383613c0e565b915061418782614120565b603382019050919050565b7f222c22696d616765223a22646174613a696d6167652f7376672b786d6c3b626160008201527f736536342c000000000000000000000000000000000000000000000000000000602082015250565b60006141ee602583613c0e565b91506141f982614192565b602582019050919050565b7f222c22616e696d6174696f6e5f75726c223a2200000000000000000000000000600082015250565b600061423a601383613c0e565b915061424582614204565b601382019050919050565b7f222c000000000000000000000000000000000000000000000000000000000000600082015250565b6000614286600283613c0e565b915061429182614250565b600282019050919050565b7f7d00000000000000000000000000000000000000000000000000000000000000600082015250565b60006142d2600183613c0e565b91506142dd8261429c565b600182019050919050565b60006142f382614065565b91506142fe826140b1565b915061430a8287613c19565b9150614315826140fd565b91506143208261416f565b915061432b826141e1565b91506143378286613c19565b91506143428261422d565b915061434e8285613ea5565b915061435982614279565b91506143658284613c19565b9150614370826142c5565b915081905095945050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e2c00000000000000000000600082015250565b60006143b4601683613c0e565b91506143bf8261437e565b601682019050919050565b60006143d5826143a7565b91506143e18284613ea5565b915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614448602683612fd0565b9150614453826143ec565b604082019050919050565b600060208201905081810360008301526144778161443b565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006144b4602083612fd0565b91506144bf8261447e565b602082019050919050565b600060208201905081810360008301526144e3816144a7565b9050919050565b7f7b2274726169745f74797065223a220000000000000000000000000000000000815250565b7f222c2276616c7565223a00000000000000000000000000000000000000000000815250565b7f7d00000000000000000000000000000000000000000000000000000000000000815250565b6000614567826144ea565b600f820191506145778285613c19565b915061458282614510565b600a820191506145928284613c19565b915061459d82614536565b6001820191508190509392505050565b7f222c2276616c7565223a22000000000000000000000000000000000000000000815250565b7f227d000000000000000000000000000000000000000000000000000000000000815250565b6000614604826144ea565b600f820191506146148285613c19565b915061461f826145ad565b600b8201915061462f8284613c19565b915061463a826145d3565b6002820191508190509392505050565b60006146568285613c19565b91506146628284613c19565b91508190509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006146a882612f91565b91506146b383612f91565b9250826146c3576146c261466e565b5b828206905092915050565b7f7661722000000000000000000000000000000000000000000000000000000000600082015250565b6000614704600483613c0e565b915061470f826146ce565b600482019050919050565b7f3d00000000000000000000000000000000000000000000000000000000000000600082015250565b6000614750600183613c0e565b915061475b8261471a565b600182019050919050565b7f3b00000000000000000000000000000000000000000000000000000000000000600082015250565b600061479c600183613c0e565b91506147a782614766565b600182019050919050565b60006147bd826146f7565b91506147c98285613ea5565b91506147d482614743565b91506147e08284613c19565b91506147eb8261478f565b91508190509392505050565b600060808201905061480c6000830187613102565b6148196020830186613102565b6148266040830185612f9b565b8181036060830152614838818461389b565b905095945050505050565b60008151905061485281612f02565b92915050565b60006020828403121561486e5761486d612ecc565b5b600061487c84828501614843565b91505092915050565b60006148918284613c19565b91508190509291505056fea264697066735822122086b5c7449e29e8de509c70ef7a3f2fac4937ae0790460649313afd14a874a0b564736f6c6343000812003300000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000001092000000000000000000000000000000000000000000000000000eebe0b40e800000000000000000000000000007e12f3f0bfceee2b92b68ed485e85b896761c7500000000000000000000000016ec9b5a0aef45ca3642000df11f0b2c42bdac45000000000000000000000000000000000000000000000000000000000000000c4574686572506c616e657473000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024550000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x60806040526004361061020f5760003560e01c806391b7f5ed11610118578063afbfbaa0116100a0578063c87b56dd1161006f578063c87b56dd14610729578063d67c52eb14610766578063d949bc5f14610791578063e985e9c5146107ba578063f2fde38b146107f75761020f565b8063afbfbaa014610689578063b3f05b97146106c6578063b88d4fde146106f1578063c204642c1461070d5761020f565b8063a0712d68116100e7578063a0712d68146105c5578063a22cb465146105e1578063a2309ff81461060a578063a3ec191a14610635578063a556f60f146106605761020f565b806391b7f5ed1461051b57806395d89b411461054457806399e8fa261461056f578063a035b1fe1461059a5761020f565b806342842e0e1161019b57806366d76b2c1161016a57806366d76b2c1461042257806370a082311461045f578063715018a61461049c5780637607b6db146104b35780638da5cb5b146104f05761020f565b806342842e0e1461038757806347535d7b146103a35780634bb278f3146103ce5780636352211e146103e55761020f565b8063095ea7b3116101e2578063095ea7b3146102e457806318160ddd146103005780631f85e3ca1461032b57806323b872dd146103545780633ccfd60b146103705761020f565b806301ffc9a714610214578063047fc9aa1461025157806306fdde031461027c578063081812fc146102a7575b600080fd5b34801561022057600080fd5b5061023b60048036038101906102369190612f2e565b610820565b6040516102489190612f76565b60405180910390f35b34801561025d57600080fd5b506102666108b2565b6040516102739190612faa565b60405180910390f35b34801561028857600080fd5b506102916108d6565b60405161029e9190613055565b60405180910390f35b3480156102b357600080fd5b506102ce60048036038101906102c991906130a3565b610968565b6040516102db9190613111565b60405180910390f35b6102fe60048036038101906102f99190613158565b6109e7565b005b34801561030c57600080fd5b50610315610b2b565b6040516103229190612faa565b60405180910390f35b34801561033757600080fd5b50610352600480360381019061034d91906131c4565b610b42565b005b61036e600480360381019061036991906131f1565b610b67565b005b34801561037c57600080fd5b50610385610e89565b005b6103a1600480360381019061039c91906131f1565b610ed1565b005b3480156103af57600080fd5b506103b8610ef1565b6040516103c59190612f76565b60405180910390f35b3480156103da57600080fd5b506103e3610f04565b005b3480156103f157600080fd5b5061040c600480360381019061040791906130a3565b610f29565b6040516104199190613111565b60405180910390f35b34801561042e57600080fd5b5061044960048036038101906104449190613562565b610f3b565b6040516104569190613055565b60405180910390f35b34801561046b57600080fd5b50610486600480360381019061048191906135ab565b61130e565b6040516104939190612faa565b60405180910390f35b3480156104a857600080fd5b506104b16113c6565b005b3480156104bf57600080fd5b506104da60048036038101906104d591906130a3565b6113da565b6040516104e79190613828565b60405180910390f35b3480156104fc57600080fd5b50610505611a1d565b6040516105129190613111565b60405180910390f35b34801561052757600080fd5b50610542600480360381019061053d91906130a3565b611a47565b005b34801561055057600080fd5b50610559611a59565b6040516105669190613055565b60405180910390f35b34801561057b57600080fd5b50610584611aeb565b6040516105919190613111565b60405180910390f35b3480156105a657600080fd5b506105af611b11565b6040516105bc9190612faa565b60405180910390f35b6105df60048036038101906105da91906130a3565b611b17565b005b3480156105ed57600080fd5b506106086004803603810190610603919061384a565b611cef565b005b34801561061657600080fd5b5061061f611dfa565b60405161062c9190612faa565b60405180910390f35b34801561064157600080fd5b5061064a611e09565b6040516106579190612faa565b60405180910390f35b34801561066c57600080fd5b50610687600480360381019061068291906135ab565b611e2d565b005b34801561069557600080fd5b506106b060048036038101906106ab9190613562565b611ec0565b6040516106bd91906138d4565b60405180910390f35b3480156106d257600080fd5b506106db611fc1565b6040516106e89190612f76565b60405180910390f35b61070b600480360381019061070691906138f6565b611fd4565b005b610727600480360381019061072291906139d4565b612047565b005b34801561073557600080fd5b50610750600480360381019061074b91906130a3565b612121565b60405161075d9190613055565b60405180910390f35b34801561077257600080fd5b5061077b61233a565b6040516107889190613111565b60405180910390f35b34801561079d57600080fd5b506107b860048036038101906107b391906135ab565b612360565b005b3480156107c657600080fd5b506107e160048036038101906107dc9190613a34565b6123f3565b6040516107ee9190612f76565b60405180910390f35b34801561080357600080fd5b5061081e600480360381019061081991906135ab565b612487565b005b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061087b57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806108ab5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b7f000000000000000000000000000000000000000000000000000000000000109281565b6060600280546108e590613aa3565b80601f016020809104026020016040519081016040528092919081815260200182805461091190613aa3565b801561095e5780601f106109335761010080835404028352916020019161095e565b820191906000526020600020905b81548152906001019060200180831161094157829003601f168201915b5050505050905090565b60006109738261250a565b6109a9576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006109f282610f29565b90508073ffffffffffffffffffffffffffffffffffffffff16610a13612569565b73ffffffffffffffffffffffffffffffffffffffff1614610a7657610a3f81610a3a612569565b6123f3565b610a75576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000610b35612571565b6001546000540303905090565b610b4a61257a565b80600c60006101000a81548160ff02191690831515021790555050565b6000610b72826125f8565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610bd9576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610be5846126c4565b91509150610bfb8187610bf6612569565b6126eb565b610c4757610c1086610c0b612569565b6123f3565b610c46576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610cad576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cba868686600161272f565b8015610cc557600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610d9385610d6f888887612735565b7c02000000000000000000000000000000000000000000000000000000001761275d565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610e195760006001850190506000600460008381526020019081526020016000205403610e17576000548114610e16578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610e818686866001612788565b505050505050565b610e9161257a565b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050610ecf57600080fd5b565b610eec83838360405180602001604052806000815250611fd4565b505050565b600c60009054906101000a900460ff1681565b610f0c61257a565b6001600c60016101000a81548160ff021916908315150217905550565b6000610f34826125f8565b9050919050565b6060610f886040518060400160405280600b81526020017f506c616e65742053697a65000000000000000000000000000000000000000000815250610f83846020015161278e565b6127df565b6110416040518060400160405280600981526020017f4861732052696e677300000000000000000000000000000000000000000000008152508460400151611005576040518060400160405280600281526020017f4e6f00000000000000000000000000000000000000000000000000000000000081525061103c565b6040518060400160405280600381526020017f59657300000000000000000000000000000000000000000000000000000000008152505b61280b565b6110fa6040518060400160405280600981526020017f48617320576174657200000000000000000000000000000000000000000000008152508560c001516110be576040518060400160405280600281526020017f4e6f0000000000000000000000000000000000000000000000000000000000008152506110f5565b6040518060400160405280600381526020017f59657300000000000000000000000000000000000000000000000000000000008152505b61280b565b6111456040518060400160405280600f81526020017f4e756d626572206f66204d6f6f6e730000000000000000000000000000000000815250611140876060015161278e565b61280b565b6112246040518060400160405280600b81526020017f506c616e65742054797065000000000000000000000000000000000000000000815250600180811115611191576111906135f6565b5b886080015160018111156111a8576111a76135f6565b5b146111e8576040518060400160405280600381526020017f476173000000000000000000000000000000000000000000000000000000000081525061121f565b6040518060400160405280600481526020017f526f636b000000000000000000000000000000000000000000000000000000008152505b61280b565b6112e36040518060400160405280600c81526020017f506c616e657420436f6c6f720000000000000000000000000000000000000000815250730e47a2b3de8c3dc9d7f11952164d73a0c1d9d5ac630d56fe878a60a001516040518263ffffffff1660e01b81526004016112989190613ae3565b600060405180830381865af41580156112b5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906112de9190613b9f565b61280b565b6040516020016112f896959493929190613c96565b6040516020818303038152906040529050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611375576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6113ce61257a565b6113d86000612837565b565b6113e2612e3a565b60007f000000000000000000000000000000000000000000000000000000000103c531836114109190613d86565b9050611457816040518060400160405280600481526020017f73656564000000000000000000000000000000000000000000000000000000008152506001620f42406128fd565b8260000181815250506114a36040518060400160405280600481526020017f7365656400000000000000000000000000000000000000000000000000000000815250836000015161296d565b8260e001516000600781106114bb576114ba613dba565b5b6020020181905250611506816040518060400160405280600a81526020017f706c616e657453697a6500000000000000000000000000000000000000000000815250601e60646128fd565b8260200181815250506115526040518060400160405280600a81526020017f706c616e657453697a6500000000000000000000000000000000000000000000815250836020015161296d565b8260e0015160016007811061156a57611569613dba565b5b602002018190525060046115b7826040518060400160405280600a81526020017f706c616e657454797065000000000000000000000000000000000000000000008152506000600a6128fd565b106115c35760016115c6565b60005b826080019060018111156115dd576115dc6135f6565b5b908160018111156115f1576115f06135f6565b5b8152505061164a6040518060400160405280600a81526020017f706c616e6574547970650000000000000000000000000000000000000000000081525083608001516001811115611645576116446135f6565b5b61296d565b8260e0015160046007811061166257611661613dba565b5b60200201819052506000600181111561167e5761167d6135f6565b5b82608001516001811115611695576116946135f6565b5b1480156116e4575060036116e2826040518060400160405280600881526020017f68617352696e67730000000000000000000000000000000000000000000000008152506000600a6128fd565b105b8260400190151590811515815250506117476040518060400160405280600881526020017f68617352696e6773000000000000000000000000000000000000000000000000815250836040015161173c57600061173f565b60015b60ff1661296d565b8260e0015160026007811061175f5761175e613dba565b5b602002018190525060006117ac826040518060400160405280600881526020017f6e756d4d6f6f6e73000000000000000000000000000000000000000000000000815250600060646128fd565b905060198110156117c7576001836060018181525050611807565b60258110156117e0576002836060018181525050611806565b60288110156117f9576003836060018181525050611805565b60008360600181815250505b5b5b61184a6040518060400160405280600881526020017f6e756d4d6f6f6e73000000000000000000000000000000000000000000000000815250846060015161296d565b8360e0015160036007811061186257611861613dba565b5b6020020181905250506118af816040518060400160405280600781526020017f626173654875650000000000000000000000000000000000000000000000000081525060006101686128fd565b8260a00181815250506118fb6040518060400160405280600781526020017f62617365487565000000000000000000000000000000000000000000000000008152508360a0015161296d565b8260e0015160056007811061191357611912613dba565b5b602002018190525060018081111561192e5761192d6135f6565b5b82608001516001811115611945576119446135f6565b5b14801561199457506003611992826040518060400160405280600881526020017f68617357617465720000000000000000000000000000000000000000000000008152506000600a6128fd565b105b8260c00190151590811515815250506119f76040518060400160405280600881526020017f68617357617465720000000000000000000000000000000000000000000000008152508360c001516119ec5760006119ef565b60015b60ff1661296d565b8260e00151600660078110611a0f57611a0e613dba565b5b602002018190525050919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b611a4f61257a565b80600b8190555050565b606060038054611a6890613aa3565b80601f0160208091040260200160405190810160405280929190818152602001828054611a9490613aa3565b8015611ae15780601f10611ab657610100808354040283529160200191611ae1565b820191906000526020600020905b815481529060010190602001808311611ac457829003601f168201915b5050505050905090565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600b5481565b600c60009054906101000a900460ff16611b5d576040517f589ed34b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000109281611b87611dfa565b611b919190613d86565b1115611bc9576040517f52df9fe500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600b54611bd79190613de9565b341015611c10576040517f356680b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c1a33826129a1565b80600b54611c289190613de9565b341115611cec5760003373ffffffffffffffffffffffffffffffffffffffff1682600b54611c569190613de9565b34611c619190613e2b565b604051611c6d90613e90565b60006040518083038185875af1925050503d8060008114611caa576040519150601f19603f3d011682016040523d82523d6000602084013e611caf565b606091505b5050905080611cea576040517ff0c49d4400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b50565b8060076000611cfc612569565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611da9612569565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611dee9190612f76565b60405180910390a35050565b6000611e04612b5c565b905090565b7f000000000000000000000000000000000000000000000000000000000103c53181565b611e3561257a565b600c60019054906101000a900460ff1615611e7c576040517f6823b07300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6060611fba8260e00151600060078110611edd57611edc613dba565b5b60200201518360e00151600160078110611efa57611ef9613dba565b5b60200201518460e00151600260078110611f1757611f16613dba565b5b60200201518560e00151600360078110611f3457611f33613dba565b5b60200201518660e00151600460078110611f5157611f50613dba565b5b60200201518760e00151600560078110611f6e57611f6d613dba565b5b60200201518860e00151600660078110611f8b57611f8a613dba565b5b6020020151604051602001611fa69796959493929190613ed6565b604051602081830303815290604052612b6f565b9050919050565b600c60019054906101000a900460ff1681565b611fdf848484610b67565b60008373ffffffffffffffffffffffffffffffffffffffff163b146120415761200a84848484612b84565b612040576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b61204f61257a565b7f0000000000000000000000000000000000000000000000000000000000001092818484905061207f9190613de9565b612087611dfa565b6120919190613d86565b11156120c9576040517f52df9fe500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8383905081101561211b576121088484838181106120ed576120ec613dba565b5b905060200201602081019061210291906135ab565b836129a1565b808061211390613f3b565b9150506120cc565b50505050565b606061212c8261250a565b612162576040517feb7d192800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061216d836113da565b9050600061217a82610f3b565b9050600061218783611ec0565b90506000612234600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c7d3625b866040518263ffffffff1660e01b81526004016121e99190613828565b600060405180830381865afa158015612206573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061222f9190613ff3565b612b6f565b90506000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bf471ba7846040518263ffffffff1660e01b815260040161229391906138d4565b600060405180830381865afa1580156122b0573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906122d99190613ff3565b905060006122e68861278e565b8383876040516020016122fc94939291906142e8565b60405160208183030381529060405290508060405160200161231e91906143ca565b6040516020818303038152906040529650505050505050919050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61236861257a565b600c60019054906101000a900460ff16156123af576040517f6823b07300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61248f61257a565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036124fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124f59061445e565b60405180910390fd5b61250781612837565b50565b600081612515612571565b11158015612524575060005482105b8015612562575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b60006001905090565b612582612cd4565b73ffffffffffffffffffffffffffffffffffffffff166125a0611a1d565b73ffffffffffffffffffffffffffffffffffffffff16146125f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125ed906144ca565b60405180910390fd5b565b60008082905080612607612571565b1161268d5760005481101561268c5760006004600083815260200190815260200160002054905060007c010000000000000000000000000000000000000000000000000000000082160361268a575b60008103612680576004600083600190039350838152602001908152602001600020549050612656565b80925050506126bf565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e861274c868684612cdc565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b60606080604051019050602081016040526000815280600019835b6001156127ca578184019350600a81066030018453600a81049050806127a9575b50828203602084039350808452505050919050565b606082826040516020016127f492919061455c565b604051602081830303815290604052905092915050565b606082826040516020016128209291906145f9565b604051602081830303815290604052905092915050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000806129328561290d8861278e565b60405160200161291e92919061464a565b604051602081830303815290604052612ce5565b905083600185856129439190613e2b565b61294d9190613d86565b82612958919061469d565b6129629190613d86565b915050949350505050565b6060826129798361278e565b60405160200161298a9291906147b2565b604051602081830303815290604052905092915050565b600080549050600082036129e1576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129ee600084838561272f565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612a6583612a566000866000612735565b612a5f85612d19565b1761275d565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b818114612b0657808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050612acb565b5060008203612b41576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000819055505050612b576000848385612788565b505050565b6000612b66612571565b60005403905090565b6060612b7d82600080612d29565b9050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612baa612569565b8786866040518563ffffffff1660e01b8152600401612bcc94939291906147f7565b6020604051808303816000875af1925050508015612c0857506040513d601f19601f82011682018060405250810190612c059190614858565b60015b612c81573d8060008114612c38576040519150601f19603f3d011682016040523d82523d6000602084013e612c3d565b606091505b506000815103612c79576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b600033905090565b60009392505050565b6000612d0f82604051602001612cfb9190614885565b604051602081830303815290604052612e2a565b60001c9050919050565b60006001821460e11b9050919050565b606083518015612e22576003600282010460021b60405192507f4142434445464748494a4b4c4d4e4f505152535455565758595a616263646566601f526102308515027f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5f03603f52602083018181015b600115612def576003880197508751603f8160121c1651600053603f81600c1c1651600153603f8160061c1651600253603f8116516003536000518352600483019250818310612de95750612def565b50612d99565b601f19601f82011660405260038406600204613d3d60f01b81840352808715150290506000818403528084038652505050505b509392505050565b6000815160208301209050919050565b60405180610100016040528060008152602001600081526020016000151581526020016000815260200160006001811115612e7857612e776135f6565b5b815260200160008152602001600015158152602001612e95612e9b565b81525090565b6040518060e001604052806007905b6060815260200190600190039081612eaa5790505090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612f0b81612ed6565b8114612f1657600080fd5b50565b600081359050612f2881612f02565b92915050565b600060208284031215612f4457612f43612ecc565b5b6000612f5284828501612f19565b91505092915050565b60008115159050919050565b612f7081612f5b565b82525050565b6000602082019050612f8b6000830184612f67565b92915050565b6000819050919050565b612fa481612f91565b82525050565b6000602082019050612fbf6000830184612f9b565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612fff578082015181840152602081019050612fe4565b60008484015250505050565b6000601f19601f8301169050919050565b600061302782612fc5565b6130318185612fd0565b9350613041818560208601612fe1565b61304a8161300b565b840191505092915050565b6000602082019050818103600083015261306f818461301c565b905092915050565b61308081612f91565b811461308b57600080fd5b50565b60008135905061309d81613077565b92915050565b6000602082840312156130b9576130b8612ecc565b5b60006130c78482850161308e565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006130fb826130d0565b9050919050565b61310b816130f0565b82525050565b60006020820190506131266000830184613102565b92915050565b613135816130f0565b811461314057600080fd5b50565b6000813590506131528161312c565b92915050565b6000806040838503121561316f5761316e612ecc565b5b600061317d85828601613143565b925050602061318e8582860161308e565b9150509250929050565b6131a181612f5b565b81146131ac57600080fd5b50565b6000813590506131be81613198565b92915050565b6000602082840312156131da576131d9612ecc565b5b60006131e8848285016131af565b91505092915050565b60008060006060848603121561320a57613209612ecc565b5b600061321886828701613143565b935050602061322986828701613143565b925050604061323a8682870161308e565b9150509250925092565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6132818261300b565b810181811067ffffffffffffffff821117156132a05761329f613249565b5b80604052505050565b60006132b3612ec2565b90506132bf8282613278565b919050565b600080fd5b600281106132d657600080fd5b50565b6000813590506132e8816132c9565b92915050565b600080fd5b600067ffffffffffffffff82111561330e5761330d613249565b5b602082029050919050565b600080fd5b600080fd5b600067ffffffffffffffff82111561333e5761333d613249565b5b6133478261300b565b9050602081019050919050565b82818337600083830152505050565b600061337661337184613323565b6132a9565b9050828152602081018484840111156133925761339161331e565b5b61339d848285613354565b509392505050565b600082601f8301126133ba576133b96132ee565b5b81356133ca848260208601613363565b91505092915050565b60006133e66133e1846132f3565b6132a9565b90508060208402830185811115613400576133ff613319565b5b835b8181101561344757803567ffffffffffffffff811115613425576134246132ee565b5b80860161343289826133a5565b85526020850194505050602081019050613402565b5050509392505050565b600082601f830112613466576134656132ee565b5b60076134738482856133d3565b91505092915050565b6000610100828403121561349357613492613244565b5b61349e6101006132a9565b905060006134ae8482850161308e565b60008301525060206134c28482850161308e565b60208301525060406134d6848285016131af565b60408301525060606134ea8482850161308e565b60608301525060806134fe848285016132d9565b60808301525060a06135128482850161308e565b60a08301525060c0613526848285016131af565b60c08301525060e082013567ffffffffffffffff81111561354a576135496132c4565b5b61355684828501613451565b60e08301525092915050565b60006020828403121561357857613577612ecc565b5b600082013567ffffffffffffffff81111561359657613595612ed1565b5b6135a28482850161347c565b91505092915050565b6000602082840312156135c1576135c0612ecc565b5b60006135cf84828501613143565b91505092915050565b6135e181612f91565b82525050565b6135f081612f5b565b82525050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60028110613636576136356135f6565b5b50565b600081905061364782613625565b919050565b600061365782613639565b9050919050565b6136678161364c565b82525050565b600060079050919050565b600081905092915050565b6000819050919050565b600081519050919050565b600082825260208201905092915050565b60006136b48261368d565b6136be8185613698565b93506136ce818560208601612fe1565b6136d78161300b565b840191505092915050565b60006136ee83836136a9565b905092915050565b6000602082019050919050565b600061370e8261366d565b6137188185613678565b93508360208202850161372a85613683565b8060005b85811015613766578484038952815161374785826136e2565b9450613752836136f6565b925060208a0199505060018101905061372e565b50829750879550505050505092915050565b60006101008301600083015161379160008601826135d8565b5060208301516137a460208601826135d8565b5060408301516137b760408601826135e7565b5060608301516137ca60608601826135d8565b5060808301516137dd608086018261365e565b5060a08301516137f060a08601826135d8565b5060c083015161380360c08601826135e7565b5060e083015184820360e086015261381b8282613703565b9150508091505092915050565b600060208201905081810360008301526138428184613778565b905092915050565b6000806040838503121561386157613860612ecc565b5b600061386f85828601613143565b9250506020613880858286016131af565b9150509250929050565b600082825260208201905092915050565b60006138a68261368d565b6138b0818561388a565b93506138c0818560208601612fe1565b6138c98161300b565b840191505092915050565b600060208201905081810360008301526138ee818461389b565b905092915050565b600080600080608085870312156139105761390f612ecc565b5b600061391e87828801613143565b945050602061392f87828801613143565b93505060406139408782880161308e565b925050606085013567ffffffffffffffff81111561396157613960612ed1565b5b61396d878288016133a5565b91505092959194509250565b600080fd5b60008083601f840112613994576139936132ee565b5b8235905067ffffffffffffffff8111156139b1576139b0613979565b5b6020830191508360208202830111156139cd576139cc613319565b5b9250929050565b6000806000604084860312156139ed576139ec612ecc565b5b600084013567ffffffffffffffff811115613a0b57613a0a612ed1565b5b613a178682870161397e565b93509350506020613a2a8682870161308e565b9150509250925092565b60008060408385031215613a4b57613a4a612ecc565b5b6000613a5985828601613143565b9250506020613a6a85828601613143565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613abb57607f821691505b602082108103613ace57613acd613a74565b5b50919050565b613add81612f91565b82525050565b6000602082019050613af86000830184613ad4565b92915050565b600067ffffffffffffffff821115613b1957613b18613249565b5b613b228261300b565b9050602081019050919050565b6000613b42613b3d84613afe565b6132a9565b905082815260208101848484011115613b5e57613b5d61331e565b5b613b69848285612fe1565b509392505050565b600082601f830112613b8657613b856132ee565b5b8151613b96848260208601613b2f565b91505092915050565b600060208284031215613bb557613bb4612ecc565b5b600082015167ffffffffffffffff811115613bd357613bd2612ed1565b5b613bdf84828501613b71565b91505092915050565b7f2261747472696275746573223a205b0000000000000000000000000000000000815250565b600081905092915050565b6000613c2482612fc5565b613c2e8185613c0e565b9350613c3e818560208601612fe1565b80840191505092915050565b7f2c00000000000000000000000000000000000000000000000000000000000000815250565b7f5d00000000000000000000000000000000000000000000000000000000000000815250565b6000613ca182613be8565b600f82019150613cb18289613c19565b9150613cbc82613c4a565b600182019150613ccc8288613c19565b9150613cd782613c4a565b600182019150613ce78287613c19565b9150613cf282613c4a565b600182019150613d028286613c19565b9150613d0d82613c4a565b600182019150613d1d8285613c19565b9150613d2882613c4a565b600182019150613d388284613c19565b9150613d4382613c70565b600182019150819050979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613d9182612f91565b9150613d9c83612f91565b9250828201905080821115613db457613db3613d57565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000613df482612f91565b9150613dff83612f91565b9250828202613e0d81612f91565b91508282048414831517613e2457613e23613d57565b5b5092915050565b6000613e3682612f91565b9150613e4183612f91565b9250828203905081811115613e5957613e58613d57565b5b92915050565b600081905092915050565b50565b6000613e7a600083613e5f565b9150613e8582613e6a565b600082019050919050565b6000613e9b82613e6d565b9150819050919050565b6000613eb08261368d565b613eba8185613e5f565b9350613eca818560208601612fe1565b80840191505092915050565b6000613ee2828a613ea5565b9150613eee8289613ea5565b9150613efa8288613ea5565b9150613f068287613ea5565b9150613f128286613ea5565b9150613f1e8285613ea5565b9150613f2a8284613ea5565b915081905098975050505050505050565b6000613f4682612f91565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613f7857613f77613d57565b5b600182019050919050565b6000613f96613f9184613323565b6132a9565b905082815260208101848484011115613fb257613fb161331e565b5b613fbd848285612fe1565b509392505050565b600082601f830112613fda57613fd96132ee565b5b8151613fea848260208601613f83565b91505092915050565b60006020828403121561400957614008612ecc565b5b600082015167ffffffffffffffff81111561402757614026612ed1565b5b61403384828501613fc5565b91505092915050565b7f7b226e616d65223a220000000000000000000000000000000000000000000000600082015250565b6000614072600983613c0e565b915061407d8261403c565b600982019050919050565b7f4574686572506c616e6574202300000000000000000000000000000000000000600082015250565b60006140be600d83613c0e565b91506140c982614088565b600d82019050919050565b7f222c20226465736372697074696f6e223a220000000000000000000000000000600082015250565b600061410a601283613c0e565b9150614115826140d4565b601282019050919050565b7f46756c6c79206f6e2d636861696e2c2070726f6365647572616c6c792067656e60008201527f6572617465642c20334420706c616e6574732e00000000000000000000000000602082015250565b600061417c603383613c0e565b915061418782614120565b603382019050919050565b7f222c22696d616765223a22646174613a696d6167652f7376672b786d6c3b626160008201527f736536342c000000000000000000000000000000000000000000000000000000602082015250565b60006141ee602583613c0e565b91506141f982614192565b602582019050919050565b7f222c22616e696d6174696f6e5f75726c223a2200000000000000000000000000600082015250565b600061423a601383613c0e565b915061424582614204565b601382019050919050565b7f222c000000000000000000000000000000000000000000000000000000000000600082015250565b6000614286600283613c0e565b915061429182614250565b600282019050919050565b7f7d00000000000000000000000000000000000000000000000000000000000000600082015250565b60006142d2600183613c0e565b91506142dd8261429c565b600182019050919050565b60006142f382614065565b91506142fe826140b1565b915061430a8287613c19565b9150614315826140fd565b91506143208261416f565b915061432b826141e1565b91506143378286613c19565b91506143428261422d565b915061434e8285613ea5565b915061435982614279565b91506143658284613c19565b9150614370826142c5565b915081905095945050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e2c00000000000000000000600082015250565b60006143b4601683613c0e565b91506143bf8261437e565b601682019050919050565b60006143d5826143a7565b91506143e18284613ea5565b915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614448602683612fd0565b9150614453826143ec565b604082019050919050565b600060208201905081810360008301526144778161443b565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006144b4602083612fd0565b91506144bf8261447e565b602082019050919050565b600060208201905081810360008301526144e3816144a7565b9050919050565b7f7b2274726169745f74797065223a220000000000000000000000000000000000815250565b7f222c2276616c7565223a00000000000000000000000000000000000000000000815250565b7f7d00000000000000000000000000000000000000000000000000000000000000815250565b6000614567826144ea565b600f820191506145778285613c19565b915061458282614510565b600a820191506145928284613c19565b915061459d82614536565b6001820191508190509392505050565b7f222c2276616c7565223a22000000000000000000000000000000000000000000815250565b7f227d000000000000000000000000000000000000000000000000000000000000815250565b6000614604826144ea565b600f820191506146148285613c19565b915061461f826145ad565b600b8201915061462f8284613c19565b915061463a826145d3565b6002820191508190509392505050565b60006146568285613c19565b91506146628284613c19565b91508190509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006146a882612f91565b91506146b383612f91565b9250826146c3576146c261466e565b5b828206905092915050565b7f7661722000000000000000000000000000000000000000000000000000000000600082015250565b6000614704600483613c0e565b915061470f826146ce565b600482019050919050565b7f3d00000000000000000000000000000000000000000000000000000000000000600082015250565b6000614750600183613c0e565b915061475b8261471a565b600182019050919050565b7f3b00000000000000000000000000000000000000000000000000000000000000600082015250565b600061479c600183613c0e565b91506147a782614766565b600182019050919050565b60006147bd826146f7565b91506147c98285613ea5565b91506147d482614743565b91506147e08284613c19565b91506147eb8261478f565b91508190509392505050565b600060808201905061480c6000830187613102565b6148196020830186613102565b6148266040830185612f9b565b8181036060830152614838818461389b565b905095945050505050565b60008151905061485281612f02565b92915050565b60006020828403121561486e5761486d612ecc565b5b600061487c84828501614843565b91505092915050565b60006148918284613c19565b91508190509291505056fea264697066735822122086b5c7449e29e8de509c70ef7a3f2fac4937ae0790460649313afd14a874a0b564736f6c63430008120033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000001092000000000000000000000000000000000000000000000000000eebe0b40e800000000000000000000000000007e12f3f0bfceee2b92b68ed485e85b896761c7500000000000000000000000016ec9b5a0aef45ca3642000df11f0b2c42bdac45000000000000000000000000000000000000000000000000000000000000000c4574686572506c616e657473000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024550000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : name (string): EtherPlanets
Arg [1] : symbol (string): EP
Arg [2] : _supply (uint256): 4242
Arg [3] : _price (uint256): 4200000000000000
Arg [4] : _thumbnailAddress (address): 0x07e12F3F0bFCeEE2B92B68eD485E85B896761C75
Arg [5] : _rendererAddress (address): 0x16ec9b5a0aef45cA3642000Df11f0b2C42Bdac45
-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [2] : 0000000000000000000000000000000000000000000000000000000000001092
Arg [3] : 000000000000000000000000000000000000000000000000000eebe0b40e8000
Arg [4] : 00000000000000000000000007e12f3f0bfceee2b92b68ed485e85b896761c75
Arg [5] : 00000000000000000000000016ec9b5a0aef45ca3642000df11f0b2c42bdac45
Arg [6] : 000000000000000000000000000000000000000000000000000000000000000c
Arg [7] : 4574686572506c616e6574730000000000000000000000000000000000000000
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [9] : 4550000000000000000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.