Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- CharityNFT
- Optimization enabled
- true
- Compiler version
- v0.8.19+commit.7dd6d404
- Optimization runs
- 1000
- EVM Version
- default
- Verified at
- 2024-09-26T15:25:13.793590Z
Contract source code
// SPDX-License-Identifier: GPL
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
}
abstract contract Ownable is Context {
address internal _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @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);
}
}
abstract contract MinterRole is Ownable {
mapping (address => bool) public minter_role;
function setMinterRole(address _who, bool _status) public onlyOwner
{
minter_role[_who] = _status;
}
modifier onlyMinter
{
require(minter_role[msg.sender], "Minter role required");
_;
}
}
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* This test is non-exhaustive, and there may be false-negatives: during the
* execution of a contract's constructor, its address will be reported as
* not containing a contract.
*
* > It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*/
function isContract(address account) internal view returns (bool) {
// This method relies in extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
// solhint-disable-next-line no-inline-assembly
assembly { size := extcodesize(account) }
return size > 0;
}
}
interface ICallistoNFT {
event NewBid (uint256 indexed tokenID, uint256 indexed bidAmount, bytes data);
event NewPrice (uint256 indexed tokenID, uint256 indexed priceValue, bytes data);
event TokenTrade (uint256 indexed tokenID, address indexed new_owner, address indexed previous_owner, uint256 priceInWEI);
event Transfer (address indexed from, address indexed to, uint256 indexed tokenId);
event TransferData (bytes data);
struct Properties {
// In this example properties of the given NFT are stored
// in a dynamically sized array of strings
// properties can be re-defined for any specific info
// that a particular NFT is intended to store.
/* Properties could look like this:
bytes property1;
bytes property2;
address property3;
*/
string[] properties;
}
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function standard() external view returns (string memory);
function balanceOf(address _who) external view returns (uint256);
function ownerOf(uint256 _tokenId) external view returns (address);
function transfer(address _to, uint256 _tokenId, bytes calldata _data) external returns (bool);
function silentTransfer(address _to, uint256 _tokenId) external returns (bool);
function priceOf(uint256 _tokenId) external view returns (uint256);
function bidOf(uint256 _tokenId) external view returns (uint256 price, address payable bidder, uint256 timestamp);
function getTokenProperties(uint256 _tokenId) external view returns (Properties memory);
function setBid(uint256 _tokenId, bytes calldata _data) payable external; // bid amount is defined by msg.value
function setPrice(uint256 _tokenId, uint256 _amountInWEI, bytes calldata _data) external;
function withdrawBid(uint256 _tokenId) external returns (bool);
function getUserContent(uint256 _tokenId) external view returns (string memory _content);
function setUserContent(uint256 _tokenId, string calldata _content) external returns (bool);
}
abstract contract NFTReceiver {
function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes calldata _data) external virtual returns(bytes4);
}
// ExtendedNFT is a version of the CallistoNFT standard token
// that implements a set of function for NFT content management
contract ExtendedNFT is ICallistoNFT, ReentrancyGuard {
using Address for address;
event TokenPropertyUpdated(uint tokenID, uint propertyID);
mapping (uint256 => Properties) private _tokenProperties;
uint256 public bidLock = 1 days; // Time required for a bid to become withdrawable.
struct Bid {
address payable bidder;
uint256 amountInWEI;
uint256 timestamp;
}
mapping (uint256 => uint256) private _asks; // tokenID => price of this token (in WEI)
mapping (uint256 => Bid) private _bids; // tokenID => price of this token (in WEI)
uint256 public next_mint_id;
// Token name
string internal _name;
// Token symbol
string internal _symbol;
// Mapping from token ID to owner address
mapping(uint256 => address) internal _owners;
// Mapping owner address to token count
mapping(address => uint256) internal _balances;
// Reward is always paid based on BID
modifier checkTrade(uint256 _tokenId, bytes calldata _data)
{
_;
(uint256 _bid, address payable _bidder,) = bidOf(_tokenId);
if(priceOf(_tokenId) > 0 && priceOf(_tokenId) <= _bid)
{
emit TokenTrade(_tokenId, _bidder, ownerOf(_tokenId), _bid);
bool sent = payable(ownerOf(_tokenId)).send(_bid);
//bytes calldata _empty;
delete _bids[_tokenId];
delete _asks[_tokenId];
_transfer(ownerOf(_tokenId), _bidder, _tokenId, _data);
}
}
function standard() public view virtual override returns (string memory)
{
return "CallistoNFT";
}
function mint() internal returns (uint256 _mintedId)
{
_safeMint(msg.sender, next_mint_id);
_mintedId = next_mint_id;
next_mint_id++;
_configureNFT(_mintedId);
}
function priceOf(uint256 _tokenId) public view virtual override returns (uint256)
{
address owner = _owners[_tokenId];
require(owner != address(0), "NFT: owner query for nonexistent token");
return _asks[_tokenId];
}
function bidOf(uint256 _tokenId) public view virtual override returns (uint256 price, address payable bidder, uint256 timestamp)
{
address owner = _owners[_tokenId];
require(owner != address(0), "NFT: owner query for nonexistent token");
return (_bids[_tokenId].amountInWEI, _bids[_tokenId].bidder, _bids[_tokenId].timestamp);
}
function getTokenProperties(uint256 _tokenId) public view virtual override returns (Properties memory)
{
return _tokenProperties[_tokenId];
}
function getTokenProperty(uint256 _tokenId, uint256 _propertyId) public view virtual returns (string memory)
{
return _tokenProperties[_tokenId].properties[_propertyId];
}
function getUserContent(uint256 _tokenId) public view virtual override returns (string memory _content)
{
return (_tokenProperties[_tokenId].properties[0]);
}
function setUserContent(uint256 _tokenId, string calldata _content) public virtual override returns (bool success)
{
require(msg.sender == ownerOf(_tokenId), "NFT: only owner can change NFT content");
_tokenProperties[_tokenId].properties[0] = _content;
emit TokenPropertyUpdated(_tokenId, 0) ;
return true;
}
function _addPropertyWithContent(uint256 _tokenId, string calldata _content) internal
{
// Check permission criteria
_tokenProperties[_tokenId].properties.push(_content);
uint newPropertyID = _tokenProperties[_tokenId].properties.length - 1;
emit TokenPropertyUpdated(_tokenId, newPropertyID);
}
function _modifyProperty(uint256 _tokenId, uint256 _propertyId, string calldata _content) internal
{
_tokenProperties[_tokenId].properties[_propertyId] = _content;
emit TokenPropertyUpdated(_tokenId, _propertyId);
}
function balanceOf(address owner) public view virtual override returns (uint256) {
require(owner != address(0), "NFT: balance query for the zero address");
return _balances[owner];
}
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
address owner = _owners[tokenId];
require(owner != address(0), "NFT: owner query for nonexistent token");
return owner;
}
/*
Price == 0, "NFT not on sale"
Price > 0, "NFT on sale"
*/
function setPrice(uint256 _tokenId, uint256 _amountInWEI, bytes calldata _data) checkTrade(_tokenId, _data) public virtual override nonReentrant {
require(ownerOf(_tokenId) == msg.sender, "Setting asks is only allowed for owned NFTs!");
_asks[_tokenId] = _amountInWEI;
emit NewPrice(_tokenId, _amountInWEI, _data);
}
function setBid(uint256 _tokenId, bytes calldata _data) payable checkTrade(_tokenId, _data) public virtual override nonReentrant
{
(uint256 _previousBid, address payable _previousBidder, ) = bidOf(_tokenId);
require(msg.value > _previousBid, "New bid must exceed the existing one");
uint256 _bid;
bool sent;
// Return previous bid if the current one exceeds it.
if(_previousBid != 0)
{
sent = _previousBidder.send(_previousBid);
}
// Refund overpaid amount if price is greater than 0
if (priceOf(_tokenId) < msg.value && priceOf(_tokenId) > 0)
{
_bid = priceOf(_tokenId);
}
else
{
_bid = msg.value;
}
_bids[_tokenId].amountInWEI = _bid;
_bids[_tokenId].bidder = payable(msg.sender);
_bids[_tokenId].timestamp = block.timestamp;
emit NewBid(_tokenId, _bid, _data);
// Send back overpaid amount.
// WARNING: Creates possibility for reentrancy.
if (priceOf(_tokenId) < msg.value && priceOf(_tokenId) > 0)
{
sent = payable(msg.sender).send(msg.value - priceOf(_tokenId));
}
}
function withdrawBid(uint256 _tokenId) public virtual override nonReentrant returns (bool)
{
(uint256 _bid, address payable _bidder, uint256 _timestamp) = bidOf(_tokenId);
require(msg.sender == _bidder, "Can not withdraw someone elses bid");
require(block.timestamp > _timestamp + bidLock, "Bid is time-locked");
bool sent = _bidder.send(_bid);
delete _bids[_tokenId];
emit NewBid(_tokenId, 0, "0x7769746864726177426964");
return true;
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function transfer(address _to, uint256 _tokenId, bytes calldata _data) public override returns (bool)
{
_transfer(msg.sender, _to, _tokenId, _data);
emit TransferData(_data);
return true;
}
function silentTransfer(address _to, uint256 _tokenId) public override returns (bool)
{
require(ExtendedNFT.ownerOf(_tokenId) == msg.sender, "NFT: transfer of token that is not own");
require(_to != address(0), "NFT: transfer to the zero address");
_asks[_tokenId] = 0; // Zero out price on transfer
// When a user transfers the NFT to another user
// it does not automatically mean that the new owner
// would like to sell this NFT at a price
// specified by the previous owner.
// However bids persist regardless of token transfers
// because we assume that the bidder still wants to buy the NFT
// no matter from whom.
_beforeTokenTransfer(msg.sender, _to, _tokenId);
_balances[msg.sender] -= 1;
_balances[_to] += 1;
_owners[_tokenId] = _to;
emit Transfer(msg.sender, _to, _tokenId);
return true;
}
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _owners[tokenId] != address(0);
}
function _safeMint(
address to,
uint256 tokenId
) internal virtual {
_mint(to, tokenId);
}
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "NFT: mint to the zero address");
require(!_exists(tokenId), "NFT: token already minted");
_beforeTokenTransfer(address(0), to, tokenId);
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(address(0), to, tokenId);
}
function _burn(uint256 tokenId) internal virtual {
address owner = ExtendedNFT.ownerOf(tokenId);
_beforeTokenTransfer(owner, address(0), tokenId);
_balances[owner] -= 1;
delete _owners[tokenId];
emit Transfer(owner, address(0), tokenId);
}
function _transfer(
address from,
address to,
uint256 tokenId,
bytes calldata data
) internal virtual {
require(ExtendedNFT.ownerOf(tokenId) == from, "NFT: transfer of token that is not own");
require(to != address(0), "NFT: transfer to the zero address");
_asks[tokenId] = 0; // Zero out price on transfer
// When a user transfers the NFT to another user
// it does not automatically mean that the new owner
// would like to sell this NFT at a price
// specified by the previous owner.
// However bids persist regardless of token transfers
// because we assume that the bidder still wants to buy the NFT
// no matter from whom.
_beforeTokenTransfer(from, to, tokenId);
_balances[from] -= 1;
_balances[to] += 1;
_owners[tokenId] = to;
if(to.isContract())
{
NFTReceiver(to).onERC721Received(msg.sender, from, tokenId, data);
}
emit Transfer(from, to, tokenId);
}
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual {}
function _configureNFT(uint256 _tokenId) internal
{
if(_tokenProperties[_tokenId].properties.length == 0)
{
_tokenProperties[_tokenId].properties.push("");
}
}
}
interface IClassifiedNFT is ICallistoNFT {
function setClassForTokenID(uint256 _tokenID, uint256 _tokenClass) external;
function addNewTokenClass(string memory _property) external;
function addTokenClassProperties(uint256 _propertiesCount, uint256 classId) external;
function modifyClassProperty(uint256 _classID, uint256 _propertyID, string memory _content) external;
function getClassProperty(uint256 _classID, uint256 _propertyID) external view returns (string memory);
function addClassProperty(uint256 _classID) external;
function getClassProperties(uint256 _classID) external view returns (string[] memory);
function getClassForTokenID(uint256 _tokenID) external view returns (uint256);
function getClassPropertiesForTokenID(uint256 _tokenID) external view returns (string[] memory);
function getClassPropertyForTokenID(uint256 _tokenID, uint256 _propertyID) external view returns (string memory);
function mintWithClass(uint256 classId) external returns (uint256 _newTokenID);
function appendClassProperty(uint256 _classID, uint256 _propertyID, string memory _content) external;
}
abstract contract ClassifiedNFT is MinterRole, ExtendedNFT, IClassifiedNFT {
event ClassPropertyUpdated(uint classID, uint propertyID);
event TokenClassChanged(uint _tokenID, uint _tokenClass);
mapping (uint256 => string[]) public class_properties;
mapping (uint256 => uint256) public token_classes;
uint256 public nextClassIndex = 0;
modifier onlyExistingClasses(uint256 classId)
{
require(classId < nextClassIndex, "Queried class does not exist");
_;
}
function setClassForTokenID(uint256 _tokenID, uint256 _tokenClass) public onlyOwner override
{
token_classes[_tokenID] = _tokenClass;
}
function addNewTokenClass(string memory _property) public onlyOwner override
{
class_properties[nextClassIndex].push(_property);
emit ClassPropertyUpdated(nextClassIndex, 0);
nextClassIndex++;
}
function addTokenClassProperties(uint256 _propertiesCount, uint256 classId) public onlyOwner override
{
for (uint i = 0; i < _propertiesCount; i++)
{
class_properties[classId].push("");
}
}
function modifyClassProperty(uint256 _classID, uint256 _propertyID, string memory _content) public onlyOwner onlyExistingClasses(_classID) override
{
class_properties[_classID][_propertyID] = _content;
emit ClassPropertyUpdated(_classID, _propertyID);
}
function getClassProperty(uint256 _classID, uint256 _propertyID) public view onlyExistingClasses(_classID) override returns (string memory)
{
return class_properties[_classID][_propertyID];
}
function addClassProperty(uint256 _classID) public onlyOwner onlyExistingClasses(_classID) override
{
class_properties[_classID].push("");
}
function addClassPropertyWithContent(uint256 _classID, string memory _content) public onlyOwner onlyExistingClasses(_classID)
{
class_properties[_classID].push(_content);
uint newPropertyID = class_properties[_classID].length - 1;
emit ClassPropertyUpdated(_classID, newPropertyID);
}
function getClassProperties(uint256 _classID) public view onlyExistingClasses(_classID) override returns (string[] memory)
{
return class_properties[_classID];
}
function getClassForTokenID(uint256 _tokenID) public view onlyExistingClasses(token_classes[_tokenID]) override returns (uint256)
{
return token_classes[_tokenID];
}
function getClassPropertiesForTokenID(uint256 _tokenID) public view onlyExistingClasses(token_classes[_tokenID]) override returns (string[] memory)
{
return class_properties[token_classes[_tokenID]];
}
function getClassPropertyForTokenID(uint256 _tokenID, uint256 _propertyID) public view onlyExistingClasses(token_classes[_tokenID]) override returns (string memory)
{
return class_properties[token_classes[_tokenID]][_propertyID];
}
function mintWithClass(uint256 classId) public onlyExistingClasses(classId) onlyMinter override returns (uint256 _newTokenID)
{
//_mint(to, tokenId);
_newTokenID = mint();
token_classes[_newTokenID] = classId;
}
function appendClassProperty(uint256 _classID, uint256 _propertyID, string memory _content) public onlyOwner onlyExistingClasses(_classID) override{}
}
contract CharityNFT is ExtendedNFT, ClassifiedNFT {
function initialize(string memory name_, string memory symbol_) external {
require(_owner == address(0), "Already initialized");
_owner = msg.sender;
emit OwnershipTransferred(address(0), msg.sender);
bidLock = 1 days;
_name = name_;
_symbol = symbol_;
}
function addPropertyWithContent(uint256 _tokenId, string calldata _content) public onlyMinter
{
_addPropertyWithContent( _tokenId, _content);
}
}
contract ActivatedByOwner is Ownable {
bool public active = true;
function setActive(bool _active) public onlyOwner
{
active = _active;
}
modifier onlyActive
{
require(active, "This contract is deactivated by owner");
_;
}
}
contract NFTMulticlassPermissiveAuction is ActivatedByOwner {
event AuctionCreated(uint256 indexed tokenClassAuctionID, uint256 timestamp);
event TokenSold(uint256 indexed tokenID, uint256 indexed tokenClassID, address indexed buyer);
event NFTContractSet(address indexed newNFTContract, address indexed oldNFTContract);
event RevenueWithdrawal(uint256 amount);
address public nft_contract;
struct NFTAuctionClass
{
uint256 amount_sold;
uint256 start_timestamp;
uint256 priceInWei;
}
mapping (uint256 => NFTAuctionClass) public auctions; // Mapping from classID (at NFT contract) to set of variables
// defining the auction for this token class.
address payable public revenue = payable(0x01000B5fE61411C466b70631d7fF070187179Bbf); // This address has the rights to withdraw funds from the auction.
constructor()
{
_owner = msg.sender;
}
function createNFTAuction(
uint256 _classID,
uint256 _start_timestamp,
uint256 _priceInWei
) public onlyOwner
{
auctions[_classID].amount_sold = 0;
auctions[_classID].start_timestamp = _start_timestamp;
auctions[_classID].priceInWei = _priceInWei;
emit AuctionCreated(_classID, block.timestamp);
}
function setRevenueAddress(address payable _revenue_address) public onlyOwner {
revenue = _revenue_address;
}
function setNFTContract(address _nftContract) public onlyOwner
{
emit NFTContractSet(_nftContract, nft_contract);
nft_contract = _nftContract;
}
receive() external payable {}
function buyNFT(uint _classID) public payable onlyActive
{
require(msg.value >= auctions[_classID].priceInWei, "Insufficient funds");
uint256 _mintedId = ClassifiedNFT(nft_contract).mintWithClass(_classID);
auctions[_classID].amount_sold++;
configureNFT(_mintedId);
ClassifiedNFT(nft_contract).transfer(msg.sender, _mintedId, "");
emit TokenSold(_mintedId, _classID, msg.sender);
}
function configureNFT(uint256 _tokenId) internal
{
CharityNFT(nft_contract).addPropertyWithContent(_tokenId, string(abi.encodePacked("Donated: ", toString(msg.value / 1e18), " CLO at ", toString(block.timestamp))));
}
function withdrawRevenue() public
{
require(msg.sender == revenue, "This action requires revenue permission");
emit RevenueWithdrawal(address(this).balance);
bool sent = revenue.send(address(this).balance);
}
function toString(uint256 value) internal pure returns (string memory) {
// Inspired by OraclizeAPI's implementation - MIT licence
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Strings.sol#L15-L35
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);
}
}
Contract ABI
[{"type":"event","name":"ClassPropertyUpdated","inputs":[{"type":"uint256","name":"classID","internalType":"uint256","indexed":false},{"type":"uint256","name":"propertyID","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"NewBid","inputs":[{"type":"uint256","name":"tokenID","internalType":"uint256","indexed":true},{"type":"uint256","name":"bidAmount","internalType":"uint256","indexed":true},{"type":"bytes","name":"data","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"NewPrice","inputs":[{"type":"uint256","name":"tokenID","internalType":"uint256","indexed":true},{"type":"uint256","name":"priceValue","internalType":"uint256","indexed":true},{"type":"bytes","name":"data","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"TokenClassChanged","inputs":[{"type":"uint256","name":"_tokenID","internalType":"uint256","indexed":false},{"type":"uint256","name":"_tokenClass","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TokenPropertyUpdated","inputs":[{"type":"uint256","name":"tokenID","internalType":"uint256","indexed":false},{"type":"uint256","name":"propertyID","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TokenTrade","inputs":[{"type":"uint256","name":"tokenID","internalType":"uint256","indexed":true},{"type":"address","name":"new_owner","internalType":"address","indexed":true},{"type":"address","name":"previous_owner","internalType":"address","indexed":true},{"type":"uint256","name":"priceInWEI","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"tokenId","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"TransferData","inputs":[{"type":"bytes","name":"data","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addClassProperty","inputs":[{"type":"uint256","name":"_classID","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addClassPropertyWithContent","inputs":[{"type":"uint256","name":"_classID","internalType":"uint256"},{"type":"string","name":"_content","internalType":"string"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addNewTokenClass","inputs":[{"type":"string","name":"_property","internalType":"string"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addPropertyWithContent","inputs":[{"type":"uint256","name":"_tokenId","internalType":"uint256"},{"type":"string","name":"_content","internalType":"string"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addTokenClassProperties","inputs":[{"type":"uint256","name":"_propertiesCount","internalType":"uint256"},{"type":"uint256","name":"classId","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"appendClassProperty","inputs":[{"type":"uint256","name":"_classID","internalType":"uint256"},{"type":"uint256","name":"_propertyID","internalType":"uint256"},{"type":"string","name":"_content","internalType":"string"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"owner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"bidLock","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"price","internalType":"uint256"},{"type":"address","name":"bidder","internalType":"address payable"},{"type":"uint256","name":"timestamp","internalType":"uint256"}],"name":"bidOf","inputs":[{"type":"uint256","name":"_tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"class_properties","inputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getClassForTokenID","inputs":[{"type":"uint256","name":"_tokenID","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string[]","name":"","internalType":"string[]"}],"name":"getClassProperties","inputs":[{"type":"uint256","name":"_classID","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string[]","name":"","internalType":"string[]"}],"name":"getClassPropertiesForTokenID","inputs":[{"type":"uint256","name":"_tokenID","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"getClassProperty","inputs":[{"type":"uint256","name":"_classID","internalType":"uint256"},{"type":"uint256","name":"_propertyID","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"getClassPropertyForTokenID","inputs":[{"type":"uint256","name":"_tokenID","internalType":"uint256"},{"type":"uint256","name":"_propertyID","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct ICallistoNFT.Properties","components":[{"type":"string[]","name":"properties","internalType":"string[]"}]}],"name":"getTokenProperties","inputs":[{"type":"uint256","name":"_tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"getTokenProperty","inputs":[{"type":"uint256","name":"_tokenId","internalType":"uint256"},{"type":"uint256","name":"_propertyId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"_content","internalType":"string"}],"name":"getUserContent","inputs":[{"type":"uint256","name":"_tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initialize","inputs":[{"type":"string","name":"name_","internalType":"string"},{"type":"string","name":"symbol_","internalType":"string"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"_newTokenID","internalType":"uint256"}],"name":"mintWithClass","inputs":[{"type":"uint256","name":"classId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"minter_role","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"modifyClassProperty","inputs":[{"type":"uint256","name":"_classID","internalType":"uint256"},{"type":"uint256","name":"_propertyID","internalType":"uint256"},{"type":"string","name":"_content","internalType":"string"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"nextClassIndex","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"next_mint_id","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"ownerOf","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"priceOf","inputs":[{"type":"uint256","name":"_tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"setBid","inputs":[{"type":"uint256","name":"_tokenId","internalType":"uint256"},{"type":"bytes","name":"_data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setClassForTokenID","inputs":[{"type":"uint256","name":"_tokenID","internalType":"uint256"},{"type":"uint256","name":"_tokenClass","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMinterRole","inputs":[{"type":"address","name":"_who","internalType":"address"},{"type":"bool","name":"_status","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPrice","inputs":[{"type":"uint256","name":"_tokenId","internalType":"uint256"},{"type":"uint256","name":"_amountInWEI","internalType":"uint256"},{"type":"bytes","name":"_data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"success","internalType":"bool"}],"name":"setUserContent","inputs":[{"type":"uint256","name":"_tokenId","internalType":"uint256"},{"type":"string","name":"_content","internalType":"string"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"silentTransfer","inputs":[{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"_tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"standard","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"token_classes","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"_tokenId","internalType":"uint256"},{"type":"bytes","name":"_data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"withdrawBid","inputs":[{"type":"uint256","name":"_tokenId","internalType":"uint256"}]}]
Contract Creation Code
0x6080604052620151806004556000600e5534801561001c57600080fd5b5060016002556133cd806100316000396000f3fe6080604052600436106102bb5760003560e01c8063649ccc141161016e5780639de4792e116100cb578063c98e0c3c1161007f578063e29fb03611610064578063e29fb036146107f5578063e64700591461080b578063f2fde38b1461082b57600080fd5b8063c98e0c3c146107b5578063cb177b1e146107d557600080fd5b8063be45fd62116100b0578063be45fd6214610748578063be67105814610768578063c1940f1b1461078857600080fd5b80639de4792e14610708578063b9186d7d1461072857600080fd5b80637eebe86e116101225780638da5cb5b116101075780638da5cb5b146106bf57806391100695146106dd57806395d89b41146106f357600080fd5b80637eebe86e1461067f57806380483a6a1461069f57600080fd5b806370a082311161015357806370a082311461062c57806373baa6511461064c5780637ab56e521461065f57600080fd5b8063649ccc14146105c957806369a137121461060c57600080fd5b80633e0bb7831161021c5780634edea111116101d0578063543dc7fa116101b5578063543dc7fa1461052b5780635a3b7e421461054b5780636352211e1461059157600080fd5b80634edea111146104ce578063510910bb146104fb57600080fd5b80634bb2ddd4116102015780634bb2ddd4146104615780634c1720a41461048e5780634cd88b76146104ae57600080fd5b80633e0bb783146104215780634774d93f1461044157600080fd5b8063290e008c116102735780633054d9cb116102585780633054d9cb146103c15780633c65b3eb146103e15780633d8073f11461040157600080fd5b8063290e008c146103815780632a6d3f44146103a157600080fd5b80630eaaf4c8116102a45780630eaaf4c81461030b5780631d734c8f1461033b5780631f38e6541461035f57600080fd5b806302ff368a146102c057806306fdde03146102f6575b600080fd5b3480156102cc57600080fd5b506102e06102db366004612b78565b61084b565b6040516102ed9190612bd7565b60405180910390f35b34801561030257600080fd5b506102e0610905565b34801561031757600080fd5b5061032b610326366004612b78565b610997565b60405190151581526020016102ed565b34801561034757600080fd5b50610351600e5481565b6040519081526020016102ed565b34801561036b57600080fd5b5061037f61037a366004612bf1565b610bae565b005b34801561038d57600080fd5b5061037f61039c366004612c5c565b610c1a565b3480156103ad57600080fd5b5061032b6103bc366004612c5c565b610c89565b3480156103cd57600080fd5b5061037f6103dc366004612d4b565b610d96565b3480156103ed57600080fd5b506103516103fc366004612b78565b610ebc565b34801561040d57600080fd5b5061037f61041c366004612d9b565b610f90565b34801561042d57600080fd5b506102e061043c366004612bf1565b6111db565b34801561044d57600080fd5b5061037f61045c366004612d4b565b611294565b34801561046d57600080fd5b5061048161047c366004612b78565b611346565b6040516102ed9190612dee565b34801561049a57600080fd5b506102e06104a9366004612bf1565b611496565b3480156104ba57600080fd5b5061037f6104c9366004612e50565b6115a6565b3480156104da57600080fd5b506104ee6104e9366004612b78565b61165e565b6040516102ed9190612eb4565b34801561050757600080fd5b5061032b610516366004612f2f565b60016020526000908152604090205460ff1681565b34801561053757600080fd5b50610351610546366004612b78565b611753565b34801561055757600080fd5b5060408051808201909152600b81527f43616c6c6973746f4e465400000000000000000000000000000000000000000060208201526102e0565b34801561059d57600080fd5b506105b16105ac366004612b78565b6117c7565b6040516001600160a01b0390911681526020016102ed565b3480156105d557600080fd5b506105e96105e4366004612b78565b611841565b604080519384526001600160a01b039092166020840152908201526060016102ed565b34801561061857600080fd5b5061037f610627366004612f4a565b6118e8565b34801561063857600080fd5b50610351610647366004612f2f565b611a11565b61037f61065a366004612c5c565b611aab565b34801561066b57600080fd5b506102e061067a366004612bf1565b611dc5565b34801561068b57600080fd5b5061037f61069a366004612f87565b611e84565b3480156106ab57600080fd5b5061037f6106ba366004612b78565b611f5e565b3480156106cb57600080fd5b506000546001600160a01b03166105b1565b3480156106e957600080fd5b5061035160045481565b3480156106ff57600080fd5b506102e0612042565b34801561071457600080fd5b506102e0610723366004612bf1565b612051565b34801561073457600080fd5b50610351610743366004612b78565b6120e2565b34801561075457600080fd5b5061032b610763366004612fc4565b61216a565b34801561077457600080fd5b5061037f610783366004612bf1565b6121bd565b34801561079457600080fd5b506103516107a3366004612b78565b600d6020526000908152604090205481565b3480156107c157600080fd5b5061032b6107d0366004613006565b61226d565b3480156107e157600080fd5b5061037f6107f0366004613030565b6123fe565b34801561080157600080fd5b5061035160075481565b34801561081757600080fd5b50610481610826366004612b78565b612483565b34801561083757600080fd5b5061037f610846366004612f2f565b6125ac565b600081815260036020526040812080546060929061086b5761086b61306c565b90600052602060002001805461088090613082565b80601f01602080910402602001604051908101604052809291908181526020018280546108ac90613082565b80156108f95780601f106108ce576101008083540402835291602001916108f9565b820191906000526020600020905b8154815290600101906020018083116108dc57829003601f168201915b50505050509050919050565b60606008805461091490613082565b80601f016020809104026020016040519081016040528092919081815260200182805461094090613082565b801561098d5780601f106109625761010080835404028352916020019161098d565b820191906000526020600020905b81548152906001019060200180831161097057829003601f168201915b5050505050905090565b600060028054036109ef5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b6002805560008080610a0085611841565b91945092509050336001600160a01b03831614610a855760405162461bcd60e51b815260206004820152602260248201527f43616e206e6f7420776974686472617720736f6d656f6e6520656c736573206260448201527f696400000000000000000000000000000000000000000000000000000000000060648201526084016109e6565b600454610a9290826130cc565b4211610ae05760405162461bcd60e51b815260206004820152601260248201527f4269642069732074696d652d6c6f636b6564000000000000000000000000000060448201526064016109e6565b6040516000906001600160a01b0384169085156108fc0290869084818181858888f160008b81526006602052604080822080546001600160a01b0319168155600181018390556002018290555191965094508a93507f223d0d5db4846341da7a5cc902b1a7c597e63b6c73b1c6267dc931d290c7affb9250610b94915060208082526018908201527f3078373736393734363836343732363137373432363936340000000000000000604082015260600190565b60405180910390a360019450505050506001600255919050565b6000546001600160a01b03163314610c085760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109e6565b6000918252600d602052604090912055565b3360009081526001602052604090205460ff16610c795760405162461bcd60e51b815260206004820152601460248201527f4d696e74657220726f6c6520726571756972656400000000000000000000000060448201526064016109e6565b610c8483838361268e565b505050565b6000610c94846117c7565b6001600160a01b0316336001600160a01b031614610d1a5760405162461bcd60e51b815260206004820152602660248201527f4e46543a206f6e6c79206f776e65722063616e206368616e6765204e4654206360448201527f6f6e74656e74000000000000000000000000000000000000000000000000000060648201526084016109e6565b600084815260036020526040812080548592859291610d3b57610d3b61306c565b906000526020600020019182610d5292919061312d565b5060408051858152600060208201527f0fe79316286f6a1e5cf32c3c4ff10c2a66b9cd66da3353db3789c4042ffb44ee910160405180910390a15060019392505050565b6000546001600160a01b03163314610df05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109e6565b82600e548110610e425760405162461bcd60e51b815260206004820152601c60248201527f5175657269656420636c61737320646f6573206e6f742065786973740000000060448201526064016109e6565b6000848152600c60205260409020805483919085908110610e6557610e6561306c565b906000526020600020019081610e7b91906131ee565b5060408051858152602081018590527f949a1ec513916b5e46ab2c5681369a4651bba074831b8da896b06a94e8d041b691015b60405180910390a150505050565b600081600e548110610f105760405162461bcd60e51b815260206004820152601c60248201527f5175657269656420636c61737320646f6573206e6f742065786973740000000060448201526064016109e6565b3360009081526001602052604090205460ff16610f6f5760405162461bcd60e51b815260206004820152601460248201527f4d696e74657220726f6c6520726571756972656400000000000000000000000060448201526064016109e6565b610f7761270c565b6000818152600d60205260409020939093555090919050565b8382826002805403610fe45760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109e6565b6002805533610ff2886117c7565b6001600160a01b03161461106e5760405162461bcd60e51b815260206004820152602c60248201527f53657474696e672061736b73206973206f6e6c7920616c6c6f77656420666f7260448201527f206f776e6564204e46547321000000000000000000000000000000000000000060648201526084016109e6565b6000878152600560205260409081902087905551869088907f403cbda48c4d379b57469bea093b63817816d893b467842ee46fd1c3c29c05f8906110b590899089906132d7565b60405180910390a360016002556000806110ce85611841565b509150915060006110de866120e2565b1180156110f35750816110f0866120e2565b11155b156111d057611101856117c7565b6001600160a01b0316816001600160a01b0316867fc9b9afd9684b23c6b22a41016c08e8954ac118220c0a52f00b8774c46580e9a38560405161114691815260200190565b60405180910390a46000611159866117c7565b6001600160a01b03166108fc849081150290604051600060405180830381858888f160008b815260066020908152604080832080546001600160a01b031916815560018101849055600201839055600590915281205594506111ce93506111c592508991506117c79050565b8388888861273e565b505b505050505050505050565b600c60205281600052604060002081815481106111f757600080fd5b9060005260206000200160009150915050805461121390613082565b80601f016020809104026020016040519081016040528092919081815260200182805461123f90613082565b801561128c5780601f106112615761010080835404028352916020019161128c565b820191906000526020600020905b81548152906001019060200180831161126f57829003601f168201915b505050505081565b6000546001600160a01b031633146112ee5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109e6565b82600e5481106113405760405162461bcd60e51b815260206004820152601c60248201527f5175657269656420636c61737320646f6573206e6f742065786973740000000060448201526064016109e6565b50505050565b6000818152600d6020526040902054600e546060919081106113aa5760405162461bcd60e51b815260206004820152601c60248201527f5175657269656420636c61737320646f6573206e6f742065786973740000000060448201526064016109e6565b6000838152600d60209081526040808320548352600c825280832080548251818502810185019093528083529193909284015b828210156114895783829060005260206000200180546113fc90613082565b80601f016020809104026020016040519081016040528092919081815260200182805461142890613082565b80156114755780601f1061144a57610100808354040283529160200191611475565b820191906000526020600020905b81548152906001019060200180831161145857829003601f168201915b5050505050815260200190600101906113dd565b5050505091505b50919050565b606082600e5481106114ea5760405162461bcd60e51b815260206004820152601c60248201527f5175657269656420636c61737320646f6573206e6f742065786973740000000060448201526064016109e6565b6000848152600c6020526040902080548490811061150a5761150a61306c565b90600052602060002001805461151f90613082565b80601f016020809104026020016040519081016040528092919081815260200182805461154b90613082565b80156115985780601f1061156d57610100808354040283529160200191611598565b820191906000526020600020905b81548152906001019060200180831161157b57829003601f168201915b505050505091505092915050565b6000546001600160a01b0316156115ff5760405162461bcd60e51b815260206004820152601360248201527f416c726561647920696e697469616c697a65640000000000000000000000000060448201526064016109e6565b600080546001600160a01b0319163390811782556040519091907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a362015180600455600861165183826131ee565b506009610c8482826131ee565b604080516020808201835260608252600084815260038252838120845181548085028201870187529381018481529495909491938593859285015b828210156117455783829060005260206000200180546116b890613082565b80601f01602080910402602001604051908101604052809291908181526020018280546116e490613082565b80156117315780601f1061170657610100808354040283529160200191611731565b820191906000526020600020905b81548152906001019060200180831161171457829003601f168201915b505050505081526020019060010190611699565b505050915250909392505050565b6000818152600d6020526040812054600e5481106117b35760405162461bcd60e51b815260206004820152601c60248201527f5175657269656420636c61737320646f6573206e6f742065786973740000000060448201526064016109e6565b50506000908152600d602052604090205490565b6000818152600a60205260408120546001600160a01b03168061183b5760405162461bcd60e51b815260206004820152602660248201527f4e46543a206f776e657220717565727920666f72206e6f6e6578697374656e74604482015265103a37b5b2b760d11b60648201526084016109e6565b92915050565b6000818152600a6020526040812054819081906001600160a01b0316806118b95760405162461bcd60e51b815260206004820152602660248201527f4e46543a206f776e657220717565727920666f72206e6f6e6578697374656e74604482015265103a37b5b2b760d11b60648201526084016109e6565b5050506000918252506006602052604090206001810154815460029092015490926001600160a01b0390921691565b6000546001600160a01b031633146119425760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109e6565b81600e5481106119945760405162461bcd60e51b815260206004820152601c60248201527f5175657269656420636c61737320646f6573206e6f742065786973740000000060448201526064016109e6565b6000838152600c60209081526040822080546001810182559083529120016119bc83826131ee565b506000838152600c60205260408120546119d8906001906132eb565b60408051868152602081018390529192507f949a1ec513916b5e46ab2c5681369a4651bba074831b8da896b06a94e8d041b69101610eae565b60006001600160a01b038216611a8f5760405162461bcd60e51b815260206004820152602760248201527f4e46543a2062616c616e636520717565727920666f7220746865207a65726f2060448201527f616464726573730000000000000000000000000000000000000000000000000060648201526084016109e6565b506001600160a01b03166000908152600b602052604090205490565b8282826002805403611aff5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109e6565b60028055600080611b0f88611841565b5091509150813411611b885760405162461bcd60e51b8152602060048201526024808201527f4e657720626964206d7573742065786365656420746865206578697374696e6760448201527f206f6e650000000000000000000000000000000000000000000000000000000060648201526084016109e6565b6000808315611bb8576040516001600160a01b0384169085156108fc029086906000818181858888f19450505050505b34611bc28b6120e2565b108015611bd757506000611bd58b6120e2565b115b15611bec57611be58a6120e2565b9150611bf0565b3491505b60008a815260066020526040908190206001810184905580546001600160a01b03191633178155426002909101555182908b907f223d0d5db4846341da7a5cc902b1a7c597e63b6c73b1c6267dc931d290c7affb90611c52908d908d906132d7565b60405180910390a334611c648b6120e2565b108015611c7957506000611c778b6120e2565b115b15611cae57336108fc611c8b8c6120e2565b611c9590346132eb565b6040518115909202916000818181858888f19450505050505b50506001600255506000905080611cc485611841565b50915091506000611cd4866120e2565b118015611ce9575081611ce6866120e2565b11155b15611dbb57611cf7856117c7565b6001600160a01b0316816001600160a01b0316867fc9b9afd9684b23c6b22a41016c08e8954ac118220c0a52f00b8774c46580e9a385604051611d3c91815260200190565b60405180910390a46000611d4f866117c7565b6001600160a01b03166108fc849081150290604051600060405180830381858888f160008b815260066020908152604080832080546001600160a01b031916815560018101849055600201839055600590915281205594506111d093506111c592508991506117c79050565b5050505050505050565b600082815260036020526040902080546060919083908110611de957611de961306c565b906000526020600020018054611dfe90613082565b80601f0160208091040260200160405190810160405280929190818152602001828054611e2a90613082565b8015611e775780601f10611e4c57610100808354040283529160200191611e77565b820191906000526020600020905b815481529060010190602001808311611e5a57829003601f168201915b5050505050905092915050565b6000546001600160a01b03163314611ede5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109e6565b600e546000908152600c6020908152604082208054600181018255908352912001611f0982826131ee565b50600e5460408051918252600060208301527f949a1ec513916b5e46ab2c5681369a4651bba074831b8da896b06a94e8d041b6910160405180910390a1600e8054906000611f56836132fe565b919050555050565b6000546001600160a01b03163314611fb85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109e6565b80600e54811061200a5760405162461bcd60e51b815260206004820152601c60248201527f5175657269656420636c61737320646f6573206e6f742065786973740000000060448201526064016109e6565b6000828152600c602090815260408083208054600181018255908452828420825193840190925292825290910190610c8490826131ee565b60606009805461091490613082565b6000828152600d6020526040902054600e546060919081106120b55760405162461bcd60e51b815260206004820152601c60248201527f5175657269656420636c61737320646f6573206e6f742065786973740000000060448201526064016109e6565b6000848152600d60209081526040808320548352600c909152902080548490811061150a5761150a61306c565b6000818152600a60205260408120546001600160a01b0316806121565760405162461bcd60e51b815260206004820152602660248201527f4e46543a206f776e657220717565727920666f72206e6f6e6578697374656e74604482015265103a37b5b2b760d11b60648201526084016109e6565b505060009081526005602052604090205490565b6000612179338686868661273e565b7f3ba9136826ac751de05d770d8d34fa4440ada49a5fb0e9aa1678aece66dad97683836040516121aa9291906132d7565b60405180910390a1506001949350505050565b6000546001600160a01b031633146122175760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109e6565b60005b82811015610c84576000828152600c60209081526040808320805460018101825590845282842082519384019092529282529091019061225a90826131ee565b5080612265816132fe565b91505061221a565b600033612279836117c7565b6001600160a01b0316146122de5760405162461bcd60e51b815260206004820152602660248201527f4e46543a207472616e73666572206f6620746f6b656e2074686174206973206e60448201526537ba1037bbb760d11b60648201526084016109e6565b6001600160a01b03831661233e5760405162461bcd60e51b815260206004820152602160248201527f4e46543a207472616e7366657220746f20746865207a65726f206164647265736044820152607360f81b60648201526084016109e6565b600082815260056020526040812055336000908152600b6020526040812080546001929061236d9084906132eb565b90915550506001600160a01b0383166000908152600b6020526040812080546001929061239b9084906130cc565b90915550506000828152600a602052604080822080546001600160a01b0319166001600160a01b0387169081179091559051849233917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9190a450600192915050565b6000546001600160a01b031633146124585760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109e6565b6001600160a01b03919091166000908152600160205260409020805460ff1916911515919091179055565b606081600e5481106124d75760405162461bcd60e51b815260206004820152601c60248201527f5175657269656420636c61737320646f6573206e6f742065786973740000000060448201526064016109e6565b6000838152600c6020908152604080832080548251818502810185019093528083529193909284015b8282101561148957838290600052602060002001805461251f90613082565b80601f016020809104026020016040519081016040528092919081815260200182805461254b90613082565b80156125985780601f1061256d57610100808354040283529160200191612598565b820191906000526020600020905b81548152906001019060200180831161257b57829003601f168201915b505050505081526020019060010190612500565b6000546001600160a01b031633146126065760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109e6565b6001600160a01b0381166126825760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016109e6565b61268b8161298b565b50565b6000838152600360209081526040822080546001810182559083529120016126b782848361312d565b506000838152600360205260408120546126d3906001906132eb565b60408051868152602081018390529192507f0fe79316286f6a1e5cf32c3c4ff10c2a66b9cd66da3353db3789c4042ffb44ee9101610eae565b600061271a336007546129db565b5060078054908190600061272d836132fe565b919050555061273b816129e9565b90565b846001600160a01b0316612751846117c7565b6001600160a01b0316146127b65760405162461bcd60e51b815260206004820152602660248201527f4e46543a207472616e73666572206f6620746f6b656e2074686174206973206e60448201526537ba1037bbb760d11b60648201526084016109e6565b6001600160a01b0384166128165760405162461bcd60e51b815260206004820152602160248201527f4e46543a207472616e7366657220746f20746865207a65726f206164647265736044820152607360f81b60648201526084016109e6565b6000838152600560205260408120556001600160a01b0385166000908152600b6020526040812080546001929061284e9084906132eb565b90915550506001600160a01b0384166000908152600b6020526040812080546001929061287c9084906130cc565b90915550506000838152600a6020526040902080546001600160a01b0319166001600160a01b0386169081179091553b15612943576040517f150b7a020000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063150b7a02906128fe9033908990889088908890600401613317565b6020604051808303816000875af115801561291d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129419190613355565b505b82846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6129e58282612a36565b5050565b600081815260036020526040812054900361268b57600081815260036020908152604080832080546001810182559084528284208251938401909252928252909101906129e590826131ee565b6001600160a01b038216612a8c5760405162461bcd60e51b815260206004820152601d60248201527f4e46543a206d696e7420746f20746865207a65726f206164647265737300000060448201526064016109e6565b6000818152600a60205260409020546001600160a01b031615612af15760405162461bcd60e51b815260206004820152601960248201527f4e46543a20746f6b656e20616c7265616479206d696e7465640000000000000060448201526064016109e6565b6001600160a01b0382166000908152600b60205260408120805460019290612b1a9084906130cc565b90915550506000818152600a602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600060208284031215612b8a57600080fd5b5035919050565b6000815180845260005b81811015612bb757602081850181015186830182015201612b9b565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000612bea6020830184612b91565b9392505050565b60008060408385031215612c0457600080fd5b50508035926020909101359150565b60008083601f840112612c2557600080fd5b50813567ffffffffffffffff811115612c3d57600080fd5b602083019150836020828501011115612c5557600080fd5b9250929050565b600080600060408486031215612c7157600080fd5b83359250602084013567ffffffffffffffff811115612c8f57600080fd5b612c9b86828701612c13565b9497909650939450505050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112612ccf57600080fd5b813567ffffffffffffffff80821115612cea57612cea612ca8565b604051601f8301601f19908116603f01168101908282118183101715612d1257612d12612ca8565b81604052838152866020858801011115612d2b57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600060608486031215612d6057600080fd5b8335925060208401359150604084013567ffffffffffffffff811115612d8557600080fd5b612d9186828701612cbe565b9150509250925092565b60008060008060608587031215612db157600080fd5b8435935060208501359250604085013567ffffffffffffffff811115612dd657600080fd5b612de287828801612c13565b95989497509550505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015612e4357603f19888603018452612e31858351612b91565b94509285019290850190600101612e15565b5092979650505050505050565b60008060408385031215612e6357600080fd5b823567ffffffffffffffff80821115612e7b57600080fd5b612e8786838701612cbe565b93506020850135915080821115612e9d57600080fd5b50612eaa85828601612cbe565b9150509250929050565b60006020808352604083018451828386015281815180845260608701915060608160051b8801019350848301925060005b81811015612e4357605f19888603018352612f01858551612b91565b94509285019291850191600101612ee5565b80356001600160a01b0381168114612f2a57600080fd5b919050565b600060208284031215612f4157600080fd5b612bea82612f13565b60008060408385031215612f5d57600080fd5b82359150602083013567ffffffffffffffff811115612f7b57600080fd5b612eaa85828601612cbe565b600060208284031215612f9957600080fd5b813567ffffffffffffffff811115612fb057600080fd5b612fbc84828501612cbe565b949350505050565b60008060008060608587031215612fda57600080fd5b612fe385612f13565b935060208501359250604085013567ffffffffffffffff811115612dd657600080fd5b6000806040838503121561301957600080fd5b61302283612f13565b946020939093013593505050565b6000806040838503121561304357600080fd5b61304c83612f13565b91506020830135801515811461306157600080fd5b809150509250929050565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168061309657607f821691505b60208210810361149057634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8082018082111561183b5761183b6130b6565b601f821115610c8457600081815260208120601f850160051c810160208610156131065750805b601f850160051c820191505b8181101561312557828155600101613112565b505050505050565b67ffffffffffffffff83111561314557613145612ca8565b613159836131538354613082565b836130df565b6000601f84116001811461318d57600085156131755750838201355b600019600387901b1c1916600186901b1783556131e7565b600083815260209020601f19861690835b828110156131be578685013582556020948501946001909201910161319e565b50868210156131db5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b815167ffffffffffffffff81111561320857613208612ca8565b61321c816132168454613082565b846130df565b602080601f83116001811461325157600084156132395750858301515b600019600386901b1c1916600185901b178555613125565b600085815260208120601f198616915b8281101561328057888601518255948401946001909101908401613261565b508582101561329e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b602081526000612fbc6020830184866132ae565b8181038181111561183b5761183b6130b6565b600060018201613310576133106130b6565b5060010190565b60006001600160a01b0380881683528087166020840152508460408301526080606083015261334a6080830184866132ae565b979650505050505050565b60006020828403121561336757600080fd5b81517fffffffff0000000000000000000000000000000000000000000000000000000081168114612bea57600080fdfea2646970667358221220846e8e6cb4223109184e5ecc18ae8f0bf522ec83373e2c14d3f93afb259e735d64736f6c63430008130033
Deployed ByteCode
0x6080604052600436106102bb5760003560e01c8063649ccc141161016e5780639de4792e116100cb578063c98e0c3c1161007f578063e29fb03611610064578063e29fb036146107f5578063e64700591461080b578063f2fde38b1461082b57600080fd5b8063c98e0c3c146107b5578063cb177b1e146107d557600080fd5b8063be45fd62116100b0578063be45fd6214610748578063be67105814610768578063c1940f1b1461078857600080fd5b80639de4792e14610708578063b9186d7d1461072857600080fd5b80637eebe86e116101225780638da5cb5b116101075780638da5cb5b146106bf57806391100695146106dd57806395d89b41146106f357600080fd5b80637eebe86e1461067f57806380483a6a1461069f57600080fd5b806370a082311161015357806370a082311461062c57806373baa6511461064c5780637ab56e521461065f57600080fd5b8063649ccc14146105c957806369a137121461060c57600080fd5b80633e0bb7831161021c5780634edea111116101d0578063543dc7fa116101b5578063543dc7fa1461052b5780635a3b7e421461054b5780636352211e1461059157600080fd5b80634edea111146104ce578063510910bb146104fb57600080fd5b80634bb2ddd4116102015780634bb2ddd4146104615780634c1720a41461048e5780634cd88b76146104ae57600080fd5b80633e0bb783146104215780634774d93f1461044157600080fd5b8063290e008c116102735780633054d9cb116102585780633054d9cb146103c15780633c65b3eb146103e15780633d8073f11461040157600080fd5b8063290e008c146103815780632a6d3f44146103a157600080fd5b80630eaaf4c8116102a45780630eaaf4c81461030b5780631d734c8f1461033b5780631f38e6541461035f57600080fd5b806302ff368a146102c057806306fdde03146102f6575b600080fd5b3480156102cc57600080fd5b506102e06102db366004612b78565b61084b565b6040516102ed9190612bd7565b60405180910390f35b34801561030257600080fd5b506102e0610905565b34801561031757600080fd5b5061032b610326366004612b78565b610997565b60405190151581526020016102ed565b34801561034757600080fd5b50610351600e5481565b6040519081526020016102ed565b34801561036b57600080fd5b5061037f61037a366004612bf1565b610bae565b005b34801561038d57600080fd5b5061037f61039c366004612c5c565b610c1a565b3480156103ad57600080fd5b5061032b6103bc366004612c5c565b610c89565b3480156103cd57600080fd5b5061037f6103dc366004612d4b565b610d96565b3480156103ed57600080fd5b506103516103fc366004612b78565b610ebc565b34801561040d57600080fd5b5061037f61041c366004612d9b565b610f90565b34801561042d57600080fd5b506102e061043c366004612bf1565b6111db565b34801561044d57600080fd5b5061037f61045c366004612d4b565b611294565b34801561046d57600080fd5b5061048161047c366004612b78565b611346565b6040516102ed9190612dee565b34801561049a57600080fd5b506102e06104a9366004612bf1565b611496565b3480156104ba57600080fd5b5061037f6104c9366004612e50565b6115a6565b3480156104da57600080fd5b506104ee6104e9366004612b78565b61165e565b6040516102ed9190612eb4565b34801561050757600080fd5b5061032b610516366004612f2f565b60016020526000908152604090205460ff1681565b34801561053757600080fd5b50610351610546366004612b78565b611753565b34801561055757600080fd5b5060408051808201909152600b81527f43616c6c6973746f4e465400000000000000000000000000000000000000000060208201526102e0565b34801561059d57600080fd5b506105b16105ac366004612b78565b6117c7565b6040516001600160a01b0390911681526020016102ed565b3480156105d557600080fd5b506105e96105e4366004612b78565b611841565b604080519384526001600160a01b039092166020840152908201526060016102ed565b34801561061857600080fd5b5061037f610627366004612f4a565b6118e8565b34801561063857600080fd5b50610351610647366004612f2f565b611a11565b61037f61065a366004612c5c565b611aab565b34801561066b57600080fd5b506102e061067a366004612bf1565b611dc5565b34801561068b57600080fd5b5061037f61069a366004612f87565b611e84565b3480156106ab57600080fd5b5061037f6106ba366004612b78565b611f5e565b3480156106cb57600080fd5b506000546001600160a01b03166105b1565b3480156106e957600080fd5b5061035160045481565b3480156106ff57600080fd5b506102e0612042565b34801561071457600080fd5b506102e0610723366004612bf1565b612051565b34801561073457600080fd5b50610351610743366004612b78565b6120e2565b34801561075457600080fd5b5061032b610763366004612fc4565b61216a565b34801561077457600080fd5b5061037f610783366004612bf1565b6121bd565b34801561079457600080fd5b506103516107a3366004612b78565b600d6020526000908152604090205481565b3480156107c157600080fd5b5061032b6107d0366004613006565b61226d565b3480156107e157600080fd5b5061037f6107f0366004613030565b6123fe565b34801561080157600080fd5b5061035160075481565b34801561081757600080fd5b50610481610826366004612b78565b612483565b34801561083757600080fd5b5061037f610846366004612f2f565b6125ac565b600081815260036020526040812080546060929061086b5761086b61306c565b90600052602060002001805461088090613082565b80601f01602080910402602001604051908101604052809291908181526020018280546108ac90613082565b80156108f95780601f106108ce576101008083540402835291602001916108f9565b820191906000526020600020905b8154815290600101906020018083116108dc57829003601f168201915b50505050509050919050565b60606008805461091490613082565b80601f016020809104026020016040519081016040528092919081815260200182805461094090613082565b801561098d5780601f106109625761010080835404028352916020019161098d565b820191906000526020600020905b81548152906001019060200180831161097057829003601f168201915b5050505050905090565b600060028054036109ef5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b6002805560008080610a0085611841565b91945092509050336001600160a01b03831614610a855760405162461bcd60e51b815260206004820152602260248201527f43616e206e6f7420776974686472617720736f6d656f6e6520656c736573206260448201527f696400000000000000000000000000000000000000000000000000000000000060648201526084016109e6565b600454610a9290826130cc565b4211610ae05760405162461bcd60e51b815260206004820152601260248201527f4269642069732074696d652d6c6f636b6564000000000000000000000000000060448201526064016109e6565b6040516000906001600160a01b0384169085156108fc0290869084818181858888f160008b81526006602052604080822080546001600160a01b0319168155600181018390556002018290555191965094508a93507f223d0d5db4846341da7a5cc902b1a7c597e63b6c73b1c6267dc931d290c7affb9250610b94915060208082526018908201527f3078373736393734363836343732363137373432363936340000000000000000604082015260600190565b60405180910390a360019450505050506001600255919050565b6000546001600160a01b03163314610c085760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109e6565b6000918252600d602052604090912055565b3360009081526001602052604090205460ff16610c795760405162461bcd60e51b815260206004820152601460248201527f4d696e74657220726f6c6520726571756972656400000000000000000000000060448201526064016109e6565b610c8483838361268e565b505050565b6000610c94846117c7565b6001600160a01b0316336001600160a01b031614610d1a5760405162461bcd60e51b815260206004820152602660248201527f4e46543a206f6e6c79206f776e65722063616e206368616e6765204e4654206360448201527f6f6e74656e74000000000000000000000000000000000000000000000000000060648201526084016109e6565b600084815260036020526040812080548592859291610d3b57610d3b61306c565b906000526020600020019182610d5292919061312d565b5060408051858152600060208201527f0fe79316286f6a1e5cf32c3c4ff10c2a66b9cd66da3353db3789c4042ffb44ee910160405180910390a15060019392505050565b6000546001600160a01b03163314610df05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109e6565b82600e548110610e425760405162461bcd60e51b815260206004820152601c60248201527f5175657269656420636c61737320646f6573206e6f742065786973740000000060448201526064016109e6565b6000848152600c60205260409020805483919085908110610e6557610e6561306c565b906000526020600020019081610e7b91906131ee565b5060408051858152602081018590527f949a1ec513916b5e46ab2c5681369a4651bba074831b8da896b06a94e8d041b691015b60405180910390a150505050565b600081600e548110610f105760405162461bcd60e51b815260206004820152601c60248201527f5175657269656420636c61737320646f6573206e6f742065786973740000000060448201526064016109e6565b3360009081526001602052604090205460ff16610f6f5760405162461bcd60e51b815260206004820152601460248201527f4d696e74657220726f6c6520726571756972656400000000000000000000000060448201526064016109e6565b610f7761270c565b6000818152600d60205260409020939093555090919050565b8382826002805403610fe45760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109e6565b6002805533610ff2886117c7565b6001600160a01b03161461106e5760405162461bcd60e51b815260206004820152602c60248201527f53657474696e672061736b73206973206f6e6c7920616c6c6f77656420666f7260448201527f206f776e6564204e46547321000000000000000000000000000000000000000060648201526084016109e6565b6000878152600560205260409081902087905551869088907f403cbda48c4d379b57469bea093b63817816d893b467842ee46fd1c3c29c05f8906110b590899089906132d7565b60405180910390a360016002556000806110ce85611841565b509150915060006110de866120e2565b1180156110f35750816110f0866120e2565b11155b156111d057611101856117c7565b6001600160a01b0316816001600160a01b0316867fc9b9afd9684b23c6b22a41016c08e8954ac118220c0a52f00b8774c46580e9a38560405161114691815260200190565b60405180910390a46000611159866117c7565b6001600160a01b03166108fc849081150290604051600060405180830381858888f160008b815260066020908152604080832080546001600160a01b031916815560018101849055600201839055600590915281205594506111ce93506111c592508991506117c79050565b8388888861273e565b505b505050505050505050565b600c60205281600052604060002081815481106111f757600080fd5b9060005260206000200160009150915050805461121390613082565b80601f016020809104026020016040519081016040528092919081815260200182805461123f90613082565b801561128c5780601f106112615761010080835404028352916020019161128c565b820191906000526020600020905b81548152906001019060200180831161126f57829003601f168201915b505050505081565b6000546001600160a01b031633146112ee5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109e6565b82600e5481106113405760405162461bcd60e51b815260206004820152601c60248201527f5175657269656420636c61737320646f6573206e6f742065786973740000000060448201526064016109e6565b50505050565b6000818152600d6020526040902054600e546060919081106113aa5760405162461bcd60e51b815260206004820152601c60248201527f5175657269656420636c61737320646f6573206e6f742065786973740000000060448201526064016109e6565b6000838152600d60209081526040808320548352600c825280832080548251818502810185019093528083529193909284015b828210156114895783829060005260206000200180546113fc90613082565b80601f016020809104026020016040519081016040528092919081815260200182805461142890613082565b80156114755780601f1061144a57610100808354040283529160200191611475565b820191906000526020600020905b81548152906001019060200180831161145857829003601f168201915b5050505050815260200190600101906113dd565b5050505091505b50919050565b606082600e5481106114ea5760405162461bcd60e51b815260206004820152601c60248201527f5175657269656420636c61737320646f6573206e6f742065786973740000000060448201526064016109e6565b6000848152600c6020526040902080548490811061150a5761150a61306c565b90600052602060002001805461151f90613082565b80601f016020809104026020016040519081016040528092919081815260200182805461154b90613082565b80156115985780601f1061156d57610100808354040283529160200191611598565b820191906000526020600020905b81548152906001019060200180831161157b57829003601f168201915b505050505091505092915050565b6000546001600160a01b0316156115ff5760405162461bcd60e51b815260206004820152601360248201527f416c726561647920696e697469616c697a65640000000000000000000000000060448201526064016109e6565b600080546001600160a01b0319163390811782556040519091907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a362015180600455600861165183826131ee565b506009610c8482826131ee565b604080516020808201835260608252600084815260038252838120845181548085028201870187529381018481529495909491938593859285015b828210156117455783829060005260206000200180546116b890613082565b80601f01602080910402602001604051908101604052809291908181526020018280546116e490613082565b80156117315780601f1061170657610100808354040283529160200191611731565b820191906000526020600020905b81548152906001019060200180831161171457829003601f168201915b505050505081526020019060010190611699565b505050915250909392505050565b6000818152600d6020526040812054600e5481106117b35760405162461bcd60e51b815260206004820152601c60248201527f5175657269656420636c61737320646f6573206e6f742065786973740000000060448201526064016109e6565b50506000908152600d602052604090205490565b6000818152600a60205260408120546001600160a01b03168061183b5760405162461bcd60e51b815260206004820152602660248201527f4e46543a206f776e657220717565727920666f72206e6f6e6578697374656e74604482015265103a37b5b2b760d11b60648201526084016109e6565b92915050565b6000818152600a6020526040812054819081906001600160a01b0316806118b95760405162461bcd60e51b815260206004820152602660248201527f4e46543a206f776e657220717565727920666f72206e6f6e6578697374656e74604482015265103a37b5b2b760d11b60648201526084016109e6565b5050506000918252506006602052604090206001810154815460029092015490926001600160a01b0390921691565b6000546001600160a01b031633146119425760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109e6565b81600e5481106119945760405162461bcd60e51b815260206004820152601c60248201527f5175657269656420636c61737320646f6573206e6f742065786973740000000060448201526064016109e6565b6000838152600c60209081526040822080546001810182559083529120016119bc83826131ee565b506000838152600c60205260408120546119d8906001906132eb565b60408051868152602081018390529192507f949a1ec513916b5e46ab2c5681369a4651bba074831b8da896b06a94e8d041b69101610eae565b60006001600160a01b038216611a8f5760405162461bcd60e51b815260206004820152602760248201527f4e46543a2062616c616e636520717565727920666f7220746865207a65726f2060448201527f616464726573730000000000000000000000000000000000000000000000000060648201526084016109e6565b506001600160a01b03166000908152600b602052604090205490565b8282826002805403611aff5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109e6565b60028055600080611b0f88611841565b5091509150813411611b885760405162461bcd60e51b8152602060048201526024808201527f4e657720626964206d7573742065786365656420746865206578697374696e6760448201527f206f6e650000000000000000000000000000000000000000000000000000000060648201526084016109e6565b6000808315611bb8576040516001600160a01b0384169085156108fc029086906000818181858888f19450505050505b34611bc28b6120e2565b108015611bd757506000611bd58b6120e2565b115b15611bec57611be58a6120e2565b9150611bf0565b3491505b60008a815260066020526040908190206001810184905580546001600160a01b03191633178155426002909101555182908b907f223d0d5db4846341da7a5cc902b1a7c597e63b6c73b1c6267dc931d290c7affb90611c52908d908d906132d7565b60405180910390a334611c648b6120e2565b108015611c7957506000611c778b6120e2565b115b15611cae57336108fc611c8b8c6120e2565b611c9590346132eb565b6040518115909202916000818181858888f19450505050505b50506001600255506000905080611cc485611841565b50915091506000611cd4866120e2565b118015611ce9575081611ce6866120e2565b11155b15611dbb57611cf7856117c7565b6001600160a01b0316816001600160a01b0316867fc9b9afd9684b23c6b22a41016c08e8954ac118220c0a52f00b8774c46580e9a385604051611d3c91815260200190565b60405180910390a46000611d4f866117c7565b6001600160a01b03166108fc849081150290604051600060405180830381858888f160008b815260066020908152604080832080546001600160a01b031916815560018101849055600201839055600590915281205594506111d093506111c592508991506117c79050565b5050505050505050565b600082815260036020526040902080546060919083908110611de957611de961306c565b906000526020600020018054611dfe90613082565b80601f0160208091040260200160405190810160405280929190818152602001828054611e2a90613082565b8015611e775780601f10611e4c57610100808354040283529160200191611e77565b820191906000526020600020905b815481529060010190602001808311611e5a57829003601f168201915b5050505050905092915050565b6000546001600160a01b03163314611ede5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109e6565b600e546000908152600c6020908152604082208054600181018255908352912001611f0982826131ee565b50600e5460408051918252600060208301527f949a1ec513916b5e46ab2c5681369a4651bba074831b8da896b06a94e8d041b6910160405180910390a1600e8054906000611f56836132fe565b919050555050565b6000546001600160a01b03163314611fb85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109e6565b80600e54811061200a5760405162461bcd60e51b815260206004820152601c60248201527f5175657269656420636c61737320646f6573206e6f742065786973740000000060448201526064016109e6565b6000828152600c602090815260408083208054600181018255908452828420825193840190925292825290910190610c8490826131ee565b60606009805461091490613082565b6000828152600d6020526040902054600e546060919081106120b55760405162461bcd60e51b815260206004820152601c60248201527f5175657269656420636c61737320646f6573206e6f742065786973740000000060448201526064016109e6565b6000848152600d60209081526040808320548352600c909152902080548490811061150a5761150a61306c565b6000818152600a60205260408120546001600160a01b0316806121565760405162461bcd60e51b815260206004820152602660248201527f4e46543a206f776e657220717565727920666f72206e6f6e6578697374656e74604482015265103a37b5b2b760d11b60648201526084016109e6565b505060009081526005602052604090205490565b6000612179338686868661273e565b7f3ba9136826ac751de05d770d8d34fa4440ada49a5fb0e9aa1678aece66dad97683836040516121aa9291906132d7565b60405180910390a1506001949350505050565b6000546001600160a01b031633146122175760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109e6565b60005b82811015610c84576000828152600c60209081526040808320805460018101825590845282842082519384019092529282529091019061225a90826131ee565b5080612265816132fe565b91505061221a565b600033612279836117c7565b6001600160a01b0316146122de5760405162461bcd60e51b815260206004820152602660248201527f4e46543a207472616e73666572206f6620746f6b656e2074686174206973206e60448201526537ba1037bbb760d11b60648201526084016109e6565b6001600160a01b03831661233e5760405162461bcd60e51b815260206004820152602160248201527f4e46543a207472616e7366657220746f20746865207a65726f206164647265736044820152607360f81b60648201526084016109e6565b600082815260056020526040812055336000908152600b6020526040812080546001929061236d9084906132eb565b90915550506001600160a01b0383166000908152600b6020526040812080546001929061239b9084906130cc565b90915550506000828152600a602052604080822080546001600160a01b0319166001600160a01b0387169081179091559051849233917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9190a450600192915050565b6000546001600160a01b031633146124585760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109e6565b6001600160a01b03919091166000908152600160205260409020805460ff1916911515919091179055565b606081600e5481106124d75760405162461bcd60e51b815260206004820152601c60248201527f5175657269656420636c61737320646f6573206e6f742065786973740000000060448201526064016109e6565b6000838152600c6020908152604080832080548251818502810185019093528083529193909284015b8282101561148957838290600052602060002001805461251f90613082565b80601f016020809104026020016040519081016040528092919081815260200182805461254b90613082565b80156125985780601f1061256d57610100808354040283529160200191612598565b820191906000526020600020905b81548152906001019060200180831161257b57829003601f168201915b505050505081526020019060010190612500565b6000546001600160a01b031633146126065760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109e6565b6001600160a01b0381166126825760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016109e6565b61268b8161298b565b50565b6000838152600360209081526040822080546001810182559083529120016126b782848361312d565b506000838152600360205260408120546126d3906001906132eb565b60408051868152602081018390529192507f0fe79316286f6a1e5cf32c3c4ff10c2a66b9cd66da3353db3789c4042ffb44ee9101610eae565b600061271a336007546129db565b5060078054908190600061272d836132fe565b919050555061273b816129e9565b90565b846001600160a01b0316612751846117c7565b6001600160a01b0316146127b65760405162461bcd60e51b815260206004820152602660248201527f4e46543a207472616e73666572206f6620746f6b656e2074686174206973206e60448201526537ba1037bbb760d11b60648201526084016109e6565b6001600160a01b0384166128165760405162461bcd60e51b815260206004820152602160248201527f4e46543a207472616e7366657220746f20746865207a65726f206164647265736044820152607360f81b60648201526084016109e6565b6000838152600560205260408120556001600160a01b0385166000908152600b6020526040812080546001929061284e9084906132eb565b90915550506001600160a01b0384166000908152600b6020526040812080546001929061287c9084906130cc565b90915550506000838152600a6020526040902080546001600160a01b0319166001600160a01b0386169081179091553b15612943576040517f150b7a020000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063150b7a02906128fe9033908990889088908890600401613317565b6020604051808303816000875af115801561291d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129419190613355565b505b82846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6129e58282612a36565b5050565b600081815260036020526040812054900361268b57600081815260036020908152604080832080546001810182559084528284208251938401909252928252909101906129e590826131ee565b6001600160a01b038216612a8c5760405162461bcd60e51b815260206004820152601d60248201527f4e46543a206d696e7420746f20746865207a65726f206164647265737300000060448201526064016109e6565b6000818152600a60205260409020546001600160a01b031615612af15760405162461bcd60e51b815260206004820152601960248201527f4e46543a20746f6b656e20616c7265616479206d696e7465640000000000000060448201526064016109e6565b6001600160a01b0382166000908152600b60205260408120805460019290612b1a9084906130cc565b90915550506000818152600a602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600060208284031215612b8a57600080fd5b5035919050565b6000815180845260005b81811015612bb757602081850181015186830182015201612b9b565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000612bea6020830184612b91565b9392505050565b60008060408385031215612c0457600080fd5b50508035926020909101359150565b60008083601f840112612c2557600080fd5b50813567ffffffffffffffff811115612c3d57600080fd5b602083019150836020828501011115612c5557600080fd5b9250929050565b600080600060408486031215612c7157600080fd5b83359250602084013567ffffffffffffffff811115612c8f57600080fd5b612c9b86828701612c13565b9497909650939450505050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112612ccf57600080fd5b813567ffffffffffffffff80821115612cea57612cea612ca8565b604051601f8301601f19908116603f01168101908282118183101715612d1257612d12612ca8565b81604052838152866020858801011115612d2b57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600060608486031215612d6057600080fd5b8335925060208401359150604084013567ffffffffffffffff811115612d8557600080fd5b612d9186828701612cbe565b9150509250925092565b60008060008060608587031215612db157600080fd5b8435935060208501359250604085013567ffffffffffffffff811115612dd657600080fd5b612de287828801612c13565b95989497509550505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015612e4357603f19888603018452612e31858351612b91565b94509285019290850190600101612e15565b5092979650505050505050565b60008060408385031215612e6357600080fd5b823567ffffffffffffffff80821115612e7b57600080fd5b612e8786838701612cbe565b93506020850135915080821115612e9d57600080fd5b50612eaa85828601612cbe565b9150509250929050565b60006020808352604083018451828386015281815180845260608701915060608160051b8801019350848301925060005b81811015612e4357605f19888603018352612f01858551612b91565b94509285019291850191600101612ee5565b80356001600160a01b0381168114612f2a57600080fd5b919050565b600060208284031215612f4157600080fd5b612bea82612f13565b60008060408385031215612f5d57600080fd5b82359150602083013567ffffffffffffffff811115612f7b57600080fd5b612eaa85828601612cbe565b600060208284031215612f9957600080fd5b813567ffffffffffffffff811115612fb057600080fd5b612fbc84828501612cbe565b949350505050565b60008060008060608587031215612fda57600080fd5b612fe385612f13565b935060208501359250604085013567ffffffffffffffff811115612dd657600080fd5b6000806040838503121561301957600080fd5b61302283612f13565b946020939093013593505050565b6000806040838503121561304357600080fd5b61304c83612f13565b91506020830135801515811461306157600080fd5b809150509250929050565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168061309657607f821691505b60208210810361149057634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8082018082111561183b5761183b6130b6565b601f821115610c8457600081815260208120601f850160051c810160208610156131065750805b601f850160051c820191505b8181101561312557828155600101613112565b505050505050565b67ffffffffffffffff83111561314557613145612ca8565b613159836131538354613082565b836130df565b6000601f84116001811461318d57600085156131755750838201355b600019600387901b1c1916600186901b1783556131e7565b600083815260209020601f19861690835b828110156131be578685013582556020948501946001909201910161319e565b50868210156131db5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b815167ffffffffffffffff81111561320857613208612ca8565b61321c816132168454613082565b846130df565b602080601f83116001811461325157600084156132395750858301515b600019600386901b1c1916600185901b178555613125565b600085815260208120601f198616915b8281101561328057888601518255948401946001909101908401613261565b508582101561329e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b602081526000612fbc6020830184866132ae565b8181038181111561183b5761183b6130b6565b600060018201613310576133106130b6565b5060010190565b60006001600160a01b0380881683528087166020840152508460408301526080606083015261334a6080830184866132ae565b979650505050505050565b60006020828403121561336757600080fd5b81517fffffffff0000000000000000000000000000000000000000000000000000000081168114612bea57600080fdfea2646970667358221220846e8e6cb4223109184e5ecc18ae8f0bf522ec83373e2c14d3f93afb259e735d64736f6c63430008130033