S Price: $0.067526 (+2.60%)
Gas: 55 Gwei

Contract

0xd261C63A53b7F7cD13963a0fe6BDF73Fcbb24D12

Overview

S Balance

Sonic LogoSonic LogoSonic Logo28.816 S

S Value

$1.95 (@ $0.07/S)

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To
Claim4Mana586805502025-12-23 11:22:1934 days ago1766488939IN
0xd261C63A...Fcbb24D12
0 S0.0028233660
Claim100Mana586805462025-12-23 11:22:1334 days ago1766488933IN
0xd261C63A...Fcbb24D12
0 S0.0028207260
Claim4Mana586805372025-12-23 11:22:0334 days ago1766488923IN
0xd261C63A...Fcbb24D12
0 S0.0028233660
Claim100Mana586805292025-12-23 11:21:5634 days ago1766488916IN
0xd261C63A...Fcbb24D12
0 S0.0026634656.655
Claim4Mana586805202025-12-23 11:21:4334 days ago1766488903IN
0xd261C63A...Fcbb24D12
0 S0.002643656.18
Claim100Mana586805132025-12-23 11:21:3434 days ago1766488894IN
0xd261C63A...Fcbb24D12
0 S0.0025856655
Claim4Mana586803722025-12-23 11:19:4634 days ago1766488786IN
0xd261C63A...Fcbb24D12
0 S0.0025880855
Claim100Mana586803652025-12-23 11:19:3834 days ago1766488778IN
0xd261C63A...Fcbb24D12
0 S0.0025856655
Claim4Mana583390282025-12-19 11:32:2238 days ago1766143942IN
0xd261C63A...Fcbb24D12
0 S0.0028238360.01
Claim100Mana583390202025-12-19 11:32:1338 days ago1766143933IN
0xd261C63A...Fcbb24D12
0 S0.0028211960.01
Claim4Mana583390102025-12-19 11:32:0538 days ago1766143925IN
0xd261C63A...Fcbb24D12
0 S0.0028238360.01
Claim100Mana583390062025-12-19 11:32:0038 days ago1766143920IN
0xd261C63A...Fcbb24D12
0 S0.0028211960.01
Claim4Mana583390012025-12-19 11:31:5238 days ago1766143912IN
0xd261C63A...Fcbb24D12
0 S0.0028238360.01
Claim100Mana583389932025-12-19 11:31:4638 days ago1766143906IN
0xd261C63A...Fcbb24D12
0 S0.0028207260
Claim4Mana583389702025-12-19 11:31:3238 days ago1766143892IN
0xd261C63A...Fcbb24D12
0 S0.0028233660
Claim100Mana583389602025-12-19 11:31:2738 days ago1766143887IN
0xd261C63A...Fcbb24D12
0 S0.0031027966
Claim4Mana582418352025-12-18 10:19:2939 days ago1766053169IN
0xd261C63A...Fcbb24D12
0 S0.0028468860.5
Claim100Mana582418252025-12-18 10:19:2339 days ago1766053163IN
0xd261C63A...Fcbb24D12
0 S0.0028442260.5
Claim4Mana582418132025-12-18 10:19:1539 days ago1766053155IN
0xd261C63A...Fcbb24D12
0 S0.0028468860.5
Claim100Mana582418002025-12-18 10:19:0839 days ago1766053148IN
0xd261C63A...Fcbb24D12
0 S0.0028442260.5
Claim4Mana582417882025-12-18 10:18:5939 days ago1766053139IN
0xd261C63A...Fcbb24D12
0 S0.0028468860.5
Claim100Mana582417832025-12-18 10:18:5439 days ago1766053134IN
0xd261C63A...Fcbb24D12
0 S0.0028442260.5
Claim4Mana582417672025-12-18 10:18:3839 days ago1766053118IN
0xd261C63A...Fcbb24D12
0 S0.0028468860.5
Claim100Mana582417572025-12-18 10:18:3139 days ago1766053111IN
0xd261C63A...Fcbb24D12
0 S0.0028442260.5
Claim4Mana581012872025-12-16 20:28:0941 days ago1765916889IN
0xd261C63A...Fcbb24D12
0 S0.0028233660
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
MANA

Compiler Version
v0.8.30+commit.73712a01

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";

interface ICharacters {
    struct Character {
        uint256 race;
        uint256 bodyId;
        uint256 classType;
        uint256 location;
        string name;
        uint256 seed;
        address minter;
    }
    
    function getCharacter(uint256 tokenId) external view returns (Character memory);
    function ownerOf(uint256 tokenId) external view returns (address);
}

contract MANA is Ownable {
    ICharacters public constant CHARACTERS = ICharacters(0x664EB769b64e5cBd41e2A832A4A4e65bfd2d22f0);
    
    // MANA tracking per token ID
    mapping(uint256 => uint256) public tokenIdToMana;

    
    // Claim tracking
    mapping(uint256 => uint256) public last100ManaClaim;
    mapping(uint256 => uint256) public last4ManaClaim;
    mapping(uint256 => bool) public hasClaimedOneTimeBonus;
    
    // Simplified token registry
    uint256[] public allTokenIds;
    mapping(uint256 => bool) public isTokenRegistered;
    
     // Chat functionality
    struct ChatMessage {
        uint256 tokenId;
        string message;
        uint256 timestamp;
        uint256 likes;
    }
    
    struct MessageLikes {
        mapping(uint256 => bool) likedBy; // Track which tokenIds have liked this message
    }
    
    ChatMessage[] public chatHistory;
    mapping(uint256 => MessageLikes) internal messageLikes; // Separate mapping for likes tracking

    uint256 public constant MAX_CHAT_HISTORY = 100;
    uint256 public constant MANA_PER_ETH_GAS = 10000; // Increased from 1000
    uint256 public constant LIKE_REWARD_WRITER = 10;
    uint256 public constant LIKE_REWARD_LIKER = 1;
    uint256 public constant MESSAGE_COST = 0.001 ether;
    uint256 public constant LIKE_COST = 0.1 ether;
    
    // Events
    event MANAClaimed(address indexed user, uint256 indexed tokenId, uint256 amount, uint256 timestamp);
    event MANADistributed(address indexed user, uint256 amount, uint256 timestamp);
    event OneTimeBonusClaimed(address indexed user, uint256 indexed tokenId, uint256 amount, uint256 timestamp);
    event RankingUpdated(uint256 indexed tokenId, uint256 newMana, uint256 timestamp);
    event TokenRegistered(uint256 indexed tokenId, address owner, uint256 timestamp);
    event MessageSent(uint256 indexed tokenId, string message, uint256 timestamp, uint256 messageIndex, uint256 manaReward);
    event MessageLiked(uint256 indexed messageIndex, uint256 indexed likedByTokenId, uint256 indexed writerTokenId, uint256 writerReward, uint256 likerReward);
    
    // Constants
    uint256 public constant CLAIM_100_COOLDOWN = 24 hours;
    uint256 public constant CLAIM_4_COOLDOWN = 1 hours;
    uint256 public constant CLAIM_100_AMOUNT = 100;
    uint256 public constant CLAIM_4_AMOUNT = 4;
    uint256 public constant ONE_TIME_BONUS = 1000;
    
    constructor() Ownable(msg.sender) {}
    
    /**
     * @dev Internal function to register a token and set its MANA
     */
    function _registerOrUpdateToken(uint256 tokenId, uint256 newMana) internal {
        tokenIdToMana[tokenId] = newMana;
    
        
        if (!isTokenRegistered[tokenId]) {
            allTokenIds.push(tokenId);
            isTokenRegistered[tokenId] = true;
            emit TokenRegistered(tokenId, msg.sender, block.timestamp);
        }
        
        emit RankingUpdated(tokenId, newMana, block.timestamp);
    }
    
    /**
     * @dev Send a chat message - costs 0.01 ETH and gives MANA reward based on gas used + bonus
     * @param tokenId The Character NFT token ID sending the message
     * @param message The chat message content
     */
    function sendMessage(uint256 tokenId, string calldata message) external payable {
        require(CHARACTERS.ownerOf(tokenId) == msg.sender, "Not token owner");
        require(bytes(message).length > 0, "Message cannot be empty");
        require(msg.value == MESSAGE_COST, "Incorrect message cost");
        
        // Calculate MANA reward based on gas (simplified - in practice you'd need more complex gas tracking)
        uint256 gasUsed = gasleft();
        
        // Add message to chat history
        _addMessage(tokenId, message);
        
        // Calculate actual gas used for this function
        gasUsed = gasUsed - gasleft();
        uint256 manaReward = 1 + (gasUsed * MANA_PER_ETH_GAS) / 1e9; // Simplified conversion
        
        if (manaReward > 0) {
            uint256 newMana = tokenIdToMana[tokenId] + manaReward;
            _registerOrUpdateToken(tokenId, newMana);
        }
        
        emit MANAClaimed(msg.sender, tokenId, manaReward, block.timestamp);
        emit MessageSent(tokenId, message, block.timestamp, chatHistory.length - 1, manaReward);
    }
    
    /**
     * @dev Internal function to add message to chat history
     */
    function _addMessage(uint256 tokenId, string calldata message) internal {
        // Create new message
        ChatMessage memory newMessage = ChatMessage({
            tokenId: tokenId,
            message: message,
            timestamp: block.timestamp,
            likes: 0
        });
        
        // If we're at max capacity, remove the oldest message
        if (chatHistory.length >= MAX_CHAT_HISTORY) {
            // Remove the first element by shifting all elements left
            for (uint256 i = 0; i < chatHistory.length - 1; i++) {
                chatHistory[i] = chatHistory[i + 1];
            }
            chatHistory.pop();
        }
        
        // Add new message to the end
        chatHistory.push(newMessage);
    }
    
    /**
     * @dev Like a message - gives MANA to both writer and liker
     * @param messageIndex Index of the message in chatHistory array
     * @param likerTokenId Token ID of the character liking the message
     */
    function likeMessage(uint256 messageIndex, uint256 likerTokenId) external payable {
        require(CHARACTERS.ownerOf(likerTokenId) == msg.sender, "Not token owner");
        require(messageIndex < chatHistory.length, "Invalid message index");
        require(msg.value == LIKE_COST, "Incorrect like cost");
        
        ChatMessage storage message = chatHistory[messageIndex];
        require(message.tokenId != likerTokenId, "Cannot like own message");
        require(!messageLikes[messageIndex].likedBy[likerTokenId], "Already liked this message");
        
        // Mark as liked
        messageLikes[messageIndex].likedBy[likerTokenId] = true;
        message.likes++;
        
        // Reward message writer
        uint256 writerMana = tokenIdToMana[message.tokenId] + LIKE_REWARD_WRITER;
        _registerOrUpdateToken(message.tokenId, writerMana);
        
        // Reward liker
        uint256 likerMana = tokenIdToMana[likerTokenId] + LIKE_REWARD_LIKER;
        _registerOrUpdateToken(likerTokenId, likerMana);
        
        emit MessageLiked(messageIndex, likerTokenId, message.tokenId, LIKE_REWARD_WRITER, LIKE_REWARD_LIKER);
        emit MANAClaimed(msg.sender, message.tokenId, LIKE_REWARD_WRITER, block.timestamp);
        emit MANAClaimed(msg.sender, likerTokenId, LIKE_REWARD_LIKER, block.timestamp);
    }
    
    /**
     * @dev Get chat history with user names
     * @return tokenIds Array of token IDs who sent messages
     * @return names Array of character names
     * @return messages Array of message content
     * @return timestamps Array of message timestamps
     * @return likesArray Array of like counts for each message
     */
    function getChatHistory() external view returns (
        uint256[] memory tokenIds,
        string[] memory names,
        string[] memory messages,
        uint256[] memory timestamps,
        uint256[] memory likesArray
    ) {
        uint256 historyLength = chatHistory.length;
        
        tokenIds = new uint256[](historyLength);
        names = new string[](historyLength);
        messages = new string[](historyLength);
        timestamps = new uint256[](historyLength);
        likesArray = new uint256[](historyLength);
        
        for (uint256 i = 0; i < historyLength; i++) {
            ChatMessage memory message = chatHistory[i];
            tokenIds[i] = message.tokenId;
            
            // Get character name
            ICharacters.Character memory character = CHARACTERS.getCharacter(message.tokenId);
            names[i] = character.name;
            
            messages[i] = message.message;
            timestamps[i] = message.timestamp;
            likesArray[i] = message.likes;
        }
    }
    
    /**
     * @dev Check if a token has liked a specific message
     * @param messageIndex Index of the message
     * @param tokenId Token ID to check
     * @return True if the token has liked the message
     */
    function hasLikedMessage(uint256 messageIndex, uint256 tokenId) external view returns (bool) {
        require(messageIndex < chatHistory.length, "Invalid message index");
        return messageLikes[messageIndex].likedBy[tokenId];
    }

    /**
    * @dev Get like count for a specific message
    * @param messageIndex Index of the message
    * @return Number of likes for the message
    */
    function getMessageLikes(uint256 messageIndex) external view returns (uint256) {
        require(messageIndex < chatHistory.length, "Invalid message index");
        return chatHistory[messageIndex].likes;
    }
    
    /**
     * @dev Get recent chat messages (last N messages)
     * @param count Number of recent messages to return
     */
    function getRecentMessages(uint256 count) external view returns (
        uint256[] memory tokenIds,
        string[] memory names,
        string[] memory messages,
        uint256[] memory timestamps,
        uint256[] memory likesArray
    ) {
        uint256 historyLength = chatHistory.length;
        if (count > historyLength) {
            count = historyLength;
        }
        
        tokenIds = new uint256[](count);
        names = new string[](count);
        messages = new string[](count);
        timestamps = new uint256[](count);
        likesArray = new uint256[](count);
        
        uint256 startIndex = historyLength - count;
        
        for (uint256 i = 0; i < count; i++) {
            uint256 messageIndex = startIndex + i;
            ChatMessage memory message = chatHistory[messageIndex];
            tokenIds[i] = message.tokenId;
            
            ICharacters.Character memory character = CHARACTERS.getCharacter(message.tokenId);
            names[i] = character.name;
            
            messages[i] = message.message;
            timestamps[i] = message.timestamp;
            likesArray[i] = message.likes;
        }
    }

     /**
     * @dev Get total chat stats
     * @return totalMessages Total number of messages ever sent
     * @return currentMessages Current number of messages in history
     * @return totalLikes Total likes across all current messages
     */
    function getChatStats() external view returns (
        uint256 totalMessages,
        uint256 currentMessages,
        uint256 totalLikes
    ) {
        currentMessages = chatHistory.length;
        totalLikes = 0;
        
        for (uint256 i = 0; i < currentMessages; i++) {
            totalLikes += chatHistory[i].likes;
        }
        
        // Note: totalMessages would require additional storage to track all-time count
        totalMessages = currentMessages; // This is just current for now
    }
    
    /**
     * @dev Claim 100 MANA with 24-hour cooldown
     * @param tokenId The Character NFT token ID
     */
    function claim100Mana(uint256 tokenId) external {
        require(CHARACTERS.ownerOf(tokenId) == msg.sender, "Not token owner");
        require(block.timestamp >= last100ManaClaim[tokenId] + CLAIM_100_COOLDOWN, "Cooldown active");
        
        last100ManaClaim[tokenId] = block.timestamp;
        
        uint256 newMana = tokenIdToMana[tokenId] + CLAIM_100_AMOUNT;
        _registerOrUpdateToken(tokenId, newMana);
        
        emit MANAClaimed(msg.sender, tokenId, CLAIM_100_AMOUNT, block.timestamp);
    }
    
    /**
     * @dev Claim 4 MANA with 1-hour cooldown
     * @param tokenId The Character NFT token ID
     */
    function claim4Mana(uint256 tokenId) external {
        require(CHARACTERS.ownerOf(tokenId) == msg.sender, "Not token owner");
        require(block.timestamp >= last4ManaClaim[tokenId] + CLAIM_4_COOLDOWN, "Cooldown active");
        
        last4ManaClaim[tokenId] = block.timestamp;
        
        uint256 newMana = tokenIdToMana[tokenId] + CLAIM_4_AMOUNT;
        _registerOrUpdateToken(tokenId, newMana);
        
        emit MANAClaimed(msg.sender, tokenId, CLAIM_4_AMOUNT, block.timestamp);
    }
    
    /**
     * @dev Claim one-time 1000 MANA bonus (incentivizes minting/buying)
     * @param tokenId The Character NFT token ID
     */
    function claimOneTimeBonus(uint256 tokenId) external {
        require(CHARACTERS.ownerOf(tokenId) == msg.sender, "Not token owner");
        require(!hasClaimedOneTimeBonus[tokenId], "Bonus already claimed");
        
        hasClaimedOneTimeBonus[tokenId] = true;
        
        uint256 newMana = tokenIdToMana[tokenId] + ONE_TIME_BONUS;
        _registerOrUpdateToken(tokenId, newMana);
        
        emit OneTimeBonusClaimed(msg.sender, tokenId, ONE_TIME_BONUS, block.timestamp);
    }
    
    /**
     * @dev Owner function to distribute MANA to multiple tokens
     * @param tokenIds Array of token IDs to receive MANA
     * @param amounts Array of MANA amounts to distribute
     */
    function distributeMANA(uint256[] calldata tokenIds, uint256[] calldata amounts) external onlyOwner {
        require(tokenIds.length == amounts.length, "Arrays length mismatch");
        
        for (uint256 i = 0; i < tokenIds.length; i++) {
            uint256 tokenId = tokenIds[i];
            require(CHARACTERS.ownerOf(tokenId) != address(0), "Invalid token ID");
            
            address tokenOwner = CHARACTERS.ownerOf(tokenId);
            uint256 newMana = tokenIdToMana[tokenId] + amounts[i];
            _registerOrUpdateToken(tokenId, newMana);
            
            emit MANADistributed(tokenOwner, amounts[i], block.timestamp);
        }
    }
    
    /**
     * @dev Get ranked leaderboard with sorting in view function
     * @param startIndex Starting index (0-based)
     * @param count Number of entries to return
     * @return tokenIds Array of token IDs in rank order
     * @return charactersData Array of Character structs
     * @return manaAmounts Array of MANA amounts
     * @return ranks Array of current ranks (1-based)
     */
    function getRankedLeaderboard(uint256 startIndex, uint256 count) 
        public 
        view 
        returns (
            uint256[] memory tokenIds,
            ICharacters.Character[] memory charactersData,
            uint256[] memory manaAmounts,
            uint256[] memory ranks
        ) 
    {
        uint256 totalTokens = allTokenIds.length;
        if (totalTokens == 0) {
            return (new uint256[](0), new ICharacters.Character[](0), new uint256[](0), new uint256[](0));
        }
        
        require(startIndex < totalTokens, "Start index out of bounds");
        
        uint256 endIndex = startIndex + count;
        if (endIndex > totalTokens) {
            endIndex = totalTokens;
        }
        uint256 resultCount = endIndex - startIndex;
        
        // Create arrays for sorting
        uint256[] memory sortedTokenIds = new uint256[](totalTokens);
        uint256[] memory sortedMana = new uint256[](totalTokens);
        
        // Copy data to memory arrays
        for (uint256 i = 0; i < totalTokens; i++) {
            sortedTokenIds[i] = allTokenIds[i];
            sortedMana[i] = tokenIdToMana[allTokenIds[i]];
        }
        
        // Sort by MANA (descending)
        _quickSort(sortedTokenIds, sortedMana, 0, int256(totalTokens - 1));
        
        // Prepare results
        tokenIds = new uint256[](resultCount);
        charactersData = new ICharacters.Character[](resultCount);
        manaAmounts = new uint256[](resultCount);
        ranks = new uint256[](resultCount);
        
        for (uint256 i = 0; i < resultCount; i++) {
            uint256 rankIndex = startIndex + i;
            tokenIds[i] = sortedTokenIds[rankIndex];
            charactersData[i] = CHARACTERS.getCharacter(sortedTokenIds[rankIndex]);
            manaAmounts[i] = sortedMana[rankIndex];
            ranks[i] = rankIndex + 1; // 1-based ranking
        }
    }
    
    /**
     * @dev QuickSort implementation for efficient sorting
     */
    function _quickSort(
        uint256[] memory tokenIds,
        uint256[] memory manaAmounts,
        int256 left,
        int256 right
    ) internal pure {
        if (left >= right) return;
        
        int256 i = left;
        int256 j = right;
        uint256 pivot = manaAmounts[uint256(left + (right - left) / 2)];
        
        while (i <= j) {
            while (manaAmounts[uint256(i)] > pivot) i++; // Descending order
            while (pivot > manaAmounts[uint256(j)]) j--;
            if (i <= j) {
                (tokenIds[uint256(i)], tokenIds[uint256(j)]) = (tokenIds[uint256(j)], tokenIds[uint256(i)]);
                (manaAmounts[uint256(i)], manaAmounts[uint256(j)]) = (manaAmounts[uint256(j)], manaAmounts[uint256(i)]);
                i++;
                j--;
            }
        }
        
        if (left < j) _quickSort(tokenIds, manaAmounts, left, j);
        if (i < right) _quickSort(tokenIds, manaAmounts, i, right);
    }
    
    /**
     * @dev Alternative: Get sorted leaderboard with pagination
     */
    function getRankedLeaderboardPaginated(uint256 page, uint256 pageSize) 
        external 
        view 
        returns (
            uint256[] memory tokenIds,
            ICharacters.Character[] memory charactersData,
            uint256[] memory manaAmounts,
            uint256[] memory ranks
        )
    {
        uint256 startIndex = page * pageSize;
        return getRankedLeaderboard(startIndex, pageSize);
    }
    
    /**
     * @dev Get rank for a specific token (requires counting higher MANA tokens)
     */
    function getRank(uint256 tokenId) public view returns (uint256 rank, uint256 manaAmount) {
        if (!isTokenRegistered[tokenId]) return (0, 0);
        
        manaAmount = tokenIdToMana[tokenId];
        uint256 totalTokens = allTokenIds.length;
        
        // Count how many tokens have higher or equal MANA (for tie handling)
        uint256 higherCount = 0;
        for (uint256 i = 0; i < totalTokens; i++) {
            if (tokenIdToMana[allTokenIds[i]] > manaAmount) {
                higherCount++;
            }
        }
        
        return (higherCount + 1, manaAmount); // 1-based ranking
    }
    
    /**
     * @dev Get top N ranked entries
     * @param n Number of top entries to return
     */
    function getTopN(uint256 n) external view returns (
        uint256[] memory tokenIds,
        ICharacters.Character[] memory charactersData,
        uint256[] memory manaAmounts
    ) {
        (tokenIds, charactersData, manaAmounts, ) = getRankedLeaderboard(0, n);
        return (tokenIds, charactersData, manaAmounts);
    }
    
    /**
     * @dev Get total number of registered tokens
     */
    function getRegisteredCount() external view returns (uint256) {
        return allTokenIds.length;
    }
    
    /**
     * @dev Get claim status for a token ID
     */
    function getClaimStatus(uint256 tokenId) external view returns (
        bool canClaim100,
        uint256 next100Claim,
        bool canClaim4,
        uint256 next4Claim,
        bool canClaimBonus
    ) {
        canClaim100 = block.timestamp >= last100ManaClaim[tokenId] + CLAIM_100_COOLDOWN;
        next100Claim = last100ManaClaim[tokenId] + CLAIM_100_COOLDOWN;
        
        canClaim4 = block.timestamp >= last4ManaClaim[tokenId] + CLAIM_4_COOLDOWN;
        next4Claim = last4ManaClaim[tokenId] + CLAIM_4_COOLDOWN;
        
        canClaimBonus = !hasClaimedOneTimeBonus[tokenId];
    }
    
    /**
     * @dev Get MANA balance for a specific token ID
     */
    function manaOf(uint256 tokenId) external view returns (uint256) {
        return tokenIdToMana[tokenId];
    }
    
    /**
     * @dev Get total MANA balance of an address (sum of all owned tokens)
     */
    function balanceOf(address user) external view returns (uint256 totalMana) {
        uint256 totalTokens = allTokenIds.length;
        for (uint256 i = 0; i < totalTokens; i++) {
            uint256 tokenId = allTokenIds[i];
            if (CHARACTERS.ownerOf(tokenId) == user) {
                totalMana += tokenIdToMana[tokenId];
            }
        }
    }
    
    /**
     * @dev Get all token IDs owned by an address with their MANA amounts
     */
    function getTokensByOwner(address user) external view returns (uint256[] memory tokenIds, uint256[] memory manaAmounts) {
        uint256 totalTokens = allTokenIds.length;
        uint256 count = 0;
        
        // First pass: count owned tokens
        for (uint256 i = 0; i < totalTokens; i++) {
            uint256 tokenId = allTokenIds[i];
            if (CHARACTERS.ownerOf(tokenId) == user) {
                count++;
            }
        }
        
        // Second pass: populate arrays
        tokenIds = new uint256[](count);
        manaAmounts = new uint256[](count);
        uint256 index = 0;
        
        for (uint256 i = 0; i < totalTokens; i++) {
            uint256 tokenId = allTokenIds[i];
            if (CHARACTERS.ownerOf(tokenId) == user) {
                tokenIds[index] = tokenId;
                manaAmounts[index] = tokenIdToMana[tokenId];
                index++;
            }
        }
    }
    
    /**
     * @dev Withdraw contract balance (for message and like fees)
     */
    function withdraw() external onlyOwner {
        uint256 balance = address(this).balance;
        require(balance > 0, "No funds to withdraw");
        payable(owner()).transfer(balance);
    }
    
    /**
     * @dev Get contract ETH balance
     */
    function getContractBalance() external view returns (uint256) {
        return address(this).balance;
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.20;

import {IERC165} from "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC-721 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 ERC-721 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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC-721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * 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 address zero.
     *
     * 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 v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;

import {Context} from "../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.
 *
 * The initial owner is set to the address provided by the deployer. 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;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @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 {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling 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 {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _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 v5.1.0) (utils/introspection/IERC165.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC-165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[ERC].
 *
 * 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[ERC 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);
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

/**
 * @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;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

Settings
{
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "remappings": []
}

Contract Security Audit

Contract ABI

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"MANAClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"MANADistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"messageIndex","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"likedByTokenId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"writerTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"writerReward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"likerReward","type":"uint256"}],"name":"MessageLiked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"string","name":"message","type":"string"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"messageIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"manaReward","type":"uint256"}],"name":"MessageSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"OneTimeBonusClaimed","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":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMana","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"RankingUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"TokenRegistered","type":"event"},{"inputs":[],"name":"CHARACTERS","outputs":[{"internalType":"contract ICharacters","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CLAIM_100_AMOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CLAIM_100_COOLDOWN","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CLAIM_4_AMOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CLAIM_4_COOLDOWN","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LIKE_COST","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LIKE_REWARD_LIKER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LIKE_REWARD_WRITER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANA_PER_ETH_GAS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_CHAT_HISTORY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MESSAGE_COST","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ONE_TIME_BONUS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allTokenIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"totalMana","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"chatHistory","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"message","type":"string"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"likes","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"claim100Mana","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"claim4Mana","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"claimOneTimeBonus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"distributeMANA","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getChatHistory","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"string[]","name":"names","type":"string[]"},{"internalType":"string[]","name":"messages","type":"string[]"},{"internalType":"uint256[]","name":"timestamps","type":"uint256[]"},{"internalType":"uint256[]","name":"likesArray","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getChatStats","outputs":[{"internalType":"uint256","name":"totalMessages","type":"uint256"},{"internalType":"uint256","name":"currentMessages","type":"uint256"},{"internalType":"uint256","name":"totalLikes","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getClaimStatus","outputs":[{"internalType":"bool","name":"canClaim100","type":"bool"},{"internalType":"uint256","name":"next100Claim","type":"uint256"},{"internalType":"bool","name":"canClaim4","type":"bool"},{"internalType":"uint256","name":"next4Claim","type":"uint256"},{"internalType":"bool","name":"canClaimBonus","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getContractBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"messageIndex","type":"uint256"}],"name":"getMessageLikes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getRank","outputs":[{"internalType":"uint256","name":"rank","type":"uint256"},{"internalType":"uint256","name":"manaAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"startIndex","type":"uint256"},{"internalType":"uint256","name":"count","type":"uint256"}],"name":"getRankedLeaderboard","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"components":[{"internalType":"uint256","name":"race","type":"uint256"},{"internalType":"uint256","name":"bodyId","type":"uint256"},{"internalType":"uint256","name":"classType","type":"uint256"},{"internalType":"uint256","name":"location","type":"uint256"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"seed","type":"uint256"},{"internalType":"address","name":"minter","type":"address"}],"internalType":"struct ICharacters.Character[]","name":"charactersData","type":"tuple[]"},{"internalType":"uint256[]","name":"manaAmounts","type":"uint256[]"},{"internalType":"uint256[]","name":"ranks","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"page","type":"uint256"},{"internalType":"uint256","name":"pageSize","type":"uint256"}],"name":"getRankedLeaderboardPaginated","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"components":[{"internalType":"uint256","name":"race","type":"uint256"},{"internalType":"uint256","name":"bodyId","type":"uint256"},{"internalType":"uint256","name":"classType","type":"uint256"},{"internalType":"uint256","name":"location","type":"uint256"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"seed","type":"uint256"},{"internalType":"address","name":"minter","type":"address"}],"internalType":"struct ICharacters.Character[]","name":"charactersData","type":"tuple[]"},{"internalType":"uint256[]","name":"manaAmounts","type":"uint256[]"},{"internalType":"uint256[]","name":"ranks","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"name":"getRecentMessages","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"string[]","name":"names","type":"string[]"},{"internalType":"string[]","name":"messages","type":"string[]"},{"internalType":"uint256[]","name":"timestamps","type":"uint256[]"},{"internalType":"uint256[]","name":"likesArray","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRegisteredCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getTokensByOwner","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"manaAmounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"n","type":"uint256"}],"name":"getTopN","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"components":[{"internalType":"uint256","name":"race","type":"uint256"},{"internalType":"uint256","name":"bodyId","type":"uint256"},{"internalType":"uint256","name":"classType","type":"uint256"},{"internalType":"uint256","name":"location","type":"uint256"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"seed","type":"uint256"},{"internalType":"address","name":"minter","type":"address"}],"internalType":"struct ICharacters.Character[]","name":"charactersData","type":"tuple[]"},{"internalType":"uint256[]","name":"manaAmounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"hasClaimedOneTimeBonus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"messageIndex","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"hasLikedMessage","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isTokenRegistered","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"last100ManaClaim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"last4ManaClaim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"messageIndex","type":"uint256"},{"internalType":"uint256","name":"likerTokenId","type":"uint256"}],"name":"likeMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"manaOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"message","type":"string"}],"name":"sendMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenIdToMana","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801561000f575f5ffd5b50335f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610081575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016100789190610196565b60405180910390fd5b6100908161009660201b60201c565b506101af565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61018082610157565b9050919050565b61019081610176565b82525050565b5f6020820190506101a95f830184610187565b92915050565b61529f806101bc5f395ff3fe608060405260043610610266575f3560e01c80638be4fec411610143578063c7d0604f116100b5578063dedd61fa11610079578063dedd61fa146109a3578063ed8caef6146109cd578063f2fde38b14610a09578063faeebbb714610a31578063fd3e25bd14610a6d578063ff26506b14610a8957610266565b8063c7d0604f14610898578063ca32a0d4146108d4578063ce6146d0146108fe578063d1a1feaf1461093d578063dca42f371461097957610266565b80639dbd9fce116101075780639dbd9fce14610784578063a4ddcaa4146107c3578063a5099bae146107ed578063aae8b5921461082a578063b1decb3114610846578063b5c5eeba1461086e57610266565b80638be4fec41461069c5780638d2f24d6146106c65780638da5cb5b146106f45780638def2a001461071e57806392f062fe1461075a57610266565b80634ab64571116101dc57806370a08231116101a057806370a082311461057e578063715018a6146105ba5780637abc0279146105d05780637d07b2d21461060c578063804986b11461064857806386a699351461067257610266565b80634ab645711461048157806356f1ffdf146104ad57806359d96e39146104ec578063654f4575146105165780636f9fb98a1461055457610266565b80631e32ef3b1161022e5780631e32ef3b1461035c5780631fd43c261461039c5780632a417a46146103c457806336dbd2f9146103ee5780633ccfd60b1461042e57806340398d671461044457610266565b80630222a4861461026a57806302b0994e146102925780630782fd08146102ce5780630a35ada8146102f65780630dd339d514610320575b5f5ffd5b348015610275575f5ffd5b50610290600480360381019061028b9190613990565b610ab3565b005b34801561029d575f5ffd5b506102b860048036038101906102b39190613990565b610cb6565b6040516102c591906139ca565b60405180910390f35b3480156102d9575f5ffd5b506102f460048036038101906102ef9190613990565b610cd0565b005b348015610301575f5ffd5b5061030a610ec2565b60405161031791906139ca565b60405180910390f35b34801561032b575f5ffd5b50610346600480360381019061034191906139e3565b610ec8565b6040516103539190613a3b565b60405180910390f35b348015610367575f5ffd5b50610382600480360381019061037d9190613990565b610f47565b604051610393959493929190613c36565b60405180910390f35b3480156103a7575f5ffd5b506103c260048036038101906103bd9190613d0b565b61134d565b005b3480156103cf575f5ffd5b506103d8611615565b6040516103e591906139ca565b60405180910390f35b3480156103f9575f5ffd5b50610414600480360381019061040f9190613990565b61161a565b604051610425959493929190613d89565b60405180910390f35b348015610439575f5ffd5b506104426116d5565b005b34801561044f575f5ffd5b5061046a60048036038101906104659190613e34565b611771565b604051610478929190613e5f565b60405180910390f35b34801561048c575f5ffd5b50610495611a86565b6040516104a493929190613e94565b60405180910390f35b3480156104b8575f5ffd5b506104d360048036038101906104ce91906139e3565b611ae8565b6040516104e3949392919061402c565b60405180910390f35b3480156104f7575f5ffd5b506105006120d3565b60405161050d91906139ca565b60405180910390f35b348015610521575f5ffd5b5061053c60048036038101906105379190613990565b6120de565b60405161054b9392919061408b565b60405180910390f35b34801561055f575f5ffd5b50610568612101565b60405161057591906139ca565b60405180910390f35b348015610589575f5ffd5b506105a4600480360381019061059f9190613e34565b612108565b6040516105b191906139ca565b60405180910390f35b3480156105c5575f5ffd5b506105ce612232565b005b3480156105db575f5ffd5b506105f660048036038101906105f19190613990565b612245565b60405161060391906139ca565b60405180910390f35b348015610617575f5ffd5b50610632600480360381019061062d9190613990565b6122b8565b60405161063f91906139ca565b60405180910390f35b348015610653575f5ffd5b5061065c6122d8565b60405161066991906139ca565b60405180910390f35b34801561067d575f5ffd5b506106866122de565b60405161069391906139ca565b60405180910390f35b3480156106a7575f5ffd5b506106b06122ea565b6040516106bd91906139ca565b60405180910390f35b3480156106d1575f5ffd5b506106da6122f1565b6040516106eb959493929190613c36565b60405180910390f35b3480156106ff575f5ffd5b506107086126c9565b60405161071591906140e4565b60405180910390f35b348015610729575f5ffd5b50610744600480360381019061073f9190613990565b6126f0565b6040516107519190613a3b565b60405180910390f35b348015610765575f5ffd5b5061076e61270d565b60405161077b91906139ca565b60405180910390f35b34801561078f575f5ffd5b506107aa60048036038101906107a591906139e3565b612712565b6040516107ba949392919061402c565b60405180910390f35b3480156107ce575f5ffd5b506107d7612743565b6040516107e49190614158565b60405180910390f35b3480156107f8575f5ffd5b50610813600480360381019061080e9190613990565b61275b565b604051610821929190614171565b60405180910390f35b610844600480360381019061083f91906141ed565b612821565b005b348015610851575f5ffd5b5061086c60048036038101906108679190613990565b612ace565b005b348015610879575f5ffd5b50610882612cbf565b60405161088f91906139ca565b60405180910390f35b3480156108a3575f5ffd5b506108be60048036038101906108b99190613990565b612cc4565b6040516108cb91906139ca565b60405180910390f35b3480156108df575f5ffd5b506108e8612cd9565b6040516108f591906139ca565b60405180910390f35b348015610909575f5ffd5b50610924600480360381019061091f9190613990565b612cde565b6040516109349493929190614292565b60405180910390f35b348015610948575f5ffd5b50610963600480360381019061095e9190613990565b612d9f565b60405161097091906139ca565b60405180910390f35b348015610984575f5ffd5b5061098d612db4565b60405161099a91906139ca565b60405180910390f35b3480156109ae575f5ffd5b506109b7612dba565b6040516109c491906139ca565b60405180910390f35b3480156109d8575f5ffd5b506109f360048036038101906109ee9190613990565b612dbf565b604051610a009190613a3b565b60405180910390f35b348015610a14575f5ffd5b50610a2f6004803603810190610a2a9190613e34565b612ddc565b005b348015610a3c575f5ffd5b50610a576004803603810190610a529190613990565b612e60565b604051610a6491906139ca565b60405180910390f35b610a876004803603810190610a8291906139e3565b612e75565b005b348015610a94575f5ffd5b50610a9d613273565b604051610aaa91906139ca565b60405180910390f35b3373ffffffffffffffffffffffffffffffffffffffff1673664eb769b64e5cbd41e2a832a4a4e65bfd2d22f073ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610b1791906139ca565b602060405180830381865afa158015610b32573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b5691906142f0565b73ffffffffffffffffffffffffffffffffffffffff1614610bac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ba390614365565b60405180910390fd5b60045f8281526020019081526020015f205f9054906101000a900460ff1615610c0a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c01906143cd565b60405180910390fd5b600160045f8381526020019081526020015f205f6101000a81548160ff0219169083151502179055505f6103e860015f8481526020019081526020015f2054610c539190614418565b9050610c5f828261327f565b813373ffffffffffffffffffffffffffffffffffffffff167fb59108fb73962c3f9d886946836d81f4708977d050e29e8a90a18888ea25b71f6103e842604051610caa929190614171565b60405180910390a35050565b5f60015f8381526020019081526020015f20549050919050565b3373ffffffffffffffffffffffffffffffffffffffff1673664eb769b64e5cbd41e2a832a4a4e65bfd2d22f073ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610d3491906139ca565b602060405180830381865afa158015610d4f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d7391906142f0565b73ffffffffffffffffffffffffffffffffffffffff1614610dc9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc090614365565b60405180910390fd5b6201518060025f8381526020019081526020015f2054610de99190614418565b421015610e2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e2290614495565b60405180910390fd5b4260025f8381526020019081526020015f20819055505f606460015f8481526020019081526020015f2054610e609190614418565b9050610e6c828261327f565b813373ffffffffffffffffffffffffffffffffffffffff167f055990c087ead69a2aa2caa8fa65fff9580fa2a33cd931ee7609b083201cba27606442604051610eb6929190614171565b60405180910390a35050565b610e1081565b5f6007805490508310610f10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f07906144fd565b60405180910390fd5b60085f8481526020019081526020015f205f015f8381526020019081526020015f205f9054906101000a900460ff16905092915050565b60608060608060605f600780549050905080871115610f64578096505b8667ffffffffffffffff811115610f7e57610f7d61451b565b5b604051908082528060200260200182016040528015610fac5781602001602082028036833780820191505090505b5095508667ffffffffffffffff811115610fc957610fc861451b565b5b604051908082528060200260200182016040528015610ffc57816020015b6060815260200190600190039081610fe75790505b5094508667ffffffffffffffff8111156110195761101861451b565b5b60405190808252806020026020018201604052801561104c57816020015b60608152602001906001900390816110375790505b5093508667ffffffffffffffff8111156110695761106861451b565b5b6040519080825280602002602001820160405280156110975781602001602082028036833780820191505090505b5092508667ffffffffffffffff8111156110b4576110b361451b565b5b6040519080825280602002602001820160405280156110e25781602001602082028036833780820191505090505b5091505f87826110f29190614548565b90505f5f90505b88811015611341575f818361110e9190614418565b90505f600782815481106111255761112461457b565b5b905f5260205f2090600402016040518060800160405290815f8201548152602001600182018054611155906145d5565b80601f0160208091040260200160405190810160405280929190818152602001828054611181906145d5565b80156111cc5780601f106111a3576101008083540402835291602001916111cc565b820191905f5260205f20905b8154815290600101906020018083116111af57829003601f168201915b50505050508152602001600282015481526020016003820154815250509050805f01518a84815181106112025761120161457b565b5b6020026020010181815250505f73664eb769b64e5cbd41e2a832a4a4e65bfd2d22f073ffffffffffffffffffffffffffffffffffffffff1663dabb0531835f01516040518263ffffffff1660e01b815260040161125f91906139ca565b5f60405180830381865afa158015611279573d5f5f3e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906112a191906147db565b905080608001518a85815181106112bb576112ba61457b565b5b602002602001018190525081602001518985815181106112de576112dd61457b565b5b602002602001018190525081604001518885815181106113015761130061457b565b5b60200260200101818152505081606001518785815181106113255761132461457b565b5b60200260200101818152505050505080806001019150506110f9565b50505091939590929450565b61135561337f565b81819050848490501461139d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113949061486c565b60405180910390fd5b5f5f90505b8484905081101561160e575f8585838181106113c1576113c061457b565b5b9050602002013590505f73ffffffffffffffffffffffffffffffffffffffff1673664eb769b64e5cbd41e2a832a4a4e65bfd2d22f073ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161142e91906139ca565b602060405180830381865afa158015611449573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061146d91906142f0565b73ffffffffffffffffffffffffffffffffffffffff16036114c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114ba906148d4565b60405180910390fd5b5f73664eb769b64e5cbd41e2a832a4a4e65bfd2d22f073ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161151191906139ca565b602060405180830381865afa15801561152c573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061155091906142f0565b90505f8585858181106115665761156561457b565b5b9050602002013560015f8581526020019081526020015f20546115899190614418565b9050611595838261327f565b8173ffffffffffffffffffffffffffffffffffffffff167f726f468aa8d525df4ba9517fa838db1ad35a3d2cc93bf79f855828477dd75fc98787878181106115e0576115df61457b565b5b90506020020135426040516115f6929190614171565b60405180910390a250505080806001019150506113a2565b5050505050565b600a81565b5f5f5f5f5f6201518060025f8881526020019081526020015f205461163f9190614418565b42101594506201518060025f8881526020019081526020015f20546116649190614418565b9350610e1060035f8881526020019081526020015f20546116859190614418565b4210159250610e1060035f8881526020019081526020015f20546116a99190614418565b915060045f8781526020019081526020015f205f9054906101000a900460ff1615905091939590929450565b6116dd61337f565b5f4790505f8111611723576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161171a9061493c565b60405180910390fd5b61172b6126c9565b73ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f1935050505015801561176d573d5f5f3e3d5ffd5b5050565b6060805f60058054905090505f5f90505f5f90505b82811015611889575f600582815481106117a3576117a261457b565b5b905f5260205f20015490508673ffffffffffffffffffffffffffffffffffffffff1673664eb769b64e5cbd41e2a832a4a4e65bfd2d22f073ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161181291906139ca565b602060405180830381865afa15801561182d573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061185191906142f0565b73ffffffffffffffffffffffffffffffffffffffff160361187b5782806118779061495a565b9350505b508080600101915050611786565b508067ffffffffffffffff8111156118a4576118a361451b565b5b6040519080825280602002602001820160405280156118d25781602001602082028036833780820191505090505b5093508067ffffffffffffffff8111156118ef576118ee61451b565b5b60405190808252806020026020018201604052801561191d5781602001602082028036833780820191505090505b5092505f5f90505f5f90505b83811015611a7d575f600582815481106119465761194561457b565b5b905f5260205f20015490508773ffffffffffffffffffffffffffffffffffffffff1673664eb769b64e5cbd41e2a832a4a4e65bfd2d22f073ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b81526004016119b591906139ca565b602060405180830381865afa1580156119d0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119f491906142f0565b73ffffffffffffffffffffffffffffffffffffffff1603611a6f5780878481518110611a2357611a2261457b565b5b60200260200101818152505060015f8281526020019081526020015f2054868481518110611a5457611a5361457b565b5b6020026020010181815250508280611a6b9061495a565b9350505b508080600101915050611929565b50505050915091565b5f5f5f60078054905091505f90505f5f90505b82811015611adf5760078181548110611ab557611ab461457b565b5b905f5260205f2090600402016003015482611ad09190614418565b91508080600101915050611a99565b50819250909192565b6060806060805f60058054905090505f8103611c3b575f67ffffffffffffffff811115611b1857611b1761451b565b5b604051908082528060200260200182016040528015611b465781602001602082028036833780820191505090505b505f67ffffffffffffffff811115611b6157611b6061451b565b5b604051908082528060200260200182016040528015611b9a57816020015b611b876138a7565b815260200190600190039081611b7f5790505b505f67ffffffffffffffff811115611bb557611bb461451b565b5b604051908082528060200260200182016040528015611be35781602001602082028036833780820191505090505b505f67ffffffffffffffff811115611bfe57611bfd61451b565b5b604051908082528060200260200182016040528015611c2c5781602001602082028036833780820191505090505b509450945094509450506120ca565b808710611c7d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c74906149eb565b60405180910390fd5b5f8688611c8a9190614418565b905081811115611c98578190505b5f8882611ca59190614548565b90505f8367ffffffffffffffff811115611cc257611cc161451b565b5b604051908082528060200260200182016040528015611cf05781602001602082028036833780820191505090505b5090505f8467ffffffffffffffff811115611d0e57611d0d61451b565b5b604051908082528060200260200182016040528015611d3c5781602001602082028036833780820191505090505b5090505f5f90505b85811015611de25760058181548110611d6057611d5f61457b565b5b905f5260205f200154838281518110611d7c57611d7b61457b565b5b60200260200101818152505060015f60058381548110611d9f57611d9e61457b565b5b905f5260205f20015481526020019081526020015f2054828281518110611dc957611dc861457b565b5b6020026020010181815250508080600101915050611d44565b50611dfb82825f600189611df69190614548565b613406565b8267ffffffffffffffff811115611e1557611e1461451b565b5b604051908082528060200260200182016040528015611e435781602001602082028036833780820191505090505b5098508267ffffffffffffffff811115611e6057611e5f61451b565b5b604051908082528060200260200182016040528015611e9957816020015b611e866138a7565b815260200190600190039081611e7e5790505b5097508267ffffffffffffffff811115611eb657611eb561451b565b5b604051908082528060200260200182016040528015611ee45781602001602082028036833780820191505090505b5096508267ffffffffffffffff811115611f0157611f0061451b565b5b604051908082528060200260200182016040528015611f2f5781602001602082028036833780820191505090505b5095505f5f90505b838110156120c3575f818d611f4c9190614418565b9050838181518110611f6157611f6061457b565b5b60200260200101518b8381518110611f7c57611f7b61457b565b5b60200260200101818152505073664eb769b64e5cbd41e2a832a4a4e65bfd2d22f073ffffffffffffffffffffffffffffffffffffffff1663dabb0531858381518110611fcb57611fca61457b565b5b60200260200101516040518263ffffffff1660e01b8152600401611fef91906139ca565b5f60405180830381865afa158015612009573d5f5f3e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061203191906147db565b8a83815181106120445761204361457b565b5b60200260200101819052508281815181106120625761206161457b565b5b602002602001015189838151811061207d5761207c61457b565b5b6020026020010181815250506001816120969190614418565b8883815181106120a9576120a861457b565b5b602002602001018181525050508080600101915050611f37565b5050505050505b92959194509250565b66038d7ea4c6800081565b60608060606120ed5f85611ae8565b508093508194508295505050509193909250565b5f47905090565b5f5f60058054905090505f5f90505b8181101561222b575f600582815481106121345761213361457b565b5b905f5260205f20015490508473ffffffffffffffffffffffffffffffffffffffff1673664eb769b64e5cbd41e2a832a4a4e65bfd2d22f073ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b81526004016121a391906139ca565b602060405180830381865afa1580156121be573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121e291906142f0565b73ffffffffffffffffffffffffffffffffffffffff160361221d5760015f8281526020019081526020015f20548461221a9190614418565b93505b508080600101915050612117565b5050919050565b61223a61337f565b6122435f61360f565b565b5f600780549050821061228d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612284906144fd565b60405180910390fd5b600782815481106122a1576122a061457b565b5b905f5260205f209060040201600301549050919050565b600581815481106122c7575f80fd5b905f5260205f20015f915090505481565b6103e881565b5f600580549050905090565b6201518081565b60608060608060605f60078054905090508067ffffffffffffffff81111561231c5761231b61451b565b5b60405190808252806020026020018201604052801561234a5781602001602082028036833780820191505090505b5095508067ffffffffffffffff8111156123675761236661451b565b5b60405190808252806020026020018201604052801561239a57816020015b60608152602001906001900390816123855790505b5094508067ffffffffffffffff8111156123b7576123b661451b565b5b6040519080825280602002602001820160405280156123ea57816020015b60608152602001906001900390816123d55790505b5093508067ffffffffffffffff8111156124075761240661451b565b5b6040519080825280602002602001820160405280156124355781602001602082028036833780820191505090505b5092508067ffffffffffffffff8111156124525761245161451b565b5b6040519080825280602002602001820160405280156124805781602001602082028036833780820191505090505b5091505f5f90505b818110156126c0575f600782815481106124a5576124a461457b565b5b905f5260205f2090600402016040518060800160405290815f82015481526020016001820180546124d5906145d5565b80601f0160208091040260200160405190810160405280929190818152602001828054612501906145d5565b801561254c5780601f106125235761010080835404028352916020019161254c565b820191905f5260205f20905b81548152906001019060200180831161252f57829003601f168201915b50505050508152602001600282015481526020016003820154815250509050805f01518883815181106125825761258161457b565b5b6020026020010181815250505f73664eb769b64e5cbd41e2a832a4a4e65bfd2d22f073ffffffffffffffffffffffffffffffffffffffff1663dabb0531835f01516040518263ffffffff1660e01b81526004016125df91906139ca565b5f60405180830381865afa1580156125f9573d5f5f3e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061262191906147db565b9050806080015188848151811061263b5761263a61457b565b5b6020026020010181905250816020015187848151811061265e5761265d61457b565b5b602002602001018190525081604001518684815181106126815761268061457b565b5b60200260200101818152505081606001518584815181106126a5576126a461457b565b5b60200260200101818152505050508080600101915050612488565b50509091929394565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6006602052805f5260405f205f915054906101000a900460ff1681565b600481565b6060806060805f85876127259190614a09565b90506127318187611ae8565b94509450945094505092959194509250565b73664eb769b64e5cbd41e2a832a4a4e65bfd2d22f081565b5f5f60065f8481526020019081526020015f205f9054906101000a900460ff1661278a575f5f9150915061281c565b60015f8481526020019081526020015f205490505f60058054905090505f5f90505f5f90505b82811015612809578360015f600584815481106127d0576127cf61457b565b5b905f5260205f20015481526020019081526020015f205411156127fc5781806127f89061495a565b9250505b80806001019150506127b0565b506001816128179190614418565b935050505b915091565b3373ffffffffffffffffffffffffffffffffffffffff1673664eb769b64e5cbd41e2a832a4a4e65bfd2d22f073ffffffffffffffffffffffffffffffffffffffff16636352211e856040518263ffffffff1660e01b815260040161288591906139ca565b602060405180830381865afa1580156128a0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128c491906142f0565b73ffffffffffffffffffffffffffffffffffffffff161461291a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161291190614365565b60405180910390fd5b5f828290501161295f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161295690614a94565b60405180910390fd5b66038d7ea4c6800034146129a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161299f90614afc565b60405180910390fd5b5f5a90506129b78484846136d0565b5a816129c39190614548565b90505f633b9aca00612710836129d99190614a09565b6129e39190614b47565b60016129ef9190614418565b90505f811115612a25575f8160015f8881526020019081526020015f2054612a179190614418565b9050612a23868261327f565b505b843373ffffffffffffffffffffffffffffffffffffffff167f055990c087ead69a2aa2caa8fa65fff9580fa2a33cd931ee7609b083201cba278342604051612a6e929190614171565b60405180910390a3847f81199b04cfb3936bbf995822d4dcbdffa0737dc42066025a1031dd09b0aaf9708585426001600780549050612aad9190614548565b86604051612abf959493929190614bb1565b60405180910390a25050505050565b3373ffffffffffffffffffffffffffffffffffffffff1673664eb769b64e5cbd41e2a832a4a4e65bfd2d22f073ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401612b3291906139ca565b602060405180830381865afa158015612b4d573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b7191906142f0565b73ffffffffffffffffffffffffffffffffffffffff1614612bc7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bbe90614365565b60405180910390fd5b610e1060035f8381526020019081526020015f2054612be69190614418565b421015612c28576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c1f90614495565b60405180910390fd5b4260035f8381526020019081526020015f20819055505f600460015f8481526020019081526020015f2054612c5d9190614418565b9050612c69828261327f565b813373ffffffffffffffffffffffffffffffffffffffff167f055990c087ead69a2aa2caa8fa65fff9580fa2a33cd931ee7609b083201cba27600442604051612cb3929190614171565b60405180910390a35050565b606481565b6003602052805f5260405f205f915090505481565b606481565b60078181548110612ced575f80fd5b905f5260205f2090600402015f91509050805f015490806001018054612d12906145d5565b80601f0160208091040260200160405190810160405280929190818152602001828054612d3e906145d5565b8015612d895780601f10612d6057610100808354040283529160200191612d89565b820191905f5260205f20905b815481529060010190602001808311612d6c57829003601f168201915b5050505050908060020154908060030154905084565b6001602052805f5260405f205f915090505481565b61271081565b600181565b6004602052805f5260405f205f915054906101000a900460ff1681565b612de461337f565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612e54575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401612e4b91906140e4565b60405180910390fd5b612e5d8161360f565b50565b6002602052805f5260405f205f915090505481565b3373ffffffffffffffffffffffffffffffffffffffff1673664eb769b64e5cbd41e2a832a4a4e65bfd2d22f073ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401612ed991906139ca565b602060405180830381865afa158015612ef4573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612f1891906142f0565b73ffffffffffffffffffffffffffffffffffffffff1614612f6e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f6590614365565b60405180910390fd5b6007805490508210612fb5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612fac906144fd565b60405180910390fd5b67016345785d8a00003414612fff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ff690614c47565b60405180910390fd5b5f600783815481106130145761301361457b565b5b905f5260205f209060040201905081815f015403613067576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161305e90614caf565b60405180910390fd5b60085f8481526020019081526020015f205f015f8381526020019081526020015f205f9054906101000a900460ff16156130d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130cd90614d17565b60405180910390fd5b600160085f8581526020019081526020015f205f015f8481526020019081526020015f205f6101000a81548160ff021916908315150217905550806003015f8154809291906131249061495a565b91905055505f600a60015f845f015481526020019081526020015f205461314b9190614418565b905061315a825f01548261327f565b5f6001805f8681526020019081526020015f20546131789190614418565b9050613184848261327f565b825f015484867f7b75ace263ae42acfd7d0783452ee2cfc6e5829756223292617e19af47f58c4f600a60016040516131bd929190614171565b60405180910390a4825f01543373ffffffffffffffffffffffffffffffffffffffff167f055990c087ead69a2aa2caa8fa65fff9580fa2a33cd931ee7609b083201cba27600a42604051613212929190614171565b60405180910390a3833373ffffffffffffffffffffffffffffffffffffffff167f055990c087ead69a2aa2caa8fa65fff9580fa2a33cd931ee7609b083201cba27600142604051613264929190614171565b60405180910390a35050505050565b67016345785d8a000081565b8060015f8481526020019081526020015f208190555060065f8381526020019081526020015f205f9054906101000a900460ff1661334157600582908060018154018082558091505060019003905f5260205f20015f9091909190915055600160065f8481526020019081526020015f205f6101000a81548160ff021916908315150217905550817f7f36fd05ce62258919a4d9eba687ce245fae44d0b5c144a11b12c25c293a86fd3342604051613338929190614d35565b60405180910390a25b817f387d01e96a7dce0e6676dd7a6ea815d3160e37ef13867fc6e9ce5fe9be85f4048242604051613373929190614171565b60405180910390a25050565b6133876138a0565b73ffffffffffffffffffffffffffffffffffffffff166133a56126c9565b73ffffffffffffffffffffffffffffffffffffffff1614613404576133c86138a0565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016133fb91906140e4565b60405180910390fd5b565b80821215613609575f8290505f8290505f85600286866134269190614d65565b6134309190614da5565b8661343b9190614e0d565b8151811061344c5761344b61457b565b5b602002602001015190505b8183136135db575b808684815181106134735761347261457b565b5b6020026020010151111561349457828061348c90614e4e565b93505061345f565b5b8582815181106134a8576134a761457b565b5b60200260200101518111156134ca5781806134c290614e95565b925050613495565b8183136135d6578682815181106134e4576134e361457b565b5b60200260200101518784815181106134ff576134fe61457b565b5b602002602001015188858151811061351a5761351961457b565b5b602002602001018985815181106135345761353361457b565b5b60200260200101828152508281525050508582815181106135585761355761457b565b5b60200260200101518684815181106135735761357261457b565b5b602002602001015187858151811061358e5761358d61457b565b5b602002602001018885815181106135a8576135a761457b565b5b602002602001018281525082815250505082806135c490614e4e565b93505081806135d290614e95565b9250505b613457565b818512156135f0576135ef87878785613406565b5b838312156136055761360487878587613406565b5b5050505b50505050565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f604051806080016040528085815260200184848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505081526020014281526020015f815250905060646007805490501061383d575f5f90505b600160078054905061375b9190614548565b8110156137ef5760076001826137719190614418565b815481106137825761378161457b565b5b905f5260205f209060040201600782815481106137a2576137a161457b565b5b905f5260205f2090600402015f820154815f0155600182018160010190816137ca9190615088565b5060028201548160020155600382015481600301559050508080600101915050613749565b5060078054806138025761380161516d565b5b600190038181905f5260205f2090600402015f5f82015f9055600182015f61382a91906138f4565b600282015f9055600382015f9055505090555b600781908060018154018082558091505060019003905f5260205f2090600402015f909190919091505f820151815f01556020820151816001019081613883919061519a565b506040820151816002015560608201518160030155505050505050565b5f33905090565b6040518060e001604052805f81526020015f81526020015f81526020015f8152602001606081526020015f81526020015f73ffffffffffffffffffffffffffffffffffffffff1681525090565b508054613900906145d5565b5f825580601f10613911575061392e565b601f0160209004905f5260205f209081019061392d9190613931565b5b50565b5b80821115613948575f815f905550600101613932565b5090565b5f604051905090565b5f5ffd5b5f5ffd5b5f819050919050565b61396f8161395d565b8114613979575f5ffd5b50565b5f8135905061398a81613966565b92915050565b5f602082840312156139a5576139a4613955565b5b5f6139b28482850161397c565b91505092915050565b6139c48161395d565b82525050565b5f6020820190506139dd5f8301846139bb565b92915050565b5f5f604083850312156139f9576139f8613955565b5b5f613a068582860161397c565b9250506020613a178582860161397c565b9150509250929050565b5f8115159050919050565b613a3581613a21565b82525050565b5f602082019050613a4e5f830184613a2c565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b613a868161395d565b82525050565b5f613a978383613a7d565b60208301905092915050565b5f602082019050919050565b5f613ab982613a54565b613ac38185613a5e565b9350613ace83613a6e565b805f5b83811015613afe578151613ae58882613a8c565b9750613af083613aa3565b925050600181019050613ad1565b5085935050505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f613b7682613b34565b613b808185613b3e565b9350613b90818560208601613b4e565b613b9981613b5c565b840191505092915050565b5f613baf8383613b6c565b905092915050565b5f602082019050919050565b5f613bcd82613b0b565b613bd78185613b15565b935083602082028501613be985613b25565b805f5b85811015613c245784840389528151613c058582613ba4565b9450613c1083613bb7565b925060208a01995050600181019050613bec565b50829750879550505050505092915050565b5f60a0820190508181035f830152613c4e8188613aaf565b90508181036020830152613c628187613bc3565b90508181036040830152613c768186613bc3565b90508181036060830152613c8a8185613aaf565b90508181036080830152613c9e8184613aaf565b90509695505050505050565b5f5ffd5b5f5ffd5b5f5ffd5b5f5f83601f840112613ccb57613cca613caa565b5b8235905067ffffffffffffffff811115613ce857613ce7613cae565b5b602083019150836020820283011115613d0457613d03613cb2565b5b9250929050565b5f5f5f5f60408587031215613d2357613d22613955565b5b5f85013567ffffffffffffffff811115613d4057613d3f613959565b5b613d4c87828801613cb6565b9450945050602085013567ffffffffffffffff811115613d6f57613d6e613959565b5b613d7b87828801613cb6565b925092505092959194509250565b5f60a082019050613d9c5f830188613a2c565b613da960208301876139bb565b613db66040830186613a2c565b613dc360608301856139bb565b613dd06080830184613a2c565b9695505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f613e0382613dda565b9050919050565b613e1381613df9565b8114613e1d575f5ffd5b50565b5f81359050613e2e81613e0a565b92915050565b5f60208284031215613e4957613e48613955565b5b5f613e5684828501613e20565b91505092915050565b5f6040820190508181035f830152613e778185613aaf565b90508181036020830152613e8b8184613aaf565b90509392505050565b5f606082019050613ea75f8301866139bb565b613eb460208301856139bb565b613ec160408301846139bb565b949350505050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b613efb81613df9565b82525050565b5f60e083015f830151613f165f860182613a7d565b506020830151613f296020860182613a7d565b506040830151613f3c6040860182613a7d565b506060830151613f4f6060860182613a7d565b5060808301518482036080860152613f678282613b6c565b91505060a0830151613f7c60a0860182613a7d565b5060c0830151613f8f60c0860182613ef2565b508091505092915050565b5f613fa58383613f01565b905092915050565b5f602082019050919050565b5f613fc382613ec9565b613fcd8185613ed3565b935083602082028501613fdf85613ee3565b805f5b8581101561401a5784840389528151613ffb8582613f9a565b945061400683613fad565b925060208a01995050600181019050613fe2565b50829750879550505050505092915050565b5f6080820190508181035f8301526140448187613aaf565b905081810360208301526140588186613fb9565b9050818103604083015261406c8185613aaf565b905081810360608301526140808184613aaf565b905095945050505050565b5f6060820190508181035f8301526140a38186613aaf565b905081810360208301526140b78185613fb9565b905081810360408301526140cb8184613aaf565b9050949350505050565b6140de81613df9565b82525050565b5f6020820190506140f75f8301846140d5565b92915050565b5f819050919050565b5f61412061411b61411684613dda565b6140fd565b613dda565b9050919050565b5f61413182614106565b9050919050565b5f61414282614127565b9050919050565b61415281614138565b82525050565b5f60208201905061416b5f830184614149565b92915050565b5f6040820190506141845f8301856139bb565b61419160208301846139bb565b9392505050565b5f5f83601f8401126141ad576141ac613caa565b5b8235905067ffffffffffffffff8111156141ca576141c9613cae565b5b6020830191508360018202830111156141e6576141e5613cb2565b5b9250929050565b5f5f5f6040848603121561420457614203613955565b5b5f6142118682870161397c565b935050602084013567ffffffffffffffff81111561423257614231613959565b5b61423e86828701614198565b92509250509250925092565b5f82825260208201905092915050565b5f61426482613b34565b61426e818561424a565b935061427e818560208601613b4e565b61428781613b5c565b840191505092915050565b5f6080820190506142a55f8301876139bb565b81810360208301526142b7818661425a565b90506142c660408301856139bb565b6142d360608301846139bb565b95945050505050565b5f815190506142ea81613e0a565b92915050565b5f6020828403121561430557614304613955565b5b5f614312848285016142dc565b91505092915050565b7f4e6f7420746f6b656e206f776e657200000000000000000000000000000000005f82015250565b5f61434f600f8361424a565b915061435a8261431b565b602082019050919050565b5f6020820190508181035f83015261437c81614343565b9050919050565b7f426f6e757320616c726561647920636c61696d656400000000000000000000005f82015250565b5f6143b760158361424a565b91506143c282614383565b602082019050919050565b5f6020820190508181035f8301526143e4816143ab565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6144228261395d565b915061442d8361395d565b9250828201905080821115614445576144446143eb565b5b92915050565b7f436f6f6c646f776e2061637469766500000000000000000000000000000000005f82015250565b5f61447f600f8361424a565b915061448a8261444b565b602082019050919050565b5f6020820190508181035f8301526144ac81614473565b9050919050565b7f496e76616c6964206d65737361676520696e64657800000000000000000000005f82015250565b5f6144e760158361424a565b91506144f2826144b3565b602082019050919050565b5f6020820190508181035f830152614514816144db565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f6145528261395d565b915061455d8361395d565b9250828203905081811115614575576145746143eb565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806145ec57607f821691505b6020821081036145ff576145fe6145a8565b5b50919050565b5f5ffd5b61461282613b5c565b810181811067ffffffffffffffff821117156146315761463061451b565b5b80604052505050565b5f61464361394c565b905061464f8282614609565b919050565b5f5ffd5b5f8151905061466681613966565b92915050565b5f5ffd5b5f67ffffffffffffffff82111561468a5761468961451b565b5b61469382613b5c565b9050602081019050919050565b5f6146b26146ad84614670565b61463a565b9050828152602081018484840111156146ce576146cd61466c565b5b6146d9848285613b4e565b509392505050565b5f82601f8301126146f5576146f4613caa565b5b81516147058482602086016146a0565b91505092915050565b5f60e0828403121561472357614722614605565b5b61472d60e061463a565b90505f61473c84828501614658565b5f83015250602061474f84828501614658565b602083015250604061476384828501614658565b604083015250606061477784828501614658565b606083015250608082015167ffffffffffffffff81111561479b5761479a614654565b5b6147a7848285016146e1565b60808301525060a06147bb84828501614658565b60a08301525060c06147cf848285016142dc565b60c08301525092915050565b5f602082840312156147f0576147ef613955565b5b5f82015167ffffffffffffffff81111561480d5761480c613959565b5b6148198482850161470e565b91505092915050565b7f417272617973206c656e677468206d69736d61746368000000000000000000005f82015250565b5f61485660168361424a565b915061486182614822565b602082019050919050565b5f6020820190508181035f8301526148838161484a565b9050919050565b7f496e76616c696420746f6b656e204944000000000000000000000000000000005f82015250565b5f6148be60108361424a565b91506148c98261488a565b602082019050919050565b5f6020820190508181035f8301526148eb816148b2565b9050919050565b7f4e6f2066756e647320746f2077697468647261770000000000000000000000005f82015250565b5f61492660148361424a565b9150614931826148f2565b602082019050919050565b5f6020820190508181035f8301526149538161491a565b9050919050565b5f6149648261395d565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614996576149956143eb565b5b600182019050919050565b7f537461727420696e646578206f7574206f6620626f756e6473000000000000005f82015250565b5f6149d560198361424a565b91506149e0826149a1565b602082019050919050565b5f6020820190508181035f830152614a02816149c9565b9050919050565b5f614a138261395d565b9150614a1e8361395d565b9250828202614a2c8161395d565b91508282048414831517614a4357614a426143eb565b5b5092915050565b7f4d6573736167652063616e6e6f7420626520656d7074790000000000000000005f82015250565b5f614a7e60178361424a565b9150614a8982614a4a565b602082019050919050565b5f6020820190508181035f830152614aab81614a72565b9050919050565b7f496e636f7272656374206d65737361676520636f7374000000000000000000005f82015250565b5f614ae660168361424a565b9150614af182614ab2565b602082019050919050565b5f6020820190508181035f830152614b1381614ada565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f614b518261395d565b9150614b5c8361395d565b925082614b6c57614b6b614b1a565b5b828204905092915050565b828183375f83830152505050565b5f614b90838561424a565b9350614b9d838584614b77565b614ba683613b5c565b840190509392505050565b5f6080820190508181035f830152614bca818789614b85565b9050614bd960208301866139bb565b614be660408301856139bb565b614bf360608301846139bb565b9695505050505050565b7f496e636f7272656374206c696b6520636f7374000000000000000000000000005f82015250565b5f614c3160138361424a565b9150614c3c82614bfd565b602082019050919050565b5f6020820190508181035f830152614c5e81614c25565b9050919050565b7f43616e6e6f74206c696b65206f776e206d6573736167650000000000000000005f82015250565b5f614c9960178361424a565b9150614ca482614c65565b602082019050919050565b5f6020820190508181035f830152614cc681614c8d565b9050919050565b7f416c7265616479206c696b65642074686973206d6573736167650000000000005f82015250565b5f614d01601a8361424a565b9150614d0c82614ccd565b602082019050919050565b5f6020820190508181035f830152614d2e81614cf5565b9050919050565b5f604082019050614d485f8301856140d5565b614d5560208301846139bb565b9392505050565b5f819050919050565b5f614d6f82614d5c565b9150614d7a83614d5c565b925082820390508181125f8412168282135f851215161715614d9f57614d9e6143eb565b5b92915050565b5f614daf82614d5c565b9150614dba83614d5c565b925082614dca57614dc9614b1a565b5b60015f0383147f800000000000000000000000000000000000000000000000000000000000000083141615614e0257614e016143eb565b5b828205905092915050565b5f614e1782614d5c565b9150614e2283614d5c565b92508282019050828112155f8312168382125f841215161715614e4857614e476143eb565b5b92915050565b5f614e5882614d5c565b91507f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614e8a57614e896143eb565b5b600182019050919050565b5f614e9f82614d5c565b91507f80000000000000000000000000000000000000000000000000000000000000008203614ed157614ed06143eb565b5b600182039050919050565b5f81549050614eea816145d5565b9050919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302614f4d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614f12565b614f578683614f12565b95508019841693508086168417925050509392505050565b5f614f89614f84614f7f8461395d565b6140fd565b61395d565b9050919050565b5f819050919050565b614fa283614f6f565b614fb6614fae82614f90565b848454614f1e565b825550505050565b5f5f905090565b614fcd614fbe565b614fd8818484614f99565b505050565b5b81811015614ffb57614ff05f82614fc5565b600181019050614fde565b5050565b601f8211156150405761501181614ef1565b61501a84614f03565b81016020851015615029578190505b61503d61503585614f03565b830182614fdd565b50505b505050565b5f82821c905092915050565b5f6150605f1984600802615045565b1980831691505092915050565b5f6150788383615051565b9150826002028217905092915050565b81810361509657505061516b565b61509f82614edc565b67ffffffffffffffff8111156150b8576150b761451b565b5b6150c282546145d5565b6150cd828285614fff565b5f601f8311600181146150fa575f84156150e8578287015490505b6150f2858261506d565b865550615164565b601f19841661510887614ef1565b965061511386614ef1565b5f5b8281101561513a57848901548255600182019150600185019450602081019050615115565b868310156151575784890154615153601f891682615051565b8355505b6001600288020188555050505b5050505050505b565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffd5b6151a382613b34565b67ffffffffffffffff8111156151bc576151bb61451b565b5b6151c682546145d5565b6151d1828285614fff565b5f60209050601f831160018114615202575f84156151f0578287015190505b6151fa858261506d565b865550615261565b601f19841661521086614ef1565b5f5b8281101561523757848901518255600182019150602085019450602081019050615212565b868310156152545784890151615250601f891682615051565b8355505b6001600288020188555050505b50505050505056fea26469706673582212207e14bc9d7281759c9b45d693303e0ee270cc9aea59d464cbfaa0c0730f6718fe64736f6c634300081e0033

Deployed Bytecode

0x608060405260043610610266575f3560e01c80638be4fec411610143578063c7d0604f116100b5578063dedd61fa11610079578063dedd61fa146109a3578063ed8caef6146109cd578063f2fde38b14610a09578063faeebbb714610a31578063fd3e25bd14610a6d578063ff26506b14610a8957610266565b8063c7d0604f14610898578063ca32a0d4146108d4578063ce6146d0146108fe578063d1a1feaf1461093d578063dca42f371461097957610266565b80639dbd9fce116101075780639dbd9fce14610784578063a4ddcaa4146107c3578063a5099bae146107ed578063aae8b5921461082a578063b1decb3114610846578063b5c5eeba1461086e57610266565b80638be4fec41461069c5780638d2f24d6146106c65780638da5cb5b146106f45780638def2a001461071e57806392f062fe1461075a57610266565b80634ab64571116101dc57806370a08231116101a057806370a082311461057e578063715018a6146105ba5780637abc0279146105d05780637d07b2d21461060c578063804986b11461064857806386a699351461067257610266565b80634ab645711461048157806356f1ffdf146104ad57806359d96e39146104ec578063654f4575146105165780636f9fb98a1461055457610266565b80631e32ef3b1161022e5780631e32ef3b1461035c5780631fd43c261461039c5780632a417a46146103c457806336dbd2f9146103ee5780633ccfd60b1461042e57806340398d671461044457610266565b80630222a4861461026a57806302b0994e146102925780630782fd08146102ce5780630a35ada8146102f65780630dd339d514610320575b5f5ffd5b348015610275575f5ffd5b50610290600480360381019061028b9190613990565b610ab3565b005b34801561029d575f5ffd5b506102b860048036038101906102b39190613990565b610cb6565b6040516102c591906139ca565b60405180910390f35b3480156102d9575f5ffd5b506102f460048036038101906102ef9190613990565b610cd0565b005b348015610301575f5ffd5b5061030a610ec2565b60405161031791906139ca565b60405180910390f35b34801561032b575f5ffd5b50610346600480360381019061034191906139e3565b610ec8565b6040516103539190613a3b565b60405180910390f35b348015610367575f5ffd5b50610382600480360381019061037d9190613990565b610f47565b604051610393959493929190613c36565b60405180910390f35b3480156103a7575f5ffd5b506103c260048036038101906103bd9190613d0b565b61134d565b005b3480156103cf575f5ffd5b506103d8611615565b6040516103e591906139ca565b60405180910390f35b3480156103f9575f5ffd5b50610414600480360381019061040f9190613990565b61161a565b604051610425959493929190613d89565b60405180910390f35b348015610439575f5ffd5b506104426116d5565b005b34801561044f575f5ffd5b5061046a60048036038101906104659190613e34565b611771565b604051610478929190613e5f565b60405180910390f35b34801561048c575f5ffd5b50610495611a86565b6040516104a493929190613e94565b60405180910390f35b3480156104b8575f5ffd5b506104d360048036038101906104ce91906139e3565b611ae8565b6040516104e3949392919061402c565b60405180910390f35b3480156104f7575f5ffd5b506105006120d3565b60405161050d91906139ca565b60405180910390f35b348015610521575f5ffd5b5061053c60048036038101906105379190613990565b6120de565b60405161054b9392919061408b565b60405180910390f35b34801561055f575f5ffd5b50610568612101565b60405161057591906139ca565b60405180910390f35b348015610589575f5ffd5b506105a4600480360381019061059f9190613e34565b612108565b6040516105b191906139ca565b60405180910390f35b3480156105c5575f5ffd5b506105ce612232565b005b3480156105db575f5ffd5b506105f660048036038101906105f19190613990565b612245565b60405161060391906139ca565b60405180910390f35b348015610617575f5ffd5b50610632600480360381019061062d9190613990565b6122b8565b60405161063f91906139ca565b60405180910390f35b348015610653575f5ffd5b5061065c6122d8565b60405161066991906139ca565b60405180910390f35b34801561067d575f5ffd5b506106866122de565b60405161069391906139ca565b60405180910390f35b3480156106a7575f5ffd5b506106b06122ea565b6040516106bd91906139ca565b60405180910390f35b3480156106d1575f5ffd5b506106da6122f1565b6040516106eb959493929190613c36565b60405180910390f35b3480156106ff575f5ffd5b506107086126c9565b60405161071591906140e4565b60405180910390f35b348015610729575f5ffd5b50610744600480360381019061073f9190613990565b6126f0565b6040516107519190613a3b565b60405180910390f35b348015610765575f5ffd5b5061076e61270d565b60405161077b91906139ca565b60405180910390f35b34801561078f575f5ffd5b506107aa60048036038101906107a591906139e3565b612712565b6040516107ba949392919061402c565b60405180910390f35b3480156107ce575f5ffd5b506107d7612743565b6040516107e49190614158565b60405180910390f35b3480156107f8575f5ffd5b50610813600480360381019061080e9190613990565b61275b565b604051610821929190614171565b60405180910390f35b610844600480360381019061083f91906141ed565b612821565b005b348015610851575f5ffd5b5061086c60048036038101906108679190613990565b612ace565b005b348015610879575f5ffd5b50610882612cbf565b60405161088f91906139ca565b60405180910390f35b3480156108a3575f5ffd5b506108be60048036038101906108b99190613990565b612cc4565b6040516108cb91906139ca565b60405180910390f35b3480156108df575f5ffd5b506108e8612cd9565b6040516108f591906139ca565b60405180910390f35b348015610909575f5ffd5b50610924600480360381019061091f9190613990565b612cde565b6040516109349493929190614292565b60405180910390f35b348015610948575f5ffd5b50610963600480360381019061095e9190613990565b612d9f565b60405161097091906139ca565b60405180910390f35b348015610984575f5ffd5b5061098d612db4565b60405161099a91906139ca565b60405180910390f35b3480156109ae575f5ffd5b506109b7612dba565b6040516109c491906139ca565b60405180910390f35b3480156109d8575f5ffd5b506109f360048036038101906109ee9190613990565b612dbf565b604051610a009190613a3b565b60405180910390f35b348015610a14575f5ffd5b50610a2f6004803603810190610a2a9190613e34565b612ddc565b005b348015610a3c575f5ffd5b50610a576004803603810190610a529190613990565b612e60565b604051610a6491906139ca565b60405180910390f35b610a876004803603810190610a8291906139e3565b612e75565b005b348015610a94575f5ffd5b50610a9d613273565b604051610aaa91906139ca565b60405180910390f35b3373ffffffffffffffffffffffffffffffffffffffff1673664eb769b64e5cbd41e2a832a4a4e65bfd2d22f073ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610b1791906139ca565b602060405180830381865afa158015610b32573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b5691906142f0565b73ffffffffffffffffffffffffffffffffffffffff1614610bac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ba390614365565b60405180910390fd5b60045f8281526020019081526020015f205f9054906101000a900460ff1615610c0a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c01906143cd565b60405180910390fd5b600160045f8381526020019081526020015f205f6101000a81548160ff0219169083151502179055505f6103e860015f8481526020019081526020015f2054610c539190614418565b9050610c5f828261327f565b813373ffffffffffffffffffffffffffffffffffffffff167fb59108fb73962c3f9d886946836d81f4708977d050e29e8a90a18888ea25b71f6103e842604051610caa929190614171565b60405180910390a35050565b5f60015f8381526020019081526020015f20549050919050565b3373ffffffffffffffffffffffffffffffffffffffff1673664eb769b64e5cbd41e2a832a4a4e65bfd2d22f073ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610d3491906139ca565b602060405180830381865afa158015610d4f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d7391906142f0565b73ffffffffffffffffffffffffffffffffffffffff1614610dc9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dc090614365565b60405180910390fd5b6201518060025f8381526020019081526020015f2054610de99190614418565b421015610e2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e2290614495565b60405180910390fd5b4260025f8381526020019081526020015f20819055505f606460015f8481526020019081526020015f2054610e609190614418565b9050610e6c828261327f565b813373ffffffffffffffffffffffffffffffffffffffff167f055990c087ead69a2aa2caa8fa65fff9580fa2a33cd931ee7609b083201cba27606442604051610eb6929190614171565b60405180910390a35050565b610e1081565b5f6007805490508310610f10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f07906144fd565b60405180910390fd5b60085f8481526020019081526020015f205f015f8381526020019081526020015f205f9054906101000a900460ff16905092915050565b60608060608060605f600780549050905080871115610f64578096505b8667ffffffffffffffff811115610f7e57610f7d61451b565b5b604051908082528060200260200182016040528015610fac5781602001602082028036833780820191505090505b5095508667ffffffffffffffff811115610fc957610fc861451b565b5b604051908082528060200260200182016040528015610ffc57816020015b6060815260200190600190039081610fe75790505b5094508667ffffffffffffffff8111156110195761101861451b565b5b60405190808252806020026020018201604052801561104c57816020015b60608152602001906001900390816110375790505b5093508667ffffffffffffffff8111156110695761106861451b565b5b6040519080825280602002602001820160405280156110975781602001602082028036833780820191505090505b5092508667ffffffffffffffff8111156110b4576110b361451b565b5b6040519080825280602002602001820160405280156110e25781602001602082028036833780820191505090505b5091505f87826110f29190614548565b90505f5f90505b88811015611341575f818361110e9190614418565b90505f600782815481106111255761112461457b565b5b905f5260205f2090600402016040518060800160405290815f8201548152602001600182018054611155906145d5565b80601f0160208091040260200160405190810160405280929190818152602001828054611181906145d5565b80156111cc5780601f106111a3576101008083540402835291602001916111cc565b820191905f5260205f20905b8154815290600101906020018083116111af57829003601f168201915b50505050508152602001600282015481526020016003820154815250509050805f01518a84815181106112025761120161457b565b5b6020026020010181815250505f73664eb769b64e5cbd41e2a832a4a4e65bfd2d22f073ffffffffffffffffffffffffffffffffffffffff1663dabb0531835f01516040518263ffffffff1660e01b815260040161125f91906139ca565b5f60405180830381865afa158015611279573d5f5f3e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906112a191906147db565b905080608001518a85815181106112bb576112ba61457b565b5b602002602001018190525081602001518985815181106112de576112dd61457b565b5b602002602001018190525081604001518885815181106113015761130061457b565b5b60200260200101818152505081606001518785815181106113255761132461457b565b5b60200260200101818152505050505080806001019150506110f9565b50505091939590929450565b61135561337f565b81819050848490501461139d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113949061486c565b60405180910390fd5b5f5f90505b8484905081101561160e575f8585838181106113c1576113c061457b565b5b9050602002013590505f73ffffffffffffffffffffffffffffffffffffffff1673664eb769b64e5cbd41e2a832a4a4e65bfd2d22f073ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161142e91906139ca565b602060405180830381865afa158015611449573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061146d91906142f0565b73ffffffffffffffffffffffffffffffffffffffff16036114c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114ba906148d4565b60405180910390fd5b5f73664eb769b64e5cbd41e2a832a4a4e65bfd2d22f073ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161151191906139ca565b602060405180830381865afa15801561152c573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061155091906142f0565b90505f8585858181106115665761156561457b565b5b9050602002013560015f8581526020019081526020015f20546115899190614418565b9050611595838261327f565b8173ffffffffffffffffffffffffffffffffffffffff167f726f468aa8d525df4ba9517fa838db1ad35a3d2cc93bf79f855828477dd75fc98787878181106115e0576115df61457b565b5b90506020020135426040516115f6929190614171565b60405180910390a250505080806001019150506113a2565b5050505050565b600a81565b5f5f5f5f5f6201518060025f8881526020019081526020015f205461163f9190614418565b42101594506201518060025f8881526020019081526020015f20546116649190614418565b9350610e1060035f8881526020019081526020015f20546116859190614418565b4210159250610e1060035f8881526020019081526020015f20546116a99190614418565b915060045f8781526020019081526020015f205f9054906101000a900460ff1615905091939590929450565b6116dd61337f565b5f4790505f8111611723576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161171a9061493c565b60405180910390fd5b61172b6126c9565b73ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f1935050505015801561176d573d5f5f3e3d5ffd5b5050565b6060805f60058054905090505f5f90505f5f90505b82811015611889575f600582815481106117a3576117a261457b565b5b905f5260205f20015490508673ffffffffffffffffffffffffffffffffffffffff1673664eb769b64e5cbd41e2a832a4a4e65bfd2d22f073ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b815260040161181291906139ca565b602060405180830381865afa15801561182d573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061185191906142f0565b73ffffffffffffffffffffffffffffffffffffffff160361187b5782806118779061495a565b9350505b508080600101915050611786565b508067ffffffffffffffff8111156118a4576118a361451b565b5b6040519080825280602002602001820160405280156118d25781602001602082028036833780820191505090505b5093508067ffffffffffffffff8111156118ef576118ee61451b565b5b60405190808252806020026020018201604052801561191d5781602001602082028036833780820191505090505b5092505f5f90505f5f90505b83811015611a7d575f600582815481106119465761194561457b565b5b905f5260205f20015490508773ffffffffffffffffffffffffffffffffffffffff1673664eb769b64e5cbd41e2a832a4a4e65bfd2d22f073ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b81526004016119b591906139ca565b602060405180830381865afa1580156119d0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119f491906142f0565b73ffffffffffffffffffffffffffffffffffffffff1603611a6f5780878481518110611a2357611a2261457b565b5b60200260200101818152505060015f8281526020019081526020015f2054868481518110611a5457611a5361457b565b5b6020026020010181815250508280611a6b9061495a565b9350505b508080600101915050611929565b50505050915091565b5f5f5f60078054905091505f90505f5f90505b82811015611adf5760078181548110611ab557611ab461457b565b5b905f5260205f2090600402016003015482611ad09190614418565b91508080600101915050611a99565b50819250909192565b6060806060805f60058054905090505f8103611c3b575f67ffffffffffffffff811115611b1857611b1761451b565b5b604051908082528060200260200182016040528015611b465781602001602082028036833780820191505090505b505f67ffffffffffffffff811115611b6157611b6061451b565b5b604051908082528060200260200182016040528015611b9a57816020015b611b876138a7565b815260200190600190039081611b7f5790505b505f67ffffffffffffffff811115611bb557611bb461451b565b5b604051908082528060200260200182016040528015611be35781602001602082028036833780820191505090505b505f67ffffffffffffffff811115611bfe57611bfd61451b565b5b604051908082528060200260200182016040528015611c2c5781602001602082028036833780820191505090505b509450945094509450506120ca565b808710611c7d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c74906149eb565b60405180910390fd5b5f8688611c8a9190614418565b905081811115611c98578190505b5f8882611ca59190614548565b90505f8367ffffffffffffffff811115611cc257611cc161451b565b5b604051908082528060200260200182016040528015611cf05781602001602082028036833780820191505090505b5090505f8467ffffffffffffffff811115611d0e57611d0d61451b565b5b604051908082528060200260200182016040528015611d3c5781602001602082028036833780820191505090505b5090505f5f90505b85811015611de25760058181548110611d6057611d5f61457b565b5b905f5260205f200154838281518110611d7c57611d7b61457b565b5b60200260200101818152505060015f60058381548110611d9f57611d9e61457b565b5b905f5260205f20015481526020019081526020015f2054828281518110611dc957611dc861457b565b5b6020026020010181815250508080600101915050611d44565b50611dfb82825f600189611df69190614548565b613406565b8267ffffffffffffffff811115611e1557611e1461451b565b5b604051908082528060200260200182016040528015611e435781602001602082028036833780820191505090505b5098508267ffffffffffffffff811115611e6057611e5f61451b565b5b604051908082528060200260200182016040528015611e9957816020015b611e866138a7565b815260200190600190039081611e7e5790505b5097508267ffffffffffffffff811115611eb657611eb561451b565b5b604051908082528060200260200182016040528015611ee45781602001602082028036833780820191505090505b5096508267ffffffffffffffff811115611f0157611f0061451b565b5b604051908082528060200260200182016040528015611f2f5781602001602082028036833780820191505090505b5095505f5f90505b838110156120c3575f818d611f4c9190614418565b9050838181518110611f6157611f6061457b565b5b60200260200101518b8381518110611f7c57611f7b61457b565b5b60200260200101818152505073664eb769b64e5cbd41e2a832a4a4e65bfd2d22f073ffffffffffffffffffffffffffffffffffffffff1663dabb0531858381518110611fcb57611fca61457b565b5b60200260200101516040518263ffffffff1660e01b8152600401611fef91906139ca565b5f60405180830381865afa158015612009573d5f5f3e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061203191906147db565b8a83815181106120445761204361457b565b5b60200260200101819052508281815181106120625761206161457b565b5b602002602001015189838151811061207d5761207c61457b565b5b6020026020010181815250506001816120969190614418565b8883815181106120a9576120a861457b565b5b602002602001018181525050508080600101915050611f37565b5050505050505b92959194509250565b66038d7ea4c6800081565b60608060606120ed5f85611ae8565b508093508194508295505050509193909250565b5f47905090565b5f5f60058054905090505f5f90505b8181101561222b575f600582815481106121345761213361457b565b5b905f5260205f20015490508473ffffffffffffffffffffffffffffffffffffffff1673664eb769b64e5cbd41e2a832a4a4e65bfd2d22f073ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b81526004016121a391906139ca565b602060405180830381865afa1580156121be573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121e291906142f0565b73ffffffffffffffffffffffffffffffffffffffff160361221d5760015f8281526020019081526020015f20548461221a9190614418565b93505b508080600101915050612117565b5050919050565b61223a61337f565b6122435f61360f565b565b5f600780549050821061228d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612284906144fd565b60405180910390fd5b600782815481106122a1576122a061457b565b5b905f5260205f209060040201600301549050919050565b600581815481106122c7575f80fd5b905f5260205f20015f915090505481565b6103e881565b5f600580549050905090565b6201518081565b60608060608060605f60078054905090508067ffffffffffffffff81111561231c5761231b61451b565b5b60405190808252806020026020018201604052801561234a5781602001602082028036833780820191505090505b5095508067ffffffffffffffff8111156123675761236661451b565b5b60405190808252806020026020018201604052801561239a57816020015b60608152602001906001900390816123855790505b5094508067ffffffffffffffff8111156123b7576123b661451b565b5b6040519080825280602002602001820160405280156123ea57816020015b60608152602001906001900390816123d55790505b5093508067ffffffffffffffff8111156124075761240661451b565b5b6040519080825280602002602001820160405280156124355781602001602082028036833780820191505090505b5092508067ffffffffffffffff8111156124525761245161451b565b5b6040519080825280602002602001820160405280156124805781602001602082028036833780820191505090505b5091505f5f90505b818110156126c0575f600782815481106124a5576124a461457b565b5b905f5260205f2090600402016040518060800160405290815f82015481526020016001820180546124d5906145d5565b80601f0160208091040260200160405190810160405280929190818152602001828054612501906145d5565b801561254c5780601f106125235761010080835404028352916020019161254c565b820191905f5260205f20905b81548152906001019060200180831161252f57829003601f168201915b50505050508152602001600282015481526020016003820154815250509050805f01518883815181106125825761258161457b565b5b6020026020010181815250505f73664eb769b64e5cbd41e2a832a4a4e65bfd2d22f073ffffffffffffffffffffffffffffffffffffffff1663dabb0531835f01516040518263ffffffff1660e01b81526004016125df91906139ca565b5f60405180830381865afa1580156125f9573d5f5f3e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061262191906147db565b9050806080015188848151811061263b5761263a61457b565b5b6020026020010181905250816020015187848151811061265e5761265d61457b565b5b602002602001018190525081604001518684815181106126815761268061457b565b5b60200260200101818152505081606001518584815181106126a5576126a461457b565b5b60200260200101818152505050508080600101915050612488565b50509091929394565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6006602052805f5260405f205f915054906101000a900460ff1681565b600481565b6060806060805f85876127259190614a09565b90506127318187611ae8565b94509450945094505092959194509250565b73664eb769b64e5cbd41e2a832a4a4e65bfd2d22f081565b5f5f60065f8481526020019081526020015f205f9054906101000a900460ff1661278a575f5f9150915061281c565b60015f8481526020019081526020015f205490505f60058054905090505f5f90505f5f90505b82811015612809578360015f600584815481106127d0576127cf61457b565b5b905f5260205f20015481526020019081526020015f205411156127fc5781806127f89061495a565b9250505b80806001019150506127b0565b506001816128179190614418565b935050505b915091565b3373ffffffffffffffffffffffffffffffffffffffff1673664eb769b64e5cbd41e2a832a4a4e65bfd2d22f073ffffffffffffffffffffffffffffffffffffffff16636352211e856040518263ffffffff1660e01b815260040161288591906139ca565b602060405180830381865afa1580156128a0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128c491906142f0565b73ffffffffffffffffffffffffffffffffffffffff161461291a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161291190614365565b60405180910390fd5b5f828290501161295f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161295690614a94565b60405180910390fd5b66038d7ea4c6800034146129a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161299f90614afc565b60405180910390fd5b5f5a90506129b78484846136d0565b5a816129c39190614548565b90505f633b9aca00612710836129d99190614a09565b6129e39190614b47565b60016129ef9190614418565b90505f811115612a25575f8160015f8881526020019081526020015f2054612a179190614418565b9050612a23868261327f565b505b843373ffffffffffffffffffffffffffffffffffffffff167f055990c087ead69a2aa2caa8fa65fff9580fa2a33cd931ee7609b083201cba278342604051612a6e929190614171565b60405180910390a3847f81199b04cfb3936bbf995822d4dcbdffa0737dc42066025a1031dd09b0aaf9708585426001600780549050612aad9190614548565b86604051612abf959493929190614bb1565b60405180910390a25050505050565b3373ffffffffffffffffffffffffffffffffffffffff1673664eb769b64e5cbd41e2a832a4a4e65bfd2d22f073ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401612b3291906139ca565b602060405180830381865afa158015612b4d573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b7191906142f0565b73ffffffffffffffffffffffffffffffffffffffff1614612bc7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bbe90614365565b60405180910390fd5b610e1060035f8381526020019081526020015f2054612be69190614418565b421015612c28576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c1f90614495565b60405180910390fd5b4260035f8381526020019081526020015f20819055505f600460015f8481526020019081526020015f2054612c5d9190614418565b9050612c69828261327f565b813373ffffffffffffffffffffffffffffffffffffffff167f055990c087ead69a2aa2caa8fa65fff9580fa2a33cd931ee7609b083201cba27600442604051612cb3929190614171565b60405180910390a35050565b606481565b6003602052805f5260405f205f915090505481565b606481565b60078181548110612ced575f80fd5b905f5260205f2090600402015f91509050805f015490806001018054612d12906145d5565b80601f0160208091040260200160405190810160405280929190818152602001828054612d3e906145d5565b8015612d895780601f10612d6057610100808354040283529160200191612d89565b820191905f5260205f20905b815481529060010190602001808311612d6c57829003601f168201915b5050505050908060020154908060030154905084565b6001602052805f5260405f205f915090505481565b61271081565b600181565b6004602052805f5260405f205f915054906101000a900460ff1681565b612de461337f565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612e54575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401612e4b91906140e4565b60405180910390fd5b612e5d8161360f565b50565b6002602052805f5260405f205f915090505481565b3373ffffffffffffffffffffffffffffffffffffffff1673664eb769b64e5cbd41e2a832a4a4e65bfd2d22f073ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401612ed991906139ca565b602060405180830381865afa158015612ef4573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612f1891906142f0565b73ffffffffffffffffffffffffffffffffffffffff1614612f6e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f6590614365565b60405180910390fd5b6007805490508210612fb5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612fac906144fd565b60405180910390fd5b67016345785d8a00003414612fff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ff690614c47565b60405180910390fd5b5f600783815481106130145761301361457b565b5b905f5260205f209060040201905081815f015403613067576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161305e90614caf565b60405180910390fd5b60085f8481526020019081526020015f205f015f8381526020019081526020015f205f9054906101000a900460ff16156130d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130cd90614d17565b60405180910390fd5b600160085f8581526020019081526020015f205f015f8481526020019081526020015f205f6101000a81548160ff021916908315150217905550806003015f8154809291906131249061495a565b91905055505f600a60015f845f015481526020019081526020015f205461314b9190614418565b905061315a825f01548261327f565b5f6001805f8681526020019081526020015f20546131789190614418565b9050613184848261327f565b825f015484867f7b75ace263ae42acfd7d0783452ee2cfc6e5829756223292617e19af47f58c4f600a60016040516131bd929190614171565b60405180910390a4825f01543373ffffffffffffffffffffffffffffffffffffffff167f055990c087ead69a2aa2caa8fa65fff9580fa2a33cd931ee7609b083201cba27600a42604051613212929190614171565b60405180910390a3833373ffffffffffffffffffffffffffffffffffffffff167f055990c087ead69a2aa2caa8fa65fff9580fa2a33cd931ee7609b083201cba27600142604051613264929190614171565b60405180910390a35050505050565b67016345785d8a000081565b8060015f8481526020019081526020015f208190555060065f8381526020019081526020015f205f9054906101000a900460ff1661334157600582908060018154018082558091505060019003905f5260205f20015f9091909190915055600160065f8481526020019081526020015f205f6101000a81548160ff021916908315150217905550817f7f36fd05ce62258919a4d9eba687ce245fae44d0b5c144a11b12c25c293a86fd3342604051613338929190614d35565b60405180910390a25b817f387d01e96a7dce0e6676dd7a6ea815d3160e37ef13867fc6e9ce5fe9be85f4048242604051613373929190614171565b60405180910390a25050565b6133876138a0565b73ffffffffffffffffffffffffffffffffffffffff166133a56126c9565b73ffffffffffffffffffffffffffffffffffffffff1614613404576133c86138a0565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016133fb91906140e4565b60405180910390fd5b565b80821215613609575f8290505f8290505f85600286866134269190614d65565b6134309190614da5565b8661343b9190614e0d565b8151811061344c5761344b61457b565b5b602002602001015190505b8183136135db575b808684815181106134735761347261457b565b5b6020026020010151111561349457828061348c90614e4e565b93505061345f565b5b8582815181106134a8576134a761457b565b5b60200260200101518111156134ca5781806134c290614e95565b925050613495565b8183136135d6578682815181106134e4576134e361457b565b5b60200260200101518784815181106134ff576134fe61457b565b5b602002602001015188858151811061351a5761351961457b565b5b602002602001018985815181106135345761353361457b565b5b60200260200101828152508281525050508582815181106135585761355761457b565b5b60200260200101518684815181106135735761357261457b565b5b602002602001015187858151811061358e5761358d61457b565b5b602002602001018885815181106135a8576135a761457b565b5b602002602001018281525082815250505082806135c490614e4e565b93505081806135d290614e95565b9250505b613457565b818512156135f0576135ef87878785613406565b5b838312156136055761360487878587613406565b5b5050505b50505050565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f604051806080016040528085815260200184848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505081526020014281526020015f815250905060646007805490501061383d575f5f90505b600160078054905061375b9190614548565b8110156137ef5760076001826137719190614418565b815481106137825761378161457b565b5b905f5260205f209060040201600782815481106137a2576137a161457b565b5b905f5260205f2090600402015f820154815f0155600182018160010190816137ca9190615088565b5060028201548160020155600382015481600301559050508080600101915050613749565b5060078054806138025761380161516d565b5b600190038181905f5260205f2090600402015f5f82015f9055600182015f61382a91906138f4565b600282015f9055600382015f9055505090555b600781908060018154018082558091505060019003905f5260205f2090600402015f909190919091505f820151815f01556020820151816001019081613883919061519a565b506040820151816002015560608201518160030155505050505050565b5f33905090565b6040518060e001604052805f81526020015f81526020015f81526020015f8152602001606081526020015f81526020015f73ffffffffffffffffffffffffffffffffffffffff1681525090565b508054613900906145d5565b5f825580601f10613911575061392e565b601f0160209004905f5260205f209081019061392d9190613931565b5b50565b5b80821115613948575f815f905550600101613932565b5090565b5f604051905090565b5f5ffd5b5f5ffd5b5f819050919050565b61396f8161395d565b8114613979575f5ffd5b50565b5f8135905061398a81613966565b92915050565b5f602082840312156139a5576139a4613955565b5b5f6139b28482850161397c565b91505092915050565b6139c48161395d565b82525050565b5f6020820190506139dd5f8301846139bb565b92915050565b5f5f604083850312156139f9576139f8613955565b5b5f613a068582860161397c565b9250506020613a178582860161397c565b9150509250929050565b5f8115159050919050565b613a3581613a21565b82525050565b5f602082019050613a4e5f830184613a2c565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b613a868161395d565b82525050565b5f613a978383613a7d565b60208301905092915050565b5f602082019050919050565b5f613ab982613a54565b613ac38185613a5e565b9350613ace83613a6e565b805f5b83811015613afe578151613ae58882613a8c565b9750613af083613aa3565b925050600181019050613ad1565b5085935050505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f613b7682613b34565b613b808185613b3e565b9350613b90818560208601613b4e565b613b9981613b5c565b840191505092915050565b5f613baf8383613b6c565b905092915050565b5f602082019050919050565b5f613bcd82613b0b565b613bd78185613b15565b935083602082028501613be985613b25565b805f5b85811015613c245784840389528151613c058582613ba4565b9450613c1083613bb7565b925060208a01995050600181019050613bec565b50829750879550505050505092915050565b5f60a0820190508181035f830152613c4e8188613aaf565b90508181036020830152613c628187613bc3565b90508181036040830152613c768186613bc3565b90508181036060830152613c8a8185613aaf565b90508181036080830152613c9e8184613aaf565b90509695505050505050565b5f5ffd5b5f5ffd5b5f5ffd5b5f5f83601f840112613ccb57613cca613caa565b5b8235905067ffffffffffffffff811115613ce857613ce7613cae565b5b602083019150836020820283011115613d0457613d03613cb2565b5b9250929050565b5f5f5f5f60408587031215613d2357613d22613955565b5b5f85013567ffffffffffffffff811115613d4057613d3f613959565b5b613d4c87828801613cb6565b9450945050602085013567ffffffffffffffff811115613d6f57613d6e613959565b5b613d7b87828801613cb6565b925092505092959194509250565b5f60a082019050613d9c5f830188613a2c565b613da960208301876139bb565b613db66040830186613a2c565b613dc360608301856139bb565b613dd06080830184613a2c565b9695505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f613e0382613dda565b9050919050565b613e1381613df9565b8114613e1d575f5ffd5b50565b5f81359050613e2e81613e0a565b92915050565b5f60208284031215613e4957613e48613955565b5b5f613e5684828501613e20565b91505092915050565b5f6040820190508181035f830152613e778185613aaf565b90508181036020830152613e8b8184613aaf565b90509392505050565b5f606082019050613ea75f8301866139bb565b613eb460208301856139bb565b613ec160408301846139bb565b949350505050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b613efb81613df9565b82525050565b5f60e083015f830151613f165f860182613a7d565b506020830151613f296020860182613a7d565b506040830151613f3c6040860182613a7d565b506060830151613f4f6060860182613a7d565b5060808301518482036080860152613f678282613b6c565b91505060a0830151613f7c60a0860182613a7d565b5060c0830151613f8f60c0860182613ef2565b508091505092915050565b5f613fa58383613f01565b905092915050565b5f602082019050919050565b5f613fc382613ec9565b613fcd8185613ed3565b935083602082028501613fdf85613ee3565b805f5b8581101561401a5784840389528151613ffb8582613f9a565b945061400683613fad565b925060208a01995050600181019050613fe2565b50829750879550505050505092915050565b5f6080820190508181035f8301526140448187613aaf565b905081810360208301526140588186613fb9565b9050818103604083015261406c8185613aaf565b905081810360608301526140808184613aaf565b905095945050505050565b5f6060820190508181035f8301526140a38186613aaf565b905081810360208301526140b78185613fb9565b905081810360408301526140cb8184613aaf565b9050949350505050565b6140de81613df9565b82525050565b5f6020820190506140f75f8301846140d5565b92915050565b5f819050919050565b5f61412061411b61411684613dda565b6140fd565b613dda565b9050919050565b5f61413182614106565b9050919050565b5f61414282614127565b9050919050565b61415281614138565b82525050565b5f60208201905061416b5f830184614149565b92915050565b5f6040820190506141845f8301856139bb565b61419160208301846139bb565b9392505050565b5f5f83601f8401126141ad576141ac613caa565b5b8235905067ffffffffffffffff8111156141ca576141c9613cae565b5b6020830191508360018202830111156141e6576141e5613cb2565b5b9250929050565b5f5f5f6040848603121561420457614203613955565b5b5f6142118682870161397c565b935050602084013567ffffffffffffffff81111561423257614231613959565b5b61423e86828701614198565b92509250509250925092565b5f82825260208201905092915050565b5f61426482613b34565b61426e818561424a565b935061427e818560208601613b4e565b61428781613b5c565b840191505092915050565b5f6080820190506142a55f8301876139bb565b81810360208301526142b7818661425a565b90506142c660408301856139bb565b6142d360608301846139bb565b95945050505050565b5f815190506142ea81613e0a565b92915050565b5f6020828403121561430557614304613955565b5b5f614312848285016142dc565b91505092915050565b7f4e6f7420746f6b656e206f776e657200000000000000000000000000000000005f82015250565b5f61434f600f8361424a565b915061435a8261431b565b602082019050919050565b5f6020820190508181035f83015261437c81614343565b9050919050565b7f426f6e757320616c726561647920636c61696d656400000000000000000000005f82015250565b5f6143b760158361424a565b91506143c282614383565b602082019050919050565b5f6020820190508181035f8301526143e4816143ab565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6144228261395d565b915061442d8361395d565b9250828201905080821115614445576144446143eb565b5b92915050565b7f436f6f6c646f776e2061637469766500000000000000000000000000000000005f82015250565b5f61447f600f8361424a565b915061448a8261444b565b602082019050919050565b5f6020820190508181035f8301526144ac81614473565b9050919050565b7f496e76616c6964206d65737361676520696e64657800000000000000000000005f82015250565b5f6144e760158361424a565b91506144f2826144b3565b602082019050919050565b5f6020820190508181035f830152614514816144db565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f6145528261395d565b915061455d8361395d565b9250828203905081811115614575576145746143eb565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806145ec57607f821691505b6020821081036145ff576145fe6145a8565b5b50919050565b5f5ffd5b61461282613b5c565b810181811067ffffffffffffffff821117156146315761463061451b565b5b80604052505050565b5f61464361394c565b905061464f8282614609565b919050565b5f5ffd5b5f8151905061466681613966565b92915050565b5f5ffd5b5f67ffffffffffffffff82111561468a5761468961451b565b5b61469382613b5c565b9050602081019050919050565b5f6146b26146ad84614670565b61463a565b9050828152602081018484840111156146ce576146cd61466c565b5b6146d9848285613b4e565b509392505050565b5f82601f8301126146f5576146f4613caa565b5b81516147058482602086016146a0565b91505092915050565b5f60e0828403121561472357614722614605565b5b61472d60e061463a565b90505f61473c84828501614658565b5f83015250602061474f84828501614658565b602083015250604061476384828501614658565b604083015250606061477784828501614658565b606083015250608082015167ffffffffffffffff81111561479b5761479a614654565b5b6147a7848285016146e1565b60808301525060a06147bb84828501614658565b60a08301525060c06147cf848285016142dc565b60c08301525092915050565b5f602082840312156147f0576147ef613955565b5b5f82015167ffffffffffffffff81111561480d5761480c613959565b5b6148198482850161470e565b91505092915050565b7f417272617973206c656e677468206d69736d61746368000000000000000000005f82015250565b5f61485660168361424a565b915061486182614822565b602082019050919050565b5f6020820190508181035f8301526148838161484a565b9050919050565b7f496e76616c696420746f6b656e204944000000000000000000000000000000005f82015250565b5f6148be60108361424a565b91506148c98261488a565b602082019050919050565b5f6020820190508181035f8301526148eb816148b2565b9050919050565b7f4e6f2066756e647320746f2077697468647261770000000000000000000000005f82015250565b5f61492660148361424a565b9150614931826148f2565b602082019050919050565b5f6020820190508181035f8301526149538161491a565b9050919050565b5f6149648261395d565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614996576149956143eb565b5b600182019050919050565b7f537461727420696e646578206f7574206f6620626f756e6473000000000000005f82015250565b5f6149d560198361424a565b91506149e0826149a1565b602082019050919050565b5f6020820190508181035f830152614a02816149c9565b9050919050565b5f614a138261395d565b9150614a1e8361395d565b9250828202614a2c8161395d565b91508282048414831517614a4357614a426143eb565b5b5092915050565b7f4d6573736167652063616e6e6f7420626520656d7074790000000000000000005f82015250565b5f614a7e60178361424a565b9150614a8982614a4a565b602082019050919050565b5f6020820190508181035f830152614aab81614a72565b9050919050565b7f496e636f7272656374206d65737361676520636f7374000000000000000000005f82015250565b5f614ae660168361424a565b9150614af182614ab2565b602082019050919050565b5f6020820190508181035f830152614b1381614ada565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f614b518261395d565b9150614b5c8361395d565b925082614b6c57614b6b614b1a565b5b828204905092915050565b828183375f83830152505050565b5f614b90838561424a565b9350614b9d838584614b77565b614ba683613b5c565b840190509392505050565b5f6080820190508181035f830152614bca818789614b85565b9050614bd960208301866139bb565b614be660408301856139bb565b614bf360608301846139bb565b9695505050505050565b7f496e636f7272656374206c696b6520636f7374000000000000000000000000005f82015250565b5f614c3160138361424a565b9150614c3c82614bfd565b602082019050919050565b5f6020820190508181035f830152614c5e81614c25565b9050919050565b7f43616e6e6f74206c696b65206f776e206d6573736167650000000000000000005f82015250565b5f614c9960178361424a565b9150614ca482614c65565b602082019050919050565b5f6020820190508181035f830152614cc681614c8d565b9050919050565b7f416c7265616479206c696b65642074686973206d6573736167650000000000005f82015250565b5f614d01601a8361424a565b9150614d0c82614ccd565b602082019050919050565b5f6020820190508181035f830152614d2e81614cf5565b9050919050565b5f604082019050614d485f8301856140d5565b614d5560208301846139bb565b9392505050565b5f819050919050565b5f614d6f82614d5c565b9150614d7a83614d5c565b925082820390508181125f8412168282135f851215161715614d9f57614d9e6143eb565b5b92915050565b5f614daf82614d5c565b9150614dba83614d5c565b925082614dca57614dc9614b1a565b5b60015f0383147f800000000000000000000000000000000000000000000000000000000000000083141615614e0257614e016143eb565b5b828205905092915050565b5f614e1782614d5c565b9150614e2283614d5c565b92508282019050828112155f8312168382125f841215161715614e4857614e476143eb565b5b92915050565b5f614e5882614d5c565b91507f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614e8a57614e896143eb565b5b600182019050919050565b5f614e9f82614d5c565b91507f80000000000000000000000000000000000000000000000000000000000000008203614ed157614ed06143eb565b5b600182039050919050565b5f81549050614eea816145d5565b9050919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302614f4d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614f12565b614f578683614f12565b95508019841693508086168417925050509392505050565b5f614f89614f84614f7f8461395d565b6140fd565b61395d565b9050919050565b5f819050919050565b614fa283614f6f565b614fb6614fae82614f90565b848454614f1e565b825550505050565b5f5f905090565b614fcd614fbe565b614fd8818484614f99565b505050565b5b81811015614ffb57614ff05f82614fc5565b600181019050614fde565b5050565b601f8211156150405761501181614ef1565b61501a84614f03565b81016020851015615029578190505b61503d61503585614f03565b830182614fdd565b50505b505050565b5f82821c905092915050565b5f6150605f1984600802615045565b1980831691505092915050565b5f6150788383615051565b9150826002028217905092915050565b81810361509657505061516b565b61509f82614edc565b67ffffffffffffffff8111156150b8576150b761451b565b5b6150c282546145d5565b6150cd828285614fff565b5f601f8311600181146150fa575f84156150e8578287015490505b6150f2858261506d565b865550615164565b601f19841661510887614ef1565b965061511386614ef1565b5f5b8281101561513a57848901548255600182019150600185019450602081019050615115565b868310156151575784890154615153601f891682615051565b8355505b6001600288020188555050505b5050505050505b565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffd5b6151a382613b34565b67ffffffffffffffff8111156151bc576151bb61451b565b5b6151c682546145d5565b6151d1828285614fff565b5f60209050601f831160018114615202575f84156151f0578287015190505b6151fa858261506d565b865550615261565b601f19841661521086614ef1565b5f5b8281101561523757848901518255600182019150602085019450602081019050615212565b868310156152545784890151615250601f891682615051565b8355505b6001600288020188555050505b50505050505056fea26469706673582212207e14bc9d7281759c9b45d693303e0ee270cc9aea59d464cbfaa0c0730f6718fe64736f6c634300081e0033

Block Transaction Gas Used Reward
view all blocks ##produced##

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
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.