Contract 0x95AE1515367aa64C462c71e87157771165B1287A 1

Contract Overview

Balance:
0 Ether
Txn Hash
Method
Block
From
To
Value
0x11a32c5cd9e5cecae0bb0f66fa3de5c4141f6bc6230b495d110f83d91b54f5aaSet104103472022-03-29 9:08:3199 days 10 hrs ago0x989f400cd59584415aa44e676b75a45873b59834 IN  0x95ae1515367aa64c462c71e87157771165b1287a0 Ether0.00015799 2.50018045
0xcd21b0911e96e33f3514ba6866c9b4517c6165d2972c854b9299d38579cbd4bcSet100737152022-01-29 3:41:27158 days 16 hrs ago0x63d5c30a7c7b7c8b7f1db6c2ff3c8735f698cbbc IN  0x95ae1515367aa64c462c71e87157771165b1287a0 Ether0.00025642 1
0xe88d183469957547915e6b1bc3d803c85b936e0b3da6e418167002f5bdb85944Set Many100735562022-01-29 3:01:41158 days 16 hrs ago0x63d5c30a7c7b7c8b7f1db6c2ff3c8735f698cbbc IN  0x95ae1515367aa64c462c71e87157771165b1287a0 Ether0.00028284 1.94000001
0x3205dadabf9b85e7f155ba0143865c35bc5f75b2173bb13aa1a2d8ec38b11020Set Many100735072022-01-29 2:49:26158 days 17 hrs ago0x63d5c30a7c7b7c8b7f1db6c2ff3c8735f698cbbc IN  0x95ae1515367aa64c462c71e87157771165b1287a0 Ether0.00018375 1.5
0xd080508db60ff81bf8013f81b91d1ff47d53bdcb1017d1c341822aa0e94d78adSet100301822022-01-21 14:10:44166 days 5 hrs ago0x989f400cd59584415aa44e676b75a45873b59834 IN  0x95ae1515367aa64c462c71e87157771165b1287a0 Ether0.00015798 2.50000007
0x42c5b7edd6813782c7a51ee2ff16e04fd5a0f953bfde52986af8dbd90a26fe08Set99900782022-01-14 14:58:40173 days 4 hrs ago0x989f400cd59584415aa44e676b75a45873b59834 IN  0x95ae1515367aa64c462c71e87157771165b1287a0 Ether0.00015798 2.50000002
0x415cfaadb8c3e555a8c322e6d1a14ac8a2cc232f69c348c7a0a53bc49f5a4b2eSet99898702022-01-14 14:06:36173 days 5 hrs ago0x989f400cd59584415aa44e676b75a45873b59834 IN  0x95ae1515367aa64c462c71e87157771165b1287a0 Ether0.00015798 2.50000001
0x998a039978d1433ad1e6b2511019ecbf687b18287566f89005c8d999fdb7d1bdSet99898322022-01-14 13:57:05173 days 5 hrs ago0x989f400cd59584415aa44e676b75a45873b59834 IN  0x95ae1515367aa64c462c71e87157771165b1287a0 Ether0.00015798 2.50000001
0x5b5c41e46fe8422744a71edf58294ecfd4c3f699f8611a04f325ae0e3f85acf3Set99895942022-01-14 12:57:35173 days 6 hrs ago0x989f400cd59584415aa44e676b75a45873b59834 IN  0x95ae1515367aa64c462c71e87157771165b1287a0 Ether0.00015798 2.50000001
0x9225b6ded4f00f916624e12ab647772ad09639f08ad6edb78d25ba7e3d21547fSet99895172022-01-14 12:38:19173 days 7 hrs ago0x989f400cd59584415aa44e676b75a45873b59834 IN  0x95ae1515367aa64c462c71e87157771165b1287a0 Ether0.00015798 2.50000001
0xbb68b1999f785dd51c50640d0dae3d1c11a0ec917de1b1a5a5d4d50b810305c6Set98771642021-12-25 17:12:47193 days 2 hrs ago0x989f400cd59584415aa44e676b75a45873b59834 IN  0x95ae1515367aa64c462c71e87157771165b1287a0 Ether0.00015798 2.5
0x2ee6d8201e54bad7db612d87c56fbf061d863ed522879b978c47569e8b982a88Set Many98485392021-12-20 17:54:21198 days 2 hrs ago0x87348226e747df4cff2b1b1e38a528df405ccd5c IN  0x95ae1515367aa64c462c71e87157771165b1287a0 Ether0.00009766 1.50000001
0xedf27b2bbd3873cfcc08926a512bbfdf2c30be84b95214f61043168b10982de3Set Many98483732021-12-20 17:12:50198 days 2 hrs ago0x87348226e747df4cff2b1b1e38a528df405ccd5c IN  0x95ae1515367aa64c462c71e87157771165b1287a0 Ether0.00023762 1.94000001
0x369869936458064880f92b68ddf8a71888212aaf03a971b6a4a52e2ad1a6cb56Set Many98483182021-12-20 16:59:05198 days 2 hrs ago0x87348226e747df4cff2b1b1e38a528df405ccd5c IN  0x95ae1515367aa64c462c71e87157771165b1287a0 Ether0.00024171 2.42500001
0x2b2505019c3689caad6106ccbc0bbff4a0cb0d3be503b6803eb8ceae0255b181Set Many98481712021-12-20 16:22:20198 days 3 hrs ago0x87348226e747df4cff2b1b1e38a528df405ccd5c IN  0x95ae1515367aa64c462c71e87157771165b1287a0 Ether0.00040836 1.50000001
0xb6da1f2df7565d9c0486f7e8ca53e922d55cc5969b11de2b6b720d3c3cb875cfSet Many98431822021-12-19 19:34:42199 days 20 mins ago0x87348226e747df4cff2b1b1e38a528df405ccd5c IN  0x95ae1515367aa64c462c71e87157771165b1287a0 Ether0.00007943 1.50000001
0x68d99c551699055705357ba12058951ce1e68828aad18591637125ad17d7d428Set Many98249502021-12-16 15:35:28202 days 4 hrs ago0x87348226e747df4cff2b1b1e38a528df405ccd5c IN  0x95ae1515367aa64c462c71e87157771165b1287a0 Ether0.00018938 1.54615172
0x884c682d51fe5c14463a551702178c34f5ec2e4e6fd1bceeb87e97d3cfcf70d5Reconfigure For98186432021-12-15 10:45:21203 days 9 hrs ago0xb3b86785a51b950fd54abdf420ff3b60e091870c IN  0x95ae1515367aa64c462c71e87157771165b1287a0 Ether0.0064476420
0xf9512de1e7293a7ee4c4606c33c0178b19b2f9658e5dcac4708a1072cd9e8030Reconfigure For98182212021-12-15 8:59:19203 days 10 hrs ago0x7ef88a779651f26a4967026a32cae4f01ff8d151 IN  0x95ae1515367aa64c462c71e87157771165b1287a0 Ether0.0064480420
0x43a8f71b227bac5d8be9811a00709693766e4e6135c931eb190a2361b5a11802Reconfigure For98181072021-12-15 8:30:47203 days 11 hrs ago0x288da3443bbebcc7a339182323aa3f23126dfe7a IN  0x95ae1515367aa64c462c71e87157771165b1287a0 Ether0.0064476420
0xc3c0386e44d9f9f5a3b6e749c752f48f808ca95aa2583364e08a57adfbd1e76fReconfigure For98145792021-12-14 17:44:21204 days 2 hrs ago0xe45541799119c1d63b60e0f834f3a381d4bedbea IN  0x95ae1515367aa64c462c71e87157771165b1287a0 Ether0.0029281620
0x503d52bbbbe8d8853b928a065a942f788eac28b5de3b2a6ed125ac0d64abdbcbSet Many98138702021-12-14 14:46:57204 days 5 hrs ago0xbe2e84efa8714aa2f104533cd3d481aff1e779f6 IN  0x95ae1515367aa64c462c71e87157771165b1287a0 Ether0.0022712318.54250344
0x5a00f0e8c460ec5673139e87374ca90aa3670bf31198630b3ac04bc43fe9d9a5Reconfigure For98087372021-12-13 17:19:19205 days 2 hrs ago0x7ef88a779651f26a4967026a32cae4f01ff8d151 IN  0x95ae1515367aa64c462c71e87157771165b1287a0 Ether0.0029279220
0x26b21c37aacef1c449cbb4b416d630240e610ff6b9d2fde0d05f3ec1ed0f8b48Set Many98085072021-12-13 16:21:34205 days 3 hrs ago0xbe2e84efa8714aa2f104533cd3d481aff1e779f6 IN  0x95ae1515367aa64c462c71e87157771165b1287a0 Ether0.000052951.00000001
0xdabbee7a5a77bfebcb9127c19bd3362eddd6a589a8b54a8811602bbaa5cecf77Set Many98078882021-12-13 13:46:13205 days 6 hrs ago0x9ccd5fe18dd4e0947b41fb460462c03904607e55 IN  0x95ae1515367aa64c462c71e87157771165b1287a0 Ether0.00007971 1.50544046
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x11a32c5cd9e5cecae0bb0f66fa3de5c4141f6bc6230b495d110f83d91b54f5aa104103472022-03-29 9:08:3199 days 10 hrs ago 0x95ae1515367aa64c462c71e87157771165b1287a 0xaad76bea7cfec82927239415bb18d2e93518ecbb0 Ether
0x11a32c5cd9e5cecae0bb0f66fa3de5c4141f6bc6230b495d110f83d91b54f5aa104103472022-03-29 9:08:3199 days 10 hrs ago 0x95ae1515367aa64c462c71e87157771165b1287a 0xaad76bea7cfec82927239415bb18d2e93518ecbb0 Ether
0xcd21b0911e96e33f3514ba6866c9b4517c6165d2972c854b9299d38579cbd4bc100737152022-01-29 3:41:27158 days 16 hrs ago 0x95ae1515367aa64c462c71e87157771165b1287a 0xaad76bea7cfec82927239415bb18d2e93518ecbb0 Ether
0xcd21b0911e96e33f3514ba6866c9b4517c6165d2972c854b9299d38579cbd4bc100737152022-01-29 3:41:27158 days 16 hrs ago 0x95ae1515367aa64c462c71e87157771165b1287a 0xaad76bea7cfec82927239415bb18d2e93518ecbb0 Ether
0xe88d183469957547915e6b1bc3d803c85b936e0b3da6e418167002f5bdb85944100735562022-01-29 3:01:41158 days 16 hrs ago 0x95ae1515367aa64c462c71e87157771165b1287a 0xaad76bea7cfec82927239415bb18d2e93518ecbb0 Ether
0xe88d183469957547915e6b1bc3d803c85b936e0b3da6e418167002f5bdb85944100735562022-01-29 3:01:41158 days 16 hrs ago 0x95ae1515367aa64c462c71e87157771165b1287a 0xaad76bea7cfec82927239415bb18d2e93518ecbb0 Ether
0x3205dadabf9b85e7f155ba0143865c35bc5f75b2173bb13aa1a2d8ec38b11020100735072022-01-29 2:49:26158 days 17 hrs ago 0x95ae1515367aa64c462c71e87157771165b1287a 0xaad76bea7cfec82927239415bb18d2e93518ecbb0 Ether
0x3205dadabf9b85e7f155ba0143865c35bc5f75b2173bb13aa1a2d8ec38b11020100735072022-01-29 2:49:26158 days 17 hrs ago 0x95ae1515367aa64c462c71e87157771165b1287a 0xaad76bea7cfec82927239415bb18d2e93518ecbb0 Ether
0xd080508db60ff81bf8013f81b91d1ff47d53bdcb1017d1c341822aa0e94d78ad100301822022-01-21 14:10:44166 days 5 hrs ago 0x95ae1515367aa64c462c71e87157771165b1287a 0xaad76bea7cfec82927239415bb18d2e93518ecbb0 Ether
0xd080508db60ff81bf8013f81b91d1ff47d53bdcb1017d1c341822aa0e94d78ad100301822022-01-21 14:10:44166 days 5 hrs ago 0x95ae1515367aa64c462c71e87157771165b1287a 0xaad76bea7cfec82927239415bb18d2e93518ecbb0 Ether
0x42c5b7edd6813782c7a51ee2ff16e04fd5a0f953bfde52986af8dbd90a26fe0899900782022-01-14 14:58:40173 days 4 hrs ago 0x95ae1515367aa64c462c71e87157771165b1287a 0xaad76bea7cfec82927239415bb18d2e93518ecbb0 Ether
0x42c5b7edd6813782c7a51ee2ff16e04fd5a0f953bfde52986af8dbd90a26fe0899900782022-01-14 14:58:40173 days 4 hrs ago 0x95ae1515367aa64c462c71e87157771165b1287a 0xaad76bea7cfec82927239415bb18d2e93518ecbb0 Ether
0x415cfaadb8c3e555a8c322e6d1a14ac8a2cc232f69c348c7a0a53bc49f5a4b2e99898702022-01-14 14:06:36173 days 5 hrs ago 0x95ae1515367aa64c462c71e87157771165b1287a 0xaad76bea7cfec82927239415bb18d2e93518ecbb0 Ether
0x415cfaadb8c3e555a8c322e6d1a14ac8a2cc232f69c348c7a0a53bc49f5a4b2e99898702022-01-14 14:06:36173 days 5 hrs ago 0x95ae1515367aa64c462c71e87157771165b1287a 0xaad76bea7cfec82927239415bb18d2e93518ecbb0 Ether
0x998a039978d1433ad1e6b2511019ecbf687b18287566f89005c8d999fdb7d1bd99898322022-01-14 13:57:05173 days 5 hrs ago 0x95ae1515367aa64c462c71e87157771165b1287a 0xaad76bea7cfec82927239415bb18d2e93518ecbb0 Ether
0x998a039978d1433ad1e6b2511019ecbf687b18287566f89005c8d999fdb7d1bd99898322022-01-14 13:57:05173 days 5 hrs ago 0x95ae1515367aa64c462c71e87157771165b1287a 0xaad76bea7cfec82927239415bb18d2e93518ecbb0 Ether
0x5b5c41e46fe8422744a71edf58294ecfd4c3f699f8611a04f325ae0e3f85acf399895942022-01-14 12:57:35173 days 6 hrs ago 0x95ae1515367aa64c462c71e87157771165b1287a 0xaad76bea7cfec82927239415bb18d2e93518ecbb0 Ether
0x5b5c41e46fe8422744a71edf58294ecfd4c3f699f8611a04f325ae0e3f85acf399895942022-01-14 12:57:35173 days 6 hrs ago 0x95ae1515367aa64c462c71e87157771165b1287a 0xaad76bea7cfec82927239415bb18d2e93518ecbb0 Ether
0x9225b6ded4f00f916624e12ab647772ad09639f08ad6edb78d25ba7e3d21547f99895172022-01-14 12:38:19173 days 7 hrs ago 0x95ae1515367aa64c462c71e87157771165b1287a 0xaad76bea7cfec82927239415bb18d2e93518ecbb0 Ether
0x9225b6ded4f00f916624e12ab647772ad09639f08ad6edb78d25ba7e3d21547f99895172022-01-14 12:38:19173 days 7 hrs ago 0x95ae1515367aa64c462c71e87157771165b1287a 0xaad76bea7cfec82927239415bb18d2e93518ecbb0 Ether
0xbb68b1999f785dd51c50640d0dae3d1c11a0ec917de1b1a5a5d4d50b810305c698771642021-12-25 17:12:47193 days 2 hrs ago 0x95ae1515367aa64c462c71e87157771165b1287a 0xaad76bea7cfec82927239415bb18d2e93518ecbb0 Ether
0xbb68b1999f785dd51c50640d0dae3d1c11a0ec917de1b1a5a5d4d50b810305c698771642021-12-25 17:12:47193 days 2 hrs ago 0x95ae1515367aa64c462c71e87157771165b1287a 0xaad76bea7cfec82927239415bb18d2e93518ecbb0 Ether
0x2ee6d8201e54bad7db612d87c56fbf061d863ed522879b978c47569e8b982a8898485392021-12-20 17:54:21198 days 2 hrs ago 0x95ae1515367aa64c462c71e87157771165b1287a 0xaad76bea7cfec82927239415bb18d2e93518ecbb0 Ether
0x2ee6d8201e54bad7db612d87c56fbf061d863ed522879b978c47569e8b982a8898485392021-12-20 17:54:21198 days 2 hrs ago 0x95ae1515367aa64c462c71e87157771165b1287a 0xaad76bea7cfec82927239415bb18d2e93518ecbb0 Ether
0xedf27b2bbd3873cfcc08926a512bbfdf2c30be84b95214f61043168b10982de398483732021-12-20 17:12:50198 days 2 hrs ago 0x95ae1515367aa64c462c71e87157771165b1287a 0xaad76bea7cfec82927239415bb18d2e93518ecbb0 Ether
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Resolver

Compiler Version
v0.5.12+commit.7709ece9

Optimization Enabled:
No with 200 runs

Other Settings:
petersburg EvmVersion
File 1 of 22 : IRegistry.sol
pragma solidity 0.5.12;

import "@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol";

contract IRegistry is IERC721Metadata {

    event NewURI(uint256 indexed tokenId, string uri);

    event NewURIPrefix(string prefix);

    event Resolve(uint256 indexed tokenId, address indexed to);

    event Sync(address indexed resolver, uint256 indexed updateId, uint256 indexed tokenId);

    /**
     * @dev Controlled function to set the token URI Prefix for all tokens.
     * @param prefix string URI to assign
     */
    function controlledSetTokenURIPrefix(string calldata prefix) external;

    /**
     * @dev Returns whether the given spender can transfer a given token ID.
     * @param spender address of the spender to query
     * @param tokenId uint256 ID of the token to be transferred
     * @return bool whether the msg.sender is approved for the given token ID,
     * is an operator of the owner, or is the owner of the token
     */
    function isApprovedOrOwner(address spender, uint256 tokenId) external view returns (bool);

    /**
     * @dev Mints a new a child token.
     * Calculates child token ID using a namehash function.
     * Requires the msg.sender to be the owner, approved, or operator of tokenId.
     * Requires the token not exist.
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the parent token
     * @param label subdomain label of the child token ID
     */
    function mintChild(address to, uint256 tokenId, string calldata label) external;

    /**
     * @dev Controlled function to mint a given token ID.
     * Requires the msg.sender to be controller.
     * Requires the token ID to not exist.
     * @param to address the given token ID will be minted to
     * @param label string that is a subdomain
     * @param tokenId uint256 ID of the parent token
     */
    function controlledMintChild(address to, uint256 tokenId, string calldata label) external;

    /**
     * @dev Transfers the ownership of a child token ID to another address.
     * Calculates child token ID using a namehash function.
     * Requires the msg.sender to be the owner, approved, or operator of tokenId.
     * Requires the token already exist.
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     * @param label subdomain label of the child token ID
     */
    function transferFromChild(address from, address to, uint256 tokenId, string calldata label) external;

    /**
     * @dev Controlled function to transfers the ownership of a token ID to
     * another address.
     * Requires the msg.sender to be controller.
     * Requires the token already exist.
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function controlledTransferFrom(address from, address to, uint256 tokenId) external;

    /**
     * @dev Safely transfers the ownership of a child token ID to another address.
     * Calculates child token ID using a namehash function.
     * Implements a ERC721Reciever check unlike transferFromChild.
     * Requires the msg.sender to be the owner, approved, or operator of tokenId.
     * Requires the token already exist.
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 parent ID of the token to be transferred
     * @param label subdomain label of the child token ID
     * @param _data bytes data to send along with a safe transfer check
     */
    function safeTransferFromChild(address from, address to, uint256 tokenId, string calldata label, bytes calldata _data) external;

    /// Shorthand for calling the above ^^^ safeTransferFromChild function with an empty _data parameter. Similar to ERC721.safeTransferFrom.
    function safeTransferFromChild(address from, address to, uint256 tokenId, string calldata label) external;

    /**
     * @dev Controlled frunction to safely transfers the ownership of a token ID
     * to another address.
     * Implements a ERC721Reciever check unlike controlledSafeTransferFrom.
     * Requires the msg.sender to be controller.
     * Requires the token already exist.
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 parent ID of the token to be transferred
     * @param _data bytes data to send along with a safe transfer check
     */
    function controlledSafeTransferFrom(address from, address to, uint256 tokenId, bytes calldata _data) external;

    /**
     * @dev Burns a child token ID.
     * Calculates child token ID using a namehash function.
     * Requires the msg.sender to be the owner, approved, or operator of tokenId.
     * Requires the token already exist.
     * @param tokenId uint256 ID of the token to be transferred
     * @param label subdomain label of the child token ID
     */
    function burnChild(uint256 tokenId, string calldata label) external;

    /**
     * @dev Controlled function to burn a given token ID.
     * Requires the msg.sender to be controller.
     * Requires the token already exist.
     * @param tokenId uint256 ID of the token to be burned
     */
    function controlledBurn(uint256 tokenId) external;

    /**
     * @dev Sets the resolver of a given token ID to another address.
     * Requires the msg.sender to be the owner, approved, or operator.
     * @param to address the given token ID will resolve to
     * @param tokenId uint256 ID of the token to be transferred
     */
    function resolveTo(address to, uint256 tokenId) external;

    /**
     * @dev Gets the resolver of the specified token ID.
     * @param tokenId uint256 ID of the token to query the resolver of
     * @return address currently marked as the resolver of the given token ID
     */
    function resolverOf(uint256 tokenId) external view returns (address);

    /**
     * @dev Controlled function to sets the resolver of a given token ID.
     * Requires the msg.sender to be controller.
     * @param to address the given token ID will resolve to
     * @param tokenId uint256 ID of the token to be transferred
     */
    function controlledResolveTo(address to, uint256 tokenId) external;

    /**
     * @dev Provides child token (subdomain) of provided tokenId.
     * @param tokenId uint256 ID of the token
     * @param label label of subdomain (for `aaa.bbb.crypto` it will be `aaa`)
     */
    function childIdOf(uint256 tokenId, string calldata label) external pure returns (uint256);

    /**
     * @dev Transfer domain ownership without resetting domain records.
     * @param to address of new domain owner
     * @param tokenId uint256 ID of the token to be transferred
     */
    function setOwner(address to, uint256 tokenId) external;
}

File 2 of 22 : IResolver.sol
pragma solidity 0.5.12;
pragma experimental ABIEncoderV2;

contract IResolver {
    /**
     * @dev Reset all domain records and set new ones
     * @param keys New record keys
     * @param values New record values
     * @param tokenId ERC-721 token id of the domain
     */
    function reconfigure(string[] memory keys, string[] memory values, uint256 tokenId) public;

    /**
     * @dev Set or update domain records
     * @param keys New record keys
     * @param values New record values
     * @param tokenId ERC-721 token id of the domain
     */
    function setMany(string[] memory keys, string[] memory values, uint256 tokenId) public;

    /**
     * @dev Function to set record.
     * @param key The key set the value of.
     * @param value The value to set key to.
     * @param tokenId ERC-721 token id to set.
     */
    function set(string calldata key, string calldata value, uint256 tokenId) external;

    /**
     * @dev Function to reset all existing records on a domain.
     * @param tokenId ERC-721 token id to set.
     */
    function reset(uint256 tokenId) external;
}

File 3 of 22 : IResolverReader.sol
pragma solidity 0.5.12;
pragma experimental ABIEncoderV2;

interface IResolverReader {
    /**
     * @dev Gets the nonce of the specified address.
     * @param tokenId token ID for nonce query
     * @return nonce of the given address
     */
    function nonceOf(uint256 tokenId) external view returns (uint256);

    /**
     * @return registry address
     */
    function registry() external view returns (address);

    /**
     * @dev Function to get record.
     * @param key The key to query the value of.
     * @param tokenId The token id to fetch.
     * @return The value string.
     */
    function get(string calldata key, uint256 tokenId)
        external
        view
        returns (string memory);

    /**
     * @dev Function to get multiple record.
     * @param keys The keys to query the value of.
     * @param tokenId The token id to fetch.
     * @return The values.
     */
    function getMany(string[] calldata keys, uint256 tokenId)
        external
        view
        returns (string[] memory);

    /**
     * @dev Function get value by provied key hash. Keys hashes can be found in Sync event emitted by Registry.sol contract.
     * @param keyHash The key to query the value of.
     * @param tokenId The token id to set.
     * @return Key and value.
     */
    function getByHash(uint256 keyHash, uint256 tokenId)
        external
        view
        returns (string memory key, string memory value);

    /**
     * @dev Function get values by provied key hashes. Keys hashes can be found in Sync event emitted by Registry.sol contract.
     * @param keyHashes The key to query the value of.
     * @param tokenId The token id to set.
     * @return Keys and values.
     */
    function getManyByHash(uint256[] calldata keyHashes, uint256 tokenId)
        external
        view
        returns (string[] memory keys, string[] memory values);
}

File 4 of 22 : Registry.sol
pragma solidity 0.5.12;

import "./IRegistry.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721Burnable.sol";
import "./util/ControllerRole.sol";

// solium-disable no-empty-blocks,error-reason

/**
 * @title Registry
 * @dev An ERC721 Token see https://eips.ethereum.org/EIPS/eip-721. With
 * additional functions so other trusted contracts to interact with the tokens.
 */
contract Registry is IRegistry, ControllerRole, ERC721Burnable {

    // Optional mapping for token URIs
    mapping(uint256 => string) internal _tokenURIs;

    string internal _prefix;

    // Mapping from token ID to resolver address
    mapping (uint256 => address) internal _tokenResolvers;

    // uint256(keccak256(abi.encodePacked(uint256(0x0), keccak256(abi.encodePacked("crypto")))))
    uint256 private constant _CRYPTO_HASH =
        0x0f4a10a4f46c288cea365fcf45cccf0e9d901b945b9829ccdb54c10dc3cb7a6f;

    modifier onlyApprovedOrOwner(uint256 tokenId) {
        require(_isApprovedOrOwner(msg.sender, tokenId));
        _;
    }

    constructor () public {
        _mint(address(0xdead), _CRYPTO_HASH);
        // register the supported interfaces to conform to ERC721 via ERC165
        _registerInterface(0x5b5e139f); // ERC721 Metadata Interface
        _tokenURIs[root()] = "crypto";
        emit NewURI(root(), "crypto");
    }

    /// ERC721 Metadata extension

    function name() external view returns (string memory) {
        return ".crypto";
    }

    function symbol() external view returns (string memory) {
        return "UD";
    }

    function tokenURI(uint256 tokenId) external view returns (string memory) {
        require(_exists(tokenId));
        return string(abi.encodePacked(_prefix, _tokenURIs[tokenId]));
    }

    function controlledSetTokenURIPrefix(string calldata prefix) external onlyController {
        _prefix = prefix;
        emit NewURIPrefix(prefix);
    }

    /// Ownership

    function isApprovedOrOwner(address spender, uint256 tokenId) external view returns (bool) {
        return _isApprovedOrOwner(spender, tokenId);
    }

    /// Registry Constants

    function root() public pure returns (uint256) {
        return _CRYPTO_HASH;
    }

    function childIdOf(uint256 tokenId, string calldata label) external pure returns (uint256) {
        return _childId(tokenId, label);
    }

    /// Minting

    function mintChild(address to, uint256 tokenId, string calldata label) external onlyApprovedOrOwner(tokenId) {
        _mintChild(to, tokenId, label);
    }

    function controlledMintChild(address to, uint256 tokenId, string calldata label) external onlyController {
        _mintChild(to, tokenId, label);
    }

    function safeMintChild(address to, uint256 tokenId, string calldata label) external onlyApprovedOrOwner(tokenId) {
        _safeMintChild(to, tokenId, label, "");
    }

    function safeMintChild(address to, uint256 tokenId, string calldata label, bytes calldata _data)
        external
        onlyApprovedOrOwner(tokenId)
    {
        _safeMintChild(to, tokenId, label, _data);
    }

    function controlledSafeMintChild(address to, uint256 tokenId, string calldata label, bytes calldata _data)
        external
        onlyController
    {
        _safeMintChild(to, tokenId, label, _data);
    }

    /// Transfering

    function setOwner(address to, uint256 tokenId) external onlyApprovedOrOwner(tokenId)  {
        super._transferFrom(ownerOf(tokenId), to, tokenId);
    }

    function transferFromChild(address from, address to, uint256 tokenId, string calldata label)
        external
        onlyApprovedOrOwner(tokenId)
    {
        _transferFrom(from, to, _childId(tokenId, label));
    }

    function controlledTransferFrom(address from, address to, uint256 tokenId) external onlyController {
        _transferFrom(from, to, tokenId);
    }

    function safeTransferFromChild(
        address from,
        address to,
        uint256 tokenId,
        string memory label,
        bytes memory _data
    ) public onlyApprovedOrOwner(tokenId) {
        uint256 childId = _childId(tokenId, label);
        _transferFrom(from, to, childId);
        require(_checkOnERC721Received(from, to, childId, _data));
    }

    function safeTransferFromChild(address from, address to, uint256 tokenId, string calldata label) external {
        safeTransferFromChild(from, to, tokenId, label, "");
    }

    function controlledSafeTransferFrom(address from, address to, uint256 tokenId, bytes calldata _data)
        external
        onlyController
    {
        _transferFrom(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data));
    }

    /// Burning

    function burnChild(uint256 tokenId, string calldata label) external onlyApprovedOrOwner(tokenId) {
        _burn(_childId(tokenId, label));
    }

    function controlledBurn(uint256 tokenId) external onlyController {
        _burn(tokenId);
    }

    /// Resolution

    function resolverOf(uint256 tokenId) external view returns (address) {
        address resolver = _tokenResolvers[tokenId];
        require(resolver != address(0));
        return resolver;
    }

    function resolveTo(address to, uint256 tokenId) external onlyApprovedOrOwner(tokenId) {
        _resolveTo(to, tokenId);
    }

    function controlledResolveTo(address to, uint256 tokenId) external onlyController {
        _resolveTo(to, tokenId);
    }

    function sync(uint256 tokenId, uint256 updateId) external {
        require(_tokenResolvers[tokenId] == msg.sender);
        emit Sync(msg.sender, updateId, tokenId);
    }

    /// Internal

    function _childId(uint256 tokenId, string memory label) internal pure returns (uint256) {
        require(bytes(label).length != 0);
        return uint256(keccak256(abi.encodePacked(tokenId, keccak256(abi.encodePacked(label)))));
    }

    function _mintChild(address to, uint256 tokenId, string memory label) internal {
        uint256 childId = _childId(tokenId, label);
        _mint(to, childId);

        require(bytes(label).length != 0);
        require(_exists(childId));

        bytes memory domain = abi.encodePacked(label, ".", _tokenURIs[tokenId]);

        _tokenURIs[childId] = string(domain);
        emit NewURI(childId, string(domain));
    }

    function _safeMintChild(address to, uint256 tokenId, string memory label, bytes memory _data) internal {
        _mintChild(to, tokenId, label);
        require(_checkOnERC721Received(address(0), to, _childId(tokenId, label), _data));
    }

    function _transferFrom(address from, address to, uint256 tokenId) internal {
        super._transferFrom(from, to, tokenId);
        // Clear resolver (if any)
        if (_tokenResolvers[tokenId] != address(0x0)) {
            delete _tokenResolvers[tokenId];
        }
    }

    function _burn(uint256 tokenId) internal {
        super._burn(tokenId);
        // Clear resolver (if any)
        if (_tokenResolvers[tokenId] != address(0x0)) {
            delete _tokenResolvers[tokenId];
        }
        // Clear metadata (if any)
        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }
    }

    function _resolveTo(address to, uint256 tokenId) internal {
        require(_exists(tokenId));
        emit Resolve(tokenId, to);
        _tokenResolvers[tokenId] = to;
    }

}

File 5 of 22 : Resolver.sol
pragma solidity 0.5.12;
pragma experimental ABIEncoderV2;

import './Registry.sol';
import './util/SignatureUtil.sol';
import './controllers/MintingController.sol';
import './IResolver.sol';
import './IResolverReader.sol';
// solium-disable error-reason

contract Resolver is IResolverReader, SignatureUtil, IResolver {

    event Set(uint256 indexed tokenId, string indexed keyIndex, string indexed valueIndex, string key, string value);
    event NewKey(uint256 indexed tokenId, string indexed keyIndex, string key);
    event ResetRecords(uint256 indexed tokenId);

    // Mapping from token ID to preset id to key to value
    mapping (uint256 => mapping (uint256 =>  mapping (string => string))) internal _records;

    // Mapping from token ID to current preset id
    mapping (uint256 => uint256) _tokenPresets;

    // All keys that were set
    mapping (uint256 => string) _hashedKeys;

    MintingController internal _mintingController;

    constructor(Registry registry, MintingController mintingController) public SignatureUtil(registry) {
        require(address(registry) == mintingController.registry());
        _mintingController = mintingController;
    }

    /**
     * @dev Throws if called when not the resolver.
     */
    modifier whenResolver(uint256 tokenId) {
        require(address(this) == _registry.resolverOf(tokenId), "RESOLVER_DETACHED_FROM_DOMAIN");
        _;
    }

    modifier whenApprovedOrOwner(uint256 tokenId) {
        require(_registry.isApprovedOrOwner(msg.sender, tokenId), "SENDER_IS_NOT_APPROVED_OR_OWNER");
        _;
    }

    function reset(uint256 tokenId) external whenApprovedOrOwner(tokenId) {
        _setPreset(now, tokenId);
    }

    function resetFor(uint256 tokenId, bytes calldata signature) external {
        _validate(keccak256(abi.encodeWithSelector(this.reset.selector, tokenId)), tokenId, signature);
        _setPreset(now, tokenId);
    }

    /**
     * @dev Function to get record.
     * @param key The key to query the value of.
     * @param tokenId The token id to fetch.
     * @return The value string.
     */
    function get(string memory key, uint256 tokenId) public view whenResolver(tokenId) returns (string memory) {
        return _records[tokenId][_tokenPresets[tokenId]][key];
    }

    /**
     * @dev Function to get key by provided hash. Keys hashes can be found in Sync event emitted by Registry.sol contract.
     * @param keyHash The key to query the value of.
     * @return The key string.
     */
    function hashToKey(uint256 keyHash) public view returns (string memory) {
        return _hashedKeys[keyHash];
    }

    /**
     * @dev Function to get keys by provided key hashes. Keys hashes can be found in Sync event emitted by Registry.sol contract.
     * @param hashes The key to query the value of.
     * @return Keys
     */
    function hashesToKeys(uint256[] memory hashes) public view returns (string[] memory) {
        uint256 keyCount = hashes.length;
        string[] memory values = new string[](keyCount);
        for (uint256 i = 0; i < keyCount; i++) {
            values[i] = hashToKey(hashes[i]);
        }

        return values;
    }

    /**
     * @dev Function get value by provied key hash. Keys hashes can be found in Sync event emitted by Registry.sol contract.
     * @param keyHash The key to query the value of.
     * @param tokenId The token id to set.
     * @return Key and value.
     */
    function getByHash(uint256 keyHash, uint256 tokenId) public view whenResolver(tokenId) returns (string memory key, string memory value) {
        key = hashToKey(keyHash);
        value = get(key, tokenId);
    }

    /**
     * @dev Function get values by provied key hashes. Keys hashes can be found in Sync event emitted by Registry.sol contract.
     * @param keyHashes The key to query the value of.
     * @param tokenId The token id to set.
     * @return Keys and values.
     */
    function getManyByHash(
        uint256[] memory keyHashes,
        uint256 tokenId
    ) public view whenResolver(tokenId) returns (string[] memory keys, string[] memory values) {
        uint256 keyCount = keyHashes.length;
        keys = new string[](keyCount);
        values = new string[](keyCount);
        for (uint256 i = 0; i < keyCount; i++) {
            (keys[i], values[i]) = getByHash(keyHashes[i], tokenId);
        }
    }

    function preconfigure(
        string[] memory keys,
        string[] memory values,
        uint256 tokenId
    ) public {
        require(_mintingController.isMinter(msg.sender), "SENDER_IS_NOT_MINTER");
        _setMany(_tokenPresets[tokenId], keys, values, tokenId);
    }

    /**
     * @dev Function to set record.
     * @param key The key set the value of.
     * @param value The value to set key to.
     * @param tokenId The token id to set.
     */
    function set(string calldata key, string calldata value, uint256 tokenId) external whenApprovedOrOwner(tokenId) {
        _set(_tokenPresets[tokenId], key, value, tokenId);
    }

    /**
     * @dev Function to set record on behalf of an address.
     * @param key The key set the value of.
     * @param value The value to set key to.
     * @param tokenId The token id to set.
     * @param signature The signature to verify the transaction with.
     */
    function setFor(
        string calldata key,
        string calldata value,
        uint256 tokenId,
        bytes calldata signature
    ) external {
        _validate(keccak256(abi.encodeWithSelector(this.set.selector, key, value, tokenId)), tokenId, signature);
        _set(_tokenPresets[tokenId], key, value, tokenId);
    }

    /**
     * @dev Function to get multiple record.
     * @param keys The keys to query the value of.
     * @param tokenId The token id to fetch.
     * @return The values.
     */
    function getMany(string[] calldata keys, uint256 tokenId) external view whenResolver(tokenId) returns (string[] memory) {
        uint256 keyCount = keys.length;
        string[] memory values = new string[](keyCount);
        uint256 preset = _tokenPresets[tokenId];
        for (uint256 i = 0; i < keyCount; i++) {
            values[i] = _records[tokenId][preset][keys[i]];
        }
        return values;
    }

    function setMany(
        string[] memory keys,
        string[] memory values,
        uint256 tokenId
    ) public whenApprovedOrOwner(tokenId) {
        _setMany(_tokenPresets[tokenId], keys, values, tokenId);
    }

    /**
     * @dev Function to set record on behalf of an address.
     * @param keys The keys set the values of.
     * @param values The values to set keys to.
     * @param tokenId The token id to set.
     * @param signature The signature to verify the transaction with.
     */
    function setManyFor(
        string[] memory keys,
        string[] memory values,
        uint256 tokenId,
        bytes memory signature
    ) public {
        _validate(keccak256(abi.encodeWithSelector(this.setMany.selector, keys, values, tokenId)), tokenId, signature);
        _setMany(_tokenPresets[tokenId], keys, values, tokenId);
    }

     /**
     * @dev Function to reset all domain records and set new ones.
     * @param keys records keys.
     * @param values records values.
     * @param tokenId domain token id.
     */
    function reconfigure(string[] memory keys, string[] memory values, uint256 tokenId) public whenApprovedOrOwner(tokenId) {
        _reconfigure(keys, values, tokenId);
    }

    /**
     * @dev Delegated version of reconfigure() function.
     * @param keys records keys.
     * @param values records values.
     * @param tokenId domain token id.
     * @param signature user signature.
     */
    function reconfigureFor(
        string[] memory keys,
        string[] memory values,
        uint256 tokenId,
        bytes memory signature
    ) public {
        _validate(keccak256(abi.encodeWithSelector(this.reconfigure.selector, keys, values, tokenId)), tokenId, signature);
        _reconfigure(keys, values, tokenId);
    }

    // reset records
    function _setPreset(uint256 presetId, uint256 tokenId) internal {
        _tokenPresets[tokenId] = presetId;
        _registry.sync(tokenId, 0); // notify registry that domain records were reset
        emit ResetRecords(tokenId);
    }

    /**
     * @dev Internal function to to set record. As opposed to set, this imposes no restrictions on msg.sender.
     * @param preset preset to set key/values on
     * @param key key of record to be set
     * @param value value of record to be set
     * @param tokenId uint256 ID of the token
     */
    function _set(uint256 preset, string memory key, string memory value, uint256 tokenId) internal {
        uint256 keyHash = uint256(keccak256(bytes(key)));
        bool isNewKey = bytes(_records[tokenId][preset][key]).length == 0;
        _registry.sync(tokenId, keyHash);
        _records[tokenId][preset][key] = value;

        if (bytes(_hashedKeys[keyHash]).length == 0) {
            _hashedKeys[keyHash] = key;
        }

        if (isNewKey) {
            emit NewKey(tokenId, key, key);
        }
        emit Set(tokenId, key, value, key, value);
    }

    /**
     * @dev Internal function to to set multiple records. As opposed to setMany, this imposes
     * no restrictions on msg.sender.
     * @param preset preset to set key/values on
     * @param keys keys of record to be set
     * @param values values of record to be set
     * @param tokenId uint256 ID of the token
     */
    function _setMany(uint256 preset, string[] memory keys, string[] memory values, uint256 tokenId) internal {
        uint256 keyCount = keys.length;
        for (uint256 i = 0; i < keyCount; i++) {
            _set(preset, keys[i], values[i], tokenId);
        }
    }

    /**
     * @dev Internal function to reset all domain records and set new ones.
     * @param keys records keys.
     * @param values records values.
     * @param tokenId domain token id.
     */
    function _reconfigure(string[] memory keys, string[] memory values, uint256 tokenId) internal {
        _setPreset(now, tokenId);
        _setMany(_tokenPresets[tokenId], keys, values, tokenId);
    }

}

File 6 of 22 : IMintingController.sol
pragma solidity 0.5.12;

interface IMintingController {

    /**
     * @dev Minter function that mints a Second Level Domain (SLD).
     * @param to address to mint the new SLD to.
     * @param label SLD label to mint.
     */
    function mintSLD(address to, string calldata label) external;

    /**
     * @dev Minter function that safely mints a Second Level Domain (SLD).
     * Implements a ERC721Reciever check unlike mintSLD.
     * @param to address to mint the new SLD to.
     * @param label SLD label to mint.
     */
    function safeMintSLD(address to, string calldata label) external;

    /**
     * @dev Minter function that safely mints a Second Level Domain (SLD).
     * Implements a ERC721Reciever check unlike mintSLD.
     * @param to address to mint the new SLD to.
     * @param label SLD label to mint.
     * @param _data bytes data to send along with a safe transfer check
     */
    function safeMintSLD(address to, string calldata label, bytes calldata _data) external;

}

File 7 of 22 : MintingController.sol
pragma solidity 0.5.12;

import "@openzeppelin/contracts/access/roles/MinterRole.sol";
import "./IMintingController.sol";
import "../Registry.sol";

/**
 * @title MintingController
 * @dev Defines the functions for distribution of Second Level Domains (SLD)s.
 */
contract MintingController is IMintingController, MinterRole {

    Registry internal _registry;

    constructor (Registry registry) public {
        _registry = registry;
    }

    function registry() external view returns (address) {
        return address(_registry);
    }

    function mintSLD(address to, string memory label) public onlyMinter {
        _registry.controlledMintChild(to, _registry.root(), label);
    }

    function safeMintSLD(address to, string calldata label) external {
        safeMintSLD(to, label, "");
    }

    function safeMintSLD(address to, string memory label, bytes memory _data) public onlyMinter {
        _registry.controlledSafeMintChild(to, _registry.root(), label, _data);
    }

    function mintSLDWithResolver(address to, string memory label, address resolver) public onlyMinter {
        _registry.controlledMintChild(to, _registry.root(), label);
        _registry.controlledResolveTo(resolver, _registry.childIdOf(_registry.root(), label));
    }

    function safeMintSLDWithResolver(address to, string calldata label, address resolver) external {
        safeMintSLD(to, label, "");
        _registry.controlledResolveTo(resolver, _registry.childIdOf(_registry.root(), label));
    }

    function safeMintSLDWithResolver(address to, string calldata label, address resolver, bytes calldata _data) external {
        safeMintSLD(to, label, _data);
        _registry.controlledResolveTo(resolver, _registry.childIdOf(_registry.root(), label));
    }

}

File 8 of 22 : ControllerRole.sol
pragma solidity 0.5.12;

import "@openzeppelin/contracts/access/Roles.sol";

// solium-disable error-reason

/**
 * @title ControllerRole
 * @dev An Controller role defined using the Open Zeppelin Role system.
 */
contract ControllerRole {

    using Roles for Roles.Role;

    // NOTE: Commented out standard Role events to save gas.
    // event ControllerAdded(address indexed account);
    // event ControllerRemoved(address indexed account);

    Roles.Role private _controllers;

    constructor () public {
        _addController(msg.sender);
    }

    modifier onlyController() {
        require(isController(msg.sender));
        _;
    }

    function isController(address account) public view returns (bool) {
        return _controllers.has(account);
    }

    function addController(address account) public onlyController {
        _addController(account);
    }

    function renounceController() public {
        _removeController(msg.sender);
    }

    function _addController(address account) internal {
        _controllers.add(account);
        // emit ControllerAdded(account);
    }

    function _removeController(address account) internal {
        _controllers.remove(account);
        // emit ControllerRemoved(account);
    }

}

File 9 of 22 : SignatureUtil.sol
pragma solidity 0.5.12;

import '../Registry.sol';
import '@openzeppelin/contracts/cryptography/ECDSA.sol';

// solium-disable error-reason

contract SignatureUtil {
    using ECDSA for bytes32;

    // Mapping from owner to a nonce
    mapping (uint256 => uint256) internal _nonces;

    Registry internal _registry;

    constructor(Registry registry) public {
        _registry = registry;
    }

    function registry() external view returns (address) {
        return address(_registry);
    }

    /**
     * @dev Gets the nonce of the specified address.
     * @param tokenId token ID for nonce query
     * @return nonce of the given address
     */
    function nonceOf(uint256 tokenId) external view returns (uint256) {
        return _nonces[tokenId];
    }

    function _validate(bytes32 hash, uint256 tokenId, bytes memory signature) internal {
        uint256 nonce = _nonces[tokenId];

        address signer = keccak256(abi.encodePacked(hash, address(this), nonce)).toEthSignedMessageHash().recover(signature);
        require(
            signer != address(0) &&
            _registry.isApprovedOrOwner(
                signer,
                tokenId
            ),
            "INVALID_SIGNATURE"
        );

        _nonces[tokenId] += 1;
    }

}

File 10 of 22 : Roles.sol
pragma solidity ^0.5.0;

/**
 * @title Roles
 * @dev Library for managing addresses assigned to a Role.
 */
library Roles {
    struct Role {
        mapping (address => bool) bearer;
    }

    /**
     * @dev Give an account access to this role.
     */
    function add(Role storage role, address account) internal {
        require(!has(role, account), "Roles: account already has role");
        role.bearer[account] = true;
    }

    /**
     * @dev Remove an account's access to this role.
     */
    function remove(Role storage role, address account) internal {
        require(has(role, account), "Roles: account does not have role");
        role.bearer[account] = false;
    }

    /**
     * @dev Check if an account has this role.
     * @return bool
     */
    function has(Role storage role, address account) internal view returns (bool) {
        require(account != address(0), "Roles: account is the zero address");
        return role.bearer[account];
    }
}

File 11 of 22 : MinterRole.sol
pragma solidity ^0.5.0;

import "../Roles.sol";

contract MinterRole {
    using Roles for Roles.Role;

    event MinterAdded(address indexed account);
    event MinterRemoved(address indexed account);

    Roles.Role private _minters;

    constructor () internal {
        _addMinter(msg.sender);
    }

    modifier onlyMinter() {
        require(isMinter(msg.sender), "MinterRole: caller does not have the Minter role");
        _;
    }

    function isMinter(address account) public view returns (bool) {
        return _minters.has(account);
    }

    function addMinter(address account) public onlyMinter {
        _addMinter(account);
    }

    function renounceMinter() public {
        _removeMinter(msg.sender);
    }

    function _addMinter(address account) internal {
        _minters.add(account);
        emit MinterAdded(account);
    }

    function _removeMinter(address account) internal {
        _minters.remove(account);
        emit MinterRemoved(account);
    }
}

File 12 of 22 : ECDSA.sol
pragma solidity ^0.5.0;

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * (.note) This call _does not revert_ if the signature is invalid, or
     * if the signer is otherwise unable to be retrieved. In those scenarios,
     * the zero address is returned.
     *
     * (.warning) `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise)
     * be too long), and then calling `toEthSignedMessageHash` on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        // Check the signature length
        if (signature.length != 65) {
            return (address(0));
        }

        // Divide the signature in r, s and v variables
        bytes32 r;
        bytes32 s;
        uint8 v;

        // ecrecover takes the signature parameters, and the only way to get them
        // currently is to use assembly.
        // solhint-disable-next-line no-inline-assembly
        assembly {
            r := mload(add(signature, 0x20))
            s := mload(add(signature, 0x40))
            v := byte(0, mload(add(signature, 0x60)))
        }

        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return address(0);
        }

        if (v != 27 && v != 28) {
            return address(0);
        }

        // If the signature is valid (and not malleable), return the signer address
        return ecrecover(hash, v, r, s);
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * replicates the behavior of the
     * [`eth_sign`](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign)
     * JSON-RPC method.
     *
     * See `recover`.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }
}

File 13 of 22 : Counters.sol
pragma solidity ^0.5.0;

import "../math/SafeMath.sol";

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the SafeMath
 * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never
 * directly accessed.
 */
library Counters {
    using SafeMath for uint256;

    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        counter._value += 1;
    }

    function decrement(Counter storage counter) internal {
        counter._value = counter._value.sub(1);
    }
}

File 14 of 22 : ERC165.sol
pragma solidity ^0.5.0;

import "./IERC165.sol";

/**
 * @dev Implementation of the `IERC165` interface.
 *
 * Contracts may inherit from this and call `_registerInterface` to declare
 * their support of an interface.
 */
contract ERC165 is IERC165 {
    /*
     * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
     */
    bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;

    /**
     * @dev Mapping of interface ids to whether or not it's supported.
     */
    mapping(bytes4 => bool) private _supportedInterfaces;

    constructor () internal {
        // Derived contracts need only register support for their own interfaces,
        // we register support for ERC165 itself here
        _registerInterface(_INTERFACE_ID_ERC165);
    }

    /**
     * @dev See `IERC165.supportsInterface`.
     *
     * Time complexity O(1), guaranteed to always use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool) {
        return _supportedInterfaces[interfaceId];
    }

    /**
     * @dev Registers the contract as an implementer of the interface defined by
     * `interfaceId`. Support of the actual ERC165 interface is automatic and
     * registering its interface id is not required.
     *
     * See `IERC165.supportsInterface`.
     *
     * Requirements:
     *
     * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
     */
    function _registerInterface(bytes4 interfaceId) internal {
        require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
        _supportedInterfaces[interfaceId] = true;
    }
}

File 15 of 22 : IERC165.sol
pragma solidity ^0.5.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * [EIP](https://eips.ethereum.org/EIPS/eip-165).
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others (`ERC165Checker`).
 *
 * For an implementation, see `ERC165`.
 */
interface 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 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 16 of 22 : SafeMath.sol
pragma solidity ^0.5.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, "SafeMath: division by zero");
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0, "SafeMath: modulo by zero");
        return a % b;
    }
}

File 17 of 22 : ERC721.sol
pragma solidity ^0.5.0;

import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol";
import "../../drafts/Counters.sol";
import "../../introspection/ERC165.sol";

/**
 * @title ERC721 Non-Fungible Token Standard basic implementation
 * @dev see https://eips.ethereum.org/EIPS/eip-721
 */
contract ERC721 is ERC165, IERC721 {
    using SafeMath for uint256;
    using Address for address;
    using Counters for Counters.Counter;

    // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
    // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`
    bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;

    // Mapping from token ID to owner
    mapping (uint256 => address) private _tokenOwner;

    // Mapping from token ID to approved address
    mapping (uint256 => address) private _tokenApprovals;

    // Mapping from owner to number of owned token
    mapping (address => Counters.Counter) private _ownedTokensCount;

    // Mapping from owner to operator approvals
    mapping (address => mapping (address => bool)) private _operatorApprovals;

    /*
     *     bytes4(keccak256('balanceOf(address)')) == 0x70a08231
     *     bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e
     *     bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3
     *     bytes4(keccak256('getApproved(uint256)')) == 0x081812fc
     *     bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
     *     bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c
     *     bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde
     *
     *     => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^
     *        0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd
     */
    bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;

    constructor () public {
        // register the supported interfaces to conform to ERC721 via ERC165
        _registerInterface(_INTERFACE_ID_ERC721);
    }

    /**
     * @dev Gets the balance of the specified address.
     * @param owner address to query the balance of
     * @return uint256 representing the amount owned by the passed address
     */
    function balanceOf(address owner) public view returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");

        return _ownedTokensCount[owner].current();
    }

    /**
     * @dev Gets the owner of the specified token ID.
     * @param tokenId uint256 ID of the token to query the owner of
     * @return address currently marked as the owner of the given token ID
     */
    function ownerOf(uint256 tokenId) public view returns (address) {
        address owner = _tokenOwner[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");

        return owner;
    }

    /**
     * @dev Approves another address to transfer the given token ID
     * The zero address indicates there is no approved address.
     * There can only be one approved address per token at a given time.
     * Can only be called by the token owner or an approved operator.
     * @param to address to be approved for the given token ID
     * @param tokenId uint256 ID of the token to be approved
     */
    function approve(address to, uint256 tokenId) public {
        address owner = ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(msg.sender == owner || isApprovedForAll(owner, msg.sender),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _tokenApprovals[tokenId] = to;
        emit Approval(owner, to, tokenId);
    }

    /**
     * @dev Gets the approved address for a token ID, or zero if no address set
     * Reverts if the token ID does not exist.
     * @param tokenId uint256 ID of the token to query the approval of
     * @return address currently approved for the given token ID
     */
    function getApproved(uint256 tokenId) public view returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev Sets or unsets the approval of a given operator
     * An operator is allowed to transfer all tokens of the sender on their behalf.
     * @param to operator address to set the approval
     * @param approved representing the status of the approval to be set
     */
    function setApprovalForAll(address to, bool approved) public {
        require(to != msg.sender, "ERC721: approve to caller");

        _operatorApprovals[msg.sender][to] = approved;
        emit ApprovalForAll(msg.sender, to, approved);
    }

    /**
     * @dev Tells whether an operator is approved by a given owner.
     * @param owner owner address which you want to query the approval of
     * @param operator operator address which you want to query the approval of
     * @return bool whether the given operator is approved by the given owner
     */
    function isApprovedForAll(address owner, address operator) public view returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev Transfers the ownership of a given token ID to another address.
     * Usage of this method is discouraged, use `safeTransferFrom` whenever possible.
     * Requires the msg.sender to be the owner, approved, or operator.
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function transferFrom(address from, address to, uint256 tokenId) public {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(msg.sender, tokenId), "ERC721: transfer caller is not owner nor approved");

        _transferFrom(from, to, tokenId);
    }

    /**
     * @dev Safely transfers the ownership of a given token ID to another address
     * If the target address is a contract, it must implement `onERC721Received`,
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * Requires the msg.sender to be the owner, approved, or operator
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) public {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev Safely transfers the ownership of a given token ID to another address
     * If the target address is a contract, it must implement `onERC721Received`,
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * Requires the msg.sender to be the owner, approved, or operator
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes data to send along with a safe transfer check
     */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public {
        transferFrom(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether the specified token exists.
     * @param tokenId uint256 ID of the token to query the existence of
     * @return bool whether the token exists
     */
    function _exists(uint256 tokenId) internal view returns (bool) {
        address owner = _tokenOwner[tokenId];
        return owner != address(0);
    }

    /**
     * @dev Returns whether the given spender can transfer a given token ID.
     * @param spender address of the spender to query
     * @param tokenId uint256 ID of the token to be transferred
     * @return bool whether the msg.sender is approved for the given token ID,
     * is an operator of the owner, or is the owner of the token
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
    }

    /**
     * @dev Internal function to mint a new token.
     * Reverts if the given token ID already exists.
     * @param to The address that will own the minted token
     * @param tokenId uint256 ID of the token to be minted
     */
    function _mint(address to, uint256 tokenId) internal {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _tokenOwner[tokenId] = to;
        _ownedTokensCount[to].increment();

        emit Transfer(address(0), to, tokenId);
    }

    /**
     * @dev Internal function to burn a specific token.
     * Reverts if the token does not exist.
     * Deprecated, use _burn(uint256) instead.
     * @param owner owner of the token to burn
     * @param tokenId uint256 ID of the token being burned
     */
    function _burn(address owner, uint256 tokenId) internal {
        require(ownerOf(tokenId) == owner, "ERC721: burn of token that is not own");

        _clearApproval(tokenId);

        _ownedTokensCount[owner].decrement();
        _tokenOwner[tokenId] = address(0);

        emit Transfer(owner, address(0), tokenId);
    }

    /**
     * @dev Internal function to burn a specific token.
     * Reverts if the token does not exist.
     * @param tokenId uint256 ID of the token being burned
     */
    function _burn(uint256 tokenId) internal {
        _burn(ownerOf(tokenId), tokenId);
    }

    /**
     * @dev Internal function to transfer ownership of a given token ID to another address.
     * As opposed to transferFrom, this imposes no restrictions on msg.sender.
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function _transferFrom(address from, address to, uint256 tokenId) internal {
        require(ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _clearApproval(tokenId);

        _ownedTokensCount[from].decrement();
        _ownedTokensCount[to].increment();

        _tokenOwner[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Internal function to invoke `onERC721Received` on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * This function is deprecated.
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
        internal returns (bool)
    {
        if (!to.isContract()) {
            return true;
        }

        bytes4 retval = IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, _data);
        return (retval == _ERC721_RECEIVED);
    }

    /**
     * @dev Private function to clear current approval of a given token ID.
     * @param tokenId uint256 ID of the token to be transferred
     */
    function _clearApproval(uint256 tokenId) private {
        if (_tokenApprovals[tokenId] != address(0)) {
            _tokenApprovals[tokenId] = address(0);
        }
    }
}

File 18 of 22 : ERC721Burnable.sol
pragma solidity ^0.5.0;

import "./ERC721.sol";

/**
 * @title ERC721 Burnable Token
 * @dev ERC721 Token that can be irreversibly burned (destroyed).
 */
contract ERC721Burnable is ERC721 {
    /**
     * @dev Burns a specific ERC721 token.
     * @param tokenId uint256 id of the ERC721 token to be burned.
     */
    function burn(uint256 tokenId) public {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(msg.sender, tokenId), "ERC721Burnable: caller is not owner nor approved");
        _burn(tokenId);
    }
}

File 19 of 22 : IERC721.sol
pragma solidity ^0.5.0;

import "../../introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
contract IERC721 is IERC165 {
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of NFTs in `owner`'s account.
     */
    function balanceOf(address owner) public view returns (uint256 balance);

    /**
     * @dev Returns the owner of the NFT specified by `tokenId`.
     */
    function ownerOf(uint256 tokenId) public view returns (address owner);

    /**
     * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
     * another (`to`).
     *
     * 
     *
     * Requirements:
     * - `from`, `to` cannot be zero.
     * - `tokenId` must be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this
     * NFT by either `approve` or `setApproveForAll`.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) public;
    /**
     * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
     * another (`to`).
     *
     * Requirements:
     * - If the caller is not `from`, it must be approved to move this NFT by
     * either `approve` or `setApproveForAll`.
     */
    function transferFrom(address from, address to, uint256 tokenId) public;
    function approve(address to, uint256 tokenId) public;
    function getApproved(uint256 tokenId) public view returns (address operator);

    function setApprovalForAll(address operator, bool _approved) public;
    function isApprovedForAll(address owner, address operator) public view returns (bool);


    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public;
}

File 20 of 22 : IERC721Metadata.sol
pragma solidity ^0.5.0;

import "./IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
contract IERC721Metadata is IERC721 {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

File 21 of 22 : IERC721Receiver.sol
pragma solidity ^0.5.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
contract IERC721Receiver {
    /**
     * @notice Handle the receipt of an NFT
     * @dev The ERC721 smart contract calls this function on the recipient
     * after a `safeTransfer`. This function MUST return the function selector,
     * otherwise the caller will revert the transaction. The selector to be
     * returned can be obtained as `this.onERC721Received.selector`. This
     * function MAY throw to revert and reject the transfer.
     * Note: the ERC721 contract address is always the message sender.
     * @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 bytes4 `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
     */
    function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data)
    public returns (bytes4);
}

File 22 of 22 : Address.sol
pragma solidity ^0.5.0;

/**
 * @dev Collection of functions related to the address type,
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * This test is non-exhaustive, and there may be false-negatives: during the
     * execution of a contract's constructor, its address will be reported as
     * not containing a contract.
     *
     * > It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     */
    function isContract(address account) internal view returns (bool) {
        // 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.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }
}

Settings
{
  "remappings": [],
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "evmVersion": "petersburg",
  "libraries": {
    "": {}
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract ABI

[{"inputs":[{"internalType":"contract Registry","name":"registry","type":"address"},{"internalType":"contract MintingController","name":"mintingController","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"string","name":"keyIndex","type":"string"},{"indexed":false,"internalType":"string","name":"key","type":"string"}],"name":"NewKey","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ResetRecords","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"string","name":"keyIndex","type":"string"},{"indexed":true,"internalType":"string","name":"valueIndex","type":"string"},{"indexed":false,"internalType":"string","name":"key","type":"string"},{"indexed":false,"internalType":"string","name":"value","type":"string"}],"name":"Set","type":"event"},{"constant":true,"inputs":[{"internalType":"string","name":"key","type":"string"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"get","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"keyHash","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getByHash","outputs":[{"internalType":"string","name":"key","type":"string"},{"internalType":"string","name":"value","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"string[]","name":"keys","type":"string[]"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getMany","outputs":[{"internalType":"string[]","name":"","type":"string[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256[]","name":"keyHashes","type":"uint256[]"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getManyByHash","outputs":[{"internalType":"string[]","name":"keys","type":"string[]"},{"internalType":"string[]","name":"values","type":"string[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"keyHash","type":"uint256"}],"name":"hashToKey","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256[]","name":"hashes","type":"uint256[]"}],"name":"hashesToKeys","outputs":[{"internalType":"string[]","name":"","type":"string[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"nonceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"string[]","name":"keys","type":"string[]"},{"internalType":"string[]","name":"values","type":"string[]"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"preconfigure","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"string[]","name":"keys","type":"string[]"},{"internalType":"string[]","name":"values","type":"string[]"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"reconfigure","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"string[]","name":"keys","type":"string[]"},{"internalType":"string[]","name":"values","type":"string[]"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"reconfigureFor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"registry","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"reset","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"resetFor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"string","name":"key","type":"string"},{"internalType":"string","name":"value","type":"string"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"set","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"string","name":"key","type":"string"},{"internalType":"string","name":"value","type":"string"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"setFor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"string[]","name":"keys","type":"string[]"},{"internalType":"string[]","name":"values","type":"string[]"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"setMany","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"string[]","name":"keys","type":"string[]"},{"internalType":"string[]","name":"values","type":"string[]"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"setManyFor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b50604051620032cb380380620032cb8339818101604052620000379190810190620001ee565b8180600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550508073ffffffffffffffffffffffffffffffffffffffff16637b1039996040518163ffffffff1660e01b815260040160206040518083038186803b158015620000c157600080fd5b505afa158015620000d6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250620000fc9190810190620001c2565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146200013457600080fd5b80600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050620002d9565b6000815190506200018e816200028b565b92915050565b600081519050620001a581620002a5565b92915050565b600081519050620001bc81620002bf565b92915050565b600060208284031215620001d557600080fd5b6000620001e5848285016200017d565b91505092915050565b600080604083850312156200020257600080fd5b60006200021285828601620001ab565b9250506020620002258582860162000194565b9150509250929050565b60006200023c826200026b565b9050919050565b600062000250826200022f565b9050919050565b600062000264826200022f565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b62000296816200022f565b8114620002a257600080fd5b50565b620002b08162000243565b8114620002bc57600080fd5b50565b620002ca8162000257565b8114620002d657600080fd5b50565b612fe280620002e96000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c80638c87a4ea116100a2578063b87abc1111610071578063b87abc11146102f0578063c59740731461030c578063ce92b33e14610328578063e837ae7414610344578063ec129eea146103605761010b565b80638c87a4ea146102575780638f69c18814610287578063a3557e6c146102a3578063b85afd28146102bf5761010b565b806347c81699116100de57806347c81699146101bc578063672b9f81146101d85780636ccbae5f146102095780637b103999146102395761010b565b80631bd8cc1a146101105780631be5e7ed146101405780632c3d376d14610170578063310bd74b146101a0575b600080fd5b61012a60048036036101259190810190612121565b61037c565b6040516101379190612a2c565b60405180910390f35b61015a600480360361015591908101906124a3565b61066a565b6040516101679190612b58565b60405180910390f35b61018a600480360361018591908101906124f7565b61087a565b6040516101979190612b58565b60405180910390f35b6101ba60048036036101b591908101906124f7565b61092f565b005b6101d660048036036101d19190810190612361565b610a2a565b005b6101f260048036036101ed9190810190612578565b610bc6565b604051610200929190612b7a565b60405180910390f35b610223600480360361021e91908101906124f7565b610d01565b6040516102309190612c31565b60405180910390f35b610241610d1d565b60405161024e91906129a4565b60405180910390f35b610271600480360361026c91908101906122a3565b610d47565b60405161027e9190612a2c565b60405180910390f35b6102a1600480360361029c91908101906121f8565b610de1565b005b6102bd60048036036102b891908101906121f8565b610e91565b005b6102d960048036036102d491908101906122e4565b610f2d565b6040516102e7929190612a4e565b60405180910390f35b61030a60048036036103059190810190612520565b611133565b005b610326600480360361032191908101906123ea565b61120d565b005b610342600480360361033d9190810190612179565b611390565b005b61035e60048036036103599190810190612179565b6114a2565b005b61037a60048036036103759190810190612179565b6115b0565b005b606081600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b3f9e4cb826040518263ffffffff1660e01b81526004016103da9190612c31565b60206040518083038186803b1580156103f257600080fd5b505afa158015610406573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061042a91908101906120f8565b73ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1614610497576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161048e90612bd1565b60405180910390fd5b60008585905090506060816040519080825280602002602001820160405280156104d557816020015b60608152602001906001900390816104c05790505b50905060006003600087815260200190815260200160002054905060008090505b8381101561065b5760026000888152602001908152602001600020600083815260200190815260200160002089898381811061052e57fe5b905060200281018035600160200383360303811261054b57600080fd5b8083019250508135905060208201915067ffffffffffffffff81111561057057600080fd5b60018102360382131561058257600080fd5b60405161059092919061294e565b90815260200160405180910390208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156106325780601f1061060757610100808354040283529160200191610632565b820191906000526020600020905b81548152906001019060200180831161061557829003601f168201915b505050505083828151811061064357fe5b602002602001018190525080806001019150506104f6565b50819450505050509392505050565b606081600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b3f9e4cb826040518263ffffffff1660e01b81526004016106c89190612c31565b60206040518083038186803b1580156106e057600080fd5b505afa1580156106f4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061071891908101906120f8565b73ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1614610785576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161077c90612bd1565b60405180910390fd5b60026000848152602001908152602001600020600060036000868152602001908152602001600020548152602001908152602001600020846040516107ca9190612967565b90815260200160405180910390208054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561086c5780601f106108415761010080835404028352916020019161086c565b820191906000526020600020905b81548152906001019060200180831161084f57829003601f168201915b505050505091505092915050565b6060600460008381526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156109235780601f106108f857610100808354040283529160200191610923565b820191906000526020600020905b81548152906001019060200180831161090657829003601f168201915b50505050509050919050565b80600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663430c208133836040518363ffffffff1660e01b815260040161098d9291906129da565b60206040518083038186803b1580156109a557600080fd5b505afa1580156109b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506109dd9190810190612338565b610a1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a1390612bf1565b60405180910390fd5b610a2642836116ae565b5050565b80600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663430c208133836040518363ffffffff1660e01b8152600401610a889291906129da565b60206040518083038186803b158015610aa057600080fd5b505afa158015610ab4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ad89190810190612338565b610b17576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0e90612bf1565b60405180910390fd5b610bbe600360008481526020019081526020016000205487878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505086868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505085611787565b505050505050565b60608082600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b3f9e4cb826040518263ffffffff1660e01b8152600401610c259190612c31565b60206040518083038186803b158015610c3d57600080fd5b505afa158015610c51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c7591908101906120f8565b73ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1614610ce2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cd990612bd1565b60405180910390fd5b610ceb8561087a565b9250610cf7838561066a565b9150509250929050565b6000806000838152602001908152602001600020549050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600082519050606081604051908082528060200260200182016040528015610d8557816020015b6060815260200190600190039081610d705790505b50905060008090505b82811015610dd657610db2858281518110610da557fe5b602002602001015161087a565b828281518110610dbe57fe5b60200260200101819052508080600101915050610d8e565b508092505050919050565b610e6c63ce92b33e60e01b858585604051602401610e0193929190612a85565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050508051906020012083836119f1565b610e8b6003600084815260200190815260200160002054858585611b9e565b50505050565b610f1c63ec129eea60e01b858585604051602401610eb193929190612a85565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050508051906020012083836119f1565b610f27848484611bf9565b50505050565b60608082600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b3f9e4cb826040518263ffffffff1660e01b8152600401610f8c9190612c31565b60206040518083038186803b158015610fa457600080fd5b505afa158015610fb8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610fdc91908101906120f8565b73ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1614611049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161104090612bd1565b60405180910390fd5b6000855190508060405190808252806020026020018201604052801561108357816020015b606081526020019060019003908161106e5790505b509350806040519080825280602002602001820160405280156110ba57816020015b60608152602001906001900390816110a55790505b50925060008090505b81811015611129576110e88782815181106110da57fe5b602002602001015187610bc6565b8191508090508683815181106110fa57fe5b6020026020010186848151811061110d57fe5b60200260200101829052829052505080806001019150506110c3565b5050509250929050565b6111fe63310bd74b60e01b8460405160240161114f9190612c31565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050805190602001208484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506119f1565b61120842846116ae565b505050565b6112e06347c8169960e01b8888888888604051602401611231959493929190612b0f565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050805190602001208484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506119f1565b611387600360008581526020019081526020016000205488888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505087878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505086611787565b50505050505050565b80600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663430c208133836040518363ffffffff1660e01b81526004016113ee9291906129da565b60206040518083038186803b15801561140657600080fd5b505afa15801561141a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061143e9190810190612338565b61147d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161147490612bf1565b60405180910390fd5b61149c6003600084815260200190815260200160002054858585611b9e565b50505050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663aa271e1a336040518263ffffffff1660e01b81526004016114fd91906129bf565b60206040518083038186803b15801561151557600080fd5b505afa158015611529573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061154d9190810190612338565b61158c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161158390612c11565b60405180910390fd5b6115ab6003600083815260200190815260200160002054848484611b9e565b505050565b80600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663430c208133836040518363ffffffff1660e01b815260040161160e9291906129da565b60206040518083038186803b15801561162657600080fd5b505afa15801561163a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061165e9190810190612338565b61169d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169490612bf1565b60405180910390fd5b6116a8848484611bf9565b50505050565b816003600083815260200190815260200160002081905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663538361a78260006040518363ffffffff1660e01b8152600401611724929190612c4c565b600060405180830381600087803b15801561173e57600080fd5b505af1158015611752573d6000803e3d6000fd5b50505050807f185c30856dadb58bf097c1f665a52ada7029752dbcad008ea3fefc73bee8c9fe60405160405180910390a25050565b6000838051906020012060001c9050600080600260008581526020019081526020016000206000888152602001908152602001600020866040516117cb9190612967565b9081526020016040518091039020805460018160011615610100020316600290049050149050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663538361a784846040518363ffffffff1660e01b815260040161184e929190612c75565b600060405180830381600087803b15801561186857600080fd5b505af115801561187c573d6000803e3d6000fd5b5050505083600260008581526020019081526020016000206000888152602001908152602001600020866040516118b39190612967565b908152602001604051809103902090805190602001906118d4929190611d43565b50600060046000848152602001908152602001600020805460018160011615610100020316600290049050141561192e578460046000848152602001908152602001600020908051906020019061192c929190611d43565b505b801561198357846040516119429190612967565b6040518091039020837f7ae4f661958fbecc2f77be6b0eb280d2a6f604b29e1e7221c82b9da0c4af7f868760405161197a9190612b58565b60405180910390a35b836040516119919190612967565b6040518091039020856040516119a79190612967565b6040518091039020847f851ffe8e74d5015261dba0a1f9e1b0e5d42c5af5d2ad1908fee897c7d80a0d9288886040516119e1929190612b7a565b60405180910390a4505050505050565b60008060008481526020019081526020016000205490506000611a4f83611a41873086604051602001611a2693929190612911565b60405160208183030381529060405280519060200120611c27565b611c5790919063ffffffff16565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015611b375750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663430c208182866040518363ffffffff1660e01b8152600401611ae6929190612a03565b60206040518083038186803b158015611afe57600080fd5b505afa158015611b12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611b369190810190612338565b5b611b76576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b6d90612bb1565b60405180910390fd5b6001600080868152602001908152602001600020600082825401925050819055505050505050565b60008351905060008090505b81811015611bf157611be486868381518110611bc257fe5b6020026020010151868481518110611bd657fe5b602002602001015186611787565b8080600101915050611baa565b505050505050565b611c0342826116ae565b611c226003600083815260200190815260200160002054848484611b9e565b505050565b600081604051602001611c3a919061297e565b604051602081830303815290604052805190602001209050919050565b60006041825114611c6b5760009050611d3d565b60008060006020850151925060408501519150606085015160001a90507f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08260001c1115611cbf5760009350505050611d3d565b601b8160ff1614158015611cd75750601c8160ff1614155b15611ce85760009350505050611d3d565b60018682858560405160008152602001604052604051611d0b9493929190612aca565b6020604051602081039080840390855afa158015611d2d573d6000803e3d6000fd5b5050506020604051035193505050505b92915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611d8457805160ff1916838001178555611db2565b82800160010185558215611db2579182015b82811115611db1578251825591602001919060010190611d96565b5b509050611dbf9190611dc3565b5090565b611de591905b80821115611de1576000816000905550600101611dc9565b5090565b90565b600081519050611df781612f5a565b92915050565b60008083601f840112611e0f57600080fd5b8235905067ffffffffffffffff811115611e2857600080fd5b602083019150836020820283011115611e4057600080fd5b9250929050565b600082601f830112611e5857600080fd5b8135611e6b611e6682612ccb565b612c9e565b9150818183526020840193506020810190508360005b83811015611eb15781358601611e97888261203b565b845260208401935060208301925050600181019050611e81565b5050505092915050565b600082601f830112611ecc57600080fd5b8135611edf611eda82612cf3565b612c9e565b91508181835260208401935060208101905083856020840282011115611f0457600080fd5b60005b83811015611f345781611f1a88826120e3565b845260208401935060208301925050600181019050611f07565b5050505092915050565b600081519050611f4d81612f71565b92915050565b60008083601f840112611f6557600080fd5b8235905067ffffffffffffffff811115611f7e57600080fd5b602083019150836001820283011115611f9657600080fd5b9250929050565b600082601f830112611fae57600080fd5b8135611fc1611fbc82612d1b565b612c9e565b91508082526020830160208301858383011115611fdd57600080fd5b611fe8838284612ec2565b50505092915050565b60008083601f84011261200357600080fd5b8235905067ffffffffffffffff81111561201c57600080fd5b60208301915083600182028301111561203457600080fd5b9250929050565b600082601f83011261204c57600080fd5b813561205f61205a82612d47565b612c9e565b9150808252602083016020830185838301111561207b57600080fd5b612086838284612ec2565b50505092915050565b600082601f8301126120a057600080fd5b81356120b36120ae82612d73565b612c9e565b915080825260208301602083018583830111156120cf57600080fd5b6120da838284612ec2565b50505092915050565b6000813590506120f281612f88565b92915050565b60006020828403121561210a57600080fd5b600061211884828501611de8565b91505092915050565b60008060006040848603121561213657600080fd5b600084013567ffffffffffffffff81111561215057600080fd5b61215c86828701611dfd565b9350935050602061216f868287016120e3565b9150509250925092565b60008060006060848603121561218e57600080fd5b600084013567ffffffffffffffff8111156121a857600080fd5b6121b486828701611e47565b935050602084013567ffffffffffffffff8111156121d157600080fd5b6121dd86828701611e47565b92505060406121ee868287016120e3565b9150509250925092565b6000806000806080858703121561220e57600080fd5b600085013567ffffffffffffffff81111561222857600080fd5b61223487828801611e47565b945050602085013567ffffffffffffffff81111561225157600080fd5b61225d87828801611e47565b935050604061226e878288016120e3565b925050606085013567ffffffffffffffff81111561228b57600080fd5b61229787828801611f9d565b91505092959194509250565b6000602082840312156122b557600080fd5b600082013567ffffffffffffffff8111156122cf57600080fd5b6122db84828501611ebb565b91505092915050565b600080604083850312156122f757600080fd5b600083013567ffffffffffffffff81111561231157600080fd5b61231d85828601611ebb565b925050602061232e858286016120e3565b9150509250929050565b60006020828403121561234a57600080fd5b600061235884828501611f3e565b91505092915050565b60008060008060006060868803121561237957600080fd5b600086013567ffffffffffffffff81111561239357600080fd5b61239f88828901611ff1565b9550955050602086013567ffffffffffffffff8111156123be57600080fd5b6123ca88828901611ff1565b935093505060406123dd888289016120e3565b9150509295509295909350565b60008060008060008060006080888a03121561240557600080fd5b600088013567ffffffffffffffff81111561241f57600080fd5b61242b8a828b01611ff1565b9750975050602088013567ffffffffffffffff81111561244a57600080fd5b6124568a828b01611ff1565b955095505060406124698a828b016120e3565b935050606088013567ffffffffffffffff81111561248657600080fd5b6124928a828b01611f53565b925092505092959891949750929550565b600080604083850312156124b657600080fd5b600083013567ffffffffffffffff8111156124d057600080fd5b6124dc8582860161208f565b92505060206124ed858286016120e3565b9150509250929050565b60006020828403121561250957600080fd5b6000612517848285016120e3565b91505092915050565b60008060006040848603121561253557600080fd5b6000612543868287016120e3565b935050602084013567ffffffffffffffff81111561256057600080fd5b61256c86828701611f53565b92509250509250925092565b6000806040838503121561258b57600080fd5b6000612599858286016120e3565b92505060206125aa858286016120e3565b9150509250929050565b60006125c08383612763565b905092915050565b6125d181612e7a565b82525050565b6125e081612e1b565b82525050565b6125f76125f282612e1b565b612f04565b82525050565b600061260882612daf565b6126128185612ddd565b93508360208202850161262485612d9f565b8060005b85811015612660578484038952815161264185826125b4565b945061264c83612dd0565b925060208a01995050600181019050612628565b50829750879550505050505092915050565b61267b81612e39565b82525050565b61269261268d82612e39565b612f16565b82525050565b6126a181612e8c565b82525050565b60006126b38385612dff565b93506126c0838584612ec2565b6126c983612f3c565b840190509392505050565b60006126e08385612e10565b93506126ed838584612ec2565b82840190509392505050565b600061270482612dc5565b61270e8185612dff565b935061271e818560208601612ed1565b61272781612f3c565b840191505092915050565b600061273d82612dc5565b6127478185612e10565b9350612757818560208601612ed1565b80840191505092915050565b600061276e82612dba565b6127788185612dee565b9350612788818560208601612ed1565b61279181612f3c565b840191505092915050565b60006127a9601c83612e10565b91507f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000830152601c82019050919050565b60006127e9601183612dff565b91507f494e56414c49445f5349474e41545552450000000000000000000000000000006000830152602082019050919050565b6000612829601d83612dff565b91507f5245534f4c5645525f44455441434845445f46524f4d5f444f4d41494e0000006000830152602082019050919050565b6000612869601f83612dff565b91507f53454e4445525f49535f4e4f545f415050524f5645445f4f525f4f574e4552006000830152602082019050919050565b60006128a9601483612dff565b91507f53454e4445525f49535f4e4f545f4d494e5445520000000000000000000000006000830152602082019050919050565b6128e581612e63565b82525050565b6128fc6128f782612e63565b612f32565b82525050565b61290b81612e6d565b82525050565b600061291d8286612681565b60208201915061292d82856125e6565b60148201915061293d82846128eb565b602082019150819050949350505050565b600061295b8284866126d4565b91508190509392505050565b60006129738284612732565b915081905092915050565b60006129898261279c565b91506129958284612681565b60208201915081905092915050565b60006020820190506129b960008301846125d7565b92915050565b60006020820190506129d460008301846125c8565b92915050565b60006040820190506129ef60008301856125c8565b6129fc60208301846128dc565b9392505050565b6000604082019050612a1860008301856125d7565b612a2560208301846128dc565b9392505050565b60006020820190508181036000830152612a4681846125fd565b905092915050565b60006040820190508181036000830152612a6881856125fd565b90508181036020830152612a7c81846125fd565b90509392505050565b60006060820190508181036000830152612a9f81866125fd565b90508181036020830152612ab381856125fd565b9050612ac260408301846128dc565b949350505050565b6000608082019050612adf6000830187612672565b612aec6020830186612902565b612af96040830185612672565b612b066060830184612672565b95945050505050565b60006060820190508181036000830152612b2a8187896126a7565b90508181036020830152612b3f8185876126a7565b9050612b4e60408301846128dc565b9695505050505050565b60006020820190508181036000830152612b7281846126f9565b905092915050565b60006040820190508181036000830152612b9481856126f9565b90508181036020830152612ba881846126f9565b90509392505050565b60006020820190508181036000830152612bca816127dc565b9050919050565b60006020820190508181036000830152612bea8161281c565b9050919050565b60006020820190508181036000830152612c0a8161285c565b9050919050565b60006020820190508181036000830152612c2a8161289c565b9050919050565b6000602082019050612c4660008301846128dc565b92915050565b6000604082019050612c6160008301856128dc565b612c6e6020830184612698565b9392505050565b6000604082019050612c8a60008301856128dc565b612c9760208301846128dc565b9392505050565b6000604051905081810181811067ffffffffffffffff82111715612cc157600080fd5b8060405250919050565b600067ffffffffffffffff821115612ce257600080fd5b602082029050602081019050919050565b600067ffffffffffffffff821115612d0a57600080fd5b602082029050602081019050919050565b600067ffffffffffffffff821115612d3257600080fd5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff821115612d5e57600080fd5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff821115612d8a57600080fd5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6000612e2682612e43565b9050919050565b60008115159050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b6000612e8582612e9e565b9050919050565b6000612e9782612e63565b9050919050565b6000612ea982612eb0565b9050919050565b6000612ebb82612e43565b9050919050565b82818337600083830152505050565b60005b83811015612eef578082015181840152602081019050612ed4565b83811115612efe576000848401525b50505050565b6000612f0f82612f20565b9050919050565b6000819050919050565b6000612f2b82612f4d565b9050919050565b6000819050919050565b6000601f19601f8301169050919050565b60008160601b9050919050565b612f6381612e1b565b8114612f6e57600080fd5b50565b612f7a81612e2d565b8114612f8557600080fd5b50565b612f9181612e63565b8114612f9c57600080fd5b5056fea365627a7a723158206ff3fb4bd7f353da264ae130b9e105542cac40162f8b09b02e60c837199e87c76c6578706572696d656e74616cf564736f6c634300050c0040000000000000000000000000aad76bea7cfec82927239415bb18d2e93518ecbb00000000000000000000000051765307aeb3df2e647014a2c501d5324212467c

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

000000000000000000000000aad76bea7cfec82927239415bb18d2e93518ecbb00000000000000000000000051765307aeb3df2e647014a2c501d5324212467c

-----Decoded View---------------
Arg [0] : registry (address): 0xaad76bea7cfec82927239415bb18d2e93518ecbb
Arg [1] : mintingController (address): 0x51765307aeb3df2e647014a2c501d5324212467c

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000aad76bea7cfec82927239415bb18d2e93518ecbb
Arg [1] : 00000000000000000000000051765307aeb3df2e647014a2c501d5324212467c


Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.