ERC-721
Overview
Max Total Supply
4,342 KYC
Holders
4,326
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
1 KYCLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
KycToken
Compiler Version
v0.4.24+commit.e67f0147
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2018-06-22 */ pragma solidity ^0.4.24; // File: @0xcert/ethereum-erc721/contracts/tokens/ERC721Enumerable.sol /** * @dev Optional enumeration extension for ERC-721 non-fungible token standard. * See https://goo.gl/pc9yoS. */ interface ERC721Enumerable { /** * @dev Returns a count of valid NFTs tracked by this contract, where each one of them has an * assigned and queryable owner not equal to the zero address. */ function totalSupply() external view returns (uint256); /** * @dev Returns the token identifier for the `_index`th NFT. Sort order is not specified. * @param _index A counter less than `totalSupply()`. */ function tokenByIndex( uint256 _index ) external view returns (uint256); /** * @dev Returns the token identifier for the `_index`th NFT assigned to `_owner`. Sort order is * not specified. It throws if `_index` >= `balanceOf(_owner)` or if `_owner` is the zero address, * representing invalid NFTs. * @param _owner An address where we are interested in NFTs owned by them. * @param _index A counter less than `balanceOf(_owner)`. */ function tokenOfOwnerByIndex( address _owner, uint256 _index ) external view returns (uint256); } // File: @0xcert/ethereum-erc721/contracts/tokens/ERC721.sol /** * @dev ERC-721 non-fungible token standard. See https://goo.gl/pc9yoS. */ interface ERC721 { /** * @dev Emits when ownership of any NFT changes by any mechanism. This event emits when NFTs are * created (`from` == 0) and destroyed (`to` == 0). Exception: during contract creation, any * number of NFTs may be created and assigned without emitting Transfer. At the time of any * transfer, the approved address for that NFT (if any) is reset to none. */ event Transfer( address indexed _from, address indexed _to, uint256 indexed _tokenId ); /** * @dev This emits when the approved address for an NFT is changed or reaffirmed. The zero * address indicates there is no approved address. When a Transfer event emits, this also * indicates that the approved address for that NFT (if any) is reset to none. */ event Approval( address indexed _owner, address indexed _approved, uint256 indexed _tokenId ); /** * @dev This emits when an operator is enabled or disabled for an owner. The operator can manage * all NFTs of the owner. */ event ApprovalForAll( address indexed _owner, address indexed _operator, bool _approved ); /** * @dev Returns the number of NFTs owned by `_owner`. NFTs assigned to the zero address are * considered invalid, and this function throws for queries about the zero address. * @param _owner Address for whom to query the balance. */ function balanceOf( address _owner ) external view returns (uint256); /** * @dev Returns the address of the owner of the NFT. NFTs assigned to zero address are considered * invalid, and queries about them do throw. * @param _tokenId The identifier for an NFT. */ function ownerOf( uint256 _tokenId ) external view returns (address); /** * @dev Transfers the ownership of an NFT from one address to another address. * @notice Throws unless `msg.sender` is the current owner, an authorized operator, or the * approved address for this NFT. Throws if `_from` is not the current owner. Throws if `_to` is * the zero address. Throws if `_tokenId` is not a valid NFT. When transfer is complete, this * function checks if `_to` is a smart contract (code size > 0). If so, it calls `onERC721Received` * on `_to` and throws if the return value is not `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`. * @param _from The current owner of the NFT. * @param _to The new owner. * @param _tokenId The NFT to transfer. * @param _data Additional data with no specified format, sent in call to `_to`. */ function safeTransferFrom( address _from, address _to, uint256 _tokenId, bytes _data ) external; /** * @dev Transfers the ownership of an NFT from one address to another address. * @notice This works identically to the other function with an extra data parameter, except this * function just sets data to "" * @param _from The current owner of the NFT. * @param _to The new owner. * @param _tokenId The NFT to transfer. */ function safeTransferFrom( address _from, address _to, uint256 _tokenId ) external; /** * @dev Throws unless `msg.sender` is the current owner, an authorized operator, or the approved * address for this NFT. Throws if `_from` is not the current owner. Throws if `_to` is the zero * address. Throws if `_tokenId` is not a valid NFT. * @notice The caller is responsible to confirm that `_to` is capable of receiving NFTs or else * they mayb be permanently lost. * @param _from The current owner of the NFT. * @param _to The new owner. * @param _tokenId The NFT to transfer. */ function transferFrom( address _from, address _to, uint256 _tokenId ) external; /** * @dev Set or reaffirm the approved address for an NFT. * @notice The zero address indicates there is no approved address. Throws unless `msg.sender` is * the current NFT owner, or an authorized operator of the current owner. * @param _approved The new approved NFT controller. * @param _tokenId The NFT to approve. */ function approve( address _approved, uint256 _tokenId ) external; /** * @dev Enables or disables approval for a third party ("operator") to manage all of * `msg.sender`'s assets. It also emits the ApprovalForAll event. * @notice The contract MUST allow multiple operators per owner. * @param _operator Address to add to the set of authorized operators. * @param _approved True if the operators is approved, false to revoke approval. */ function setApprovalForAll( address _operator, bool _approved ) external; /** * @dev Get the approved address for a single NFT. * @notice Throws if `_tokenId` is not a valid NFT. * @param _tokenId The NFT to find the approved address for. */ function getApproved( uint256 _tokenId ) external view returns (address); /** * @dev Returns true if `_operator` is an approved operator for `_owner`, false otherwise. * @param _owner The address that owns the NFTs. * @param _operator The address that acts on behalf of the owner. */ function isApprovedForAll( address _owner, address _operator ) external view returns (bool); } // File: @0xcert/ethereum-erc721/contracts/tokens/ERC721TokenReceiver.sol /** * @dev ERC-721 interface for accepting safe transfers. See https://goo.gl/pc9yoS. */ interface ERC721TokenReceiver { /** * @dev Handle the receipt of a NFT. The ERC721 smart contract calls this function on the * recipient after a `transfer`. This function MAY throw to revert and reject the transfer. Return * of other than the magic value MUST result in the transaction being reverted. * Returns `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` unless throwing. * @notice The contract address is always the message sender. A wallet/broker/auction application * MUST implement the wallet interface if it will accept safe transfers. * @param _operator The address which called `safeTransferFrom` function. * @param _from The sending address. * @param _tokenId The NFT identifier which is being transferred. * @param _data Additional data with no specified format. */ function onERC721Received( address _operator, address _from, uint256 _tokenId, bytes _data ) external returns(bytes4); } // File: @0xcert/ethereum-utils/contracts/math/SafeMath.sol /** * @dev Math operations with safety checks that throw on error. This contract is based * on the source code at https://goo.gl/iyQsmU. */ library SafeMath { /** * @dev Multiplies two numbers, throws on overflow. * @param _a Factor number. * @param _b Factor number. */ function mul( uint256 _a, uint256 _b ) internal pure returns (uint256) { if (_a == 0) { return 0; } uint256 c = _a * _b; assert(c / _a == _b); return c; } /** * @dev Integer division of two numbers, truncating the quotient. * @param _a Dividend number. * @param _b Divisor number. */ function div( uint256 _a, uint256 _b ) internal pure returns (uint256) { uint256 c = _a / _b; // assert(b > 0); // Solidity automatically throws when dividing by 0 // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Substracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). * @param _a Minuend number. * @param _b Subtrahend number. */ function sub( uint256 _a, uint256 _b ) internal pure returns (uint256) { assert(_b <= _a); return _a - _b; } /** * @dev Adds two numbers, throws on overflow. * @param _a Number. * @param _b Number. */ function add( uint256 _a, uint256 _b ) internal pure returns (uint256) { uint256 c = _a + _b; assert(c >= _a); return c; } } // File: @0xcert/ethereum-utils/contracts/ownership/Ownable.sol /** * @dev The contract has an owner address, and provides basic authorization control whitch * simplifies the implementation of user permissions. This contract is based on the source code * at https://goo.gl/n2ZGVt. */ contract Ownable { address public owner; /** * @dev An event which is triggered when the owner is changed. * @param previousOwner The address of the previous owner. * @param newOwner The address of the new owner. */ event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /** * @dev The constructor sets the original `owner` of the contract to the sender account. */ constructor() public { owner = msg.sender; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(msg.sender == owner); _; } /** * @dev Allows the current owner to transfer control of the contract to a newOwner. * @param _newOwner The address to transfer ownership to. */ function transferOwnership( address _newOwner ) onlyOwner public { require(_newOwner != address(0)); emit OwnershipTransferred(owner, _newOwner); owner = _newOwner; } } // File: @0xcert/ethereum-utils/contracts/utils/AddressUtils.sol /** * @dev Utility library of inline functions on addresses. */ library AddressUtils { /** * @dev Returns whether the target address is a contract. * @param _addr Address to check. */ function isContract( address _addr ) internal view returns (bool) { uint256 size; /** * XXX Currently there is no better way to check if there is a contract in an address than to * check the size of the code at that address. * See https://ethereum.stackexchange.com/a/14016/36603 for more details about how this works. * TODO: Check this again before the Serenity release, because all addresses will be * contracts then. */ assembly { size := extcodesize(_addr) } // solium-disable-line security/no-inline-assembly return size > 0; } } // File: @0xcert/ethereum-utils/contracts/utils/ERC165.sol /** * @dev A standard for detecting smart contract interfaces. See https://goo.gl/cxQCse. */ interface ERC165 { /** * @dev Checks if the smart contract includes a specific interface. * @notice This function uses less than 30,000 gas. * @param _interfaceID The interface identifier, as specified in ERC-165. */ function supportsInterface( bytes4 _interfaceID ) external view returns (bool); } // File: @0xcert/ethereum-utils/contracts/utils/SupportsInterface.sol /** * @dev Implementation of standard for detect smart contract interfaces. */ contract SupportsInterface is ERC165 { /** * @dev Mapping of supported intefraces. * @notice You must not set element 0xffffffff to true. */ mapping(bytes4 => bool) internal supportedInterfaces; /** * @dev Contract constructor. */ constructor() public { supportedInterfaces[0x01ffc9a7] = true; // ERC165 } /** * @dev Function to check which interfaces are suported by this contract. * @param _interfaceID Id of the interface. */ function supportsInterface( bytes4 _interfaceID ) external view returns (bool) { return supportedInterfaces[_interfaceID]; } } // File: @0xcert/ethereum-erc721/contracts/tokens/NFToken.sol /** * @dev Implementation of ERC-721 non-fungible token standard. */ contract NFToken is Ownable, ERC721, SupportsInterface { using SafeMath for uint256; using AddressUtils for address; /** * @dev A mapping from NFT ID to the address that owns it. */ mapping (uint256 => address) internal idToOwner; /** * @dev Mapping from NFT ID to approved address. */ mapping (uint256 => address) internal idToApprovals; /** * @dev Mapping from owner address to count of his tokens. */ mapping (address => uint256) internal ownerToNFTokenCount; /** * @dev Mapping from owner address to mapping of operator addresses. */ mapping (address => mapping (address => bool)) internal ownerToOperators; /** * @dev Magic value of a smart contract that can recieve NFT. * Equal to: bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")). */ bytes4 constant MAGIC_ON_ERC721_RECEIVED = 0x150b7a02; /** * @dev Emits when ownership of any NFT changes by any mechanism. This event emits when NFTs are * created (`from` == 0) and destroyed (`to` == 0). Exception: during contract creation, any * number of NFTs may be created and assigned without emitting Transfer. At the time of any * transfer, the approved address for that NFT (if any) is reset to none. * @param _from Sender of NFT (if address is zero address it indicates token creation). * @param _to Receiver of NFT (if address is zero address it indicates token destruction). * @param _tokenId The NFT that got transfered. */ event Transfer( address indexed _from, address indexed _to, uint256 indexed _tokenId ); /** * @dev This emits when the approved address for an NFT is changed or reaffirmed. The zero * address indicates there is no approved address. When a Transfer event emits, this also * indicates that the approved address for that NFT (if any) is reset to none. * @param _owner Owner of NFT. * @param _approved Address that we are approving. * @param _tokenId NFT which we are approving. */ event Approval( address indexed _owner, address indexed _approved, uint256 indexed _tokenId ); /** * @dev This emits when an operator is enabled or disabled for an owner. The operator can manage * all NFTs of the owner. * @param _owner Owner of NFT. * @param _operator Address to which we are setting operator rights. * @param _approved Status of operator rights(true if operator rights are given and false if * revoked). */ event ApprovalForAll( address indexed _owner, address indexed _operator, bool _approved ); /** * @dev Guarantees that the msg.sender is an owner or operator of the given NFT. * @param _tokenId ID of the NFT to validate. */ modifier canOperate( uint256 _tokenId ) { address tokenOwner = idToOwner[_tokenId]; require(tokenOwner == msg.sender || ownerToOperators[tokenOwner][msg.sender]); _; } /** * @dev Guarantees that the msg.sender is allowed to transfer NFT. * @param _tokenId ID of the NFT to transfer. */ modifier canTransfer( uint256 _tokenId ) { address tokenOwner = idToOwner[_tokenId]; require( tokenOwner == msg.sender || getApproved(_tokenId) == msg.sender || ownerToOperators[tokenOwner][msg.sender] ); _; } /** * @dev Guarantees that _tokenId is a valid Token. * @param _tokenId ID of the NFT to validate. */ modifier validNFToken( uint256 _tokenId ) { require(idToOwner[_tokenId] != address(0)); _; } /** * @dev Contract constructor. */ constructor() public { supportedInterfaces[0x80ac58cd] = true; // ERC721 } /** * @dev Returns the number of NFTs owned by `_owner`. NFTs assigned to the zero address are * considered invalid, and this function throws for queries about the zero address. * @param _owner Address for whom to query the balance. */ function balanceOf( address _owner ) external view returns (uint256) { require(_owner != address(0)); return ownerToNFTokenCount[_owner]; } /** * @dev Returns the address of the owner of the NFT. NFTs assigned to zero address are considered * invalid, and queries about them do throw. * @param _tokenId The identifier for an NFT. */ function ownerOf( uint256 _tokenId ) external view returns (address _owner) { _owner = idToOwner[_tokenId]; require(_owner != address(0)); } /** * @dev Transfers the ownership of an NFT from one address to another address. * @notice Throws unless `msg.sender` is the current owner, an authorized operator, or the * approved address for this NFT. Throws if `_from` is not the current owner. Throws if `_to` is * the zero address. Throws if `_tokenId` is not a valid NFT. When transfer is complete, this * function checks if `_to` is a smart contract (code size > 0). If so, it calls `onERC721Received` * on `_to` and throws if the return value is not `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`. * @param _from The current owner of the NFT. * @param _to The new owner. * @param _tokenId The NFT to transfer. * @param _data Additional data with no specified format, sent in call to `_to`. */ function safeTransferFrom( address _from, address _to, uint256 _tokenId, bytes _data ) external { _safeTransferFrom(_from, _to, _tokenId, _data); } /** * @dev Transfers the ownership of an NFT from one address to another address. * @notice This works identically to the other function with an extra data parameter, except this * function just sets data to "" * @param _from The current owner of the NFT. * @param _to The new owner. * @param _tokenId The NFT to transfer. */ function safeTransferFrom( address _from, address _to, uint256 _tokenId ) external { _safeTransferFrom(_from, _to, _tokenId, ""); } /** * @dev Throws unless `msg.sender` is the current owner, an authorized operator, or the approved * address for this NFT. Throws if `_from` is not the current owner. Throws if `_to` is the zero * address. Throws if `_tokenId` is not a valid NFT. * @notice The caller is responsible to confirm that `_to` is capable of receiving NFTs or else * they maybe be permanently lost. * @param _from The current owner of the NFT. * @param _to The new owner. * @param _tokenId The NFT to transfer. */ function transferFrom( address _from, address _to, uint256 _tokenId ) external canTransfer(_tokenId) validNFToken(_tokenId) { address tokenOwner = idToOwner[_tokenId]; require(tokenOwner == _from); require(_to != address(0)); _transfer(_to, _tokenId); } /** * @dev Set or reaffirm the approved address for an NFT. * @notice The zero address indicates there is no approved address. Throws unless `msg.sender` is * the current NFT owner, or an authorized operator of the current owner. * @param _approved Address to be approved for the given NFT ID. * @param _tokenId ID of the token to be approved. */ function approve( address _approved, uint256 _tokenId ) external canOperate(_tokenId) validNFToken(_tokenId) { address tokenOwner = idToOwner[_tokenId]; require(_approved != tokenOwner); idToApprovals[_tokenId] = _approved; emit Approval(tokenOwner, _approved, _tokenId); } /** * @dev Enables or disables approval for a third party ("operator") to manage all of * `msg.sender`'s assets. It also emits the ApprovalForAll event. * @notice This works even if sender doesn't own any tokens at the time. * @param _operator Address to add to the set of authorized operators. * @param _approved True if the operators is approved, false to revoke approval. */ function setApprovalForAll( address _operator, bool _approved ) external { require(_operator != address(0)); ownerToOperators[msg.sender][_operator] = _approved; emit ApprovalForAll(msg.sender, _operator, _approved); } /** * @dev Get the approved address for a single NFT. * @notice Throws if `_tokenId` is not a valid NFT. * @param _tokenId ID of the NFT to query the approval of. */ function getApproved( uint256 _tokenId ) public view validNFToken(_tokenId) returns (address) { return idToApprovals[_tokenId]; } /** * @dev Checks if `_operator` is an approved operator for `_owner`. * @param _owner The address that owns the NFTs. * @param _operator The address that acts on behalf of the owner. */ function isApprovedForAll( address _owner, address _operator ) external view returns (bool) { require(_owner != address(0)); require(_operator != address(0)); return ownerToOperators[_owner][_operator]; } /** * @dev Actually perform the safeTransferFrom. * @param _from The current owner of the NFT. * @param _to The new owner. * @param _tokenId The NFT to transfer. * @param _data Additional data with no specified format, sent in call to `_to`. */ function _safeTransferFrom( address _from, address _to, uint256 _tokenId, bytes _data ) internal canTransfer(_tokenId) validNFToken(_tokenId) { address tokenOwner = idToOwner[_tokenId]; require(tokenOwner == _from); require(_to != address(0)); _transfer(_to, _tokenId); if (_to.isContract()) { bytes4 retval = ERC721TokenReceiver(_to).onERC721Received(msg.sender, _from, _tokenId, _data); require(retval == MAGIC_ON_ERC721_RECEIVED); } } /** * @dev Actually preforms the transfer. * @notice Does NO checks. * @param _to Address of a new owner. * @param _tokenId The NFT that is being transferred. */ function _transfer( address _to, uint256 _tokenId ) private { address from = idToOwner[_tokenId]; clearApproval(from, _tokenId); removeNFToken(from, _tokenId); addNFToken(_to, _tokenId); emit Transfer(from, _to, _tokenId); } /** * @dev Mints a new NFT. * @notice This is a private function which should be called from user-implemented external * mint function. Its purpose is to show and properly initialize data structures when using this * implementation. * @param _to The address that will own the minted NFT. * @param _tokenId of the NFT to be minted by the msg.sender. */ function _mint( address _to, uint256 _tokenId ) internal { require(_to != address(0)); require(_tokenId != 0); require(idToOwner[_tokenId] == address(0)); addNFToken(_to, _tokenId); emit Transfer(address(0), _to, _tokenId); } /** * @dev Burns a NFT. * @notice This is a private function which should be called from user-implemented external * burn function. Its purpose is to show and properly initialize data structures when using this * implementation. * @param _owner Address of the NFT owner. * @param _tokenId ID of the NFT to be burned. */ function _burn( address _owner, uint256 _tokenId ) validNFToken(_tokenId) internal { clearApproval(_owner, _tokenId); removeNFToken(_owner, _tokenId); emit Transfer(_owner, address(0), _tokenId); } /** * @dev Clears the current approval of a given NFT ID. * @param _tokenId ID of the NFT to be transferred. */ function clearApproval( address _owner, uint256 _tokenId ) internal { delete idToApprovals[_tokenId]; emit Approval(_owner, 0, _tokenId); } /** * @dev Removes a NFT from owner. * @notice Use and override this function with caution. Wrong usage can have serious consequences. * @param _from Address from wich we want to remove the NFT. * @param _tokenId Which NFT we want to remove. */ function removeNFToken( address _from, uint256 _tokenId ) internal { require(idToOwner[_tokenId] == _from); assert(ownerToNFTokenCount[_from] > 0); ownerToNFTokenCount[_from] = ownerToNFTokenCount[_from].sub(1); delete idToOwner[_tokenId]; } /** * @dev Assignes a new NFT to owner. * @notice Use and override this function with caution. Wrong usage can have serious consequences. * @param _to Address to wich we want to add the NFT. * @param _tokenId Which NFT we want to add. */ function addNFToken( address _to, uint256 _tokenId ) internal { require(idToOwner[_tokenId] == address(0)); idToOwner[_tokenId] = _to; ownerToNFTokenCount[_to] = ownerToNFTokenCount[_to].add(1); } } // File: @0xcert/ethereum-erc721/contracts/tokens/NFTokenEnumerable.sol /** * @dev Optional enumeration implementation for ERC-721 non-fungible token standard. */ contract NFTokenEnumerable is NFToken, ERC721Enumerable { /** * @dev Array of all NFT IDs. */ uint256[] internal tokens; /** * @dev Mapping from owner address to a list of owned NFT IDs. */ mapping(uint256 => uint256) internal idToIndex; /** * @dev Mapping from owner to list of owned NFT IDs. */ mapping(address => uint256[]) internal ownerToIds; /** * @dev Mapping from NFT ID to its index in the owner tokens list. */ mapping(uint256 => uint256) internal idToOwnerIndex; /** * @dev Contract constructor. */ constructor() public { supportedInterfaces[0x780e9d63] = true; // ERC721Enumerable } /** * @dev Mints a new NFT. * @notice This is a private function which should be called from user-implemented external * mint function. Its purpose is to show and properly initialize data structures when using this * implementation. * @param _to The address that will own the minted NFT. * @param _tokenId of the NFT to be minted by the msg.sender. */ function _mint( address _to, uint256 _tokenId ) internal { super._mint(_to, _tokenId); tokens.push(_tokenId); } /** * @dev Burns a NFT. * @notice This is a private function which should be called from user-implemented external * burn function. Its purpose is to show and properly initialize data structures when using this * implementation. * @param _owner Address of the NFT owner. * @param _tokenId ID of the NFT to be burned. */ function _burn( address _owner, uint256 _tokenId ) internal { assert(tokens.length > 0); super._burn(_owner, _tokenId); uint256 tokenIndex = idToIndex[_tokenId]; uint256 lastTokenIndex = tokens.length.sub(1); uint256 lastToken = tokens[lastTokenIndex]; tokens[tokenIndex] = lastToken; tokens[lastTokenIndex] = 0; tokens.length--; idToIndex[_tokenId] = 0; idToIndex[lastToken] = tokenIndex; } /** * @dev Removes a NFT from an address. * @notice Use and override this function with caution. Wrong usage can have serious consequences. * @param _from Address from wich we want to remove the NFT. * @param _tokenId Which NFT we want to remove. */ function removeNFToken( address _from, uint256 _tokenId ) internal { super.removeNFToken(_from, _tokenId); assert(ownerToIds[_from].length > 0); uint256 tokenToRemoveIndex = idToOwnerIndex[_tokenId]; uint256 lastTokenIndex = ownerToIds[_from].length.sub(1); uint256 lastToken = ownerToIds[_from][lastTokenIndex]; ownerToIds[_from][tokenToRemoveIndex] = lastToken; ownerToIds[_from].length--; idToOwnerIndex[_tokenId] = 0; idToOwnerIndex[lastToken] = tokenToRemoveIndex; } /** * @dev Assignes a new NFT to an address. * @notice Use and override this function with caution. Wrong usage can have serious consequences. * @param _to Address to wich we want to add the NFT. * @param _tokenId Which NFT we want to add. */ function addNFToken( address _to, uint256 _tokenId ) internal { super.addNFToken(_to, _tokenId); uint256 length = ownerToIds[_to].length; ownerToIds[_to].push(_tokenId); idToOwnerIndex[_tokenId] = length; } /** * @dev Returns the count of all existing NFTokens. */ function totalSupply() external view returns (uint256) { return tokens.length; } /** * @dev Returns NFT ID by its index. * @param _index A counter less than `totalSupply()`. */ function tokenByIndex( uint256 _index ) external view returns (uint256) { require(_index < tokens.length); return tokens[_index]; } /** * @dev returns the n-th NFT ID from a list of owner's tokens. * @param _owner Token owner's address. * @param _index Index number representing n-th token in owner's list of tokens. */ function tokenOfOwnerByIndex( address _owner, uint256 _index ) external view returns (uint256) { require(_index < ownerToIds[_owner].length); return ownerToIds[_owner][_index]; } } // File: @0xcert/ethereum-erc721/contracts/tokens/ERC721Metadata.sol /** * @dev Optional metadata extension for ERC-721 non-fungible token standard. * See https://goo.gl/pc9yoS. */ interface ERC721Metadata { /** * @dev Returns a descriptive name for a collection of NFTs in this contract. */ function name() external view returns (string _name); /** * @dev Returns a abbreviated name for a collection of NFTs in this contract. */ function symbol() external view returns (string _symbol); /** * @dev Returns a distinct Uniform Resource Identifier (URI) for a given asset. It Throws if * `_tokenId` is not a valid NFT. URIs are defined in RFC3986. The URI may point to a JSON file * that conforms to the "ERC721 Metadata JSON Schema". */ function tokenURI(uint256 _tokenId) external view returns (string); } // File: @0xcert/ethereum-erc721/contracts/tokens/NFTokenMetadata.sol /** * @dev Optional metadata implementation for ERC-721 non-fungible token standard. */ contract NFTokenMetadata is NFToken, ERC721Metadata { /** * @dev A descriptive name for a collection of NFTs. */ string internal nftName; /** * @dev An abbreviated name for NFTokens. */ string internal nftSymbol; /** * @dev Mapping from NFT ID to metadata uri. */ mapping (uint256 => string) internal idToUri; /** * @dev Contract constructor. * @notice When implementing this contract don't forget to set nftName and nftSymbol. */ constructor() public { supportedInterfaces[0x5b5e139f] = true; // ERC721Metadata } /** * @dev Burns a NFT. * @notice This is a internal function which should be called from user-implemented external * burn function. Its purpose is to show and properly initialize data structures when using this * implementation. * @param _owner Address of the NFT owner. * @param _tokenId ID of the NFT to be burned. */ function _burn( address _owner, uint256 _tokenId ) internal { super._burn(_owner, _tokenId); if (bytes(idToUri[_tokenId]).length != 0) { delete idToUri[_tokenId]; } } /** * @dev Set a distinct URI (RFC 3986) for a given NFT ID. * @notice this is a internal function which should be called from user-implemented external * function. Its purpose is to show and properly initialize data structures when using this * implementation. * @param _tokenId Id for which we want uri. * @param _uri String representing RFC 3986 URI. */ function _setTokenUri( uint256 _tokenId, string _uri ) validNFToken(_tokenId) internal { idToUri[_tokenId] = _uri; } /** * @dev Returns a descriptive name for a collection of NFTokens. */ function name() external view returns (string _name) { _name = nftName; } /** * @dev Returns an abbreviated name for NFTokens. */ function symbol() external view returns (string _symbol) { _symbol = nftSymbol; } /** * @dev A distinct URI (RFC 3986) for a given NFT. * @param _tokenId Id for which we want uri. */ function tokenURI( uint256 _tokenId ) validNFToken(_tokenId) external view returns (string) { return idToUri[_tokenId]; } } // File: contracts/tokens/Xcert.sol /** * @dev Xcert implementation. */ contract Xcert is NFTokenEnumerable, NFTokenMetadata { using SafeMath for uint256; using AddressUtils for address; /** * @dev Unique ID which determines each Xcert smart contract type by its JSON convention. * @notice Calculated as bytes4(keccak256(jsonSchema)). */ bytes4 internal nftConventionId; /** * @dev Maps NFT ID to proof. */ mapping (uint256 => string) internal idToProof; /** * @dev Maps NFT ID to protocol config. */ mapping (uint256 => bytes32[]) internal config; /** * @dev Maps NFT ID to convention data. */ mapping (uint256 => bytes32[]) internal data; /** * @dev Maps address to authorization of contract. */ mapping (address => bool) internal addressToAuthorized; /** * @dev Emits when an address is authorized to some contract control or the authorization is revoked. * The _target has some contract controle like minting new NFTs. * @param _target Address to set authorized state. * @param _authorized True if the _target is authorised, false to revoke authorization. */ event AuthorizedAddress( address indexed _target, bool _authorized ); /** * @dev Guarantees that msg.sender is allowed to mint a new NFT. */ modifier isAuthorized() { require(msg.sender == owner || addressToAuthorized[msg.sender]); _; } /** * @dev Contract constructor. * @notice When implementing this contract don't forget to set nftConventionId, nftName and * nftSymbol. */ constructor() public { supportedInterfaces[0x6be14f75] = true; // Xcert } /** * @dev Mints a new NFT. * @param _to The address that will own the minted NFT. * @param _id The NFT to be minted by the msg.sender. * @param _uri An URI pointing to NFT metadata. * @param _proof Cryptographic asset imprint. * @param _config Array of protocol config values where 0 index represents token expiration * timestamp, other indexes are not yet definied but are ready for future xcert upgrades. * @param _data Array of convention data values. */ function mint( address _to, uint256 _id, string _uri, string _proof, bytes32[] _config, bytes32[] _data ) external isAuthorized() { require(_config.length > 0); require(bytes(_proof).length > 0); super._mint(_to, _id); super._setTokenUri(_id, _uri); idToProof[_id] = _proof; config[_id] = _config; data[_id] = _data; } /** * @dev Returns a bytes4 of keccak256 of json schema representing 0xcert protocol convention. */ function conventionId() external view returns (bytes4 _conventionId) { _conventionId = nftConventionId; } /** * @dev Returns proof for NFT. * @param _tokenId Id of the NFT. */ function tokenProof( uint256 _tokenId ) validNFToken(_tokenId) external view returns(string) { return idToProof[_tokenId]; } /** * @dev Returns convention data value for a given index field. * @param _tokenId Id of the NFT we want to get value for key. * @param _index for which we want to get value. */ function tokenDataValue( uint256 _tokenId, uint256 _index ) validNFToken(_tokenId) public view returns(bytes32 value) { require(_index < data[_tokenId].length); value = data[_tokenId][_index]; } /** * @dev Returns expiration date from 0 index of token config values. * @param _tokenId Id of the NFT we want to get expiration time of. */ function tokenExpirationTime( uint256 _tokenId ) validNFToken(_tokenId) external view returns(bytes32) { return config[_tokenId][0]; } /** * @dev Sets authorised address for minting. * @param _target Address to set authorized state. * @param _authorized True if the _target is authorised, false to revoke authorization. */ function setAuthorizedAddress( address _target, bool _authorized ) onlyOwner external { require(_target != address(0)); addressToAuthorized[_target] = _authorized; emit AuthorizedAddress(_target, _authorized); } /** * @dev Sets mint authorised address. * @param _target Address for which we want to check if it is authorized. * @return Is authorized or not. */ function isAuthorizedAddress( address _target ) external view returns (bool) { require(_target != address(0)); return addressToAuthorized[_target]; } } // File: contracts/tokens/MutableXcert.sol /** * @dev Xcert implementation where token data can be changed by authorized address. */ contract MutableXcert is Xcert { /** * @dev Emits when an Token data is changed. * @param _id NFT that data got changed. * @param _data New data. */ event TokenDataChange( uint256 indexed _id, bytes32[] _data ); /** * @dev Contract constructor. * @notice When implementing this contract don't forget to set nftConventionId, nftName and * nftSymbol. */ constructor() public { supportedInterfaces[0x59118221] = true; // MutableXcert } /** * @dev Modifies convention data by setting a new value for a given index field. * @param _tokenId Id of the NFT we want to set key value data. * @param _data New token data. */ function setTokenData( uint256 _tokenId, bytes32[] _data ) validNFToken(_tokenId) isAuthorized() external { data[_tokenId] = _data; emit TokenDataChange(_tokenId, _data); } } // File: contracts/tokens/PausableXcert.sol /** * @dev Xcert implementation where tokens transfer can be paused/unpaused. */ contract PausableXcert is Xcert { /** * @dev This emits when ability of beeing able to transfer NFTs changes (paused/unpaused). */ event IsPaused(bool _isPaused); /** * @dev Are NFT paused or not. */ bool public isPaused; /** * @dev Contract constructor. * @notice When implementing this contract don't forget to set nftConventionId, nftName, * nftSymbol and isPaused. */ constructor() public { supportedInterfaces[0xbedb86fb] = true; // PausableXcert } /** * @dev Guarantees that the msg.sender is allowed to transfer NFT. * @param _tokenId ID of the NFT to transfer. */ modifier canTransfer( uint256 _tokenId ) { address owner = idToOwner[_tokenId]; require(!isPaused && ( owner == msg.sender || getApproved(_tokenId) == msg.sender || ownerToOperators[owner][msg.sender]) ); _; } /** * @dev Sets if NFTs are paused or not. * @param _isPaused Pause status. */ function setPause( bool _isPaused ) external onlyOwner { require(isPaused != _isPaused); isPaused = _isPaused; emit IsPaused(_isPaused); } } // File: contracts/tokens/RevokableXcert.sol /** * @dev Xcert implementation where tokens can be destroyed by the issuer. */ contract RevokableXcert is Xcert { /** * @dev Contract constructor. * @notice When implementing this contract don't forget to set nftConventionId, nftName and * nftSymbol. */ constructor() public { supportedInterfaces[0x20c5429b] = true; // RevokableXcert } /** * @dev Revokes a specified NFT. * @param _tokenId Id of the NFT we want to revoke. */ function revoke( uint256 _tokenId ) validNFToken(_tokenId) onlyOwner external { address tokenOwner = idToOwner[_tokenId]; super._burn(tokenOwner, _tokenId); delete data[_tokenId]; delete config[_tokenId]; delete idToProof[_tokenId]; } } // File: contracts/mocks/KycToken.sol contract KycToken is PausableXcert, RevokableXcert, MutableXcert { constructor() public { nftName = "0xcert KYC"; nftSymbol = "KYC"; nftConventionId = 0xfc3ee448; isPaused = true; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_id","type":"uint256"},{"name":"_uri","type":"string"},{"name":"_proof","type":"string"},{"name":"_config","type":"bytes32[]"},{"name":"_data","type":"bytes32[]"}],"name":"mint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"_name","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_approved","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"approve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_target","type":"address"},{"name":"_authorized","type":"bool"}],"name":"setAuthorizedAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"revoke","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_target","type":"address"}],"name":"isAuthorizedAddress","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_tokenId","type":"uint256"},{"name":"_data","type":"bytes32[]"}],"name":"setTokenData","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"conventionId","outputs":[{"name":"_conventionId","type":"bytes4"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"name":"_owner","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"tokenProof","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"_symbol","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_operator","type":"address"},{"name":"_approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"},{"name":"_index","type":"uint256"}],"name":"tokenDataValue","outputs":[{"name":"value","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isPaused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"tokenExpirationTime","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_isPaused","type":"bool"}],"name":"setPause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_id","type":"uint256"},{"indexed":false,"name":"_data","type":"bytes32[]"}],"name":"TokenDataChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_isPaused","type":"bool"}],"name":"IsPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_target","type":"address"},{"indexed":false,"name":"_authorized","type":"bool"}],"name":"AuthorizedAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":true,"name":"_tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_approved","type":"address"},{"indexed":true,"name":"_tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_operator","type":"address"},{"indexed":false,"name":"_approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060008054600160a060020a03191633178155600160208181527fb45820386466a8e01597d6e1efaf8f11ba4467972de5ca6c1f8aa3544ac2888e805460ff1990811684179091557fb8349d7b7b0b2b924bf96f90971cda8c7ac1ea4cde292a182bd2a203eef6c5d080548216841790557f0e20bd7b4297895bdd985faac9360f413d46658b4c96e853899576249f1474ab80548216841790557fce9309d5fe1c6050fdfde39d28ca0616e34393306d1cba1a247c40f9ef5c5d0980548216841790557ff3fb99723eb92c18954006ee319df86b099006c39a1d98f956085be573f4551180548216841790557fb4368fd0ef2ab72f947c292e326912e5d1b72971af1d1b535f6998b77c75905080548216841790557f58a596ea3514289d7cbc129799a1ad30a67c3077cf47f4aac1c1689a8c478e7c80548216841790557f59118221000000000000000000000000000000000000000000000000000000009093527f7d3987275a39df06c7f0c62c4273bcbe6c1e1855a7375cc0d5786891c7629256805490931690911790915560408051808201909152600a8082527f307863657274204b59430000000000000000000000000000000000000000000091909201908152620001e391908162000251565b506040805180820190915260038082527f4b5943000000000000000000000000000000000000000000000000000000000060209092019182526200022a91600b9162000251565b50600d805463ffffffff191663fc3ee4481790556012805460ff19166001179055620002f6565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200029457805160ff1916838001178555620002c4565b82800160010185558215620002c4579182015b82811115620002c4578251825591602001919060010190620002a7565b50620002d2929150620002d6565b5090565b620002f391905b80821115620002d25760008155600101620002dd565b90565b611cbb80620003066000396000f3006080604052600436106101735763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041662ea81c0811461017857806301ffc9a7146101cf57806306fdde0314610205578063081812fc1461028f578063095ea7b3146102c35780631351cf51146102e757806318160ddd1461030d57806320c5429b1461033457806323b872dd1461034c5780632f745c591461037657806342842e0e1461039a5780634a85280e146103c45780634f6ccce7146103e557806359118221146103fd5780635f54fa98146104215780636352211e1461045357806370a082311461046b5780637c8ff8ac1461048c5780638da5cb5b146104a457806395d89b41146104b9578063a22cb465146104ce578063acec460f146104f4578063b187bd261461050f578063b88d4fde14610524578063bde86dd11461055d578063bedb86fb14610575578063c87b56dd1461058f578063e985e9c5146105a7578063f2fde38b146105ce575b600080fd5b34801561018457600080fd5b506101cd60048035600160a060020a031690602480359160443580830192908201359160643580830192908201359160843580830192908201359160a4359182019101356105ef565b005b3480156101db57600080fd5b506101f1600160e060020a0319600435166106da565b604080519115158252519081900360200190f35b34801561021157600080fd5b5061021a6106fd565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561025457818101518382015260200161023c565b50505050905090810190601f1680156102815780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561029b57600080fd5b506102a7600435610793565b60408051600160a060020a039092168252519081900360200190f35b3480156102cf57600080fd5b506101cd600160a060020a03600435166024356107d5565b3480156102f357600080fd5b506101cd600160a060020a036004351660243515156108e6565b34801561031957600080fd5b50610322610972565b60408051918252519081900360200190f35b34801561034057600080fd5b506101cd600435610979565b34801561035857600080fd5b506101cd600160a060020a0360043581169060243516604435610a23565b34801561038257600080fd5b50610322600160a060020a0360043516602435610b22565b3480156103a657600080fd5b506101cd600160a060020a0360043581169060243516604435610b7d565b3480156103d057600080fd5b506101f1600160a060020a0360043516610b99565b3480156103f157600080fd5b50610322600435610bcf565b34801561040957600080fd5b506101cd600480359060248035908101910135610c00565b34801561042d57600080fd5b50610436610ccc565b60408051600160e060020a03199092168252519081900360200190f35b34801561045f57600080fd5b506102a7600435610cf1565b34801561047757600080fd5b50610322600160a060020a0360043516610d15565b34801561049857600080fd5b5061021a600435610d48565b3480156104b057600080fd5b506102a7610e10565b3480156104c557600080fd5b5061021a610e1f565b3480156104da57600080fd5b506101cd600160a060020a03600435166024351515610e80565b34801561050057600080fd5b50610322600435602435610f03565b34801561051b57600080fd5b506101f1610f70565b34801561053057600080fd5b506101cd600160a060020a0360048035821691602480359091169160443591606435908101910135610f79565b34801561056957600080fd5b50610322600435610fbc565b34801561058157600080fd5b506101cd600435151561100f565b34801561059b57600080fd5b5061021a600435611083565b3480156105b357600080fd5b506101f1600160a060020a0360043581169060243516611113565b3480156105da57600080fd5b506101cd600160a060020a036004351661116e565b600054600160a060020a031633148061061757503360009081526011602052604090205460ff165b151561062257600080fd5b6000831161062f57600080fd5b6000851161063c57600080fd5b6106468a8a611202565b6106808989898080601f01602080910402602001604051908101604052809392919081815260200183838082843750611242945050505050565b6000898152600e60205260409020610699908787611ac7565b506000898152600f602052604090206106b3908585611b45565b5060008981526010602052604090206106cd908383611b45565b5050505050505050505050565b600160e060020a0319811660009081526001602052604090205460ff165b919050565b600a8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156107895780601f1061075e57610100808354040283529160200191610789565b820191906000526020600020905b81548152906001019060200180831161076c57829003601f168201915b5050505050905090565b6000818152600260205260408120548290600160a060020a031615156107b857600080fd5b5050600090815260036020526040902054600160a060020a031690565b6000818152600260205260408120548290600160a060020a0316338114806108205750600160a060020a038116600090815260056020908152604080832033845290915290205460ff165b151561082b57600080fd5b6000848152600260205260409020548490600160a060020a0316151561085057600080fd5b600085815260026020526040902054600160a060020a039081169450861684141561087a57600080fd5b600085815260036020526040808220805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a038a811691821790925591518893918816917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050505050565b600054600160a060020a031633146108fd57600080fd5b600160a060020a038216151561091257600080fd5b600160a060020a038216600081815260116020908152604091829020805460ff1916851515908117909155825190815291517f9947ea94054b1344203190ef8b59684fb00675104126f16896617c2630a2771a9281900390910190a25050565b6006545b90565b6000818152600260205260408120548290600160a060020a0316151561099e57600080fd5b600054600160a060020a031633146109b557600080fd5b600083815260026020526040902054600160a060020a031691506109d9828461128c565b60008381526010602052604081206109f091611b82565b6000838152600f60205260408120610a0791611b82565b6000838152600e60205260408120610a1e91611ba3565b505050565b6000818152600260205260408120546012548391600160a060020a03169060ff16158015610aa15750600160a060020a038116331480610a73575033610a6883610793565b600160a060020a0316145b80610aa15750600160a060020a038116600090815260056020908152604080832033845290915290205460ff165b1515610aac57600080fd5b6000848152600260205260409020548490600160a060020a03161515610ad157600080fd5b600085815260026020526040902054600160a060020a03908116945087168414610afa57600080fd5b600160a060020a0386161515610b0f57600080fd5b610b1986866112d8565b50505050505050565b600160a060020a0382166000908152600860205260408120548210610b4657600080fd5b600160a060020a0383166000908152600860205260409020805483908110610b6a57fe5b9060005260206000200154905092915050565b610a1e8383836020604051908101604052806000815250611354565b6000600160a060020a0382161515610bb057600080fd5b50600160a060020a031660009081526011602052604090205460ff1690565b6006546000908210610be057600080fd5b6006805483908110610bee57fe5b90600052602060002001549050919050565b6000838152600260205260409020548390600160a060020a03161515610c2557600080fd5b600054600160a060020a0316331480610c4d57503360009081526011602052604090205460ff165b1515610c5857600080fd5b6000848152601060205260409020610c71908484611b45565b50837f5b79b007b3d1922ba2ad22a94efca28a60de5713df39285a095603300653097984846040518080602001828103825284848281815260200192506020028082843760405192018290039550909350505050a250505050565b600d547c01000000000000000000000000000000000000000000000000000000000290565b600081815260026020526040902054600160a060020a03168015156106f857600080fd5b6000600160a060020a0382161515610d2c57600080fd5b50600160a060020a031660009081526004602052604090205490565b6000818152600260205260409020546060908290600160a060020a03161515610d7057600080fd5b6000838152600e602090815260409182902080548351601f600260001961010060018616150201909316929092049182018490048402810184019094528084529091830182828015610e035780601f10610dd857610100808354040283529160200191610e03565b820191906000526020600020905b815481529060010190602001808311610de657829003601f168201915b5050505050915050919050565b600054600160a060020a031681565b600b8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156107895780601f1061075e57610100808354040283529160200191610789565b600160a060020a0382161515610e9557600080fd5b336000818152600560209081526040808320600160a060020a03871680855290835292819020805460ff1916861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b6000828152600260205260408120548390600160a060020a03161515610f2857600080fd5b6000848152601060205260409020548310610f4257600080fd5b6000848152601060205260409020805484908110610f5c57fe5b906000526020600020015491505092915050565b60125460ff1681565b610fb585858585858080601f01602080910402602001604051908101604052809392919081815260200183838082843750611354945050505050565b5050505050565b6000818152600260205260408120548290600160a060020a03161515610fe157600080fd5b6000838152600f6020526040812080549091908110610ffc57fe5b9060005260206000200154915050919050565b600054600160a060020a0316331461102657600080fd5b60125460ff161515811515141561103c57600080fd5b6012805482151560ff19909116811790915560408051918252517fff4a5dbbab6b1963d10f5edd139f33a7987ecb3c4f65969be77ddba28d9465949181900360200190a150565b6000818152600260205260409020546060908290600160a060020a031615156110ab57600080fd5b6000838152600c602090815260409182902080548351601f600260001961010060018616150201909316929092049182018490048402810184019094528084529091830182828015610e035780601f10610dd857610100808354040283529160200191610e03565b6000600160a060020a038316151561112a57600080fd5b600160a060020a038216151561113f57600080fd5b50600160a060020a03918216600090815260056020908152604080832093909416825291909152205460ff1690565b600054600160a060020a0316331461118557600080fd5b600160a060020a038116151561119a57600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b61120c82826115b6565b600680546001810182556000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f015550565b6000828152600260205260409020548290600160a060020a0316151561126757600080fd5b6000838152600c60209081526040909120835161128692850190611be7565b50505050565b611296828261163f565b6000818152600c602052604090205460026000196101006001841615020190911604156112d4576000818152600c602052604081206112d491611ba3565b5050565b600081815260026020526040902054600160a060020a03166112fa8183611708565b611304818361176a565b61130e8383611891565b8183600160a060020a031682600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60008281526002602052604081205460125482918591600160a060020a039091169060ff161580156113d65750600160a060020a0381163314806113a857503361139d83610793565b600160a060020a0316145b806113d65750600160a060020a038116600090815260056020908152604080832033845290915290205460ff165b15156113e157600080fd5b6000868152600260205260409020548690600160a060020a0316151561140657600080fd5b600087815260026020526040902054600160a060020a0390811695508916851461142f57600080fd5b600160a060020a038816151561144457600080fd5b61144e88886112d8565b61146088600160a060020a03166118da565b156115ab576040517f150b7a020000000000000000000000000000000000000000000000000000000081523360048201818152600160a060020a038c81166024850152604484018b90526080606485019081528a5160848601528a51918d169463150b7a0294938f938e938e93909160a490910190602085019080838360005b838110156114f85781810151838201526020016114e0565b50505050905090810190601f1680156115255780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b15801561154757600080fd5b505af115801561155b573d6000803e3d6000fd5b505050506040513d602081101561157157600080fd5b50519350600160e060020a031984167f150b7a0200000000000000000000000000000000000000000000000000000000146115ab57600080fd5b505050505050505050565b600160a060020a03821615156115cb57600080fd5b8015156115d757600080fd5b600081815260026020526040902054600160a060020a0316156115f957600080fd5b6116038282611891565b6040518190600160a060020a038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60065460009081908190811061165157fe5b61165b85856118e2565b60008481526007602052604090205460065490935061168190600163ffffffff61195816565b915060068281548110151561169257fe5b90600052602060002001549050806006848154811015156116af57fe5b600091825260208220019190915560068054849081106116cb57fe5b60009182526020909120015560068054906116ea906000198301611c55565b50600093845260076020526040808520859055908452909220555050565b600081815260036020526040808220805473ffffffffffffffffffffffffffffffffffffffff1916905551829190600160a060020a038516907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925908390a45050565b6000806000611779858561196a565b600160a060020a0385166000908152600860205260408120541161179957fe5b600084815260096020908152604080832054600160a060020a03891684526008909252909120549093506117d490600163ffffffff61195816565b600160a060020a0386166000908152600860205260409020805491935090839081106117fc57fe5b90600052602060002001549050806008600087600160a060020a0316600160a060020a031681526020019081526020016000208481548110151561183c57fe5b6000918252602080832090910192909255600160a060020a0387168152600890915260409020805490611873906000198301611c55565b50600093845260096020526040808520859055908452909220555050565b600061189d8383611a20565b50600160a060020a039091166000908152600860209081526040808320805460018101825590845282842081018590559383526009909152902055565b6000903b1190565b6000818152600260205260409020548190600160a060020a0316151561190757600080fd5b6119118383611708565b61191b838361176a565b6040518290600090600160a060020a038616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a4505050565b60008282111561196457fe5b50900390565b600081815260026020526040902054600160a060020a0383811691161461199057600080fd5b600160a060020a038216600090815260046020526040812054116119b057fe5b600160a060020a0382166000908152600460205260409020546119da90600163ffffffff61195816565b600160a060020a03909216600090815260046020908152604080832094909455918152600290915220805473ffffffffffffffffffffffffffffffffffffffff19169055565b600081815260026020526040902054600160a060020a031615611a4257600080fd5b6000818152600260209081526040808320805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03871690811790915583526004909152902054611a91906001611ab1565b600160a060020a0390921660009081526004602052604090209190915550565b600082820183811015611ac057fe5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611b085782800160ff19823516178555611b35565b82800160010185558215611b35579182015b82811115611b35578235825591602001919060010190611b1a565b50611b41929150611c75565b5090565b828054828255906000526020600020908101928215611b35579160200282015b82811115611b355782358255602090920191600190910190611b65565b5080546000825590600052602060002090810190611ba09190611c75565b50565b50805460018160011615610100020316600290046000825580601f10611bc95750611ba0565b601f016020900490600052602060002090810190611ba09190611c75565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611c2857805160ff1916838001178555611b35565b82800160010185558215611b35579182015b82811115611b35578251825591602001919060010190611c3a565b815481835581811115610a1e57600083815260209020610a1e9181019083015b61097691905b80821115611b415760008155600101611c7b5600a165627a7a723058202ec2ce27f979d12cd420746f06090e197f7f1bf0a9064b8ee39911ea717e54dd0029
Deployed Bytecode
0x6080604052600436106101735763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041662ea81c0811461017857806301ffc9a7146101cf57806306fdde0314610205578063081812fc1461028f578063095ea7b3146102c35780631351cf51146102e757806318160ddd1461030d57806320c5429b1461033457806323b872dd1461034c5780632f745c591461037657806342842e0e1461039a5780634a85280e146103c45780634f6ccce7146103e557806359118221146103fd5780635f54fa98146104215780636352211e1461045357806370a082311461046b5780637c8ff8ac1461048c5780638da5cb5b146104a457806395d89b41146104b9578063a22cb465146104ce578063acec460f146104f4578063b187bd261461050f578063b88d4fde14610524578063bde86dd11461055d578063bedb86fb14610575578063c87b56dd1461058f578063e985e9c5146105a7578063f2fde38b146105ce575b600080fd5b34801561018457600080fd5b506101cd60048035600160a060020a031690602480359160443580830192908201359160643580830192908201359160843580830192908201359160a4359182019101356105ef565b005b3480156101db57600080fd5b506101f1600160e060020a0319600435166106da565b604080519115158252519081900360200190f35b34801561021157600080fd5b5061021a6106fd565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561025457818101518382015260200161023c565b50505050905090810190601f1680156102815780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561029b57600080fd5b506102a7600435610793565b60408051600160a060020a039092168252519081900360200190f35b3480156102cf57600080fd5b506101cd600160a060020a03600435166024356107d5565b3480156102f357600080fd5b506101cd600160a060020a036004351660243515156108e6565b34801561031957600080fd5b50610322610972565b60408051918252519081900360200190f35b34801561034057600080fd5b506101cd600435610979565b34801561035857600080fd5b506101cd600160a060020a0360043581169060243516604435610a23565b34801561038257600080fd5b50610322600160a060020a0360043516602435610b22565b3480156103a657600080fd5b506101cd600160a060020a0360043581169060243516604435610b7d565b3480156103d057600080fd5b506101f1600160a060020a0360043516610b99565b3480156103f157600080fd5b50610322600435610bcf565b34801561040957600080fd5b506101cd600480359060248035908101910135610c00565b34801561042d57600080fd5b50610436610ccc565b60408051600160e060020a03199092168252519081900360200190f35b34801561045f57600080fd5b506102a7600435610cf1565b34801561047757600080fd5b50610322600160a060020a0360043516610d15565b34801561049857600080fd5b5061021a600435610d48565b3480156104b057600080fd5b506102a7610e10565b3480156104c557600080fd5b5061021a610e1f565b3480156104da57600080fd5b506101cd600160a060020a03600435166024351515610e80565b34801561050057600080fd5b50610322600435602435610f03565b34801561051b57600080fd5b506101f1610f70565b34801561053057600080fd5b506101cd600160a060020a0360048035821691602480359091169160443591606435908101910135610f79565b34801561056957600080fd5b50610322600435610fbc565b34801561058157600080fd5b506101cd600435151561100f565b34801561059b57600080fd5b5061021a600435611083565b3480156105b357600080fd5b506101f1600160a060020a0360043581169060243516611113565b3480156105da57600080fd5b506101cd600160a060020a036004351661116e565b600054600160a060020a031633148061061757503360009081526011602052604090205460ff165b151561062257600080fd5b6000831161062f57600080fd5b6000851161063c57600080fd5b6106468a8a611202565b6106808989898080601f01602080910402602001604051908101604052809392919081815260200183838082843750611242945050505050565b6000898152600e60205260409020610699908787611ac7565b506000898152600f602052604090206106b3908585611b45565b5060008981526010602052604090206106cd908383611b45565b5050505050505050505050565b600160e060020a0319811660009081526001602052604090205460ff165b919050565b600a8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156107895780601f1061075e57610100808354040283529160200191610789565b820191906000526020600020905b81548152906001019060200180831161076c57829003601f168201915b5050505050905090565b6000818152600260205260408120548290600160a060020a031615156107b857600080fd5b5050600090815260036020526040902054600160a060020a031690565b6000818152600260205260408120548290600160a060020a0316338114806108205750600160a060020a038116600090815260056020908152604080832033845290915290205460ff165b151561082b57600080fd5b6000848152600260205260409020548490600160a060020a0316151561085057600080fd5b600085815260026020526040902054600160a060020a039081169450861684141561087a57600080fd5b600085815260036020526040808220805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a038a811691821790925591518893918816917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050505050565b600054600160a060020a031633146108fd57600080fd5b600160a060020a038216151561091257600080fd5b600160a060020a038216600081815260116020908152604091829020805460ff1916851515908117909155825190815291517f9947ea94054b1344203190ef8b59684fb00675104126f16896617c2630a2771a9281900390910190a25050565b6006545b90565b6000818152600260205260408120548290600160a060020a0316151561099e57600080fd5b600054600160a060020a031633146109b557600080fd5b600083815260026020526040902054600160a060020a031691506109d9828461128c565b60008381526010602052604081206109f091611b82565b6000838152600f60205260408120610a0791611b82565b6000838152600e60205260408120610a1e91611ba3565b505050565b6000818152600260205260408120546012548391600160a060020a03169060ff16158015610aa15750600160a060020a038116331480610a73575033610a6883610793565b600160a060020a0316145b80610aa15750600160a060020a038116600090815260056020908152604080832033845290915290205460ff165b1515610aac57600080fd5b6000848152600260205260409020548490600160a060020a03161515610ad157600080fd5b600085815260026020526040902054600160a060020a03908116945087168414610afa57600080fd5b600160a060020a0386161515610b0f57600080fd5b610b1986866112d8565b50505050505050565b600160a060020a0382166000908152600860205260408120548210610b4657600080fd5b600160a060020a0383166000908152600860205260409020805483908110610b6a57fe5b9060005260206000200154905092915050565b610a1e8383836020604051908101604052806000815250611354565b6000600160a060020a0382161515610bb057600080fd5b50600160a060020a031660009081526011602052604090205460ff1690565b6006546000908210610be057600080fd5b6006805483908110610bee57fe5b90600052602060002001549050919050565b6000838152600260205260409020548390600160a060020a03161515610c2557600080fd5b600054600160a060020a0316331480610c4d57503360009081526011602052604090205460ff165b1515610c5857600080fd5b6000848152601060205260409020610c71908484611b45565b50837f5b79b007b3d1922ba2ad22a94efca28a60de5713df39285a095603300653097984846040518080602001828103825284848281815260200192506020028082843760405192018290039550909350505050a250505050565b600d547c01000000000000000000000000000000000000000000000000000000000290565b600081815260026020526040902054600160a060020a03168015156106f857600080fd5b6000600160a060020a0382161515610d2c57600080fd5b50600160a060020a031660009081526004602052604090205490565b6000818152600260205260409020546060908290600160a060020a03161515610d7057600080fd5b6000838152600e602090815260409182902080548351601f600260001961010060018616150201909316929092049182018490048402810184019094528084529091830182828015610e035780601f10610dd857610100808354040283529160200191610e03565b820191906000526020600020905b815481529060010190602001808311610de657829003601f168201915b5050505050915050919050565b600054600160a060020a031681565b600b8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156107895780601f1061075e57610100808354040283529160200191610789565b600160a060020a0382161515610e9557600080fd5b336000818152600560209081526040808320600160a060020a03871680855290835292819020805460ff1916861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b6000828152600260205260408120548390600160a060020a03161515610f2857600080fd5b6000848152601060205260409020548310610f4257600080fd5b6000848152601060205260409020805484908110610f5c57fe5b906000526020600020015491505092915050565b60125460ff1681565b610fb585858585858080601f01602080910402602001604051908101604052809392919081815260200183838082843750611354945050505050565b5050505050565b6000818152600260205260408120548290600160a060020a03161515610fe157600080fd5b6000838152600f6020526040812080549091908110610ffc57fe5b9060005260206000200154915050919050565b600054600160a060020a0316331461102657600080fd5b60125460ff161515811515141561103c57600080fd5b6012805482151560ff19909116811790915560408051918252517fff4a5dbbab6b1963d10f5edd139f33a7987ecb3c4f65969be77ddba28d9465949181900360200190a150565b6000818152600260205260409020546060908290600160a060020a031615156110ab57600080fd5b6000838152600c602090815260409182902080548351601f600260001961010060018616150201909316929092049182018490048402810184019094528084529091830182828015610e035780601f10610dd857610100808354040283529160200191610e03565b6000600160a060020a038316151561112a57600080fd5b600160a060020a038216151561113f57600080fd5b50600160a060020a03918216600090815260056020908152604080832093909416825291909152205460ff1690565b600054600160a060020a0316331461118557600080fd5b600160a060020a038116151561119a57600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b61120c82826115b6565b600680546001810182556000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f015550565b6000828152600260205260409020548290600160a060020a0316151561126757600080fd5b6000838152600c60209081526040909120835161128692850190611be7565b50505050565b611296828261163f565b6000818152600c602052604090205460026000196101006001841615020190911604156112d4576000818152600c602052604081206112d491611ba3565b5050565b600081815260026020526040902054600160a060020a03166112fa8183611708565b611304818361176a565b61130e8383611891565b8183600160a060020a031682600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60008281526002602052604081205460125482918591600160a060020a039091169060ff161580156113d65750600160a060020a0381163314806113a857503361139d83610793565b600160a060020a0316145b806113d65750600160a060020a038116600090815260056020908152604080832033845290915290205460ff165b15156113e157600080fd5b6000868152600260205260409020548690600160a060020a0316151561140657600080fd5b600087815260026020526040902054600160a060020a0390811695508916851461142f57600080fd5b600160a060020a038816151561144457600080fd5b61144e88886112d8565b61146088600160a060020a03166118da565b156115ab576040517f150b7a020000000000000000000000000000000000000000000000000000000081523360048201818152600160a060020a038c81166024850152604484018b90526080606485019081528a5160848601528a51918d169463150b7a0294938f938e938e93909160a490910190602085019080838360005b838110156114f85781810151838201526020016114e0565b50505050905090810190601f1680156115255780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b15801561154757600080fd5b505af115801561155b573d6000803e3d6000fd5b505050506040513d602081101561157157600080fd5b50519350600160e060020a031984167f150b7a0200000000000000000000000000000000000000000000000000000000146115ab57600080fd5b505050505050505050565b600160a060020a03821615156115cb57600080fd5b8015156115d757600080fd5b600081815260026020526040902054600160a060020a0316156115f957600080fd5b6116038282611891565b6040518190600160a060020a038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60065460009081908190811061165157fe5b61165b85856118e2565b60008481526007602052604090205460065490935061168190600163ffffffff61195816565b915060068281548110151561169257fe5b90600052602060002001549050806006848154811015156116af57fe5b600091825260208220019190915560068054849081106116cb57fe5b60009182526020909120015560068054906116ea906000198301611c55565b50600093845260076020526040808520859055908452909220555050565b600081815260036020526040808220805473ffffffffffffffffffffffffffffffffffffffff1916905551829190600160a060020a038516907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925908390a45050565b6000806000611779858561196a565b600160a060020a0385166000908152600860205260408120541161179957fe5b600084815260096020908152604080832054600160a060020a03891684526008909252909120549093506117d490600163ffffffff61195816565b600160a060020a0386166000908152600860205260409020805491935090839081106117fc57fe5b90600052602060002001549050806008600087600160a060020a0316600160a060020a031681526020019081526020016000208481548110151561183c57fe5b6000918252602080832090910192909255600160a060020a0387168152600890915260409020805490611873906000198301611c55565b50600093845260096020526040808520859055908452909220555050565b600061189d8383611a20565b50600160a060020a039091166000908152600860209081526040808320805460018101825590845282842081018590559383526009909152902055565b6000903b1190565b6000818152600260205260409020548190600160a060020a0316151561190757600080fd5b6119118383611708565b61191b838361176a565b6040518290600090600160a060020a038616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a4505050565b60008282111561196457fe5b50900390565b600081815260026020526040902054600160a060020a0383811691161461199057600080fd5b600160a060020a038216600090815260046020526040812054116119b057fe5b600160a060020a0382166000908152600460205260409020546119da90600163ffffffff61195816565b600160a060020a03909216600090815260046020908152604080832094909455918152600290915220805473ffffffffffffffffffffffffffffffffffffffff19169055565b600081815260026020526040902054600160a060020a031615611a4257600080fd5b6000818152600260209081526040808320805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03871690811790915583526004909152902054611a91906001611ab1565b600160a060020a0390921660009081526004602052604090209190915550565b600082820183811015611ac057fe5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611b085782800160ff19823516178555611b35565b82800160010185558215611b35579182015b82811115611b35578235825591602001919060010190611b1a565b50611b41929150611c75565b5090565b828054828255906000526020600020908101928215611b35579160200282015b82811115611b355782358255602090920191600190910190611b65565b5080546000825590600052602060002090810190611ba09190611c75565b50565b50805460018160011615610100020316600290046000825580601f10611bc95750611ba0565b601f016020900490600052602060002090810190611ba09190611c75565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611c2857805160ff1916838001178555611b35565b82800160010185558215611b35579182015b82811115611b35578251825591602001919060010190611c3a565b815481835581811115610a1e57600083815260209020610a1e9181019083015b61097691905b80821115611b415760008155600101611c7b5600a165627a7a723058202ec2ce27f979d12cd420746f06090e197f7f1bf0a9064b8ee39911ea717e54dd0029
Swarm Source
bzzr://2ec2ce27f979d12cd420746f06090e197f7f1bf0a9064b8ee39911ea717e54dd
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.