Polygon Sponsored slots available. Book your slot here!
More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 258,431 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Redeem | 70626775 | 12 hrs ago | IN | 0 POL | 0.00537312 | ||||
Handle Claim | 70506670 | 3 days ago | IN | 0 POL | 0.00431823 | ||||
Redeem | 70436937 | 5 days ago | IN | 0 POL | 0.00351546 | ||||
Redeem | 70400952 | 6 days ago | IN | 0 POL | 0.00351342 | ||||
Redeem | 70400733 | 6 days ago | IN | 0 POL | 0.00351522 | ||||
Redeem | 70400355 | 6 days ago | IN | 0 POL | 0.00351558 | ||||
Handle Claim | 70399808 | 6 days ago | IN | 0 POL | 0.00374823 | ||||
Redeem | 70399702 | 6 days ago | IN | 0 POL | 0.00402642 | ||||
Handle Claim | 70357082 | 7 days ago | IN | 0 POL | 0.00374543 | ||||
Handle Claim | 70323669 | 8 days ago | IN | 0 POL | 0.0052484 | ||||
Handle Claim | 70276161 | 9 days ago | IN | 0 POL | 0.00374663 | ||||
Handle Claim | 70275611 | 9 days ago | IN | 0 POL | 0.0052436 | ||||
Set Approval For... | 70217856 | 10 days ago | IN | 0 POL | 0.00066663 | ||||
Set Approval For... | 70217848 | 10 days ago | IN | 0 POL | 0.00066663 | ||||
Handle Claim | 70216781 | 10 days ago | IN | 0 POL | 0.00374839 | ||||
Handle Claim | 70210331 | 10 days ago | IN | 0 POL | 0.00431823 | ||||
Redeem | 70190382 | 11 days ago | IN | 0 POL | 0.00364411 | ||||
Handle Claim | 70160985 | 12 days ago | IN | 0 POL | 0.00431823 | ||||
Redeem | 70094436 | 13 days ago | IN | 0 POL | 0.00508798 | ||||
Handle Claim | 70093404 | 13 days ago | IN | 0 POL | 0.0052348 | ||||
Handle Claim | 70093305 | 13 days ago | IN | 0 POL | 0.00768821 | ||||
Handle Claim | 70050604 | 14 days ago | IN | 0 POL | 0.00691821 | ||||
Handle Claim | 70050297 | 14 days ago | IN | 0 POL | 0.01068128 | ||||
Handle Claim | 70043505 | 14 days ago | IN | 0 POL | 0.00431823 | ||||
Transfer From | 70029455 | 15 days ago | IN | 0 POL | 0.00078312 |
Loading...
Loading
Contract Name:
DecryptLearn
Compiler Version
v0.8.9+commit.e5eed63a
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity ^0.8.9; // SPDX-License-Identifier: MIT import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; error Soulbound(); contract DecryptLearn is ERC721, Ownable { using Counters for Counters.Counter; /*/////////////////////////////////////////////////////////////// TOKEN STORAGE //////////////////////////////////////////////////////////////*/ Counters.Counter public _tokenIdCounter; string[] public _certificateTypes; mapping(string => mapping(address => uint256)) public _certificateMintList; mapping(string => string) public _certificateTypeToURI; mapping(uint => string) public _tokenIdToType; /*/////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event CertificateTypeAdded(string certificateType, string certificateURI); event CertificateTypeChanged(string certificateType, string certificateURI); /*/////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor(string memory name, string memory symbol) ERC721(name, symbol) {} /*/////////////////////////////////////////////////////////////// CERTIFICATE LOGIC //////////////////////////////////////////////////////////////*/ /** * @notice Add a new certificate type */ function addCertificateType( string memory certificateType, string memory certificateUri ) external onlyOwner { require( _certificateMintList[certificateType][address(0)] != 1, "Certificate type already exists" ); _certificateTypes.push(certificateType); _certificateMintList[certificateType][address(0)] = 1; _certificateTypeToURI[certificateType] = certificateUri; emit CertificateTypeAdded(certificateType, certificateUri); } /** * @notice Change metadata associated with a certificate type */ function changeCertificateType( string memory certificateType, string memory certificateUri ) external onlyOwner { require( _certificateMintList[certificateType][address(0)] == 1, "Certificate type does not exist" ); _certificateTypeToURI[certificateType] = certificateUri; emit CertificateTypeChanged(certificateType, certificateUri); } function totalSupply() public view returns (uint256) { return _tokenIdCounter.current(); } /** * @notice Redeem a certificate by external user */ function redeem( address account, bytes calldata signature, string memory certificateType ) external validCertificateType(certificateType) notMintedYet(certificateType, account) { require(msg.sender == account, "You can only redeem for yourself"); require(_verify(_hash(account), signature), "Invalid signature"); mintCertificate(account, certificateType); } /** * @notice Handle a claim by a user * */ function handleClaim(address account, string memory certificateType) external onlyOwner validCertificateType(certificateType) notMintedYet(certificateType, account) { mintCertificate(account, certificateType); } function mintCertificate(address account, string memory certificateType) private { _tokenIdCounter.increment(); uint256 tokenId = _tokenIdCounter.current(); _tokenIdToType[tokenId] = certificateType; // Mark address as having claimed _certificateMintList[certificateType][account] = 1; _safeMint(account, tokenId); } /*/////////////////////////////////////////////////////////////// TOKEN LOGIC //////////////////////////////////////////////////////////////*/ /** * @notice SOULBOUND: Block transfers. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual override(ERC721) { require( from == address(0) || to == address(0), "SOULBOUND: Non-Transferable" ); super._beforeTokenTransfer(from, to, tokenId); } /** * @notice SOULBOUND: Block approvals. */ function setApprovalForAll(address operator, bool _approved) public virtual override(ERC721) { revert Soulbound(); } /** * @notice SOULBOUND: Block approvals. */ function approve(address to, uint256 tokenId) public virtual override(ERC721) { revert Soulbound(); } /** * @notice Return tokenURI based on certificate type */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require( _exists(tokenId), "ERC721Metadata: URI query for nonexistent token" ); return _certificateTypeToURI[_tokenIdToType[tokenId]]; } /*/////////////////////////////////////////////////////////////// MODIFIERS //////////////////////////////////////////////////////////////*/ /** * @notice Check certificate type exists */ modifier validCertificateType(string memory certificateType) { require( _certificateMintList[certificateType][address(0)] != 0, "Certificate type does not exist" ); _; } /** * @notice Check user has not minted this certificate yet */ modifier notMintedYet(string memory certificateType, address account) { require( _certificateMintList[certificateType][account] != 1, "User already minted this certificate" ); _; } /*/////////////////////////////////////////////////////////////// UTILS //////////////////////////////////////////////////////////////*/ /** * @notice Compute hash of account */ function _hash(address account) internal pure returns (bytes32) { return ECDSA.toEthSignedMessageHash(keccak256(abi.encodePacked(account))); } /** * @notice Verify signature belongs to owner */ function _verify(bytes32 digest, bytes memory signature) internal view returns (bool) { return owner() == ECDSA.recover(digest, signature); } function withdraw() public onlyOwner { uint256 balance = address(this).balance; payable(msg.sender).transfer(balance); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; import "./IERC721.sol"; import "./IERC721Receiver.sol"; import "./extensions/IERC721Metadata.sol"; import "../../utils/Address.sol"; import "../../utils/Context.sol"; import "../../utils/Strings.sol"; import "../../utils/introspection/ERC165.sol"; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: address zero is not a valid owner"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _owners[tokenId]; require(owner != address(0), "ERC721: invalid token ID"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not token owner nor approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { _requireMinted(tokenId); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory data ) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved"); _safeTransfer(from, to, tokenId, data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory data ) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _owners[tokenId] != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { address owner = ERC721.ownerOf(tokenId); return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId); _balances[to] += 1; _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); _balances[owner] -= 1; delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _balances[from] -= 1; _balances[to] += 1; _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` has not been minted yet. */ function _requireMinted(uint256 tokenId) internal view virtual { require(_exists(tokenId), "ERC721: invalid token ID"); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @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 ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. 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;` */ library Counters { 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 { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../Strings.sol"; /** * @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 { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } else if (error == RecoverError.InvalidSignatureV) { revert("ECDSA: invalid signature 'v' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. 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. * * IMPORTANT: `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. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { // Check the signature length // - case 65: r,s,v signature (standard) // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._ if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else if (signature.length == 64) { bytes32 r; bytes32 vs; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) vs := mload(add(signature, 0x40)) } return tryRecover(hash, r, vs); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @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. * * IMPORTANT: `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) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // 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 (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): 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), RecoverError.InvalidSignatureS); } if (v != 27 && v != 28) { return (address(0), RecoverError.InvalidSignatureV); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * 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)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; import "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * 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 * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * 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); }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Soulbound","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"certificateType","type":"string"},{"indexed":false,"internalType":"string","name":"certificateURI","type":"string"}],"name":"CertificateTypeAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"certificateType","type":"string"},{"indexed":false,"internalType":"string","name":"certificateURI","type":"string"}],"name":"CertificateTypeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"address","name":"","type":"address"}],"name":"_certificateMintList","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"_certificateTypeToURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"_certificateTypes","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_tokenIdCounter","outputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"_tokenIdToType","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"certificateType","type":"string"},{"internalType":"string","name":"certificateUri","type":"string"}],"name":"addCertificateType","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"certificateType","type":"string"},{"internalType":"string","name":"certificateUri","type":"string"}],"name":"changeCertificateType","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"string","name":"certificateType","type":"string"}],"name":"handleClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"string","name":"certificateType","type":"string"}],"name":"redeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"_approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b506040516200440c3803806200440c8339818101604052810190620000379190620003b0565b818181600090805190602001906200005192919062000163565b5080600190805190602001906200006a92919062000163565b5050506200008d620000816200009560201b60201c565b6200009d60201b60201c565b50506200049a565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b828054620001719062000464565b90600052602060002090601f016020900481019282620001955760008555620001e1565b82601f10620001b057805160ff1916838001178555620001e1565b82800160010185558215620001e1579182015b82811115620001e0578251825591602001919060010190620001c3565b5b509050620001f09190620001f4565b5090565b5b808211156200020f576000816000905550600101620001f5565b5090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200027c8262000231565b810181811067ffffffffffffffff821117156200029e576200029d62000242565b5b80604052505050565b6000620002b362000213565b9050620002c1828262000271565b919050565b600067ffffffffffffffff821115620002e457620002e362000242565b5b620002ef8262000231565b9050602081019050919050565b60005b838110156200031c578082015181840152602081019050620002ff565b838111156200032c576000848401525b50505050565b6000620003496200034384620002c6565b620002a7565b9050828152602081018484840111156200036857620003676200022c565b5b62000375848285620002fc565b509392505050565b600082601f83011262000395576200039462000227565b5b8151620003a784826020860162000332565b91505092915050565b60008060408385031215620003ca57620003c96200021d565b5b600083015167ffffffffffffffff811115620003eb57620003ea62000222565b5b620003f9858286016200037d565b925050602083015167ffffffffffffffff8111156200041d576200041c62000222565b5b6200042b858286016200037d565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200047d57607f821691505b6020821081141562000494576200049362000435565b5b50919050565b613f6280620004aa6000396000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c806370a08231116100f95780639d2b5f0911610097578063c87b56dd11610071578063c87b56dd146104a4578063e985e9c5146104d4578063f2fde38b14610504578063f46d5f5914610520576101a9565b80639d2b5f0914610450578063a22cb4651461046c578063b88d4fde14610488576101a9565b80638da5cb5b116100d35780638da5cb5b146103b45780639486c6e6146103d257806395d89b41146104025780639ad3464d14610420576101a9565b806370a082311461035c578063715018a61461038c57806384c4bd4b14610396576101a9565b806323b872dd1161016657806342842e0e1161014057806342842e0e146102d8578063575c4481146102f45780636352211e1461031057806365d0734d14610340576101a9565b806323b872dd146102965780632858ccd8146102b25780633ccfd60b146102ce576101a9565b806301ffc9a7146101ae57806306fdde03146101de57806307cd1f28146101fc578063081812fc1461022c578063095ea7b31461025c57806318160ddd14610278575b600080fd5b6101c860048036038101906101c391906127a2565b610550565b6040516101d591906127ea565b60405180910390f35b6101e6610632565b6040516101f3919061289e565b60405180910390f35b610216600480360381019061021191906128f6565b6106c4565b604051610223919061289e565b60405180910390f35b610246600480360381019061024191906128f6565b610764565b6040516102539190612964565b60405180910390f35b610276600480360381019061027191906129ab565b6107aa565b005b6102806107dc565b60405161028d91906129fa565b60405180910390f35b6102b060048036038101906102ab9190612a15565b6107ed565b005b6102cc60048036038101906102c79190612b9d565b61084d565b005b6102d6610963565b005b6102f260048036038101906102ed9190612a15565b6109ba565b005b61030e60048036038101906103099190612c15565b6109da565b005b61032a600480360381019061032591906128f6565b610b34565b6040516103379190612964565b60405180910390f35b61035a60048036038101906103559190612cd1565b610be6565b005b61037660048036038101906103719190612d61565b610e3d565b60405161038391906129fa565b60405180910390f35b610394610ef5565b005b61039e610f09565b6040516103ab91906129fa565b60405180910390f35b6103bc610f15565b6040516103c99190612964565b60405180910390f35b6103ec60048036038101906103e79190612d8e565b610f3f565b6040516103f991906129fa565b60405180910390f35b61040a610f7a565b604051610417919061289e565b60405180910390f35b61043a60048036038101906104359190612dea565b61100c565b604051610447919061289e565b60405180910390f35b61046a60048036038101906104659190612b9d565b6110c2565b005b61048660048036038101906104819190612e5f565b611276565b005b6104a2600480360381019061049d9190612f40565b6112a8565b005b6104be60048036038101906104b991906128f6565b61130a565b6040516104cb919061289e565b60405180910390f35b6104ee60048036038101906104e99190612fc3565b611414565b6040516104fb91906127ea565b60405180910390f35b61051e60048036038101906105199190612d61565b6114a8565b005b61053a600480360381019061053591906128f6565b61152c565b604051610547919061289e565b60405180910390f35b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061061b57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061062b575061062a826115d8565b5b9050919050565b60606000805461064190613032565b80601f016020809104026020016040519081016040528092919081815260200182805461066d90613032565b80156106ba5780601f1061068f576101008083540402835291602001916106ba565b820191906000526020600020905b81548152906001019060200180831161069d57829003601f168201915b5050505050905090565b600b60205280600052604060002060009150905080546106e390613032565b80601f016020809104026020016040519081016040528092919081815260200182805461070f90613032565b801561075c5780601f106107315761010080835404028352916020019161075c565b820191906000526020600020905b81548152906001019060200180831161073f57829003601f168201915b505050505081565b600061076f82611642565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6040517fa4420a9500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006107e8600761168d565b905090565b6107fe6107f861169b565b826116a3565b61083d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610834906130d6565b60405180910390fd5b610848838383611738565b505050565b61085561199f565b60016009836040516108679190613132565b908152602001604051809103902060008073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054146108f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ea90613195565b60405180910390fd5b80600a836040516109049190613132565b90815260200160405180910390209080519060200190610925929190612693565b507fb4cce6c7f95a454e8c04665280ea1544dececcbe0fb306b7606bce145c1e938282826040516109579291906131b5565b60405180910390a15050565b61096b61199f565b60004790503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156109b6573d6000803e3d6000fd5b5050565b6109d5838383604051806020016040528060008152506112a8565b505050565b6109e261199f565b8060006009826040516109f59190613132565b908152602001604051809103902060008073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541415610a82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7990613195565b60405180910390fd5b81836001600983604051610a969190613132565b908152602001604051809103902060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541415610b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1a9061325e565b60405180910390fd5b610b2d8585611a1d565b5050505050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610bdd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bd4906132ca565b60405180910390fd5b80915050919050565b806000600982604051610bf99190613132565b908152602001604051809103902060008073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541415610c86576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c7d90613195565b60405180910390fd5b81856001600983604051610c9a9190613132565b908152602001604051809103902060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541415610d27576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d1e9061325e565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d95576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d8c90613336565b60405180910390fd5b610deb610da188611acd565b87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611b05565b610e2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e21906133a2565b60405180910390fd5b610e348785611a1d565b50505050505050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610eae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea590613434565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b610efd61199f565b610f076000611b4e565b565b60078060000154905081565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600982805160208101820180518482526020830160208501208183528095505050505050602052806000526040600020600091509150505481565b606060018054610f8990613032565b80601f0160208091040260200160405190810160405280929190818152602001828054610fb590613032565b80156110025780601f10610fd757610100808354040283529160200191611002565b820191906000526020600020905b815481529060010190602001808311610fe557829003601f168201915b5050505050905090565b600a81805160208101820180518482526020830160208501208183528095505050505050600091509050805461104190613032565b80601f016020809104026020016040519081016040528092919081815260200182805461106d90613032565b80156110ba5780601f1061108f576101008083540402835291602001916110ba565b820191906000526020600020905b81548152906001019060200180831161109d57829003601f168201915b505050505081565b6110ca61199f565b60016009836040516110dc9190613132565b908152602001604051809103902060008073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541415611169576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611160906134a0565b60405180910390fd5b6008829080600181540180825580915050600190039060005260206000200160009091909190915090805190602001906111a4929190612693565b5060016009836040516111b79190613132565b908152602001604051809103902060008073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555080600a836040516112179190613132565b90815260200160405180910390209080519060200190611238929190612693565b507f63f00c100b199db1cdec5617dc6a6300ec0e9ca5f220230ec8e0be9a5434e082828260405161126a9291906131b5565b60405180910390a15050565b6040517fa4420a9500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112b96112b361169b565b836116a3565b6112f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ef906130d6565b60405180910390fd5b61130484848484611c14565b50505050565b606061131582611c70565b611354576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134b90613532565b60405180910390fd5b600a600b600084815260200190815260200160002060405161137691906135e6565b9081526020016040518091039020805461138f90613032565b80601f01602080910402602001604051908101604052809291908181526020018280546113bb90613032565b80156114085780601f106113dd57610100808354040283529160200191611408565b820191906000526020600020905b8154815290600101906020018083116113eb57829003601f168201915b50505050509050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6114b061199f565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611520576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115179061366f565b60405180910390fd5b61152981611b4e565b50565b6008818154811061153c57600080fd5b90600052602060002001600091509050805461155790613032565b80601f016020809104026020016040519081016040528092919081815260200182805461158390613032565b80156115d05780601f106115a5576101008083540402835291602001916115d0565b820191906000526020600020905b8154815290600101906020018083116115b357829003601f168201915b505050505081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b61164b81611c70565b61168a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611681906132ca565b60405180910390fd5b50565b600081600001549050919050565b600033905090565b6000806116af83610b34565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806116f157506116f08185611414565b5b8061172f57508373ffffffffffffffffffffffffffffffffffffffff1661171784610764565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661175882610b34565b73ffffffffffffffffffffffffffffffffffffffff16146117ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117a590613701565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561181e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161181590613793565b60405180910390fd5b611829838383611cdc565b611834600082611d92565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461188491906137e2565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546118db9190613816565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461199a838383611e4b565b505050565b6119a761169b565b73ffffffffffffffffffffffffffffffffffffffff166119c5610f15565b73ffffffffffffffffffffffffffffffffffffffff1614611a1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a12906138b8565b60405180910390fd5b565b611a276007611e50565b6000611a33600761168d565b905081600b60008381526020019081526020016000209080519060200190611a5c929190612693565b506001600983604051611a6f9190613132565b908152602001604051809103902060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611ac88382611e66565b505050565b6000611afe82604051602001611ae39190613920565b60405160208183030381529060405280519060200120611e84565b9050919050565b6000611b118383611eb4565b73ffffffffffffffffffffffffffffffffffffffff16611b2f610f15565b73ffffffffffffffffffffffffffffffffffffffff1614905092915050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611c1f848484611738565b611c2b84848484611edb565b611c6a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c61906139ad565b60405180910390fd5b50505050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161480611d435750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b611d82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7990613a19565b60405180910390fd5b611d8d838383612072565b505050565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611e0583610b34565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b505050565b6001816000016000828254019250508190555050565b611e80828260405180602001604052806000815250612077565b5050565b600081604051602001611e979190613ab0565b604051602081830303815290604052805190602001209050919050565b6000806000611ec385856120d2565b91509150611ed081612155565b819250505092915050565b6000611efc8473ffffffffffffffffffffffffffffffffffffffff1661232a565b15612065578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611f2561169b565b8786866040518563ffffffff1660e01b8152600401611f479493929190613b2b565b602060405180830381600087803b158015611f6157600080fd5b505af1925050508015611f9257506040513d601f19601f82011682018060405250810190611f8f9190613b8c565b60015b612015573d8060008114611fc2576040519150601f19603f3d011682016040523d82523d6000602084013e611fc7565b606091505b5060008151141561200d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612004906139ad565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061206a565b600190505b949350505050565b505050565b612081838361234d565b61208e6000848484611edb565b6120cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120c4906139ad565b60405180910390fd5b505050565b6000806041835114156121145760008060006020860151925060408601519150606086015160001a905061210887828585612527565b9450945050505061214e565b60408351141561214557600080602085015191506040850151905061213a868383612634565b93509350505061214e565b60006002915091505b9250929050565b6000600481111561216957612168613bb9565b5b81600481111561217c5761217b613bb9565b5b141561218757612327565b6001600481111561219b5761219a613bb9565b5b8160048111156121ae576121ad613bb9565b5b14156121ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121e690613c34565b60405180910390fd5b6002600481111561220357612202613bb9565b5b81600481111561221657612215613bb9565b5b1415612257576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161224e90613ca0565b60405180910390fd5b6003600481111561226b5761226a613bb9565b5b81600481111561227e5761227d613bb9565b5b14156122bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b690613d32565b60405180910390fd5b6004808111156122d2576122d1613bb9565b5b8160048111156122e5576122e4613bb9565b5b1415612326576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161231d90613dc4565b60405180910390fd5b5b50565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156123bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123b490613e30565b60405180910390fd5b6123c681611c70565b15612406576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123fd90613e9c565b60405180910390fd5b61241260008383611cdc565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546124629190613816565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461252360008383611e4b565b5050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c111561256257600060039150915061262b565b601b8560ff161415801561257a5750601c8560ff1614155b1561258c57600060049150915061262b565b6000600187878787604051600081526020016040526040516125b19493929190613ee7565b6020604051602081039080840390855afa1580156125d3573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156126225760006001925092505061262b565b80600092509250505b94509492505050565b60008060007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60001b841690506000601b60ff8660001c901c6126779190613816565b905061268587828885612527565b935093505050935093915050565b82805461269f90613032565b90600052602060002090601f0160209004810192826126c15760008555612708565b82601f106126da57805160ff1916838001178555612708565b82800160010185558215612708579182015b828111156127075782518255916020019190600101906126ec565b5b5090506127159190612719565b5090565b5b8082111561273257600081600090555060010161271a565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61277f8161274a565b811461278a57600080fd5b50565b60008135905061279c81612776565b92915050565b6000602082840312156127b8576127b7612740565b5b60006127c68482850161278d565b91505092915050565b60008115159050919050565b6127e4816127cf565b82525050565b60006020820190506127ff60008301846127db565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561283f578082015181840152602081019050612824565b8381111561284e576000848401525b50505050565b6000601f19601f8301169050919050565b600061287082612805565b61287a8185612810565b935061288a818560208601612821565b61289381612854565b840191505092915050565b600060208201905081810360008301526128b88184612865565b905092915050565b6000819050919050565b6128d3816128c0565b81146128de57600080fd5b50565b6000813590506128f0816128ca565b92915050565b60006020828403121561290c5761290b612740565b5b600061291a848285016128e1565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061294e82612923565b9050919050565b61295e81612943565b82525050565b60006020820190506129796000830184612955565b92915050565b61298881612943565b811461299357600080fd5b50565b6000813590506129a58161297f565b92915050565b600080604083850312156129c2576129c1612740565b5b60006129d085828601612996565b92505060206129e1858286016128e1565b9150509250929050565b6129f4816128c0565b82525050565b6000602082019050612a0f60008301846129eb565b92915050565b600080600060608486031215612a2e57612a2d612740565b5b6000612a3c86828701612996565b9350506020612a4d86828701612996565b9250506040612a5e868287016128e1565b9150509250925092565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612aaa82612854565b810181811067ffffffffffffffff82111715612ac957612ac8612a72565b5b80604052505050565b6000612adc612736565b9050612ae88282612aa1565b919050565b600067ffffffffffffffff821115612b0857612b07612a72565b5b612b1182612854565b9050602081019050919050565b82818337600083830152505050565b6000612b40612b3b84612aed565b612ad2565b905082815260208101848484011115612b5c57612b5b612a6d565b5b612b67848285612b1e565b509392505050565b600082601f830112612b8457612b83612a68565b5b8135612b94848260208601612b2d565b91505092915050565b60008060408385031215612bb457612bb3612740565b5b600083013567ffffffffffffffff811115612bd257612bd1612745565b5b612bde85828601612b6f565b925050602083013567ffffffffffffffff811115612bff57612bfe612745565b5b612c0b85828601612b6f565b9150509250929050565b60008060408385031215612c2c57612c2b612740565b5b6000612c3a85828601612996565b925050602083013567ffffffffffffffff811115612c5b57612c5a612745565b5b612c6785828601612b6f565b9150509250929050565b600080fd5b600080fd5b60008083601f840112612c9157612c90612a68565b5b8235905067ffffffffffffffff811115612cae57612cad612c71565b5b602083019150836001820283011115612cca57612cc9612c76565b5b9250929050565b60008060008060608587031215612ceb57612cea612740565b5b6000612cf987828801612996565b945050602085013567ffffffffffffffff811115612d1a57612d19612745565b5b612d2687828801612c7b565b9350935050604085013567ffffffffffffffff811115612d4957612d48612745565b5b612d5587828801612b6f565b91505092959194509250565b600060208284031215612d7757612d76612740565b5b6000612d8584828501612996565b91505092915050565b60008060408385031215612da557612da4612740565b5b600083013567ffffffffffffffff811115612dc357612dc2612745565b5b612dcf85828601612b6f565b9250506020612de085828601612996565b9150509250929050565b600060208284031215612e0057612dff612740565b5b600082013567ffffffffffffffff811115612e1e57612e1d612745565b5b612e2a84828501612b6f565b91505092915050565b612e3c816127cf565b8114612e4757600080fd5b50565b600081359050612e5981612e33565b92915050565b60008060408385031215612e7657612e75612740565b5b6000612e8485828601612996565b9250506020612e9585828601612e4a565b9150509250929050565b600067ffffffffffffffff821115612eba57612eb9612a72565b5b612ec382612854565b9050602081019050919050565b6000612ee3612ede84612e9f565b612ad2565b905082815260208101848484011115612eff57612efe612a6d565b5b612f0a848285612b1e565b509392505050565b600082601f830112612f2757612f26612a68565b5b8135612f37848260208601612ed0565b91505092915050565b60008060008060808587031215612f5a57612f59612740565b5b6000612f6887828801612996565b9450506020612f7987828801612996565b9350506040612f8a878288016128e1565b925050606085013567ffffffffffffffff811115612fab57612faa612745565b5b612fb787828801612f12565b91505092959194509250565b60008060408385031215612fda57612fd9612740565b5b6000612fe885828601612996565b9250506020612ff985828601612996565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061304a57607f821691505b6020821081141561305e5761305d613003565b5b50919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b60006130c0602e83612810565b91506130cb82613064565b604082019050919050565b600060208201905081810360008301526130ef816130b3565b9050919050565b600081905092915050565b600061310c82612805565b61311681856130f6565b9350613126818560208601612821565b80840191505092915050565b600061313e8284613101565b915081905092915050565b7f4365727469666963617465207479706520646f6573206e6f7420657869737400600082015250565b600061317f601f83612810565b915061318a82613149565b602082019050919050565b600060208201905081810360008301526131ae81613172565b9050919050565b600060408201905081810360008301526131cf8185612865565b905081810360208301526131e38184612865565b90509392505050565b7f5573657220616c7265616479206d696e7465642074686973206365727469666960008201527f6361746500000000000000000000000000000000000000000000000000000000602082015250565b6000613248602483612810565b9150613253826131ec565b604082019050919050565b600060208201905081810360008301526132778161323b565b9050919050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b60006132b4601883612810565b91506132bf8261327e565b602082019050919050565b600060208201905081810360008301526132e3816132a7565b9050919050565b7f596f752063616e206f6e6c792072656465656d20666f7220796f757273656c66600082015250565b6000613320602083612810565b915061332b826132ea565b602082019050919050565b6000602082019050818103600083015261334f81613313565b9050919050565b7f496e76616c6964207369676e6174757265000000000000000000000000000000600082015250565b600061338c601183612810565b915061339782613356565b602082019050919050565b600060208201905081810360008301526133bb8161337f565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b600061341e602983612810565b9150613429826133c2565b604082019050919050565b6000602082019050818103600083015261344d81613411565b9050919050565b7f4365727469666963617465207479706520616c72656164792065786973747300600082015250565b600061348a601f83612810565b915061349582613454565b602082019050919050565b600060208201905081810360008301526134b98161347d565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b600061351c602f83612810565b9150613527826134c0565b604082019050919050565b6000602082019050818103600083015261354b8161350f565b9050919050565b60008190508160005260206000209050919050565b6000815461357481613032565b61357e81866130f6565b9450600182166000811461359957600181146135aa576135dd565b60ff198316865281860193506135dd565b6135b385613552565b60005b838110156135d5578154818901526001820191506020810190506135b6565b838801955050505b50505092915050565b60006135f28284613567565b915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613659602683612810565b9150613664826135fd565b604082019050919050565b600060208201905081810360008301526136888161364c565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b60006136eb602583612810565b91506136f68261368f565b604082019050919050565b6000602082019050818103600083015261371a816136de565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b600061377d602483612810565b915061378882613721565b604082019050919050565b600060208201905081810360008301526137ac81613770565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006137ed826128c0565b91506137f8836128c0565b92508282101561380b5761380a6137b3565b5b828203905092915050565b6000613821826128c0565b915061382c836128c0565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613861576138606137b3565b5b828201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006138a2602083612810565b91506138ad8261386c565b602082019050919050565b600060208201905081810360008301526138d181613895565b9050919050565b60008160601b9050919050565b60006138f0826138d8565b9050919050565b6000613902826138e5565b9050919050565b61391a61391582612943565b6138f7565b82525050565b600061392c8284613909565b60148201915081905092915050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b6000613997603283612810565b91506139a28261393b565b604082019050919050565b600060208201905081810360008301526139c68161398a565b9050919050565b7f534f554c424f554e443a204e6f6e2d5472616e7366657261626c650000000000600082015250565b6000613a03601b83612810565b9150613a0e826139cd565b602082019050919050565b60006020820190508181036000830152613a32816139f6565b9050919050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b6000613a6f601c836130f6565b9150613a7a82613a39565b601c82019050919050565b6000819050919050565b6000819050919050565b613aaa613aa582613a85565b613a8f565b82525050565b6000613abb82613a62565b9150613ac78284613a99565b60208201915081905092915050565b600081519050919050565b600082825260208201905092915050565b6000613afd82613ad6565b613b078185613ae1565b9350613b17818560208601612821565b613b2081612854565b840191505092915050565b6000608082019050613b406000830187612955565b613b4d6020830186612955565b613b5a60408301856129eb565b8181036060830152613b6c8184613af2565b905095945050505050565b600081519050613b8681612776565b92915050565b600060208284031215613ba257613ba1612740565b5b6000613bb084828501613b77565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b6000613c1e601883612810565b9150613c2982613be8565b602082019050919050565b60006020820190508181036000830152613c4d81613c11565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b6000613c8a601f83612810565b9150613c9582613c54565b602082019050919050565b60006020820190508181036000830152613cb981613c7d565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000613d1c602283612810565b9150613d2782613cc0565b604082019050919050565b60006020820190508181036000830152613d4b81613d0f565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202776272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000613dae602283612810565b9150613db982613d52565b604082019050919050565b60006020820190508181036000830152613ddd81613da1565b9050919050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000613e1a602083612810565b9150613e2582613de4565b602082019050919050565b60006020820190508181036000830152613e4981613e0d565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000613e86601c83612810565b9150613e9182613e50565b602082019050919050565b60006020820190508181036000830152613eb581613e79565b9050919050565b613ec581613a85565b82525050565b600060ff82169050919050565b613ee181613ecb565b82525050565b6000608082019050613efc6000830187613ebc565b613f096020830186613ed8565b613f166040830185613ebc565b613f236060830184613ebc565b9594505050505056fea26469706673582212206e6ced4f1292252e8eef44b8fce6dcc9a9df765c1e8c1836b2b85289791dd06964736f6c6343000809003300000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000d44656372797074204c6561726e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054c4541524e000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101a95760003560e01c806370a08231116100f95780639d2b5f0911610097578063c87b56dd11610071578063c87b56dd146104a4578063e985e9c5146104d4578063f2fde38b14610504578063f46d5f5914610520576101a9565b80639d2b5f0914610450578063a22cb4651461046c578063b88d4fde14610488576101a9565b80638da5cb5b116100d35780638da5cb5b146103b45780639486c6e6146103d257806395d89b41146104025780639ad3464d14610420576101a9565b806370a082311461035c578063715018a61461038c57806384c4bd4b14610396576101a9565b806323b872dd1161016657806342842e0e1161014057806342842e0e146102d8578063575c4481146102f45780636352211e1461031057806365d0734d14610340576101a9565b806323b872dd146102965780632858ccd8146102b25780633ccfd60b146102ce576101a9565b806301ffc9a7146101ae57806306fdde03146101de57806307cd1f28146101fc578063081812fc1461022c578063095ea7b31461025c57806318160ddd14610278575b600080fd5b6101c860048036038101906101c391906127a2565b610550565b6040516101d591906127ea565b60405180910390f35b6101e6610632565b6040516101f3919061289e565b60405180910390f35b610216600480360381019061021191906128f6565b6106c4565b604051610223919061289e565b60405180910390f35b610246600480360381019061024191906128f6565b610764565b6040516102539190612964565b60405180910390f35b610276600480360381019061027191906129ab565b6107aa565b005b6102806107dc565b60405161028d91906129fa565b60405180910390f35b6102b060048036038101906102ab9190612a15565b6107ed565b005b6102cc60048036038101906102c79190612b9d565b61084d565b005b6102d6610963565b005b6102f260048036038101906102ed9190612a15565b6109ba565b005b61030e60048036038101906103099190612c15565b6109da565b005b61032a600480360381019061032591906128f6565b610b34565b6040516103379190612964565b60405180910390f35b61035a60048036038101906103559190612cd1565b610be6565b005b61037660048036038101906103719190612d61565b610e3d565b60405161038391906129fa565b60405180910390f35b610394610ef5565b005b61039e610f09565b6040516103ab91906129fa565b60405180910390f35b6103bc610f15565b6040516103c99190612964565b60405180910390f35b6103ec60048036038101906103e79190612d8e565b610f3f565b6040516103f991906129fa565b60405180910390f35b61040a610f7a565b604051610417919061289e565b60405180910390f35b61043a60048036038101906104359190612dea565b61100c565b604051610447919061289e565b60405180910390f35b61046a60048036038101906104659190612b9d565b6110c2565b005b61048660048036038101906104819190612e5f565b611276565b005b6104a2600480360381019061049d9190612f40565b6112a8565b005b6104be60048036038101906104b991906128f6565b61130a565b6040516104cb919061289e565b60405180910390f35b6104ee60048036038101906104e99190612fc3565b611414565b6040516104fb91906127ea565b60405180910390f35b61051e60048036038101906105199190612d61565b6114a8565b005b61053a600480360381019061053591906128f6565b61152c565b604051610547919061289e565b60405180910390f35b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061061b57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061062b575061062a826115d8565b5b9050919050565b60606000805461064190613032565b80601f016020809104026020016040519081016040528092919081815260200182805461066d90613032565b80156106ba5780601f1061068f576101008083540402835291602001916106ba565b820191906000526020600020905b81548152906001019060200180831161069d57829003601f168201915b5050505050905090565b600b60205280600052604060002060009150905080546106e390613032565b80601f016020809104026020016040519081016040528092919081815260200182805461070f90613032565b801561075c5780601f106107315761010080835404028352916020019161075c565b820191906000526020600020905b81548152906001019060200180831161073f57829003601f168201915b505050505081565b600061076f82611642565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6040517fa4420a9500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006107e8600761168d565b905090565b6107fe6107f861169b565b826116a3565b61083d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610834906130d6565b60405180910390fd5b610848838383611738565b505050565b61085561199f565b60016009836040516108679190613132565b908152602001604051809103902060008073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054146108f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ea90613195565b60405180910390fd5b80600a836040516109049190613132565b90815260200160405180910390209080519060200190610925929190612693565b507fb4cce6c7f95a454e8c04665280ea1544dececcbe0fb306b7606bce145c1e938282826040516109579291906131b5565b60405180910390a15050565b61096b61199f565b60004790503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156109b6573d6000803e3d6000fd5b5050565b6109d5838383604051806020016040528060008152506112a8565b505050565b6109e261199f565b8060006009826040516109f59190613132565b908152602001604051809103902060008073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541415610a82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7990613195565b60405180910390fd5b81836001600983604051610a969190613132565b908152602001604051809103902060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541415610b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1a9061325e565b60405180910390fd5b610b2d8585611a1d565b5050505050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610bdd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bd4906132ca565b60405180910390fd5b80915050919050565b806000600982604051610bf99190613132565b908152602001604051809103902060008073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541415610c86576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c7d90613195565b60405180910390fd5b81856001600983604051610c9a9190613132565b908152602001604051809103902060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541415610d27576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d1e9061325e565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d95576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d8c90613336565b60405180910390fd5b610deb610da188611acd565b87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611b05565b610e2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e21906133a2565b60405180910390fd5b610e348785611a1d565b50505050505050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610eae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea590613434565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b610efd61199f565b610f076000611b4e565b565b60078060000154905081565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600982805160208101820180518482526020830160208501208183528095505050505050602052806000526040600020600091509150505481565b606060018054610f8990613032565b80601f0160208091040260200160405190810160405280929190818152602001828054610fb590613032565b80156110025780601f10610fd757610100808354040283529160200191611002565b820191906000526020600020905b815481529060010190602001808311610fe557829003601f168201915b5050505050905090565b600a81805160208101820180518482526020830160208501208183528095505050505050600091509050805461104190613032565b80601f016020809104026020016040519081016040528092919081815260200182805461106d90613032565b80156110ba5780601f1061108f576101008083540402835291602001916110ba565b820191906000526020600020905b81548152906001019060200180831161109d57829003601f168201915b505050505081565b6110ca61199f565b60016009836040516110dc9190613132565b908152602001604051809103902060008073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541415611169576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611160906134a0565b60405180910390fd5b6008829080600181540180825580915050600190039060005260206000200160009091909190915090805190602001906111a4929190612693565b5060016009836040516111b79190613132565b908152602001604051809103902060008073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555080600a836040516112179190613132565b90815260200160405180910390209080519060200190611238929190612693565b507f63f00c100b199db1cdec5617dc6a6300ec0e9ca5f220230ec8e0be9a5434e082828260405161126a9291906131b5565b60405180910390a15050565b6040517fa4420a9500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112b96112b361169b565b836116a3565b6112f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ef906130d6565b60405180910390fd5b61130484848484611c14565b50505050565b606061131582611c70565b611354576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134b90613532565b60405180910390fd5b600a600b600084815260200190815260200160002060405161137691906135e6565b9081526020016040518091039020805461138f90613032565b80601f01602080910402602001604051908101604052809291908181526020018280546113bb90613032565b80156114085780601f106113dd57610100808354040283529160200191611408565b820191906000526020600020905b8154815290600101906020018083116113eb57829003601f168201915b50505050509050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6114b061199f565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611520576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115179061366f565b60405180910390fd5b61152981611b4e565b50565b6008818154811061153c57600080fd5b90600052602060002001600091509050805461155790613032565b80601f016020809104026020016040519081016040528092919081815260200182805461158390613032565b80156115d05780601f106115a5576101008083540402835291602001916115d0565b820191906000526020600020905b8154815290600101906020018083116115b357829003601f168201915b505050505081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b61164b81611c70565b61168a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611681906132ca565b60405180910390fd5b50565b600081600001549050919050565b600033905090565b6000806116af83610b34565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806116f157506116f08185611414565b5b8061172f57508373ffffffffffffffffffffffffffffffffffffffff1661171784610764565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661175882610b34565b73ffffffffffffffffffffffffffffffffffffffff16146117ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117a590613701565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561181e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161181590613793565b60405180910390fd5b611829838383611cdc565b611834600082611d92565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461188491906137e2565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546118db9190613816565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461199a838383611e4b565b505050565b6119a761169b565b73ffffffffffffffffffffffffffffffffffffffff166119c5610f15565b73ffffffffffffffffffffffffffffffffffffffff1614611a1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a12906138b8565b60405180910390fd5b565b611a276007611e50565b6000611a33600761168d565b905081600b60008381526020019081526020016000209080519060200190611a5c929190612693565b506001600983604051611a6f9190613132565b908152602001604051809103902060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611ac88382611e66565b505050565b6000611afe82604051602001611ae39190613920565b60405160208183030381529060405280519060200120611e84565b9050919050565b6000611b118383611eb4565b73ffffffffffffffffffffffffffffffffffffffff16611b2f610f15565b73ffffffffffffffffffffffffffffffffffffffff1614905092915050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611c1f848484611738565b611c2b84848484611edb565b611c6a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c61906139ad565b60405180910390fd5b50505050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161480611d435750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b611d82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7990613a19565b60405180910390fd5b611d8d838383612072565b505050565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611e0583610b34565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b505050565b6001816000016000828254019250508190555050565b611e80828260405180602001604052806000815250612077565b5050565b600081604051602001611e979190613ab0565b604051602081830303815290604052805190602001209050919050565b6000806000611ec385856120d2565b91509150611ed081612155565b819250505092915050565b6000611efc8473ffffffffffffffffffffffffffffffffffffffff1661232a565b15612065578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611f2561169b565b8786866040518563ffffffff1660e01b8152600401611f479493929190613b2b565b602060405180830381600087803b158015611f6157600080fd5b505af1925050508015611f9257506040513d601f19601f82011682018060405250810190611f8f9190613b8c565b60015b612015573d8060008114611fc2576040519150601f19603f3d011682016040523d82523d6000602084013e611fc7565b606091505b5060008151141561200d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612004906139ad565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061206a565b600190505b949350505050565b505050565b612081838361234d565b61208e6000848484611edb565b6120cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120c4906139ad565b60405180910390fd5b505050565b6000806041835114156121145760008060006020860151925060408601519150606086015160001a905061210887828585612527565b9450945050505061214e565b60408351141561214557600080602085015191506040850151905061213a868383612634565b93509350505061214e565b60006002915091505b9250929050565b6000600481111561216957612168613bb9565b5b81600481111561217c5761217b613bb9565b5b141561218757612327565b6001600481111561219b5761219a613bb9565b5b8160048111156121ae576121ad613bb9565b5b14156121ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121e690613c34565b60405180910390fd5b6002600481111561220357612202613bb9565b5b81600481111561221657612215613bb9565b5b1415612257576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161224e90613ca0565b60405180910390fd5b6003600481111561226b5761226a613bb9565b5b81600481111561227e5761227d613bb9565b5b14156122bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b690613d32565b60405180910390fd5b6004808111156122d2576122d1613bb9565b5b8160048111156122e5576122e4613bb9565b5b1415612326576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161231d90613dc4565b60405180910390fd5b5b50565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156123bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123b490613e30565b60405180910390fd5b6123c681611c70565b15612406576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123fd90613e9c565b60405180910390fd5b61241260008383611cdc565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546124629190613816565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461252360008383611e4b565b5050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c111561256257600060039150915061262b565b601b8560ff161415801561257a5750601c8560ff1614155b1561258c57600060049150915061262b565b6000600187878787604051600081526020016040526040516125b19493929190613ee7565b6020604051602081039080840390855afa1580156125d3573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156126225760006001925092505061262b565b80600092509250505b94509492505050565b60008060007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60001b841690506000601b60ff8660001c901c6126779190613816565b905061268587828885612527565b935093505050935093915050565b82805461269f90613032565b90600052602060002090601f0160209004810192826126c15760008555612708565b82601f106126da57805160ff1916838001178555612708565b82800160010185558215612708579182015b828111156127075782518255916020019190600101906126ec565b5b5090506127159190612719565b5090565b5b8082111561273257600081600090555060010161271a565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61277f8161274a565b811461278a57600080fd5b50565b60008135905061279c81612776565b92915050565b6000602082840312156127b8576127b7612740565b5b60006127c68482850161278d565b91505092915050565b60008115159050919050565b6127e4816127cf565b82525050565b60006020820190506127ff60008301846127db565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561283f578082015181840152602081019050612824565b8381111561284e576000848401525b50505050565b6000601f19601f8301169050919050565b600061287082612805565b61287a8185612810565b935061288a818560208601612821565b61289381612854565b840191505092915050565b600060208201905081810360008301526128b88184612865565b905092915050565b6000819050919050565b6128d3816128c0565b81146128de57600080fd5b50565b6000813590506128f0816128ca565b92915050565b60006020828403121561290c5761290b612740565b5b600061291a848285016128e1565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061294e82612923565b9050919050565b61295e81612943565b82525050565b60006020820190506129796000830184612955565b92915050565b61298881612943565b811461299357600080fd5b50565b6000813590506129a58161297f565b92915050565b600080604083850312156129c2576129c1612740565b5b60006129d085828601612996565b92505060206129e1858286016128e1565b9150509250929050565b6129f4816128c0565b82525050565b6000602082019050612a0f60008301846129eb565b92915050565b600080600060608486031215612a2e57612a2d612740565b5b6000612a3c86828701612996565b9350506020612a4d86828701612996565b9250506040612a5e868287016128e1565b9150509250925092565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612aaa82612854565b810181811067ffffffffffffffff82111715612ac957612ac8612a72565b5b80604052505050565b6000612adc612736565b9050612ae88282612aa1565b919050565b600067ffffffffffffffff821115612b0857612b07612a72565b5b612b1182612854565b9050602081019050919050565b82818337600083830152505050565b6000612b40612b3b84612aed565b612ad2565b905082815260208101848484011115612b5c57612b5b612a6d565b5b612b67848285612b1e565b509392505050565b600082601f830112612b8457612b83612a68565b5b8135612b94848260208601612b2d565b91505092915050565b60008060408385031215612bb457612bb3612740565b5b600083013567ffffffffffffffff811115612bd257612bd1612745565b5b612bde85828601612b6f565b925050602083013567ffffffffffffffff811115612bff57612bfe612745565b5b612c0b85828601612b6f565b9150509250929050565b60008060408385031215612c2c57612c2b612740565b5b6000612c3a85828601612996565b925050602083013567ffffffffffffffff811115612c5b57612c5a612745565b5b612c6785828601612b6f565b9150509250929050565b600080fd5b600080fd5b60008083601f840112612c9157612c90612a68565b5b8235905067ffffffffffffffff811115612cae57612cad612c71565b5b602083019150836001820283011115612cca57612cc9612c76565b5b9250929050565b60008060008060608587031215612ceb57612cea612740565b5b6000612cf987828801612996565b945050602085013567ffffffffffffffff811115612d1a57612d19612745565b5b612d2687828801612c7b565b9350935050604085013567ffffffffffffffff811115612d4957612d48612745565b5b612d5587828801612b6f565b91505092959194509250565b600060208284031215612d7757612d76612740565b5b6000612d8584828501612996565b91505092915050565b60008060408385031215612da557612da4612740565b5b600083013567ffffffffffffffff811115612dc357612dc2612745565b5b612dcf85828601612b6f565b9250506020612de085828601612996565b9150509250929050565b600060208284031215612e0057612dff612740565b5b600082013567ffffffffffffffff811115612e1e57612e1d612745565b5b612e2a84828501612b6f565b91505092915050565b612e3c816127cf565b8114612e4757600080fd5b50565b600081359050612e5981612e33565b92915050565b60008060408385031215612e7657612e75612740565b5b6000612e8485828601612996565b9250506020612e9585828601612e4a565b9150509250929050565b600067ffffffffffffffff821115612eba57612eb9612a72565b5b612ec382612854565b9050602081019050919050565b6000612ee3612ede84612e9f565b612ad2565b905082815260208101848484011115612eff57612efe612a6d565b5b612f0a848285612b1e565b509392505050565b600082601f830112612f2757612f26612a68565b5b8135612f37848260208601612ed0565b91505092915050565b60008060008060808587031215612f5a57612f59612740565b5b6000612f6887828801612996565b9450506020612f7987828801612996565b9350506040612f8a878288016128e1565b925050606085013567ffffffffffffffff811115612fab57612faa612745565b5b612fb787828801612f12565b91505092959194509250565b60008060408385031215612fda57612fd9612740565b5b6000612fe885828601612996565b9250506020612ff985828601612996565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061304a57607f821691505b6020821081141561305e5761305d613003565b5b50919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206e6f7220617070726f766564000000000000000000000000000000000000602082015250565b60006130c0602e83612810565b91506130cb82613064565b604082019050919050565b600060208201905081810360008301526130ef816130b3565b9050919050565b600081905092915050565b600061310c82612805565b61311681856130f6565b9350613126818560208601612821565b80840191505092915050565b600061313e8284613101565b915081905092915050565b7f4365727469666963617465207479706520646f6573206e6f7420657869737400600082015250565b600061317f601f83612810565b915061318a82613149565b602082019050919050565b600060208201905081810360008301526131ae81613172565b9050919050565b600060408201905081810360008301526131cf8185612865565b905081810360208301526131e38184612865565b90509392505050565b7f5573657220616c7265616479206d696e7465642074686973206365727469666960008201527f6361746500000000000000000000000000000000000000000000000000000000602082015250565b6000613248602483612810565b9150613253826131ec565b604082019050919050565b600060208201905081810360008301526132778161323b565b9050919050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b60006132b4601883612810565b91506132bf8261327e565b602082019050919050565b600060208201905081810360008301526132e3816132a7565b9050919050565b7f596f752063616e206f6e6c792072656465656d20666f7220796f757273656c66600082015250565b6000613320602083612810565b915061332b826132ea565b602082019050919050565b6000602082019050818103600083015261334f81613313565b9050919050565b7f496e76616c6964207369676e6174757265000000000000000000000000000000600082015250565b600061338c601183612810565b915061339782613356565b602082019050919050565b600060208201905081810360008301526133bb8161337f565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b600061341e602983612810565b9150613429826133c2565b604082019050919050565b6000602082019050818103600083015261344d81613411565b9050919050565b7f4365727469666963617465207479706520616c72656164792065786973747300600082015250565b600061348a601f83612810565b915061349582613454565b602082019050919050565b600060208201905081810360008301526134b98161347d565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b600061351c602f83612810565b9150613527826134c0565b604082019050919050565b6000602082019050818103600083015261354b8161350f565b9050919050565b60008190508160005260206000209050919050565b6000815461357481613032565b61357e81866130f6565b9450600182166000811461359957600181146135aa576135dd565b60ff198316865281860193506135dd565b6135b385613552565b60005b838110156135d5578154818901526001820191506020810190506135b6565b838801955050505b50505092915050565b60006135f28284613567565b915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613659602683612810565b9150613664826135fd565b604082019050919050565b600060208201905081810360008301526136888161364c565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b60006136eb602583612810565b91506136f68261368f565b604082019050919050565b6000602082019050818103600083015261371a816136de565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b600061377d602483612810565b915061378882613721565b604082019050919050565b600060208201905081810360008301526137ac81613770565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006137ed826128c0565b91506137f8836128c0565b92508282101561380b5761380a6137b3565b5b828203905092915050565b6000613821826128c0565b915061382c836128c0565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613861576138606137b3565b5b828201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006138a2602083612810565b91506138ad8261386c565b602082019050919050565b600060208201905081810360008301526138d181613895565b9050919050565b60008160601b9050919050565b60006138f0826138d8565b9050919050565b6000613902826138e5565b9050919050565b61391a61391582612943565b6138f7565b82525050565b600061392c8284613909565b60148201915081905092915050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b6000613997603283612810565b91506139a28261393b565b604082019050919050565b600060208201905081810360008301526139c68161398a565b9050919050565b7f534f554c424f554e443a204e6f6e2d5472616e7366657261626c650000000000600082015250565b6000613a03601b83612810565b9150613a0e826139cd565b602082019050919050565b60006020820190508181036000830152613a32816139f6565b9050919050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b6000613a6f601c836130f6565b9150613a7a82613a39565b601c82019050919050565b6000819050919050565b6000819050919050565b613aaa613aa582613a85565b613a8f565b82525050565b6000613abb82613a62565b9150613ac78284613a99565b60208201915081905092915050565b600081519050919050565b600082825260208201905092915050565b6000613afd82613ad6565b613b078185613ae1565b9350613b17818560208601612821565b613b2081612854565b840191505092915050565b6000608082019050613b406000830187612955565b613b4d6020830186612955565b613b5a60408301856129eb565b8181036060830152613b6c8184613af2565b905095945050505050565b600081519050613b8681612776565b92915050565b600060208284031215613ba257613ba1612740565b5b6000613bb084828501613b77565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b6000613c1e601883612810565b9150613c2982613be8565b602082019050919050565b60006020820190508181036000830152613c4d81613c11565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b6000613c8a601f83612810565b9150613c9582613c54565b602082019050919050565b60006020820190508181036000830152613cb981613c7d565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000613d1c602283612810565b9150613d2782613cc0565b604082019050919050565b60006020820190508181036000830152613d4b81613d0f565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202776272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000613dae602283612810565b9150613db982613d52565b604082019050919050565b60006020820190508181036000830152613ddd81613da1565b9050919050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000613e1a602083612810565b9150613e2582613de4565b602082019050919050565b60006020820190508181036000830152613e4981613e0d565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000613e86601c83612810565b9150613e9182613e50565b602082019050919050565b60006020820190508181036000830152613eb581613e79565b9050919050565b613ec581613a85565b82525050565b600060ff82169050919050565b613ee181613ecb565b82525050565b6000608082019050613efc6000830187613ebc565b613f096020830186613ed8565b613f166040830185613ebc565b613f236060830184613ebc565b9594505050505056fea26469706673582212206e6ced4f1292252e8eef44b8fce6dcc9a9df765c1e8c1836b2b85289791dd06964736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000d44656372797074204c6561726e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054c4541524e000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : name (string): Decrypt Learn
Arg [1] : symbol (string): LEARN
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [2] : 000000000000000000000000000000000000000000000000000000000000000d
Arg [3] : 44656372797074204c6561726e00000000000000000000000000000000000000
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [5] : 4c4541524e000000000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
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.