Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- CVRT
- Optimization enabled
- true
- Compiler version
- v0.8.6+commit.11564f7e
- Optimization runs
- 200
- EVM Version
- default
- Verified at
- 2024-09-26T15:25:27.215183Z
Contract source code
// SPDX-License-Identifier: MIT // File: https://github.com/0xcert/ethereum-erc721/blob/master/src/contracts/ownership/ownable.sol pragma solidity ^0.8.0; /** * @dev The contract has an owner address, and provides basic authorization control whitch * simplifies the implementation of user permissions. This contract is based on the source code at: * https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/ownership/Ownable.sol */ contract Ownable { /** * @dev Error constants. */ string public constant NOT_CURRENT_OWNER = "018001"; string public constant CANNOT_TRANSFER_TO_ZERO_ADDRESS = "018002"; /** * @dev Current owner address. */ address public owner; /** * @dev An event which is triggered when the owner is changed. * @param previousOwner The address of the previous owner. * @param newOwner The address of the new owner. */ event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /** * @dev The constructor sets the original `owner` of the contract to the sender account. */ constructor() { owner = msg.sender; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(msg.sender == owner, NOT_CURRENT_OWNER); _; } /** * @dev Allows the current owner to transfer control of the contract to a newOwner. * @param _newOwner The address to transfer ownership to. */ function transferOwnership( address _newOwner ) public onlyOwner { require(_newOwner != address(0), CANNOT_TRANSFER_TO_ZERO_ADDRESS); emit OwnershipTransferred(owner, _newOwner); owner = _newOwner; } } // File: https://github.com/0xcert/ethereum-erc721/blob/master/src/contracts/tokens/erc721-metadata.sol pragma solidity ^0.8.0; /** * @dev Optional metadata extension for ERC-721 non-fungible token standard. * See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md. */ interface ERC721Metadata { /** * @dev Returns a descriptive name for a collection of NFTs in this contract. * @return _name Representing name. */ function name() external view returns (string memory _name); /** * @dev Returns a abbreviated name for a collection of NFTs in this contract. * @return _symbol Representing symbol. */ function symbol() external view returns (string memory _symbol); /** * @dev Returns a distinct Uniform Resource Identifier (URI) for a given asset. It Throws if * `_tokenId` is not a valid NFT. URIs are defined in RFC3986. The URI may point to a JSON file * that conforms to the "ERC721 Metadata JSON Schema". * @return URI of _tokenId. */ function tokenURI(uint256 _tokenId) external view returns (string memory); } // File: https://github.com/0xcert/ethereum-erc721/blob/master/src/contracts/utils/address-utils.sol pragma solidity ^0.8.0; /** * @notice Based on: * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol * Requires EIP-1052. * @dev Utility library of inline functions on addresses. */ library AddressUtils { /** * @dev Returns whether the target address is a contract. * @param _addr Address to check. * @return addressCheck True if _addr is a contract, false if not. */ function isContract( address _addr ) internal view returns (bool addressCheck) { // This method relies in extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; assembly { codehash := extcodehash(_addr) } // solhint-disable-line addressCheck = (codehash != 0x0 && codehash != accountHash); } } // File: https://github.com/0xcert/ethereum-erc721/blob/master/src/contracts/utils/erc165.sol pragma solidity ^0.8.0; /** * @dev A standard for detecting smart contract interfaces. * See: https://eips.ethereum.org/EIPS/eip-165. */ interface ERC165 { /** * @dev Checks if the smart contract includes a specific interface. * This function uses less than 30,000 gas. * @param _interfaceID The interface identifier, as specified in ERC-165. * @return True if _interfaceID is supported, false otherwise. */ function supportsInterface( bytes4 _interfaceID ) external view returns (bool); } // File: https://github.com/0xcert/ethereum-erc721/blob/master/src/contracts/utils/supports-interface.sol pragma solidity ^0.8.0; /** * @dev Implementation of standard for detect smart contract interfaces. */ contract SupportsInterface is ERC165 { /** * @dev Mapping of supported intefraces. You must not set element 0xffffffff to true. */ mapping(bytes4 => bool) internal supportedInterfaces; /** * @dev Contract constructor. */ constructor() { supportedInterfaces[0x01ffc9a7] = true; // ERC165 } /** * @dev Function to check which interfaces are suported by this contract. * @param _interfaceID Id of the interface. * @return True if _interfaceID is supported, false otherwise. */ function supportsInterface( bytes4 _interfaceID ) external override view returns (bool) { return supportedInterfaces[_interfaceID]; } } // File: https://github.com/0xcert/ethereum-erc721/blob/master/src/contracts/tokens/erc721-token-receiver.sol pragma solidity ^0.8.0; /** * @dev ERC-721 interface for accepting safe transfers. * See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md. */ interface ERC721TokenReceiver { /** * @notice The contract address is always the message sender. A wallet/broker/auction application * MUST implement the wallet interface if it will accept safe transfers. * @dev Handle the receipt of a NFT. The ERC721 smart contract calls this function on the * recipient after a `transfer`. This function MAY throw to revert and reject the transfer. Return * of other than the magic value MUST result in the transaction being reverted. * Returns `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` unless throwing. * @param _operator The address which called `safeTransferFrom` function. * @param _from The address which previously owned the token. * @param _tokenId The NFT identifier which is being transferred. * @param _data Additional data with no specified format. * @return Returns `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`. */ function onERC721Received( address _operator, address _from, uint256 _tokenId, bytes calldata _data ) external returns(bytes4); } // File: https://github.com/0xcert/ethereum-erc721/blob/master/src/contracts/tokens/erc721.sol pragma solidity ^0.8.0; /** * @dev ERC-721 non-fungible token standard. * See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md. */ interface ERC721 { /** * @dev Emits when ownership of any NFT changes by any mechanism. This event emits when NFTs are * created (`from` == 0) and destroyed (`to` == 0). Exception: during contract creation, any * number of NFTs may be created and assigned without emitting Transfer. At the time of any * transfer, the approved address for that NFT (if any) is reset to none. */ event Transfer( address indexed _from, address indexed _to, uint256 indexed _tokenId ); /** * @dev This emits when the approved address for an NFT is changed or reaffirmed. The zero * address indicates there is no approved address. When a Transfer event emits, this also * indicates that the approved address for that NFT (if any) is reset to none. */ event Approval( address indexed _owner, address indexed _approved, uint256 indexed _tokenId ); /** * @dev This emits when an operator is enabled or disabled for an owner. The operator can manage * all NFTs of the owner. */ event ApprovalForAll( address indexed _owner, address indexed _operator, bool _approved ); /** * @notice Throws unless `msg.sender` is the current owner, an authorized operator, or the * approved address for this NFT. Throws if `_from` is not the current owner. Throws if `_to` is * the zero address. Throws if `_tokenId` is not a valid NFT. When transfer is complete, this * function checks if `_to` is a smart contract (code size > 0). If so, it calls * `onERC721Received` on `_to` and throws if the return value is not * `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`. * @dev Transfers the ownership of an NFT from one address to another address. This function can * be changed to payable. * @param _from The current owner of the NFT. * @param _to The new owner. * @param _tokenId The NFT to transfer. * @param _data Additional data with no specified format, sent in call to `_to`. */ function safeTransferFrom( address _from, address _to, uint256 _tokenId, bytes calldata _data ) external; /** * @notice This works identically to the other function with an extra data parameter, except this * function just sets data to "" * @dev Transfers the ownership of an NFT from one address to another address. This function can * be changed to payable. * @param _from The current owner of the NFT. * @param _to The new owner. * @param _tokenId The NFT to transfer. */ function safeTransferFrom( address _from, address _to, uint256 _tokenId ) external; /** * @notice The caller is responsible to confirm that `_to` is capable of receiving NFTs or else * they may be permanently lost. * @dev Throws unless `msg.sender` is the current owner, an authorized operator, or the approved * address for this NFT. Throws if `_from` is not the current owner. Throws if `_to` is the zero * address. Throws if `_tokenId` is not a valid NFT. This function can be changed to payable. * @param _from The current owner of the NFT. * @param _to The new owner. * @param _tokenId The NFT to transfer. */ function transferFrom( address _from, address _to, uint256 _tokenId ) external; /** * @notice The zero address indicates there is no approved address. Throws unless `msg.sender` is * the current NFT owner, or an authorized operator of the current owner. * @param _approved The new approved NFT controller. * @dev Set or reaffirm the approved address for an NFT. This function can be changed to payable. * @param _tokenId The NFT to approve. */ function approve( address _approved, uint256 _tokenId ) external; /** * @notice The contract MUST allow multiple operators per owner. * @dev Enables or disables approval for a third party ("operator") to manage all of * `msg.sender`'s assets. It also emits the ApprovalForAll event. * @param _operator Address to add to the set of authorized operators. * @param _approved True if the operators is approved, false to revoke approval. */ function setApprovalForAll( address _operator, bool _approved ) external; /** * @dev Returns the number of NFTs owned by `_owner`. NFTs assigned to the zero address are * considered invalid, and this function throws for queries about the zero address. * @notice Count all NFTs assigned to an owner. * @param _owner Address for whom to query the balance. * @return Balance of _owner. */ function balanceOf( address _owner ) external view returns (uint256); /** * @notice Find the owner of an NFT. * @dev Returns the address of the owner of the NFT. NFTs assigned to the zero address are * considered invalid, and queries about them do throw. * @param _tokenId The identifier for an NFT. * @return Address of _tokenId owner. */ function ownerOf( uint256 _tokenId ) external view returns (address); /** * @notice Throws if `_tokenId` is not a valid NFT. * @dev Get the approved address for a single NFT. * @param _tokenId The NFT to find the approved address for. * @return Address that _tokenId is approved for. */ function getApproved( uint256 _tokenId ) external view returns (address); /** * @notice Query if an address is an authorized operator for another address. * @dev Returns true if `_operator` is an approved operator for `_owner`, false otherwise. * @param _owner The address that owns the NFTs. * @param _operator The address that acts on behalf of the owner. * @return True if approved for all, false otherwise. */ function isApprovedForAll( address _owner, address _operator ) external view returns (bool); } // File: https://github.com/0xcert/ethereum-erc721/blob/master/src/contracts/tokens/nf-token.sol pragma solidity ^0.8.0; /** * @dev Implementation of ERC-721 non-fungible token standard. */ contract NFToken is ERC721, SupportsInterface { using AddressUtils for address; /** * @dev List of revert message codes. Implementing dApp should handle showing the correct message. * Based on 0xcert framework error codes. */ string constant ZERO_ADDRESS = "003001"; string constant NOT_VALID_NFT = "003002"; string constant NOT_OWNER_OR_OPERATOR = "003003"; string constant NOT_OWNER_APPROVED_OR_OPERATOR = "003004"; string constant NOT_ABLE_TO_RECEIVE_NFT = "003005"; string constant NFT_ALREADY_EXISTS = "003006"; string constant NOT_OWNER = "003007"; string constant IS_OWNER = "003008"; /** * @dev Magic value of a smart contract that can receive NFT. * Equal to: bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")). */ bytes4 internal constant MAGIC_ON_ERC721_RECEIVED = 0x150b7a02; /** * @dev A mapping from NFT ID to the address that owns it. */ mapping (uint256 => address) internal idToOwner; /** * @dev Mapping from NFT ID to approved address. */ mapping (uint256 => address) internal idToApproval; /** * @dev Mapping from owner address to count of their tokens. */ mapping (address => uint256) private ownerToNFTokenCount; /** * @dev Mapping from owner address to mapping of operator addresses. */ mapping (address => mapping (address => bool)) internal ownerToOperators; /** * @dev Guarantees that the msg.sender is an owner or operator of the given NFT. * @param _tokenId ID of the NFT to validate. */ modifier canOperate( uint256 _tokenId ) { address tokenOwner = idToOwner[_tokenId]; require( tokenOwner == msg.sender || ownerToOperators[tokenOwner][msg.sender], NOT_OWNER_OR_OPERATOR ); _; } /** * @dev Guarantees that the msg.sender is allowed to transfer NFT. * @param _tokenId ID of the NFT to transfer. */ modifier canTransfer( uint256 _tokenId ) { address tokenOwner = idToOwner[_tokenId]; require( tokenOwner == msg.sender || idToApproval[_tokenId] == msg.sender || ownerToOperators[tokenOwner][msg.sender], NOT_OWNER_APPROVED_OR_OPERATOR ); _; } /** * @dev Guarantees that _tokenId is a valid Token. * @param _tokenId ID of the NFT to validate. */ modifier validNFToken( uint256 _tokenId ) { require(idToOwner[_tokenId] != address(0), NOT_VALID_NFT); _; } /** * @dev Contract constructor. */ constructor() { supportedInterfaces[0x80ac58cd] = true; // ERC721 } /** * @notice Throws unless `msg.sender` is the current owner, an authorized operator, or the * approved address for this NFT. Throws if `_from` is not the current owner. Throws if `_to` is * the zero address. Throws if `_tokenId` is not a valid NFT. When transfer is complete, this * function checks if `_to` is a smart contract (code size > 0). If so, it calls * `onERC721Received` on `_to` and throws if the return value is not * `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`. * @dev Transfers the ownership of an NFT from one address to another address. This function can * be changed to payable. * @param _from The current owner of the NFT. * @param _to The new owner. * @param _tokenId The NFT to transfer. * @param _data Additional data with no specified format, sent in call to `_to`. */ function safeTransferFrom( address _from, address _to, uint256 _tokenId, bytes calldata _data ) external override { _safeTransferFrom(_from, _to, _tokenId, _data); } /** * @notice This works identically to the other function with an extra data parameter, except this * function just sets data to "". * @dev Transfers the ownership of an NFT from one address to another address. This function can * be changed to payable. * @param _from The current owner of the NFT. * @param _to The new owner. * @param _tokenId The NFT to transfer. */ function safeTransferFrom( address _from, address _to, uint256 _tokenId ) external override { _safeTransferFrom(_from, _to, _tokenId, ""); } /** * @notice The caller is responsible to confirm that `_to` is capable of receiving NFTs or else * they may be permanently lost. * @dev Throws unless `msg.sender` is the current owner, an authorized operator, or the approved * address for this NFT. Throws if `_from` is not the current owner. Throws if `_to` is the zero * address. Throws if `_tokenId` is not a valid NFT. This function can be changed to payable. * @param _from The current owner of the NFT. * @param _to The new owner. * @param _tokenId The NFT to transfer. */ function transferFrom( address _from, address _to, uint256 _tokenId ) external override canTransfer(_tokenId) validNFToken(_tokenId) { address tokenOwner = idToOwner[_tokenId]; require(tokenOwner == _from, NOT_OWNER); require(_to != address(0), ZERO_ADDRESS); _transfer(_to, _tokenId); } /** * @notice The zero address indicates there is no approved address. Throws unless `msg.sender` is * the current NFT owner, or an authorized operator of the current owner. * @dev Set or reaffirm the approved address for an NFT. This function can be changed to payable. * @param _approved Address to be approved for the given NFT ID. * @param _tokenId ID of the token to be approved. */ function approve( address _approved, uint256 _tokenId ) external override canOperate(_tokenId) validNFToken(_tokenId) { address tokenOwner = idToOwner[_tokenId]; require(_approved != tokenOwner, IS_OWNER); idToApproval[_tokenId] = _approved; emit Approval(tokenOwner, _approved, _tokenId); } /** * @notice This works even if sender doesn't own any tokens at the time. * @dev Enables or disables approval for a third party ("operator") to manage all of * `msg.sender`'s assets. It also emits the ApprovalForAll event. * @param _operator Address to add to the set of authorized operators. * @param _approved True if the operators is approved, false to revoke approval. */ function setApprovalForAll( address _operator, bool _approved ) external override { ownerToOperators[msg.sender][_operator] = _approved; emit ApprovalForAll(msg.sender, _operator, _approved); } /** * @dev Returns the number of NFTs owned by `_owner`. NFTs assigned to the zero address are * considered invalid, and this function throws for queries about the zero address. * @param _owner Address for whom to query the balance. * @return Balance of _owner. */ function balanceOf( address _owner ) external override view returns (uint256) { require(_owner != address(0), ZERO_ADDRESS); return _getOwnerNFTCount(_owner); } /** * @dev Returns the address of the owner of the NFT. NFTs assigned to the zero address are * considered invalid, and queries about them do throw. * @param _tokenId The identifier for an NFT. * @return _owner Address of _tokenId owner. */ function ownerOf( uint256 _tokenId ) external override view returns (address _owner) { _owner = idToOwner[_tokenId]; require(_owner != address(0), NOT_VALID_NFT); } /** * @notice Throws if `_tokenId` is not a valid NFT. * @dev Get the approved address for a single NFT. * @param _tokenId ID of the NFT to query the approval of. * @return Address that _tokenId is approved for. */ function getApproved( uint256 _tokenId ) external override view validNFToken(_tokenId) returns (address) { return idToApproval[_tokenId]; } /** * @dev Checks if `_operator` is an approved operator for `_owner`. * @param _owner The address that owns the NFTs. * @param _operator The address that acts on behalf of the owner. * @return True if approved for all, false otherwise. */ function isApprovedForAll( address _owner, address _operator ) external override view returns (bool) { return ownerToOperators[_owner][_operator]; } /** * @notice Does NO checks. * @dev Actually performs the transfer. * @param _to Address of a new owner. * @param _tokenId The NFT that is being transferred. */ function _transfer( address _to, uint256 _tokenId ) internal virtual { address from = idToOwner[_tokenId]; _clearApproval(_tokenId); _removeNFToken(from, _tokenId); _addNFToken(_to, _tokenId); emit Transfer(from, _to, _tokenId); } /** * @notice This is an internal function which should be called from user-implemented external * mint function. Its purpose is to show and properly initialize data structures when using this * implementation. * @dev Mints a new NFT. * @param _to The address that will own the minted NFT. * @param _tokenId of the NFT to be minted by the msg.sender. */ function _mint( address _to, uint256 _tokenId ) internal virtual { require(_to != address(0), ZERO_ADDRESS); require(idToOwner[_tokenId] == address(0), NFT_ALREADY_EXISTS); _addNFToken(_to, _tokenId); emit Transfer(address(0), _to, _tokenId); } /** * @notice This is an internal function which should be called from user-implemented external burn * function. Its purpose is to show and properly initialize data structures when using this * implementation. Also, note that this burn implementation allows the minter to re-mint a burned * NFT. * @dev Burns a NFT. * @param _tokenId ID of the NFT to be burned. */ function _burn( uint256 _tokenId ) internal virtual validNFToken(_tokenId) { address tokenOwner = idToOwner[_tokenId]; _clearApproval(_tokenId); _removeNFToken(tokenOwner, _tokenId); emit Transfer(tokenOwner, address(0), _tokenId); } /** * @notice Use and override this function with caution. Wrong usage can have serious consequences. * @dev Removes a NFT from owner. * @param _from Address from which we want to remove the NFT. * @param _tokenId Which NFT we want to remove. */ function _removeNFToken( address _from, uint256 _tokenId ) internal virtual { require(idToOwner[_tokenId] == _from, NOT_OWNER); ownerToNFTokenCount[_from] -= 1; delete idToOwner[_tokenId]; } /** * @notice Use and override this function with caution. Wrong usage can have serious consequences. * @dev Assigns a new NFT to owner. * @param _to Address to which we want to add the NFT. * @param _tokenId Which NFT we want to add. */ function _addNFToken( address _to, uint256 _tokenId ) internal virtual { require(idToOwner[_tokenId] == address(0), NFT_ALREADY_EXISTS); idToOwner[_tokenId] = _to; ownerToNFTokenCount[_to] += 1; } /** * @dev Helper function that gets NFT count of owner. This is needed for overriding in enumerable * extension to remove double storage (gas optimization) of owner NFT count. * @param _owner Address for whom to query the count. * @return Number of _owner NFTs. */ function _getOwnerNFTCount( address _owner ) internal virtual view returns (uint256) { return ownerToNFTokenCount[_owner]; } /** * @dev Actually perform the safeTransferFrom. * @param _from The current owner of the NFT. * @param _to The new owner. * @param _tokenId The NFT to transfer. * @param _data Additional data with no specified format, sent in call to `_to`. */ function _safeTransferFrom( address _from, address _to, uint256 _tokenId, bytes memory _data ) private canTransfer(_tokenId) validNFToken(_tokenId) { address tokenOwner = idToOwner[_tokenId]; require(tokenOwner == _from, NOT_OWNER); require(_to != address(0), ZERO_ADDRESS); _transfer(_to, _tokenId); if (_to.isContract()) { bytes4 retval = ERC721TokenReceiver(_to).onERC721Received(msg.sender, _from, _tokenId, _data); require(retval == MAGIC_ON_ERC721_RECEIVED, NOT_ABLE_TO_RECEIVE_NFT); } } /** * @dev Clears the current approval of a given NFT ID. * @param _tokenId ID of the NFT to be transferred. */ function _clearApproval( uint256 _tokenId ) private { delete idToApproval[_tokenId]; } } // File: https://github.com/0xcert/ethereum-erc721/blob/master/src/contracts/tokens/nf-token-metadata.sol pragma solidity ^0.8.0; /** * @dev Optional metadata implementation for ERC-721 non-fungible token standard. */ contract NFTokenMetadata is NFToken, ERC721Metadata { /** * @dev A descriptive name for a collection of NFTs. */ string internal nftName; /** * @dev An abbreviated name for NFTokens. */ string internal nftSymbol; /** * @dev Mapping from NFT ID to metadata uri. */ mapping (uint256 => string) internal idToUri; /** * @notice When implementing this contract don't forget to set nftName and nftSymbol. * @dev Contract constructor. */ constructor() { supportedInterfaces[0x5b5e139f] = true; // ERC721Metadata } /** * @dev Returns a descriptive name for a collection of NFTokens. * @return _name Representing name. */ function name() external override view returns (string memory _name) { _name = nftName; } /** * @dev Returns an abbreviated name for NFTokens. * @return _symbol Representing symbol. */ function symbol() external override view returns (string memory _symbol) { _symbol = nftSymbol; } /** * @dev A distinct URI (RFC 3986) for a given NFT. * @param _tokenId Id for which we want uri. * @return URI of _tokenId. */ function tokenURI( uint256 _tokenId ) external override view validNFToken(_tokenId) returns (string memory) { return _tokenURI(_tokenId); } /** * @notice This is an internal function that can be overriden if you want to implement a different * way to generate token URI. * @param _tokenId Id for which we want uri. * @return URI of _tokenId. */ function _tokenURI( uint256 _tokenId ) internal virtual view returns (string memory) { return idToUri[_tokenId]; } /** * @notice This is an internal function which should be called from user-implemented external * burn function. Its purpose is to show and properly initialize data structures when using this * implementation. Also, note that this burn implementation allows the minter to re-mint a burned * NFT. * @dev Burns a NFT. * @param _tokenId ID of the NFT to be burned. */ function _burn( uint256 _tokenId ) internal override virtual { super._burn(_tokenId); delete idToUri[_tokenId]; } /** * @notice This is an internal function which should be called from user-implemented external * function. Its purpose is to show and properly initialize data structures when using this * implementation. * @dev Set a distinct URI (RFC 3986) for a given NFT ID. * @param _tokenId Id for which we want URI. * @param _uri String representing RFC 3986 URI. */ function _setTokenUri( uint256 _tokenId, string memory _uri ) internal validNFToken(_tokenId) { idToUri[_tokenId] = _uri; } } // File: mynft.sol pragma solidity 0.8.6; contract CVRT is NFTokenMetadata, Ownable { constructor() { nftName = "CryptoVIR NFT Test"; nftSymbol = "CVRT"; } function mint(address _to, uint256 _tokenId, string calldata _uri) external onlyOwner { super._mint(_to, _tokenId); super._setTokenUri(_tokenId, _uri); } }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[]},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"_owner","internalType":"address","indexed":true},{"type":"address","name":"_approved","internalType":"address","indexed":true},{"type":"uint256","name":"_tokenId","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"ApprovalForAll","inputs":[{"type":"address","name":"_owner","internalType":"address","indexed":true},{"type":"address","name":"_operator","internalType":"address","indexed":true},{"type":"bool","name":"_approved","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"_from","internalType":"address","indexed":true},{"type":"address","name":"_to","internalType":"address","indexed":true},{"type":"uint256","name":"_tokenId","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"CANNOT_TRANSFER_TO_ZERO_ADDRESS","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"NOT_CURRENT_OWNER","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"approve","inputs":[{"type":"address","name":"_approved","internalType":"address"},{"type":"uint256","name":"_tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"_owner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"getApproved","inputs":[{"type":"uint256","name":"_tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isApprovedForAll","inputs":[{"type":"address","name":"_owner","internalType":"address"},{"type":"address","name":"_operator","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"mint","inputs":[{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"_tokenId","internalType":"uint256"},{"type":"string","name":"_uri","internalType":"string"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"_name","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"_owner","internalType":"address"}],"name":"ownerOf","inputs":[{"type":"uint256","name":"_tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"safeTransferFrom","inputs":[{"type":"address","name":"_from","internalType":"address"},{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"_tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"safeTransferFrom","inputs":[{"type":"address","name":"_from","internalType":"address"},{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"_tokenId","internalType":"uint256"},{"type":"bytes","name":"_data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setApprovalForAll","inputs":[{"type":"address","name":"_operator","internalType":"address"},{"type":"bool","name":"_approved","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"supportsInterface","inputs":[{"type":"bytes4","name":"_interfaceID","internalType":"bytes4"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"_symbol","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"tokenURI","inputs":[{"type":"uint256","name":"_tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferFrom","inputs":[{"type":"address","name":"_from","internalType":"address"},{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"_tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"_newOwner","internalType":"address"}]}]
Contract Creation Code
0x60806040523480156200001157600080fd5b50600060208181527f67be87c3ff9960ca1e9cfac5cab2ff4747269cf9ed20c9b7306235ac35a491c5805460ff1990811660019081179092557ff7815fccbf112960a73756e185887fedcb9fc64ca0a16cc5923b7960ed7808008054821683179055635b5e139f60e01b9093527f9562381dfbc2d8b8b66e765249f330164b73e329e5f01670660643571d1974df805490931617909155600880546001600160a01b031916331790556040805180820190915260128082527110dc9e5c1d1bd59254881391950815195cdd60721b91909201908152620000f591600591906200012a565b506040805180820190915260048082526310d5949560e21b602090920191825262000123916006916200012a565b506200020d565b8280546200013890620001d0565b90600052602060002090601f0160209004810192826200015c5760008555620001a7565b82601f106200017757805160ff1916838001178555620001a7565b82800160010185558215620001a7579182015b82811115620001a75782518255916020019190600101906200018a565b50620001b5929150620001b9565b5090565b5b80821115620001b55760008155600101620001ba565b600181811c90821680620001e557607f821691505b602082108114156200020757634e487b7160e01b600052602260045260246000fd5b50919050565b611642806200021d6000396000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638da5cb5b116100a2578063c87b56dd11610071578063c87b56dd14610272578063d3fc986414610285578063e985e9c514610298578063f2fde38b146102d4578063f3fe3bc3146102e757600080fd5b80638da5cb5b1461023157806395d89b4114610244578063a22cb4651461024c578063b88d4fde1461025f57600080fd5b806323b872dd116100e957806323b872dd146101b257806342842e0e146101c55780636352211e146101d857806370a08231146101eb578063860d248a1461020c57600080fd5b806301ffc9a71461011b57806306fdde031461015d578063081812fc14610172578063095ea7b31461019d575b600080fd5b610148610129366004611489565b6001600160e01b03191660009081526020819052604090205460ff1690565b60405190151581526020015b60405180910390f35b61016561030c565b6040516101549190611566565b6101856101803660046114c3565b61039e565b6040516001600160a01b039091168152602001610154565b6101b06101ab366004611405565b610420565b005b6101b06101c036600461131e565b6105c2565b6101b06101d336600461131e565b61077d565b6101856101e63660046114c3565b61079d565b6101fe6101f93660046112d0565b6107f5565b604051908152602001610154565b6101656040518060400160405280600681526020016518189c18181960d11b81525081565b600854610185906001600160a01b031681565b610165610859565b6101b061025a3660046113c9565b610868565b6101b061026d36600461135a565b6108d4565b6101656102803660046114c3565b61091d565b6101b061029336600461142f565b610989565b6101486102a63660046112eb565b6001600160a01b03918216600090815260046020908152604080832093909416825291909152205460ff1690565b6101b06102e23660046112d0565b610a23565b6101656040518060400160405280600681526020016530313830303160d01b81525081565b60606005805461031b906115a8565b80601f0160208091040260200160405190810160405280929190818152602001828054610347906115a8565b80156103945780601f1061036957610100808354040283529160200191610394565b820191906000526020600020905b81548152906001019060200180831161037757829003601f168201915b5050505050905090565b6000818152600160209081526040808320548151808301909252600682526518181998181960d11b9282019290925283916001600160a01b03166103fe5760405162461bcd60e51b81526004016103f59190611566565b60405180910390fd5b506000838152600260205260409020546001600160a01b031691505b50919050565b60008181526001602052604090205481906001600160a01b03163381148061046b57506001600160a01b038116600090815260046020908152604080832033845290915290205460ff165b6040518060400160405280600681526020016530303330303360d01b815250906104a85760405162461bcd60e51b81526004016103f59190611566565b50600083815260016020908152604091829020548251808401909352600683526518181998181960d11b918301919091528491906001600160a01b03166105025760405162461bcd60e51b81526004016103f59190611566565b50600084815260016020908152604091829020548251808401909352600683526506060666060760d31b918301919091526001600160a01b03908116919087168214156105625760405162461bcd60e51b81526004016103f59190611566565b5060008581526002602052604080822080546001600160a01b0319166001600160a01b038a811691821790925591518893918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050505050565b60008181526001602052604090205481906001600160a01b03163381148061060057506000828152600260205260409020546001600160a01b031633145b8061062e57506001600160a01b038116600090815260046020908152604080832033845290915290205460ff165b604051806040016040528060068152602001650c0c0ccc0c0d60d21b8152509061066b5760405162461bcd60e51b81526004016103f59190611566565b50600083815260016020908152604091829020548251808401909352600683526518181998181960d11b918301919091528491906001600160a01b03166106c55760405162461bcd60e51b81526004016103f59190611566565b50600084815260016020908152604091829020548251808401909352600683526530303330303760d01b918301919091526001600160a01b039081169190881682146107245760405162461bcd60e51b81526004016103f59190611566565b5060408051808201909152600681526530303330303160d01b60208201526001600160a01b0387166107695760405162461bcd60e51b81526004016103f59190611566565b506107748686610b0e565b50505050505050565b61079883838360405180602001604052806000815250610b99565b505050565b600081815260016020908152604091829020548251808401909352600683526518181998181960d11b918301919091526001600160a01b0316908161041a5760405162461bcd60e51b81526004016103f59190611566565b60408051808201909152600681526530303330303160d01b60208201526000906001600160a01b03831661083c5760405162461bcd60e51b81526004016103f59190611566565b50506001600160a01b031660009081526003602052604090205490565b60606006805461031b906115a8565b3360008181526004602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b61091685858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610b9992505050565b5050505050565b600081815260016020908152604091829020548251808401909352600683526518181998181960d11b9183019190915260609183916001600160a01b03166109785760405162461bcd60e51b81526004016103f59190611566565b5061098283610e47565b9392505050565b60085460408051808201909152600681526530313830303160d01b6020820152906001600160a01b031633146109d25760405162461bcd60e51b81526004016103f59190611566565b506109dd8484610ee9565b610a1d8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610fcc92505050565b50505050565b60085460408051808201909152600681526530313830303160d01b6020820152906001600160a01b03163314610a6c5760405162461bcd60e51b81526004016103f59190611566565b5060408051808201909152600681526518189c18181960d11b60208201526001600160a01b038216610ab15760405162461bcd60e51b81526004016103f59190611566565b506008546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600880546001600160a01b0319166001600160a01b0392909216919091179055565b600081815260016020908152604080832054600290925290912080546001600160a01b03191690556001600160a01b0316610b498183611045565b610b5383836110ee565b81836001600160a01b0316826001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60008281526001602052604090205482906001600160a01b031633811480610bd757506000828152600260205260409020546001600160a01b031633145b80610c0557506001600160a01b038116600090815260046020908152604080832033845290915290205460ff165b604051806040016040528060068152602001650c0c0ccc0c0d60d21b81525090610c425760405162461bcd60e51b81526004016103f59190611566565b50600084815260016020908152604091829020548251808401909352600683526518181998181960d11b918301919091528591906001600160a01b0316610c9c5760405162461bcd60e51b81526004016103f59190611566565b50600085815260016020908152604091829020548251808401909352600683526530303330303760d01b918301919091526001600160a01b03908116919089168214610cfb5760405162461bcd60e51b81526004016103f59190611566565b5060408051808201909152600681526530303330303160d01b60208201526001600160a01b038816610d405760405162461bcd60e51b81526004016103f59190611566565b50610d4b8787610b0e565b610d5d876001600160a01b0316611196565b15610e3d57604051630a85bd0160e11b81526000906001600160a01b0389169063150b7a0290610d979033908d908c908c90600401611529565b602060405180830381600087803b158015610db157600080fd5b505af1158015610dc5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610de991906114a6565b60408051808201909152600681526530303330303560d01b60208201529091506001600160e01b03198216630a85bd0160e11b14610e3a5760405162461bcd60e51b81526004016103f59190611566565b50505b5050505050505050565b6000818152600760205260409020805460609190610e64906115a8565b80601f0160208091040260200160405190810160405280929190818152602001828054610e90906115a8565b8015610edd5780601f10610eb257610100808354040283529160200191610edd565b820191906000526020600020905b815481529060010190602001808311610ec057829003601f168201915b50505050509050919050565b60408051808201909152600681526530303330303160d01b60208201526001600160a01b038316610f2d5760405162461bcd60e51b81526004016103f59190611566565b50600081815260016020908152604091829020548251808401909352600683526518181998181b60d11b918301919091526001600160a01b031615610f855760405162461bcd60e51b81526004016103f59190611566565b50610f9082826110ee565b60405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600082815260016020908152604091829020548251808401909352600683526518181998181960d11b918301919091528391906001600160a01b03166110255760405162461bcd60e51b81526004016103f59190611566565b5060008381526007602090815260409091208351610a1d928501906111d2565b600081815260016020908152604091829020548251808401909352600683526530303330303760d01b918301919091526001600160a01b038481169116146110a05760405162461bcd60e51b81526004016103f59190611566565b506001600160a01b03821660009081526003602052604081208054600192906110ca908490611591565b9091555050600090815260016020526040902080546001600160a01b031916905550565b600081815260016020908152604091829020548251808401909352600683526518181998181b60d11b918301919091526001600160a01b0316156111455760405162461bcd60e51b81526004016103f59190611566565b50600081815260016020818152604080842080546001600160a01b0319166001600160a01b03881690811790915584526003909152822080549192909161118d908490611579565b90915550505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081158015906111ca5750808214155b949350505050565b8280546111de906115a8565b90600052602060002090601f0160209004810192826112005760008555611246565b82601f1061121957805160ff1916838001178555611246565b82800160010185558215611246579182015b8281111561124657825182559160200191906001019061122b565b50611252929150611256565b5090565b5b808211156112525760008155600101611257565b80356001600160a01b038116811461128257600080fd5b919050565b60008083601f84011261129957600080fd5b50813567ffffffffffffffff8111156112b157600080fd5b6020830191508360208285010111156112c957600080fd5b9250929050565b6000602082840312156112e257600080fd5b6109828261126b565b600080604083850312156112fe57600080fd5b6113078361126b565b91506113156020840161126b565b90509250929050565b60008060006060848603121561133357600080fd5b61133c8461126b565b925061134a6020850161126b565b9150604084013590509250925092565b60008060008060006080868803121561137257600080fd5b61137b8661126b565b94506113896020870161126b565b935060408601359250606086013567ffffffffffffffff8111156113ac57600080fd5b6113b888828901611287565b969995985093965092949392505050565b600080604083850312156113dc57600080fd5b6113e58361126b565b9150602083013580151581146113fa57600080fd5b809150509250929050565b6000806040838503121561141857600080fd5b6114218361126b565b946020939093013593505050565b6000806000806060858703121561144557600080fd5b61144e8561126b565b935060208501359250604085013567ffffffffffffffff81111561147157600080fd5b61147d87828801611287565b95989497509550505050565b60006020828403121561149b57600080fd5b8135610982816115f3565b6000602082840312156114b857600080fd5b8151610982816115f3565b6000602082840312156114d557600080fd5b5035919050565b6000815180845260005b81811015611502576020818501810151868301820152016114e6565b81811115611514576000602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061155c908301846114dc565b9695505050505050565b60208152600061098260208301846114dc565b6000821982111561158c5761158c6115dd565b500190565b6000828210156115a3576115a36115dd565b500390565b600181811c908216806115bc57607f821691505b6020821081141561041a57634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6001600160e01b03198116811461160957600080fd5b5056fea264697066735822122025c5903da72830614e39ee33291c4a30d358c4296e104e85250abea634a662a764736f6c63430008060033
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638da5cb5b116100a2578063c87b56dd11610071578063c87b56dd14610272578063d3fc986414610285578063e985e9c514610298578063f2fde38b146102d4578063f3fe3bc3146102e757600080fd5b80638da5cb5b1461023157806395d89b4114610244578063a22cb4651461024c578063b88d4fde1461025f57600080fd5b806323b872dd116100e957806323b872dd146101b257806342842e0e146101c55780636352211e146101d857806370a08231146101eb578063860d248a1461020c57600080fd5b806301ffc9a71461011b57806306fdde031461015d578063081812fc14610172578063095ea7b31461019d575b600080fd5b610148610129366004611489565b6001600160e01b03191660009081526020819052604090205460ff1690565b60405190151581526020015b60405180910390f35b61016561030c565b6040516101549190611566565b6101856101803660046114c3565b61039e565b6040516001600160a01b039091168152602001610154565b6101b06101ab366004611405565b610420565b005b6101b06101c036600461131e565b6105c2565b6101b06101d336600461131e565b61077d565b6101856101e63660046114c3565b61079d565b6101fe6101f93660046112d0565b6107f5565b604051908152602001610154565b6101656040518060400160405280600681526020016518189c18181960d11b81525081565b600854610185906001600160a01b031681565b610165610859565b6101b061025a3660046113c9565b610868565b6101b061026d36600461135a565b6108d4565b6101656102803660046114c3565b61091d565b6101b061029336600461142f565b610989565b6101486102a63660046112eb565b6001600160a01b03918216600090815260046020908152604080832093909416825291909152205460ff1690565b6101b06102e23660046112d0565b610a23565b6101656040518060400160405280600681526020016530313830303160d01b81525081565b60606005805461031b906115a8565b80601f0160208091040260200160405190810160405280929190818152602001828054610347906115a8565b80156103945780601f1061036957610100808354040283529160200191610394565b820191906000526020600020905b81548152906001019060200180831161037757829003601f168201915b5050505050905090565b6000818152600160209081526040808320548151808301909252600682526518181998181960d11b9282019290925283916001600160a01b03166103fe5760405162461bcd60e51b81526004016103f59190611566565b60405180910390fd5b506000838152600260205260409020546001600160a01b031691505b50919050565b60008181526001602052604090205481906001600160a01b03163381148061046b57506001600160a01b038116600090815260046020908152604080832033845290915290205460ff165b6040518060400160405280600681526020016530303330303360d01b815250906104a85760405162461bcd60e51b81526004016103f59190611566565b50600083815260016020908152604091829020548251808401909352600683526518181998181960d11b918301919091528491906001600160a01b03166105025760405162461bcd60e51b81526004016103f59190611566565b50600084815260016020908152604091829020548251808401909352600683526506060666060760d31b918301919091526001600160a01b03908116919087168214156105625760405162461bcd60e51b81526004016103f59190611566565b5060008581526002602052604080822080546001600160a01b0319166001600160a01b038a811691821790925591518893918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050505050565b60008181526001602052604090205481906001600160a01b03163381148061060057506000828152600260205260409020546001600160a01b031633145b8061062e57506001600160a01b038116600090815260046020908152604080832033845290915290205460ff165b604051806040016040528060068152602001650c0c0ccc0c0d60d21b8152509061066b5760405162461bcd60e51b81526004016103f59190611566565b50600083815260016020908152604091829020548251808401909352600683526518181998181960d11b918301919091528491906001600160a01b03166106c55760405162461bcd60e51b81526004016103f59190611566565b50600084815260016020908152604091829020548251808401909352600683526530303330303760d01b918301919091526001600160a01b039081169190881682146107245760405162461bcd60e51b81526004016103f59190611566565b5060408051808201909152600681526530303330303160d01b60208201526001600160a01b0387166107695760405162461bcd60e51b81526004016103f59190611566565b506107748686610b0e565b50505050505050565b61079883838360405180602001604052806000815250610b99565b505050565b600081815260016020908152604091829020548251808401909352600683526518181998181960d11b918301919091526001600160a01b0316908161041a5760405162461bcd60e51b81526004016103f59190611566565b60408051808201909152600681526530303330303160d01b60208201526000906001600160a01b03831661083c5760405162461bcd60e51b81526004016103f59190611566565b50506001600160a01b031660009081526003602052604090205490565b60606006805461031b906115a8565b3360008181526004602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b61091685858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610b9992505050565b5050505050565b600081815260016020908152604091829020548251808401909352600683526518181998181960d11b9183019190915260609183916001600160a01b03166109785760405162461bcd60e51b81526004016103f59190611566565b5061098283610e47565b9392505050565b60085460408051808201909152600681526530313830303160d01b6020820152906001600160a01b031633146109d25760405162461bcd60e51b81526004016103f59190611566565b506109dd8484610ee9565b610a1d8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610fcc92505050565b50505050565b60085460408051808201909152600681526530313830303160d01b6020820152906001600160a01b03163314610a6c5760405162461bcd60e51b81526004016103f59190611566565b5060408051808201909152600681526518189c18181960d11b60208201526001600160a01b038216610ab15760405162461bcd60e51b81526004016103f59190611566565b506008546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600880546001600160a01b0319166001600160a01b0392909216919091179055565b600081815260016020908152604080832054600290925290912080546001600160a01b03191690556001600160a01b0316610b498183611045565b610b5383836110ee565b81836001600160a01b0316826001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60008281526001602052604090205482906001600160a01b031633811480610bd757506000828152600260205260409020546001600160a01b031633145b80610c0557506001600160a01b038116600090815260046020908152604080832033845290915290205460ff165b604051806040016040528060068152602001650c0c0ccc0c0d60d21b81525090610c425760405162461bcd60e51b81526004016103f59190611566565b50600084815260016020908152604091829020548251808401909352600683526518181998181960d11b918301919091528591906001600160a01b0316610c9c5760405162461bcd60e51b81526004016103f59190611566565b50600085815260016020908152604091829020548251808401909352600683526530303330303760d01b918301919091526001600160a01b03908116919089168214610cfb5760405162461bcd60e51b81526004016103f59190611566565b5060408051808201909152600681526530303330303160d01b60208201526001600160a01b038816610d405760405162461bcd60e51b81526004016103f59190611566565b50610d4b8787610b0e565b610d5d876001600160a01b0316611196565b15610e3d57604051630a85bd0160e11b81526000906001600160a01b0389169063150b7a0290610d979033908d908c908c90600401611529565b602060405180830381600087803b158015610db157600080fd5b505af1158015610dc5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610de991906114a6565b60408051808201909152600681526530303330303560d01b60208201529091506001600160e01b03198216630a85bd0160e11b14610e3a5760405162461bcd60e51b81526004016103f59190611566565b50505b5050505050505050565b6000818152600760205260409020805460609190610e64906115a8565b80601f0160208091040260200160405190810160405280929190818152602001828054610e90906115a8565b8015610edd5780601f10610eb257610100808354040283529160200191610edd565b820191906000526020600020905b815481529060010190602001808311610ec057829003601f168201915b50505050509050919050565b60408051808201909152600681526530303330303160d01b60208201526001600160a01b038316610f2d5760405162461bcd60e51b81526004016103f59190611566565b50600081815260016020908152604091829020548251808401909352600683526518181998181b60d11b918301919091526001600160a01b031615610f855760405162461bcd60e51b81526004016103f59190611566565b50610f9082826110ee565b60405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600082815260016020908152604091829020548251808401909352600683526518181998181960d11b918301919091528391906001600160a01b03166110255760405162461bcd60e51b81526004016103f59190611566565b5060008381526007602090815260409091208351610a1d928501906111d2565b600081815260016020908152604091829020548251808401909352600683526530303330303760d01b918301919091526001600160a01b038481169116146110a05760405162461bcd60e51b81526004016103f59190611566565b506001600160a01b03821660009081526003602052604081208054600192906110ca908490611591565b9091555050600090815260016020526040902080546001600160a01b031916905550565b600081815260016020908152604091829020548251808401909352600683526518181998181b60d11b918301919091526001600160a01b0316156111455760405162461bcd60e51b81526004016103f59190611566565b50600081815260016020818152604080842080546001600160a01b0319166001600160a01b03881690811790915584526003909152822080549192909161118d908490611579565b90915550505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081158015906111ca5750808214155b949350505050565b8280546111de906115a8565b90600052602060002090601f0160209004810192826112005760008555611246565b82601f1061121957805160ff1916838001178555611246565b82800160010185558215611246579182015b8281111561124657825182559160200191906001019061122b565b50611252929150611256565b5090565b5b808211156112525760008155600101611257565b80356001600160a01b038116811461128257600080fd5b919050565b60008083601f84011261129957600080fd5b50813567ffffffffffffffff8111156112b157600080fd5b6020830191508360208285010111156112c957600080fd5b9250929050565b6000602082840312156112e257600080fd5b6109828261126b565b600080604083850312156112fe57600080fd5b6113078361126b565b91506113156020840161126b565b90509250929050565b60008060006060848603121561133357600080fd5b61133c8461126b565b925061134a6020850161126b565b9150604084013590509250925092565b60008060008060006080868803121561137257600080fd5b61137b8661126b565b94506113896020870161126b565b935060408601359250606086013567ffffffffffffffff8111156113ac57600080fd5b6113b888828901611287565b969995985093965092949392505050565b600080604083850312156113dc57600080fd5b6113e58361126b565b9150602083013580151581146113fa57600080fd5b809150509250929050565b6000806040838503121561141857600080fd5b6114218361126b565b946020939093013593505050565b6000806000806060858703121561144557600080fd5b61144e8561126b565b935060208501359250604085013567ffffffffffffffff81111561147157600080fd5b61147d87828801611287565b95989497509550505050565b60006020828403121561149b57600080fd5b8135610982816115f3565b6000602082840312156114b857600080fd5b8151610982816115f3565b6000602082840312156114d557600080fd5b5035919050565b6000815180845260005b81811015611502576020818501810151868301820152016114e6565b81811115611514576000602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061155c908301846114dc565b9695505050505050565b60208152600061098260208301846114dc565b6000821982111561158c5761158c6115dd565b500190565b6000828210156115a3576115a36115dd565b500390565b600181811c908216806115bc57607f821691505b6020821081141561041a57634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6001600160e01b03198116811461160957600080fd5b5056fea264697066735822122025c5903da72830614e39ee33291c4a30d358c4296e104e85250abea634a662a764736f6c63430008060033