EthereumEthereum
0x80...4d6E
Proof of Rock

Proof of Rock

POR

收藏品
大小
100
收藏品
所有者
84
84% 独特的所有者
此合同的源代码已经过验证!
合同元数据
编译器
0.8.3+commit.8d00100c
语言
Solidity
合同源代码
文件 1 的 1:ProofOfRockTethered.sol
// SPDX-License-Identifier: NONE

pragma solidity 0.8.3;



// Part: ERC721TokenReceiver

/// @dev Note: the ERC-165 identifier for this interface is 0x150b7a02.
interface ERC721TokenReceiver {
    /// @notice Handle the receipt of an NFT
    /// @dev The ERC721 smart contract calls this function on the recipient
    ///  after a `transfer`. This function MAY throw to revert and reject the
    ///  transfer. Return of other than the magic value MUST result in the
    ///  transaction being reverted.
    ///  Note: the contract address is always the message sender.
    /// @param _operator The address which called `safeTransferFrom` function
    /// @param _from The address which previously owned the token
    /// @param _tokenId The NFT identifier which is being transferred
    /// @param _data Additional data with no specified format
    /// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
    ///         unless throwing
    function onERC721Received(
        address _operator,
        address _from,
        uint256 _tokenId,
        bytes memory _data
    ) external returns (bytes4);
}

// Part: EtherRock

interface EtherRock {
    function getRockInfo(uint256 rockNumber) external view returns (address);

    function rockOwners(address owner, uint256 idx)
        external
        view
        returns (uint256);
}

// Part: ProofOfRock

/**
    @title Proof Of Rock
    @notice ERC721-ish contract where token ownership is 1:1 pegged with ownership of EtherRocks
 */
abstract contract ProofOfRock {
    EtherRock public constant etherRock =
        EtherRock(0x41f28833Be34e6EDe3c58D1f597bef429861c4E2);

    string public name;
    string public symbol;
    uint256 public totalSupply;

    mapping(bytes4 => bool) public supportsInterface;

    string[100] tokenURIs;
    address[100] tokenApprovals;

    mapping(address => mapping(address => bool)) private operatorApprovals;

    bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;
    bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
    bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;
    bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;
    bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;

    event Transfer(
        address indexed _from,
        address indexed _to,
        uint256 indexed _tokenId
    );
    event Approval(
        address indexed _owner,
        address indexed _approved,
        uint256 indexed _tokenId
    );
    event ApprovalForAll(
        address indexed _owner,
        address indexed _operator,
        bool _approved
    );

    constructor(string memory _name, string memory _symbol) {
        name = _name;
        symbol = _symbol;
        supportsInterface[_INTERFACE_ID_ERC165] = true;
        supportsInterface[_INTERFACE_ID_ERC721] = true;
        supportsInterface[_INTERFACE_ID_ERC721_METADATA] = true;
        supportsInterface[_INTERFACE_ID_ERC721_ENUMERABLE] = true;
    }

    /// @notice Count all NFTs assigned to an owner
    function balanceOf(address _owner) public view virtual returns (uint256);

    /// @notice Find the owner of an NFT
    function ownerOf(uint256 tokenId) public view virtual returns (address);

    function tokenOfOwnerByIndex(address _owner, uint256 _index)
        public
        view
        virtual
        returns (uint256);

    function _transfer(
        address _from,
        address _to,
        uint256 _tokenId
    ) internal virtual;

    /// @notice Transfers the ownership of an NFT from one address to another address
    /// @dev Throws unless `msg.sender` is the current owner, an authorized
    ///  operator, or the approved address for this NFT. Throws if `_from` is
    ///  not the current owner. Throws if `_to` is the zero address. Throws if
    ///  `_tokenId` is not a valid NFT. When transfer is complete, this function
    ///  checks if `_to` is a smart contract (code size > 0). If so, it calls
    ///  `onERC721Received` on `_to` and throws if the return value is not
    ///  `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
    /// @param _from The current owner of the NFT
    /// @param _to The new owner
    /// @param _tokenId The NFT to transfer
    /// @param _data Additional data with no specified format, sent in call to `_to`
    function safeTransferFrom(
        address _from,
        address _to,
        uint256 _tokenId,
        bytes memory _data
    ) public {
        _transfer(_from, _to, _tokenId);
        require(
            _checkOnERC721Received(_from, _to, _tokenId, _data),
            "Transfer to non ERC721 receiver"
        );
    }

    /// @notice Transfers the ownership of an NFT from one address to another address
    /// @dev This works identically to the other function with an extra data parameter,
    ///  except this function just sets data to "".
    /// @param _from The current owner of the NFT
    /// @param _to The new owner
    /// @param _tokenId The NFT to transfer
    function safeTransferFrom(
        address _from,
        address _to,
        uint256 _tokenId
    ) external {
        safeTransferFrom(_from, _to, _tokenId, bytes(""));
    }

    /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE
    ///  TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE
    ///  THEY MAY BE PERMANENTLY LOST
    /// @dev Throws unless `msg.sender` is the current owner, an authorized
    ///  operator, or the approved address for this NFT. Throws if `_from` is
    ///  not the current owner. Throws if `_to` is the zero address. Throws if
    ///  `_tokenId` is not a valid NFT.
    /// @param _from The current owner of the NFT
    /// @param _to The new owner
    /// @param _tokenId The NFT to transfer
    function transferFrom(
        address _from,
        address _to,
        uint256 _tokenId
    ) external {
        _transfer(_from, _to, _tokenId);
    }

    /// @notice Change or reaffirm the approved address for an NFT
    function approve(address approved, uint256 tokenId) public {
        address owner = ownerOf(tokenId);
        require(
            msg.sender == owner || isApprovedForAll(owner, msg.sender),
            "Not owner nor approved for all"
        );
        tokenApprovals[tokenId] = approved;
        emit Approval(owner, approved, tokenId);
    }

    /// @notice Get the approved address for a single NFT
    function getApproved(uint256 tokenId) public view returns (address) {
        ownerOf(tokenId);
        return tokenApprovals[tokenId];
    }

    /// @notice Enable or disable approval for a third party ("operator") to manage
    ///         all of `msg.sender`'s assets
    function setApprovalForAll(address operator, bool approved) external {
        operatorApprovals[msg.sender][operator] = approved;
        emit ApprovalForAll(msg.sender, operator, approved);
    }

    /// @notice Query if an address is an authorized operator for another address
    function isApprovedForAll(address owner, address operator)
        public
        view
        returns (bool)
    {
        return operatorApprovals[owner][operator];
    }

    /// @notice Concatenates tokenId to baseURI and returns the string.
    function tokenURI(uint256 tokenId) public view returns (string memory) {
        ownerOf(tokenId);
        return tokenURIs[tokenId];
    }

    /// @notice Enumerate valid NFTs
    function tokenByIndex(uint256 _index) external view returns (uint256) {
        require(_index < totalSupply, "Index out of bounds");
        return _index;
    }

    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly {
            size := extcodesize(to)
        }
        if (size == 0) {
            return true;
        }

        (bool success, bytes memory returnData) = to.call{value: 0}(
            abi.encodeWithSelector(
                ERC721TokenReceiver(to).onERC721Received.selector,
                msg.sender,
                from,
                tokenId,
                _data
            )
        );
        require(success, "Transfer to non ERC721 receiver");
        bytes4 returnValue = abi.decode(returnData, (bytes4));
        return (returnValue == _ERC721_RECEIVED);
    }
}

// File: PoRTethered.sol

/**
    @title Proof Of Rock: Tethered
    @notice ERC721-ish contract where token ownership is 1:1 pegged with ownership of EtherRocks
 */
contract ProofOfRockTethered is ProofOfRock {
    constructor(string memory _name, string memory _symbol)
        ProofOfRock(_name, _symbol)
    {
        totalSupply = 100;
        tokenURIs = [
            "QmPJ8qzTuu4ThCJNDxa7ib1DUYhEbAPzMUpasinnucC5AH",
            "QmXNSt14kaGKauW37VxLShLSqfvLyShzBnVBmbhXbJdci6",
            "QmdtQsrEzrgztRYuKvpnYMxcYLfQxS59x9M5fBQVGvSx3q",
            "QmVwExvwgZuKDavcTGEYLi8wrSEUerRXcSD7NEfbzZgFLE",
            "QmekTo6LMCVRKrdrHPqiMhYwU3uiCqZgVtjjtTRmTk4w5v",
            "QmadAqBoMXm7AdLXWNsLqyBjwEUh9XrEALftKWSVqyb2Ws",
            "QmZi6WxyVEMLzRA6bm51iDNw9qTxbieEJDzAkYbr4b1DMo",
            "Qme1fuKKBUFsGzzwBRDjDtnrfiUHP9zkb3Jgi9ojKk7Hv5",
            "QmRucC5Ux7FvmWCScTKLxCiorxXY8daCyTPx3tGZDRRccb",
            "QmYaNk6gGbQ9QoabN9jurwPQ5py7GjW8M5WWJdwKmzvL9Z",
            "QmYojyCWKPM9e2xYj54H7c2bD67Nbbx2mVjLQZHo7P4WhS",
            "QmVPgPH4yZizyjVHd3YpAHwxQHP5jXfsg3UqnbAWXs5v7d",
            "QmYrzkgg4UVrCuxeYn5ij8Pmygof2rhd7BqrMgTNPBnQ8d",
            "QmTzAzj93EDEMq3jmoRPFV4fsB5rTQHNBFy9EMTSEPh5QA",
            "QmcjQMD9LSZinXWVFqmMdPXXiwqiTUpgSc8pyWRE4QvfuZ",
            "QmfCP8PT934BR4FVsSzsxze8NfLMepwNFb2ZYih4Gz4ZJt",
            "QmNxr6zrdeFZuAdQFmWevQ9BdVuboZevxzrhMcPQRnCjTb",
            "QmUXgtKx6tVvKk1aqDD5aZwB7C5ct3R1tS7m45kgKsgKf2",
            "QmXhvWC3xTBUFe85GLWrqUNay347EVD7hYKc1aBHoyr2Co",
            "QmRUN2R6wLNCfxAz3zK3bdnCYkT4EzGmSQMqLaKaAF1w6G",
            "QmRChgYU8CraSPB4YU1HN9RXuTmx7USR3LPuCHArv5EAGG",
            "Qme5gCUYKxQaqrAEq428dDMpt1neBWkaZnD7YTKxVGwFxU",
            "Qmf8Db6UE3sdcexkG8eK3p88p3bTbL1tSsVFiPTzKuUwdQ",
            "Qmb8C1sfx8cvmo5E5CENzZX4WBJyJdYbf5zVgcfsUH9v1m",
            "QmVdgUU4VBSp8goWBxgAj7zQuCNBYRk1kCkL5a59z2QHbE",
            "QmU3iddwTtYhQUBvxJHmrH4tB71qo7DnvJ9yoEwJfipUK3",
            "QmWH894qumXwCupitw4U1YQ7P6rhZhxAjJSSCj9Jm9tZu7",
            "QmR2JTwZLTurjFfL2nrqVuFJBo9TvnerrybGuDsA4uv3EP",
            "QmdAWM9HnxehbX1mEHN6FAPTuksNrZjEVhKHoSRtWYxYct",
            "QmTLi4PMR9oas2Rtq3LjXxGfFKbVqFGxh7xrQd98tZxHWp",
            "QmcVWASAA2oDVmUyiP1pLMtbAQx4MimWEJZLjxgQmZv9cW",
            "QmY5cmDU3VuRkJV8hA1wRcvxK6ECLD9nmsvQXqV69MUFyg",
            "QmNi2Th3LdhyeccUJZNHjVRBKvpB9MFYJi26w9rZiRwJkT",
            "QmfFEoTsJCvzuRE8z184sTEzYdEtDkaFtDuzAKT5QWMKHo",
            "Qmf5HTTWV9EST9J4QMXM5VRpLVw9NdQLxgPJYGp35NseZz",
            "QmbpSpiEKzXwjq41MeCxqPfMkdt2xRNHGQ26uKRyekwuQ8",
            "QmZmHDrodoc1KvZwb2SzVo6Bu3zouWogmEQG9GMGrFLuAR",
            "QmdvxaEqZA5tihnm2kQ3maPq6njZ66EXRzVamYnHaPjipb",
            "QmRcdQbuuTyc2wp6jsbJog7Cf31WkXC6LptXs9VgErjBPK",
            "QmSkGRL66jKDqwVwvU2vGsGtgq8Ejy7LdGy7Fyc8RsuZzC",
            "QmXnwPkxfvSuTFwV9Wk4ibVo9ci8qKmjmMXWjTJXf8pgTs",
            "QmcdrEVE5KKTCU59gCuFJ87HijSovzdpBF8USmubhd4d6z",
            "QmQt7KDGaPVxxzFiuvKpfdSjDfbT9ATHdK7JY1EEdZzT52",
            "QmPijpreFELWBJnxKd4F9gekV4JSjM27szw9VSKC6GxoiX",
            "QmU1Db1Ft4gXLkdHNCw7uM98dLpfVq39b8aK1oLWMZN7QT",
            "QmaynTAHbVGg2ERcDbpnBukoFgwL8f4eKDDVuBYfRFi4Qu",
            "QmWnLxpYCG4HmCCiULdBSpayqw3JtfJvz4gkTuobzeVLQ1",
            "QmSWERGitRfcD5ABk322z8RGf2dWS5MvJi3wisHX7dMknN",
            "QmdBxsrXs1sK1btiQKybveyLTqeG2kHG1xuKt6c6piEHNF",
            "QmVmMoYeBUc9o1NFA5ucDwmi2BGpbaEoCQ2ARBGC7LP6jR",
            "QmSupSUfBfnyCqoBHzCnxkSWRzqHoJRAQJjWYDzg5Jhb6C",
            "Qmd2ZuNVGSTbj2qBfLSUkgcKTcfWgMpgtbyhkdJrPQSgm8",
            "QmNoTWLsm6BYPsyVRDdKjhMPBsMJ8f2TZQmKtGk5fu7tWz",
            "QmcFmPHiGmoYjZ5nrj2EnkvcgNgT6e8oADyBZ6Gk6SE8Y9",
            "QmdcSqkNo5Txp3hoZWftHmt98kenvTWAuKjXPHJfSsv3RC",
            "QmU3eBA5q7b94rUThWARPvMobedNRSZ7ueBxCTGZmzv1nR",
            "QmSbmXujufQtFTi6K2SAcQ8etQSS2GtY7gf2RPYfyjo1nv",
            "QmVmSeqorghs6omNbRSnrBFjWun4qxrZ8buEkyMruuRbpB",
            "QmQT3gfDXYvk8iix1iv68UpoCJbpnsBay7Lpf5X67mGzRV",
            "QmeraW9Drh6VuaLk1ev7xpTDqEzh5tHFjd5CttMC57xmVX",
            "QmQ4ABH8SLDrLaZiHhebfbQEUudcgkvdVAvWUQyCE46Yqo",
            "QmRqJimbHkndUmYG1pxMFYMWp51P2qg9KdorEKZhU6XDt2",
            "QmPwzA4UKaQQeJmjtfXdaVhUodAz3TvA5pkympumeU4BEF",
            "QmcgJWLMF7q3eJScKrD9F6cqg6Fa4MivJCcKaU7SQYhYhM",
            "QmRXKHKvnBhKyEteGxw59DLqsouTPBYvTuHyHSmbxCLtND",
            "QmTVRZH86PEF2MDucSH7grQip9i9fGbLoT5euSW5jG1mis",
            "QmP5r2yf19BJ4VzzL9Z5Txh7TcZcZr2brGWyQY14mEABG8",
            "QmaTryHgQ6ARUJAUedTnPy97njS642zm3Vy6xjfLFEX32Q",
            "QmfDVU77wCGtebMxgxTjvFd2HDiskv34H3xBvLyJUAQNJa",
            "QmXYtx1Xks3mvDNLweSkCjwrhQssUW1afK9vXKHciBLNMn",
            "QmRkCenqbXhKxykcBDmuvzWKxnmuvB93vSmUeG5YSrDj6e",
            "Qmasg7UKJvdaTDTNxZ54w7gAVyaK1YDNy1vxuqCoX52W6q",
            "QmX8JyrSE2BdLsenHKdQV84tFWSzDX5LfmWnfgpNfQp9AX",
            "Qmf9ydFPcJXwqYU1NPUyJ3RHM5jZCeTkJrntjA6DBmTb7C",
            "QmTSzAeyv9a6oW3ZZ8sP9WogQWBqFWHd3oGFudMabvo6xX",
            "QmQrXSFQiW3rF4iztos6Rdy5R8PCpRAzLndaBQ9MYm5SNL",
            "QmZQhsWMDtQnJnGWACaZAhm449cbKQonG4XWhQNeMBtNQa",
            "QmQMwHXwLCHnh9DT5xXGRrt8SLTQB1yEmmVKuE2EfHjT1r",
            "QmVwrxXGsPx5QU4RQ7H5eY67GkUpCa1tukmZ8ARZVqzBR9",
            "QmY22M4fAR4xabVeJeWF7wPx9PiyCLYXuwo1ZHqxrbtnuz",
            "QmV8DPURTE9mxnMnUU97LsCveYj7EHJQwcKGeDacGHtRuP",
            "QmTogHdDApN1kTDEtAYbs43m9jRDc3JNvxSWjgkQrPV6ja",
            "QmTKSW2PzUpoAj6oiVa7tSh3pzJvpJU6H2YrTLSx746D9f",
            "QmbQjggJpXPkCmLYHt46VuZ6hSPvS51WcXBRvvy6ezzjGW",
            "QmRV35WjZwvdaBoPVr1YX8oqLHxnDcYfNXju7QvWXCV7h9",
            "QmTbzjS9RUajbKfELMDyYTpoopi8VTgwhYRefSect6RowM",
            "QmZus6AWjsVAsinnGimJ1sTfFRaQn4R2abupHY8DimNcdc",
            "QmVawAxirBmd56DNv7RuxP1m4m1UNR8goCt9H9H1ME3PDc",
            "QmThmqdMEAyyE7rdN7uE1AgQKfM4cRiWkTDWs1QGuqDBWe",
            "QmP9MtgGpANWKujcWUpRZkANDNhcfM4yTncQMzAeNZ34N8",
            "QmajtUPkX3EzfsRq9EwQTYo88DNfCnKHVWE1po1dCc7JGL",
            "QmaLqdQs1X3AKs2BRxZUxJjbVJqtXLfC1SycJysafbW8Tp",
            "QmUVxfFwRbPGxY9sM65QeRvg4ng4Vt2hsCMSL6kGBTZbtg",
            "QmdzVD1XC4D7ydPa2dP98WmDpvkcxizApebc1ujJvwzThb",
            "QmStSzhebV5cvokQ6Q3PRgnHLfciiMFPbh9DMnCvHZ2KXG",
            "QmW8zFv1CFqDnqxjBnR69db5Gj54RnYrim4qqwtqZ5kMyC",
            "QmahcvNu6XbtwDLHz45iYqrzf9qzxTRZ4qtn9o7JaZ8VBv",
            "QmaMvgiHEZSEnU9THJPwAthYNbQuwSdZkPqiC3FiwnRJfX",
            "QmP7FQNXYhe5eWWQEHRT4SihCTF7dZbv3LSMBtXY3HyBto",
            "QmRxC4a7Uo23KCYVqUxsHmimKA1wYTukJ6CGRgm8aCZ1Gd"
        ];

        for (uint256 i = 0; i < 100; i++) {
            // We must fire this event once per rock in order for OpenSea to recognize
            // the NFTs. When an EtherRock is transfered after deployment, OpenSea
            // will notice the change in ownership of this NFT within 24 hours.
            emit Transfer(address(0), etherRock.getRockInfo(i), i);
        }
    }

    /// @notice Count all NFTs assigned to an owner
    function balanceOf(address _owner) public view override returns (uint256) {
        uint256 index;
        while (true) {
            try etherRock.rockOwners(_owner, index) returns (uint256) {
                index++;
            } catch {
                return index;
            }
        }
    }

    /// @notice Find the owner of an NFT
    function ownerOf(uint256 tokenId) public view override returns (address) {
        if (tokenId < 100) {
            return etherRock.getRockInfo(tokenId);
        }
        revert("Query for nonexistent tokenId");
    }

    function _transfer(
        address _from,
        address _to,
        uint256 _tokenId
    ) internal override {
        revert("NFT is attached to rock");
    }

    function tokenOfOwnerByIndex(address _owner, uint256 _index)
        public
        view
        override
        returns (uint256)
    {
        try etherRock.rockOwners(_owner, _index) returns (uint256 tokenId) {
            return tokenId;
        } catch {
            revert("Index out of bounds");
        }
    }
}
设置
{
  "compilationTarget": {
    "ProofOfRockTethered.sol": "ProofOfRockTethered"
  },
  "evmVersion": "istanbul",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": []
}
ABI
[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_operator","type":"address"},{"indexed":false,"internalType":"bool","name":"_approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"approved","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"etherRock","outputs":[{"internalType":"contract EtherRock","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}]