Contract 0xbcB32f13f90978a9e059E8Cb40FaA9e6619d98e7

Contract Overview

Balance:
0 Ether
Txn Hash
Method
Block
From
To
Value
0x55af707328760cbbe6a70238c89908a73683465681a6493ea10a0d2f02b90b2bRenounce Minter97848572021-12-09 13:35:38209 days 6 hrs ago0x3c45a6935d3d2eb9d1e348faafca78bdd6ae0906 IN  0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether0.0000307 1.00000001
0x304a92e155b67d7ecbf044d344c4da88d0b16ab95a560798245e2b84006164e4Relay88971862021-07-07 22:05:56363 days 21 hrs ago0xc5db83845f530c966e022d31717b18f5765639d0 IN  0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether0.000149281
0x20430309c65d803ce531d239262c6b3c11a26e79f69df589efd31e24aa1c2b1cRelay88968752021-07-07 20:47:48363 days 23 hrs ago0xc5db83845f530c966e022d31717b18f5765639d0 IN  0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether0.000149251
0x4c085d68e27d68f58fd20bea83099488af00feff92312dd617fbc6aff614558eRelay88963052021-07-07 18:23:55364 days 1 hr ago0xc5db83845f530c966e022d31717b18f5765639d0 IN  0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether0.000149241
0xb5cd32f16f85fc806513867e4ff0f00ae20ef8d82049b40a8e32cf3c77766b2dMint SLD To Defa...88960692021-07-07 17:24:39364 days 2 hrs ago0x7ac8596cfbb0504dfdec08d5088b67e7fbfae47f IN  0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether0.0026908820
0xb030cce366c341111cc8846b138f76a46a4a404dd9cf249315b856c80bf76f99Relay88951102021-07-07 13:24:25364 days 6 hrs ago0xc5db83845f530c966e022d31717b18f5765639d0 IN  0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether0.000149161
0x7e855f26c99cc7dba39a670bfb98441b8672c638ddd581785c2f97cae8e72982Mint SLD To Defa...88892202021-07-06 12:49:52365 days 7 hrs ago0x7ac8596cfbb0504dfdec08d5088b67e7fbfae47f IN  0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether0.0026891420
0x38b9b52eb374a52985227e9370c94a467fd8a029e373ca780a7fa2bc85981a89Mint SLD To Defa...88892162021-07-06 12:48:52365 days 7 hrs ago0xdb36b5c4cf1d96f020d7629a09cb54ab787414d6 IN  0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether0.0026891420
0x0c0a156476fbc67f2946a37f240ad8c990e7fb73b9ac3fab3861ffddc3ea45cfMint SLD To Defa...88892162021-07-06 12:48:52365 days 7 hrs ago0x903aa579b9ef13862fda73275b349017d8fd09eb IN  0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether0.0026891420
0xaee245531e42db3a41801859883b65a548af725a898abbe98f90f6a1a1b4a9ebMint SLD To Defa...88891532021-07-06 12:33:07365 days 7 hrs ago0xdb36b5c4cf1d96f020d7629a09cb54ab787414d6 IN  0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether0.0026891420
0xb947309f2ec54850e4673aa8a3f3f72df8fd7d017e42926f15c7ae4c07c98845Mint SLD To Defa...88891532021-07-06 12:33:07365 days 7 hrs ago0x7ac8596cfbb0504dfdec08d5088b67e7fbfae47f IN  0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether0.0026891420
0x31b788fdeabb23e74a03eed9ad7a636b323e8fbbda40befe0a262348bd8c6cacMint SLD To Defa...88891532021-07-06 12:33:07365 days 7 hrs ago0xb83180632b72f988585af02fc27229bf2eabd139 IN  0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether0.0026908820
0x7e2343b3f365cd4020df865aeafc13ae661bbcd09d5345471beb859a93bb22a6Mint SLD To Defa...88890002021-07-06 11:54:50365 days 8 hrs ago0xb83180632b72f988585af02fc27229bf2eabd139 IN  0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether0.0026908820
0xae31dab664047192accc74bdf79177f4a8c98e40c460f0bbcff8dd61ef895c09Mint SLD To Defa...88889962021-07-06 11:53:50365 days 8 hrs ago0x7ac8596cfbb0504dfdec08d5088b67e7fbfae47f IN  0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether0.0026908820
0xb6a7b8918e1b3990bb5ea3acc6a45ba00f71416cfa5b71b50d1c8982e5e66e6bMint SLD To Defa...88889942021-07-06 11:53:20365 days 8 hrs ago0x903aa579b9ef13862fda73275b349017d8fd09eb IN  0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether0.0026908820
0x126f39629af53157626a67fd9ee4b64bb04ed76f234169d025616ebe35619906Mint SLD To Defa...88889822021-07-06 11:50:19365 days 8 hrs ago0xdb36b5c4cf1d96f020d7629a09cb54ab787414d6 IN  0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether0.0030328820
0x3513bcd5290a47eb5a9c344aa3f359665ae9e89eeddb70410f17f167f209f5b3Relay88212612021-06-24 17:23:36377 days 2 hrs ago0x499dd6d875787869670900a2130223d85d4f6aa7 IN  0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether0.000149241
0xe8a97e9058b19766e77a804a1d315cb50fbd95e918ec3db21b770ec9ac6334caRelay88212592021-06-24 17:23:06377 days 2 hrs ago0x499dd6d875787869670900a2130223d85d4f6aa7 IN  0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether0.000149181
0x9176bf90226958864c15e2d5888d8280919017ba5807eedd0367daa06f31a2adRelay88210152021-06-24 16:22:04377 days 3 hrs ago0x499dd6d875787869670900a2130223d85d4f6aa7 IN  0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether0.00014921
0x4523bae1dadffb86385e0c7fa99ccb439cb3ef95a37f773ee761b5dbe356ffd3Relay88209622021-06-24 16:08:49377 days 3 hrs ago0x499dd6d875787869670900a2130223d85d4f6aa7 IN  0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether0.000149341
0xb55462685296a68f91fe88878dbfa8337743310071da78bf1133a613854c626cRelay88207192021-06-24 15:08:03377 days 4 hrs ago0x499dd6d875787869670900a2130223d85d4f6aa7 IN  0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether0.000171441
0xe9bf73dff5282a4e8a82f2027efcada39c97c9209d2a080b60bc6e840ac12a6aRelay88206102021-06-24 14:40:47377 days 5 hrs ago0x499dd6d875787869670900a2130223d85d4f6aa7 IN  0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether0.00014911
0x66e6fc5598c6a5b59e49d54ed02955760923e6cbcb461eee408d602e38588e54Relay88196592021-06-24 10:42:55377 days 9 hrs ago0xc5db83845f530c966e022d31717b18f5765639d0 IN  0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether0.000149141
0x8b9b49c16d8165541344edf16c1f6a858f40bd5fba495e75a407e167aa1b577eRelay87475832021-06-11 22:18:58389 days 21 hrs ago0xc5db83845f530c966e022d31717b18f5765639d0 IN  0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether0.000171451
0xff093ecb72ee823e3b9ce940167de4d1224f2ac90a88fbd676747bc6f8b72859Relay87462672021-06-11 16:49:42390 days 3 hrs ago0xc5db83845f530c966e022d31717b18f5765639d0 IN  0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether0.000194111
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x55af707328760cbbe6a70238c89908a73683465681a6493ea10a0d2f02b90b2b97848572021-12-09 13:35:38209 days 6 hrs ago 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e7 0x51765307aeb3df2e647014a2c501d5324212467c0 Ether
0x304a92e155b67d7ecbf044d344c4da88d0b16ab95a560798245e2b84006164e488971862021-07-07 22:05:56363 days 21 hrs ago 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e7 0x51765307aeb3df2e647014a2c501d5324212467c0 Ether
0x304a92e155b67d7ecbf044d344c4da88d0b16ab95a560798245e2b84006164e488971862021-07-07 22:05:56363 days 21 hrs ago 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e7 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether
0x20430309c65d803ce531d239262c6b3c11a26e79f69df589efd31e24aa1c2b1c88968752021-07-07 20:47:48363 days 23 hrs ago 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e7 0x51765307aeb3df2e647014a2c501d5324212467c0 Ether
0x20430309c65d803ce531d239262c6b3c11a26e79f69df589efd31e24aa1c2b1c88968752021-07-07 20:47:48363 days 23 hrs ago 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e7 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether
0x4c085d68e27d68f58fd20bea83099488af00feff92312dd617fbc6aff614558e88963052021-07-07 18:23:55364 days 1 hr ago 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e7 0x51765307aeb3df2e647014a2c501d5324212467c0 Ether
0x4c085d68e27d68f58fd20bea83099488af00feff92312dd617fbc6aff614558e88963052021-07-07 18:23:55364 days 1 hr ago 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e7 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether
0xb5cd32f16f85fc806513867e4ff0f00ae20ef8d82049b40a8e32cf3c77766b2d88960692021-07-07 17:24:39364 days 2 hrs ago 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e7 0x51765307aeb3df2e647014a2c501d5324212467c0 Ether
0xb030cce366c341111cc8846b138f76a46a4a404dd9cf249315b856c80bf76f9988951102021-07-07 13:24:25364 days 6 hrs ago 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e7 0x51765307aeb3df2e647014a2c501d5324212467c0 Ether
0xb030cce366c341111cc8846b138f76a46a4a404dd9cf249315b856c80bf76f9988951102021-07-07 13:24:25364 days 6 hrs ago 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e7 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether
0x7e855f26c99cc7dba39a670bfb98441b8672c638ddd581785c2f97cae8e7298288892202021-07-06 12:49:52365 days 7 hrs ago 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e7 0x51765307aeb3df2e647014a2c501d5324212467c0 Ether
0x38b9b52eb374a52985227e9370c94a467fd8a029e373ca780a7fa2bc85981a8988892162021-07-06 12:48:52365 days 7 hrs ago 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e7 0x51765307aeb3df2e647014a2c501d5324212467c0 Ether
0x0c0a156476fbc67f2946a37f240ad8c990e7fb73b9ac3fab3861ffddc3ea45cf88892162021-07-06 12:48:52365 days 7 hrs ago 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e7 0x51765307aeb3df2e647014a2c501d5324212467c0 Ether
0xaee245531e42db3a41801859883b65a548af725a898abbe98f90f6a1a1b4a9eb88891532021-07-06 12:33:07365 days 7 hrs ago 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e7 0x51765307aeb3df2e647014a2c501d5324212467c0 Ether
0xb947309f2ec54850e4673aa8a3f3f72df8fd7d017e42926f15c7ae4c07c9884588891532021-07-06 12:33:07365 days 7 hrs ago 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e7 0x51765307aeb3df2e647014a2c501d5324212467c0 Ether
0x31b788fdeabb23e74a03eed9ad7a636b323e8fbbda40befe0a262348bd8c6cac88891532021-07-06 12:33:07365 days 7 hrs ago 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e7 0x51765307aeb3df2e647014a2c501d5324212467c0 Ether
0x7e2343b3f365cd4020df865aeafc13ae661bbcd09d5345471beb859a93bb22a688890002021-07-06 11:54:50365 days 8 hrs ago 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e7 0x51765307aeb3df2e647014a2c501d5324212467c0 Ether
0xae31dab664047192accc74bdf79177f4a8c98e40c460f0bbcff8dd61ef895c0988889962021-07-06 11:53:50365 days 8 hrs ago 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e7 0x51765307aeb3df2e647014a2c501d5324212467c0 Ether
0xb6a7b8918e1b3990bb5ea3acc6a45ba00f71416cfa5b71b50d1c8982e5e66e6b88889942021-07-06 11:53:20365 days 8 hrs ago 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e7 0x51765307aeb3df2e647014a2c501d5324212467c0 Ether
0x126f39629af53157626a67fd9ee4b64bb04ed76f234169d025616ebe3561990688889822021-07-06 11:50:19365 days 8 hrs ago 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e7 0x51765307aeb3df2e647014a2c501d5324212467c0 Ether
0x3513bcd5290a47eb5a9c344aa3f359665ae9e89eeddb70410f17f167f209f5b388212612021-06-24 17:23:36377 days 2 hrs ago 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e7 0x51765307aeb3df2e647014a2c501d5324212467c0 Ether
0x3513bcd5290a47eb5a9c344aa3f359665ae9e89eeddb70410f17f167f209f5b388212612021-06-24 17:23:36377 days 2 hrs ago 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e7 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether
0xe8a97e9058b19766e77a804a1d315cb50fbd95e918ec3db21b770ec9ac6334ca88212592021-06-24 17:23:06377 days 2 hrs ago 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e7 0x51765307aeb3df2e647014a2c501d5324212467c0 Ether
0xe8a97e9058b19766e77a804a1d315cb50fbd95e918ec3db21b770ec9ac6334ca88212592021-06-24 17:23:06377 days 2 hrs ago 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e7 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e70 Ether
0x9176bf90226958864c15e2d5888d8280919017ba5807eedd0367daa06f31a2ad88210152021-06-24 16:22:04377 days 3 hrs ago 0xbcb32f13f90978a9e059e8cb40faa9e6619d98e7 0x51765307aeb3df2e647014a2c501d5324212467c0 Ether
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
WhitelistedMinter

Compiler Version
v0.5.12+commit.7709ece9

Optimization Enabled:
No with 200 runs

Other Settings:
petersburg EvmVersion
File 1 of 26 : 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 26 : 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 26 : 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 26 : 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 26 : 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 26 : 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 26 : 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 26 : BulkWhitelistedRole.sol
pragma solidity 0.5.12;

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

/**
 * @title BulkWhitelistedRole
 * @dev a Whitelist role defined using the Open Zeppelin Role system with the addition of bulkAddWhitelisted and
 * bulkRemoveWhitelisted.
 * @dev Whitelisted accounts have been approved by a WhitelistAdmin to perform certain actions (e.g. participate in a
 * crowdsale). This role is special in that the only accounts that can add it are WhitelistAdmins (who can also remove
 * it), and not Whitelisteds themselves.
 */
contract BulkWhitelistedRole is WhitelistedRole {

    function bulkAddWhitelisted(address[] memory accounts) public onlyWhitelistAdmin {
        for (uint256 index = 0; index < accounts.length; index++) {
            _addWhitelisted(accounts[index]);
        }
    }

    function bulkRemoveWhitelisted(address[] memory accounts) public onlyWhitelistAdmin {
        for (uint256 index = 0; index < accounts.length; index++) {
            _removeWhitelisted(accounts[index]);
        }
    }

}

File 9 of 26 : 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 10 of 26 : 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 11 of 26 : WhitelistedMinter.sol
pragma solidity 0.5.12;
pragma experimental ABIEncoderV2;

import '@openzeppelin/contracts/cryptography/ECDSA.sol';
import "./BulkWhitelistedRole.sol";
import "../controllers/IMintingController.sol";
import "../controllers/MintingController.sol";
import "../Registry.sol";
import "../Resolver.sol";

/**
 * @title WhitelistedMinter
 * @dev Defines the functions for distribution of Second Level Domains (SLD)s.
 */
contract WhitelistedMinter is IMintingController, BulkWhitelistedRole {
    using ECDSA for bytes32;

    event Relayed(address indexed sender, address indexed signer, bytes4 indexed funcSig, bytes32 dataHash);

    string public constant NAME = 'Unstoppable Whitelisted Minter';
    string public constant VERSION = '0.3.0';

    MintingController internal _mintingController;
    Resolver internal _resolver;
    Registry internal _registry;

    /*
     * bytes4(keccak256('mintSLD(address,string)')) == 0x4c0b0ed2
     */
    bytes4 private constant _SIG_MINT = 0x4c0b0ed2;

    /*
     * bytes4(keccak256('mintSLDToDefaultResolver(address,string,string[],string[])')) == 0x3d7989fe
     */
    bytes4 private constant _SIG_MINT_DEF_RESOLVER = 0x3d7989fe;

    /*
     * bytes4(keccak256('mintSLDToResolver(address,string,string[],string[],address)')) == 0xaceb4764
     */
    bytes4 private constant _SIG_MINT_RESOLVER = 0xaceb4764;

    /*
     * bytes4(keccak256('safeMintSLD(address,string)')) == 0xb2da2979
     */
    bytes4 private constant _SIG_SAFE_MINT = 0xb2da2979;

    /*
     * bytes4(keccak256('safeMintSLD(address,string,bytes)')) == 0xbe362e2e
     */
    bytes4 private constant _SIG_SAFE_MINT_DATA = 0xbe362e2e;

    /*
     * bytes4(keccak256('safeMintSLDToDefaultResolver(address,string,string[],string[])')) == 0x61050ffd
     */
    bytes4 private constant _SIG_SAFE_MINT_DEF_RESOLVER = 0x61050ffd;

    /*
     * bytes4(keccak256('safeMintSLDToDefaultResolver(address,string,string[],string[],bytes)')) == 0x4b18abea
     */
    bytes4 private constant _SIG_SAFE_MINT_DEF_RESOLVER_DATA = 0x4b18abea;

    /*
     * bytes4(keccak256('safeMintSLDToResolver(address,string,string[],string[],address)')) == 0x4b44c01a
     */
    bytes4 private constant _SIG_SAFE_MINT_RESOLVER = 0x4b44c01a;

    /*
     * bytes4(keccak256('safeMintSLDToResolver(address,string,string[],string[],bytes,address)')) == 0x898851f8
     */
    bytes4 private constant _SIG_SAFE_MINT_RESOLVER_DATA = 0x898851f8;

    constructor(MintingController mintingController) public {
        _mintingController = mintingController;
        _registry = Registry(mintingController.registry());
        _addWhitelisted(address(this));
    }

    function renounceMinter() external onlyWhitelistAdmin {
        _mintingController.renounceMinter();
    }

    /**
     * Renounce whitelisted account with funds' forwarding
     */
    function closeWhitelisted(address payable receiver)
        external
        payable
        onlyWhitelisted
    {
        require(receiver != address(0x0), "WhitelistedMinter: RECEIVER_IS_EMPTY");

        renounceWhitelisted();
        receiver.transfer(msg.value);
    }

    /**
     * Replace whitelisted account by new account with funds' forwarding
     */
    function rotateWhitelisted(address payable receiver)
        external
        payable
        onlyWhitelisted
    {
        require(receiver != address(0x0), "WhitelistedMinter: RECEIVER_IS_EMPTY");

        _addWhitelisted(receiver);
        renounceWhitelisted();
        receiver.transfer(msg.value);
    }

    function mintSLD(address to, string calldata label)
        external
        onlyWhitelisted
    {
        _mintingController.mintSLD(to, label);
    }

    function safeMintSLD(address to, string calldata label)
        external
        onlyWhitelisted
    {
        _mintingController.safeMintSLD(to, label);
    }

    function safeMintSLD(
        address to,
        string calldata label,
        bytes calldata _data
    ) external onlyWhitelisted {
        _mintingController.safeMintSLD(to, label, _data);
    }

    function mintSLDToDefaultResolver(
        address to,
        string memory label,
        string[] memory keys,
        string[] memory values
    ) public onlyWhitelisted {
        mintSLDToResolver(to, label, keys, values, address(_resolver));
    }

    function mintSLDToResolver(
        address to,
        string memory label,
        string[] memory keys,
        string[] memory values,
        address resolver
    ) public onlyWhitelisted {
        _mintingController.mintSLDWithResolver(to, label, resolver);
        preconfigureResolver(label, keys, values, resolver);
    }

    function safeMintSLDToDefaultResolver(
        address to,
        string memory label,
        string[] memory keys,
        string[] memory values
    ) public onlyWhitelisted {
        safeMintSLDToResolver(to, label, keys, values, address(_resolver));
    }

    function safeMintSLDToResolver(
        address to,
        string memory label,
        string[] memory keys,
        string[] memory values,
        address resolver
    ) public onlyWhitelisted {
        _mintingController.safeMintSLDWithResolver(to, label, resolver);
        preconfigureResolver(label, keys, values, resolver);
    }

    function safeMintSLDToDefaultResolver(
        address to,
        string memory label,
        string[] memory keys,
        string[] memory values,
        bytes memory _data
    ) public onlyWhitelisted {
        safeMintSLDToResolver(to, label, keys, values, _data, address(_resolver));
    }

    function safeMintSLDToResolver(
        address to,
        string memory label,
        string[] memory keys,
        string[] memory values,
        bytes memory _data,
        address resolver
    ) public onlyWhitelisted {
        _mintingController.safeMintSLDWithResolver(to, label, resolver, _data);
        preconfigureResolver(label, keys, values, resolver);
    }

    function setDefaultResolver(address resolver) external onlyWhitelistAdmin {
        _resolver = Resolver(resolver);
    }

    function getDefaultResolver() external view returns (address) {
        return address(_resolver);
    }

    /**
     * Relay allows execute transaction on behalf of whitelisted minter.
     * The function verify signature of call data parameter before execution.
     * It allows anybody send transaction on-chain when minter has provided proper parameters.
     * The function allows to relaying calls of fixed functions. The restriction defined in function `verifyCall`
     */
    function relay(bytes calldata data, bytes calldata signature) external returns(bytes memory) {
        bytes32 dataHash = keccak256(data);
        address signer = verifySigner(dataHash, signature);
        bytes memory _data = data;
        bytes4 funcSig = verifyCall(_data);

        /* solium-disable-next-line security/no-low-level-calls */
        (bool success, bytes memory result) = address(this).call(data);
        if (success == false) {
            /* solium-disable-next-line security/no-inline-assembly */
            assembly {
                let ptr := mload(0x40)
                let size := returndatasize
                returndatacopy(ptr, 0, size)
                revert(ptr, size)
            }
        }

        emit Relayed(msg.sender, signer, funcSig, dataHash);
        return result;
    }

    function preconfigureResolver(
        string memory label,
        string[] memory keys,
        string[] memory values,
        address resolver
    ) private {
        if(keys.length == 0) {
            return;
        }

        Resolver(resolver).preconfigure(keys, values, _registry.childIdOf(_registry.root(), label));
    }

    function verifySigner(bytes32 data, bytes memory signature) private view returns(address signer) {
        signer = keccak256(abi.encodePacked(data, address(this)))
            .toEthSignedMessageHash()
            .recover(signature);
        require(signer != address(0), 'WhitelistedMinter: SIGNATURE_IS_INVALID');
        require(isWhitelisted(signer), 'WhitelistedMinter: SIGNER_IS_NOT_WHITELISTED');
    }

    function verifyCall(bytes memory data) private pure returns(bytes4 sig) {
        /* solium-disable-next-line security/no-inline-assembly */
        assembly {
            sig := mload(add(data, add(0x20, 0)))
        }

        bool isSupported = sig == _SIG_MINT ||
            sig == _SIG_MINT_DEF_RESOLVER ||
            sig == _SIG_MINT_RESOLVER ||
            sig == _SIG_SAFE_MINT ||
            sig == _SIG_SAFE_MINT_DATA ||
            sig == _SIG_SAFE_MINT_DEF_RESOLVER ||
            sig == _SIG_SAFE_MINT_DEF_RESOLVER_DATA ||
            sig == _SIG_SAFE_MINT_RESOLVER ||
            sig == _SIG_SAFE_MINT_RESOLVER_DATA;

        require(isSupported, 'WhitelistedMinter: UNSUPPORTED_CALL');
    }
}

File 12 of 26 : 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 13 of 26 : 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 14 of 26 : WhitelistAdminRole.sol
pragma solidity ^0.5.0;

import "../Roles.sol";

/**
 * @title WhitelistAdminRole
 * @dev WhitelistAdmins are responsible for assigning and removing Whitelisted accounts.
 */
contract WhitelistAdminRole {
    using Roles for Roles.Role;

    event WhitelistAdminAdded(address indexed account);
    event WhitelistAdminRemoved(address indexed account);

    Roles.Role private _whitelistAdmins;

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

    modifier onlyWhitelistAdmin() {
        require(isWhitelistAdmin(msg.sender), "WhitelistAdminRole: caller does not have the WhitelistAdmin role");
        _;
    }

    function isWhitelistAdmin(address account) public view returns (bool) {
        return _whitelistAdmins.has(account);
    }

    function addWhitelistAdmin(address account) public onlyWhitelistAdmin {
        _addWhitelistAdmin(account);
    }

    function renounceWhitelistAdmin() public {
        _removeWhitelistAdmin(msg.sender);
    }

    function _addWhitelistAdmin(address account) internal {
        _whitelistAdmins.add(account);
        emit WhitelistAdminAdded(account);
    }

    function _removeWhitelistAdmin(address account) internal {
        _whitelistAdmins.remove(account);
        emit WhitelistAdminRemoved(account);
    }
}

File 15 of 26 : WhitelistedRole.sol
pragma solidity ^0.5.0;

import "../Roles.sol";
import "./WhitelistAdminRole.sol";

/**
 * @title WhitelistedRole
 * @dev Whitelisted accounts have been approved by a WhitelistAdmin to perform certain actions (e.g. participate in a
 * crowdsale). This role is special in that the only accounts that can add it are WhitelistAdmins (who can also remove
 * it), and not Whitelisteds themselves.
 */
contract WhitelistedRole is WhitelistAdminRole {
    using Roles for Roles.Role;

    event WhitelistedAdded(address indexed account);
    event WhitelistedRemoved(address indexed account);

    Roles.Role private _whitelisteds;

    modifier onlyWhitelisted() {
        require(isWhitelisted(msg.sender), "WhitelistedRole: caller does not have the Whitelisted role");
        _;
    }

    function isWhitelisted(address account) public view returns (bool) {
        return _whitelisteds.has(account);
    }

    function addWhitelisted(address account) public onlyWhitelistAdmin {
        _addWhitelisted(account);
    }

    function removeWhitelisted(address account) public onlyWhitelistAdmin {
        _removeWhitelisted(account);
    }

    function renounceWhitelisted() public {
        _removeWhitelisted(msg.sender);
    }

    function _addWhitelisted(address account) internal {
        _whitelisteds.add(account);
        emit WhitelistedAdded(account);
    }

    function _removeWhitelisted(address account) internal {
        _whitelisteds.remove(account);
        emit WhitelistedRemoved(account);
    }
}

File 16 of 26 : 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 17 of 26 : 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 18 of 26 : 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 19 of 26 : 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 20 of 26 : 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 21 of 26 : 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 22 of 26 : 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 23 of 26 : 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 24 of 26 : 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 25 of 26 : 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 26 of 26 : 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 MintingController","name":"mintingController","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"signer","type":"address"},{"indexed":true,"internalType":"bytes4","name":"funcSig","type":"bytes4"},{"indexed":false,"internalType":"bytes32","name":"dataHash","type":"bytes32"}],"name":"Relayed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"WhitelistAdminAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"WhitelistAdminRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"WhitelistedAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"WhitelistedRemoved","type":"event"},{"constant":true,"inputs":[],"name":"NAME","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addWhitelistAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addWhitelisted","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"bulkAddWhitelisted","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"bulkRemoveWhitelisted","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address payable","name":"receiver","type":"address"}],"name":"closeWhitelisted","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"getDefaultResolver","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isWhitelistAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"string","name":"label","type":"string"}],"name":"mintSLD","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"string","name":"label","type":"string"},{"internalType":"string[]","name":"keys","type":"string[]"},{"internalType":"string[]","name":"values","type":"string[]"}],"name":"mintSLDToDefaultResolver","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"string","name":"label","type":"string"},{"internalType":"string[]","name":"keys","type":"string[]"},{"internalType":"string[]","name":"values","type":"string[]"},{"internalType":"address","name":"resolver","type":"address"}],"name":"mintSLDToResolver","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"relay","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeWhitelisted","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceMinter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceWhitelistAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceWhitelisted","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address payable","name":"receiver","type":"address"}],"name":"rotateWhitelisted","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"string","name":"label","type":"string"}],"name":"safeMintSLD","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"string","name":"label","type":"string"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeMintSLD","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"string","name":"label","type":"string"},{"internalType":"string[]","name":"keys","type":"string[]"},{"internalType":"string[]","name":"values","type":"string[]"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeMintSLDToDefaultResolver","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"string","name":"label","type":"string"},{"internalType":"string[]","name":"keys","type":"string[]"},{"internalType":"string[]","name":"values","type":"string[]"}],"name":"safeMintSLDToDefaultResolver","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"string","name":"label","type":"string"},{"internalType":"string[]","name":"keys","type":"string[]"},{"internalType":"string[]","name":"values","type":"string[]"},{"internalType":"address","name":"resolver","type":"address"}],"name":"safeMintSLDToResolver","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"string","name":"label","type":"string"},{"internalType":"string[]","name":"keys","type":"string[]"},{"internalType":"string[]","name":"values","type":"string[]"},{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"address","name":"resolver","type":"address"}],"name":"safeMintSLDToResolver","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"resolver","type":"address"}],"name":"setDefaultResolver","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b5060405162003a3038038062003a308339818101604052620000379190810190620003fd565b62000048336200016360201b60201c565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16637b1039996040518163ffffffff1660e01b815260040160206040518083038186803b158015620000d057600080fd5b505afa158015620000e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506200010b9190810190620003d1565b600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506200015c30620001c460201b60201c565b50620005a4565b6200017e8160006200022560201b62001ce91790919060201c565b8073ffffffffffffffffffffffffffffffffffffffff167f22380c05984257a1cb900161c713dd71d39e74820f1aea43bd3f1bdd2096129960405160405180910390a250565b620001df8160016200022560201b62001ce91790919060201c565b8073ffffffffffffffffffffffffffffffffffffffff167fee1504a83b6d4a361f4c1dc78ab59bfa30d6a3b6612c403e86bb01ef2984295f60405160405180910390a250565b620002378282620002d860201b60201c565b156200027a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200027190620004d3565b60405180910390fd5b60018260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156200034c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200034390620004f5565b60405180910390fd5b8260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600081519050620003b48162000570565b92915050565b600081519050620003cb816200058a565b92915050565b600060208284031215620003e457600080fd5b6000620003f484828501620003a3565b91505092915050565b6000602082840312156200041057600080fd5b60006200042084828501620003ba565b91505092915050565b600062000438601f8362000517565b91507f526f6c65733a206163636f756e7420616c72656164792068617320726f6c65006000830152602082019050919050565b60006200047a60228362000517565b91507f526f6c65733a206163636f756e7420697320746865207a65726f20616464726560008301527f73730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006020820190508181036000830152620004ee8162000429565b9050919050565b6000602082019050818103600083015262000510816200046b565b9050919050565b600082825260208201905092915050565b6000620005358262000550565b9050919050565b6000620005498262000528565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6200057b8162000528565b81146200058757600080fd5b50565b62000595816200053c565b8114620005a157600080fd5b50565b61347c80620005b46000396000f3fe6080604052600436106101815760003560e01c8063898851f8116100d1578063be362e2e1161008a578063f6e491aa11610064578063f6e491aa14610509578063f8a6c3d614610532578063f8a8d0c91461055b578063ffa1ad741461057757610181565b8063be362e2e146104a0578063c66485b2146104c9578063d6cd9473146104f257610181565b8063898851f8146103a657806398650275146103cf578063a3f4df7e146103e6578063aceb476414610411578063b2da29791461043a578063bb5f747b1461046357610181565b80634b18abea1161013e5780634c5a628c116101185780634c5a628c14610300578063564a51581461031757806361050ffd146103545780637362d9c81461037d57610181565b80634b18abea146102855780634b44c01a146102ae5780634c0b0ed2146102d757610181565b806310154bad14610186578063291d9549146101af578063350959be146101d85780633af32abf146101f45780633d7989fe146102315780633efa047f1461025a575b600080fd5b34801561019257600080fd5b506101ad60048036036101a8919081019061221a565b6105a2565b005b3480156101bb57600080fd5b506101d660048036036101d1919081019061221a565b6105f6565b005b6101f260048036036101ed9190810190612243565b61064a565b005b34801561020057600080fd5b5061021b6004803603610216919081019061221a565b610754565b6040516102289190612f42565b60405180910390f35b34801561023d57600080fd5b506102586004803603610253919081019061234d565b610771565b005b34801561026657600080fd5b5061026f6107ee565b60405161027c9190612dd6565b60405180910390f35b34801561029157600080fd5b506102ac60048036036102a791908101906124b7565b610818565b005b3480156102ba57600080fd5b506102d560048036036102d091908101906123f8565b610897565b005b3480156102e357600080fd5b506102fe60048036036102f9919081019061226c565b610983565b005b34801561030c57600080fd5b50610315610a61565b005b34801561032357600080fd5b5061033e600480360361033991908101906126b8565b610a6c565b60405161034b9190612fbd565b60405180910390f35b34801561036057600080fd5b5061037b6004803603610376919081019061234d565b610c54565b005b34801561038957600080fd5b506103a4600480360361039f919081019061221a565b610cd1565b005b3480156103b257600080fd5b506103cd60048036036103c8919081019061258e565b610d25565b005b3480156103db57600080fd5b506103e4610e14565b005b3480156103f257600080fd5b506103fb610ee0565b6040516104089190612fdf565b60405180910390f35b34801561041d57600080fd5b50610438600480360361043391908101906123f8565b610f19565b005b34801561044657600080fd5b50610461600480360361045c919081019061226c565b611005565b005b34801561046f57600080fd5b5061048a6004803603610485919081019061221a565b6110e3565b6040516104979190612f42565b60405180910390f35b3480156104ac57600080fd5b506104c760048036036104c291908101906122c4565b611100565b005b3480156104d557600080fd5b506104f060048036036104eb919081019061221a565b6111e4565b005b3480156104fe57600080fd5b50610507611270565b005b34801561051557600080fd5b50610530600480360361052b9190810190612677565b61127b565b005b34801561053e57600080fd5b5061055960048036036105549190810190612677565b6112ff565b005b61057560048036036105709190810190612243565b611383565b005b34801561058357600080fd5b5061058c611496565b6040516105999190612fdf565b60405180910390f35b6105ab336110e3565b6105ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e190613081565b60405180910390fd5b6105f3816114cf565b50565b6105ff336110e3565b61063e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161063590613081565b60405180910390fd5b61064781611529565b50565b61065333610754565b610692576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610689906130e1565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610702576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106f990613021565b60405180910390fd5b61070a611270565b8073ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f19350505050158015610750573d6000803e3d6000fd5b5050565b600061076a82600161158390919063ffffffff16565b9050919050565b61077a33610754565b6107b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107b0906130e1565b60405180910390fd5b6107e884848484600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610f19565b50505050565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61082133610754565b610860576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610857906130e1565b60405180910390fd5b6108908585858585600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610d25565b5050505050565b6108a033610754565b6108df576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108d6906130e1565b60405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638ad364f88686846040518463ffffffff1660e01b815260040161093e93929190612e6c565b600060405180830381600087803b15801561095857600080fd5b505af115801561096c573d6000803e3d6000fd5b5050505061097c8484848461164b565b5050505050565b61098c33610754565b6109cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109c2906130e1565b60405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634c0b0ed28484846040518463ffffffff1660e01b8152600401610a2a93929190612df1565b600060405180830381600087803b158015610a4457600080fd5b505af1158015610a58573d6000803e3d6000fd5b50505050505050565b610a6a3361181b565b565b606060008585604051610a80929190612d97565b604051809103902090506000610ada8286868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611875565b9050606087878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505090506000610b308261197a565b9050600060603073ffffffffffffffffffffffffffffffffffffffff168b8b604051610b5d929190612d97565b6000604051808303816000865af19150503d8060008114610b9a576040519150601f19603f3d011682016040523d82523d6000602084013e610b9f565b606091505b5091509150600015158215151415610bbe576040513d806000833e8082fd5b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168573ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9490f91465d0d2c12728b9ad47d5f1dd2ac3ef39394796e54a48b94db0b3372589604051610c3b9190612f5d565b60405180910390a4809650505050505050949350505050565b610c5d33610754565b610c9c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c93906130e1565b60405180910390fd5b610ccb84848484600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610897565b50505050565b610cda336110e3565b610d19576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d1090613081565b60405180910390fd5b610d2281611c8f565b50565b610d2e33610754565b610d6d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d64906130e1565b60405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637caf3ad8878784866040518563ffffffff1660e01b8152600401610dce9493929190612eaa565b600060405180830381600087803b158015610de857600080fd5b505af1158015610dfc573d6000803e3d6000fd5b50505050610e0c8585858461164b565b505050505050565b610e1d336110e3565b610e5c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5390613081565b60405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663986502756040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610ec657600080fd5b505af1158015610eda573d6000803e3d6000fd5b50505050565b6040518060400160405280601e81526020017f556e73746f707061626c652057686974656c6973746564204d696e746572000081525081565b610f2233610754565b610f61576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f58906130e1565b60405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c36c21258686846040518463ffffffff1660e01b8152600401610fc093929190612e6c565b600060405180830381600087803b158015610fda57600080fd5b505af1158015610fee573d6000803e3d6000fd5b50505050610ffe8484848461164b565b5050505050565b61100e33610754565b61104d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611044906130e1565b60405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b2da29798484846040518463ffffffff1660e01b81526004016110ac93929190612df1565b600060405180830381600087803b1580156110c657600080fd5b505af11580156110da573d6000803e3d6000fd5b50505050505050565b60006110f982600061158390919063ffffffff16565b9050919050565b61110933610754565b611148576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161113f906130e1565b60405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663be362e2e86868686866040518663ffffffff1660e01b81526004016111ab959493929190612e23565b600060405180830381600087803b1580156111c557600080fd5b505af11580156111d9573d6000803e3d6000fd5b505050505050505050565b6111ed336110e3565b61122c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161122390613081565b60405180910390fd5b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61127933611529565b565b611284336110e3565b6112c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ba90613081565b60405180910390fd5b60008090505b81518110156112fb576112ee8282815181106112e157fe5b60200260200101516114cf565b80806001019150506112c9565b5050565b611308336110e3565b611347576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161133e90613081565b60405180910390fd5b60008090505b815181101561137f5761137282828151811061136557fe5b6020026020010151611529565b808060010191505061134d565b5050565b61138c33610754565b6113cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113c2906130e1565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561143b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161143290613021565b60405180910390fd5b611444816114cf565b61144c611270565b8073ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f19350505050158015611492573d6000803e3d6000fd5b5050565b6040518060400160405280600581526020017f302e332e3000000000000000000000000000000000000000000000000000000081525081565b6114e3816001611ce990919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff167fee1504a83b6d4a361f4c1dc78ab59bfa30d6a3b6612c403e86bb01ef2984295f60405160405180910390a250565b61153d816001611d9190919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff167f270d9b30cf5b0793bbfd54c9d5b94aeb49462b8148399000265144a8722da6b660405160405180910390a250565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156115f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115eb90613061565b60405180910390fd5b8260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60008351141561165a57611815565b8073ffffffffffffffffffffffffffffffffffffffff1663e837ae748484600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166368b62d32600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ebf0c7176040518163ffffffff1660e01b815260040160206040518083038186803b15801561171e57600080fd5b505afa158015611732573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611756919081019061272d565b8a6040518363ffffffff1660e01b8152600401611774929190613121565b60206040518083038186803b15801561178c57600080fd5b505afa1580156117a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506117c4919081019061272d565b6040518463ffffffff1660e01b81526004016117e293929190612efd565b600060405180830381600087803b1580156117fc57600080fd5b505af1158015611810573d6000803e3d6000fd5b505050505b50505050565b61182f816000611d9190919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff167f0a8eb35e5ca14b3d6f28e4abf2f128dbab231a58b56e89beb5d636115001e16560405160405180910390a250565b60006118ba826118ac8530604051602001611891929190612d6b565b60405160208183030381529060405280519060200120611e38565b611e6890919063ffffffff16565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561192c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611923906130a1565b60405180910390fd5b61193581610754565b611974576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196b90613101565b60405180910390fd5b92915050565b60008060200182015190506000634c0b0ed260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611a1e5750633d7989fe60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611a6d575063aceb476460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611abc575063b2da297960e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611b0b575063be362e2e60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611b5a57506361050ffd60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611ba95750634b18abea60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611bf85750634b44c01a60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611c47575063898851f860e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b905080611c89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c80906130c1565b60405180910390fd5b50919050565b611ca3816000611ce990919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff167f22380c05984257a1cb900161c713dd71d39e74820f1aea43bd3f1bdd2096129960405160405180910390a250565b611cf38282611583565b15611d33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d2a90613001565b60405180910390fd5b60018260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b611d9b8282611583565b611dda576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dd190613041565b60405180910390fd5b60008260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b600081604051602001611e4b9190612db0565b604051602081830303815290604052805190602001209050919050565b60006041825114611e7c5760009050611f4e565b60008060006020850151925060408501519150606085015160001a90507f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08260001c1115611ed05760009350505050611f4e565b601b8160ff1614158015611ee85750601c8160ff1614155b15611ef95760009350505050611f4e565b60018682858560405160008152602001604052604051611f1c9493929190612f78565b6020604051602081039080840390855afa158015611f3e573d6000803e3d6000fd5b5050506020604051035193505050505b92915050565b600081359050611f63816133f4565b92915050565b600081359050611f788161340b565b92915050565b600082601f830112611f8f57600080fd5b8135611fa2611f9d8261317e565b613151565b91508181835260208401935060208101905083856020840282011115611fc757600080fd5b60005b83811015611ff75781611fdd8882611f54565b845260208401935060208301925050600181019050611fca565b5050505092915050565b600082601f83011261201257600080fd5b8135612025612020826131a6565b613151565b9150818183526020840193506020810190508360005b8381101561206b5781358601612051888261215d565b84526020840193506020830192505060018101905061203b565b5050505092915050565b60008083601f84011261208757600080fd5b8235905067ffffffffffffffff8111156120a057600080fd5b6020830191508360018202830111156120b857600080fd5b9250929050565b600082601f8301126120d057600080fd5b81356120e36120de826131ce565b613151565b915080825260208301602083018583830111156120ff57600080fd5b61210a838284613366565b50505092915050565b60008083601f84011261212557600080fd5b8235905067ffffffffffffffff81111561213e57600080fd5b60208301915083600182028301111561215657600080fd5b9250929050565b600082601f83011261216e57600080fd5b813561218161217c826131fa565b613151565b9150808252602083016020830185838301111561219d57600080fd5b6121a8838284613366565b50505092915050565b600082601f8301126121c257600080fd5b81356121d56121d082613226565b613151565b915080825260208301602083018583830111156121f157600080fd5b6121fc838284613366565b50505092915050565b60008151905061221481613422565b92915050565b60006020828403121561222c57600080fd5b600061223a84828501611f54565b91505092915050565b60006020828403121561225557600080fd5b600061226384828501611f69565b91505092915050565b60008060006040848603121561228157600080fd5b600061228f86828701611f54565b935050602084013567ffffffffffffffff8111156122ac57600080fd5b6122b886828701612113565b92509250509250925092565b6000806000806000606086880312156122dc57600080fd5b60006122ea88828901611f54565b955050602086013567ffffffffffffffff81111561230757600080fd5b61231388828901612113565b9450945050604086013567ffffffffffffffff81111561233257600080fd5b61233e88828901612075565b92509250509295509295909350565b6000806000806080858703121561236357600080fd5b600061237187828801611f54565b945050602085013567ffffffffffffffff81111561238e57600080fd5b61239a878288016121b1565b935050604085013567ffffffffffffffff8111156123b757600080fd5b6123c387828801612001565b925050606085013567ffffffffffffffff8111156123e057600080fd5b6123ec87828801612001565b91505092959194509250565b600080600080600060a0868803121561241057600080fd5b600061241e88828901611f54565b955050602086013567ffffffffffffffff81111561243b57600080fd5b612447888289016121b1565b945050604086013567ffffffffffffffff81111561246457600080fd5b61247088828901612001565b935050606086013567ffffffffffffffff81111561248d57600080fd5b61249988828901612001565b92505060806124aa88828901611f54565b9150509295509295909350565b600080600080600060a086880312156124cf57600080fd5b60006124dd88828901611f54565b955050602086013567ffffffffffffffff8111156124fa57600080fd5b612506888289016121b1565b945050604086013567ffffffffffffffff81111561252357600080fd5b61252f88828901612001565b935050606086013567ffffffffffffffff81111561254c57600080fd5b61255888828901612001565b925050608086013567ffffffffffffffff81111561257557600080fd5b612581888289016120bf565b9150509295509295909350565b60008060008060008060c087890312156125a757600080fd5b60006125b589828a01611f54565b965050602087013567ffffffffffffffff8111156125d257600080fd5b6125de89828a016121b1565b955050604087013567ffffffffffffffff8111156125fb57600080fd5b61260789828a01612001565b945050606087013567ffffffffffffffff81111561262457600080fd5b61263089828a01612001565b935050608087013567ffffffffffffffff81111561264d57600080fd5b61265989828a016120bf565b92505060a061266a89828a01611f54565b9150509295509295509295565b60006020828403121561268957600080fd5b600082013567ffffffffffffffff8111156126a357600080fd5b6126af84828501611f7e565b91505092915050565b600080600080604085870312156126ce57600080fd5b600085013567ffffffffffffffff8111156126e857600080fd5b6126f487828801612075565b9450945050602085013567ffffffffffffffff81111561271357600080fd5b61271f87828801612075565b925092505092959194509250565b60006020828403121561273f57600080fd5b600061274d84828501612205565b91505092915050565b6000612762838361292b565b905092915050565b612773816132f5565b82525050565b61278a612785826132f5565b6133a8565b82525050565b600061279b82613262565b6127a5818561329b565b9350836020820285016127b785613252565b8060005b858110156127f357848403895281516127d48582612756565b94506127df8361328e565b925060208a019950506001810190506127bb565b50829750879550505050505092915050565b61280e81613319565b82525050565b61281d81613325565b82525050565b61283461282f82613325565b6133ba565b82525050565b600061284683856132ac565b9350612853838584613366565b61285c836133d6565b840190509392505050565b600061287383856132bd565b9350612880838584613366565b82840190509392505050565b60006128978261326d565b6128a181856132ac565b93506128b1818560208601613375565b6128ba816133d6565b840191505092915050565b60006128d183856132d9565b93506128de838584613366565b6128e7836133d6565b840190509392505050565b60006128fd82613283565b61290781856132d9565b9350612917818560208601613375565b612920816133d6565b840191505092915050565b600061293682613278565b61294081856132c8565b9350612950818560208601613375565b612959816133d6565b840191505092915050565b600061296f82613278565b61297981856132d9565b9350612989818560208601613375565b612992816133d6565b840191505092915050565b60006129aa601f836132d9565b91507f526f6c65733a206163636f756e7420616c72656164792068617320726f6c65006000830152602082019050919050565b60006129ea601c836132ea565b91507f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000830152601c82019050919050565b6000612a2a6024836132d9565b91507f57686974656c69737465644d696e7465723a2052454345495645525f49535f4560008301527f4d505459000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000612a906021836132d9565b91507f526f6c65733a206163636f756e7420646f6573206e6f74206861766520726f6c60008301527f65000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000612af66022836132d9565b91507f526f6c65733a206163636f756e7420697320746865207a65726f20616464726560008301527f73730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000612b5c6040836132d9565b91507f57686974656c69737441646d696e526f6c653a2063616c6c657220646f65732060008301527f6e6f742068617665207468652057686974656c69737441646d696e20726f6c656020830152604082019050919050565b6000612bc26027836132d9565b91507f57686974656c69737465644d696e7465723a205349474e41545552455f49535f60008301527f494e56414c4944000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000612c286023836132d9565b91507f57686974656c69737465644d696e7465723a20554e535550504f525445445f4360008301527f414c4c00000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000612c8e603a836132d9565b91507f57686974656c6973746564526f6c653a2063616c6c657220646f6573206e6f7460008301527f2068617665207468652057686974656c697374656420726f6c650000000000006020830152604082019050919050565b6000612cf4602c836132d9565b91507f57686974656c69737465644d696e7465723a205349474e45525f49535f4e4f5460008301527f5f57484954454c495354454400000000000000000000000000000000000000006020830152604082019050919050565b612d568161334f565b82525050565b612d6581613359565b82525050565b6000612d778285612823565b602082019150612d878284612779565b6014820191508190509392505050565b6000612da4828486612867565b91508190509392505050565b6000612dbb826129dd565b9150612dc78284612823565b60208201915081905092915050565b6000602082019050612deb600083018461276a565b92915050565b6000604082019050612e06600083018661276a565b8181036020830152612e198184866128c5565b9050949350505050565b6000606082019050612e38600083018861276a565b8181036020830152612e4b8186886128c5565b90508181036040830152612e6081848661283a565b90509695505050505050565b6000606082019050612e81600083018661276a565b8181036020830152612e9381856128f2565b9050612ea2604083018461276a565b949350505050565b6000608082019050612ebf600083018761276a565b8181036020830152612ed181866128f2565b9050612ee0604083018561276a565b8181036060830152612ef2818461288c565b905095945050505050565b60006060820190508181036000830152612f178186612790565b90508181036020830152612f2b8185612790565b9050612f3a6040830184612d4d565b949350505050565b6000602082019050612f576000830184612805565b92915050565b6000602082019050612f726000830184612814565b92915050565b6000608082019050612f8d6000830187612814565b612f9a6020830186612d5c565b612fa76040830185612814565b612fb46060830184612814565b95945050505050565b60006020820190508181036000830152612fd7818461288c565b905092915050565b60006020820190508181036000830152612ff98184612964565b905092915050565b6000602082019050818103600083015261301a8161299d565b9050919050565b6000602082019050818103600083015261303a81612a1d565b9050919050565b6000602082019050818103600083015261305a81612a83565b9050919050565b6000602082019050818103600083015261307a81612ae9565b9050919050565b6000602082019050818103600083015261309a81612b4f565b9050919050565b600060208201905081810360008301526130ba81612bb5565b9050919050565b600060208201905081810360008301526130da81612c1b565b9050919050565b600060208201905081810360008301526130fa81612c81565b9050919050565b6000602082019050818103600083015261311a81612ce7565b9050919050565b60006040820190506131366000830185612d4d565b818103602083015261314881846128f2565b90509392505050565b6000604051905081810181811067ffffffffffffffff8211171561317457600080fd5b8060405250919050565b600067ffffffffffffffff82111561319557600080fd5b602082029050602081019050919050565b600067ffffffffffffffff8211156131bd57600080fd5b602082029050602081019050919050565b600067ffffffffffffffff8211156131e557600080fd5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff82111561321157600080fd5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff82111561323d57600080fd5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b60006133008261332f565b9050919050565b60006133128261332f565b9050919050565b60008115159050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b82818337600083830152505050565b60005b83811015613393578082015181840152602081019050613378565b838111156133a2576000848401525b50505050565b60006133b3826133c4565b9050919050565b6000819050919050565b60006133cf826133e7565b9050919050565b6000601f19601f8301169050919050565b60008160601b9050919050565b6133fd816132f5565b811461340857600080fd5b50565b61341481613307565b811461341f57600080fd5b50565b61342b8161334f565b811461343657600080fd5b5056fea365627a7a72315820fba7787a2333da4a0399f4857616b5fb435314fd9dcaf1fcb055eb78c0c3f18a6c6578706572696d656e74616cf564736f6c634300050c004000000000000000000000000051765307aeb3df2e647014a2c501d5324212467c

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

00000000000000000000000051765307aeb3df2e647014a2c501d5324212467c

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

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 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.