EthereumEthereum
0xa1...3cf5
Tulip 1637

Tulip 1637

TULP

收藏品
底价
1.1 ETH
$2,345.34
大小
16
收藏品
所有者
11
69% 独特的所有者
此合同的源代码已经过验证!
合同元数据
编译器
0.6.12+commit.27d51765
语言
Solidity
合同源代码
文件 1 的 1:HDDrop.sol
/**
 *Submitted for verification at Etherscan.io on 2021-05-12
*/

// SPDX-License-Identifier: NLPL AND GPL-3.0-or-later
pragma solidity >=0.6.0 >=0.6.12 <0.7.0;

////// lib/hd-drop/lib/erc721/src/erc721.sol
/// erc721.sol -- API for the ERC721 token standard

// See <https://github.com/ethereum/EIPs/issues/721>.

// This file likely does not meet the threshold of originality
// required for copyright to apply.  As a result, this is free and
// unencumbered software belonging to the public domain.

/* pragma solidity >=0.6.0; */

interface ERC721Metadata {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function tokenURI(uint256 nft) external view returns (string memory);
}

interface ERC721Enumerable {
    function totalSupply() external view returns (uint256);
    function tokenByIndex(uint256 idx) external view returns (uint256);
    function tokenOfOwnerByIndex(address guy, uint256 idx) external view returns (uint256);
}

interface ERC721Events {
    event Transfer(address indexed src, address indexed dst, uint256 nft);
    event Approval(address indexed src, address indexed guy, uint256 nft);
    event ApprovalForAll(address indexed guy, address indexed op, bool ok);
}

interface ERC721TokenReceiver {
    function onERC721Received(address op, address src, uint256 nft, bytes calldata what) external returns(bytes4);
}

interface ERC165 {
    function supportsInterface(bytes4 interfaceID) external view returns (bool);
}

interface ERC721 is ERC165, ERC721Events, ERC721TokenReceiver {
    function balanceOf(address guy) external view returns (uint256);
    function ownerOf(uint256 nft) external view returns (address);
    function safeTransferFrom(address src, address dst, uint256 nft, bytes calldata what) external payable;
    function safeTransferFrom(address src, address dst, uint256 nft) external payable;
    function transferFrom(address src, address dst, uint256 nft) external payable;
    function approve(address guy, uint256 nft) external payable;
    function setApprovalForAll(address op, bool ok) external;
    function getApproved(uint256 nft) external returns (address);
    function isApprovedForAll(address guy, address op) external view returns (bool);
}

////// lib/hd-drop/src/IEIP2981Royalties.sol

/* pragma solidity >=0.6.0; */

interface IEIP2981Royalties {
    event ReceivedRoyalties(
        address indexed _royaltyRecipient,
        address indexed _buyer,
        uint256 indexed _tokenId,
        address _tokenPaid,
        uint256 _amount
    );

    function royaltyInfo(
        uint256 nft
    ) external returns (address gal, uint256 fee);
    function receivedRoyalties(
        address gal, address buyer, uint256 nft, address gem, uint256 fee
    ) external;
}

////// lib/hd-drop/src/IOpenSeaContractLevelMetadata.sol

/* pragma solidity >=0.6.0; */

interface IOpenSeaContractLevelMetadata {
    function contractURI() external view returns (string memory);
}


////// lib/hd-drop/src/IRaribleRoyaltiesV1.sol

/* pragma solidity >=0.6.0; */

interface IRaribleRoyaltiesV1 {
    event SecondarySaleFees(uint256 tokenId, address[] recipients, uint[] bps);

    function getFeeRecipients(
        uint256 nft
    ) external view returns (address payable[] memory);
    function getFeeBps(uint256 nft) external view returns (uint[] memory);
}

////// lib/hd-drop/src/drop.sol

/// drop.sol -- ERC721 implementation with royalties and proof-of-work

// Copyright (C) 2020 Hashdrop

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

/* pragma solidity ^0.6.12; */

/* import "erc721/erc721.sol"; */
/* import "./IEIP2981Royalties.sol"; */
/* import "./IOpenSeaContractLevelMetadata.sol"; */
/* import "./IRaribleRoyaltiesV1.sol"; */

contract HDDrop is
    ERC721,
    ERC721Enumerable,
    ERC721Metadata,
    IEIP2981Royalties,
    IOpenSeaContractLevelMetadata,
    IRaribleRoyaltiesV1
    {

    uint8                            public   hard;

    bool                             public   stopped;
    mapping (address => uint)        public   wards;

    uint256                          private  _ids;

    string                           internal _name;
    string                           internal _symbol;
    string                           internal _uri;

    mapping (uint256 => string)      internal _uris;

    mapping (bytes4 => bool)         internal _interfaces;

    uint256[]                        internal _allDrops;
    mapping (address => uint256[])   internal _usrDrops;
    mapping (uint256 => Drop)        internal _drops;
    mapping (address => mapping (address => bool)) internal _operators;

    struct Drop {
        uint256      pos;     // position in _allDrops
        uint256     upos;     // position in _usrDrops
        address      guy;     // creator
        address approved;     // appoved usr
        uint256    nonce;     // nonce to prove work
        address      gal;     // fee recipient
        uint256      fee;     // fee 0 or [100_000, 10_000_000]
    }

    // events
    event Stop();
    event Start();
    event Rely(address indexed guy);
    event Deny(address indexed guy);

    // safe math
    function sub(uint x, uint y) internal pure returns (uint z) {
        require((z = x - y) <= x);
    }
    function mul(uint x, uint y) internal pure returns (uint z) {
        require(y == 0 || (z = x * y) / y == x);
    }

    constructor(
        string memory name,
        string memory symbol,
        uint8 _hard,
        string memory uri
    ) public {
        _name = name;
        _symbol = symbol;
        hard = _hard;
        _uri = uri;

        _addInterface(0x80ac58cd); // ERC721
        _addInterface(0x5b5e139f); // ERC721Metadata
        _addInterface(0x780e9d63); // ERC721Enumerable
        _addInterface(0x4b7f2c2d); // IERC2981Royalties
        _addInterface(0xe8a3d485); // IOpenSeaContractLevelMetadata
        _addInterface(0xb7799584); // IRaribleRoyaltiesV1

        wards[msg.sender] = 1;
        emit Rely(msg.sender);
    }

    modifier nod(uint256 nft) {
        require(
            _drops[nft].guy == msg.sender ||
            _drops[nft].approved == msg.sender ||
            _operators[_drops[nft].guy][msg.sender],
            "hd-drop-insufficient-approval"
        );
        _;
    }

    modifier stoppable {
        require(!stopped, "hd-drop-is-stopped");
        _;
    }

    modifier auth {
        require(wards[msg.sender] == 1, "hd-drop-not-authorized");
        _;
    }

    function name() external override view returns (string memory) {
        return _name;
    }

    function symbol() external override view returns (string memory) {
        return _symbol;
    }

    function tokenURI(
        uint256 nft
    ) external override view returns (string memory) {
        return _uris[nft];
    }

    function totalSupply() external override view returns (uint256) {
        return _allDrops.length;
    }

    function tokenByIndex(
        uint256 idx
    ) external override view returns (uint256) {
        return _allDrops[idx];
    }

    function tokenOfOwnerByIndex(
        address guy, uint256 idx
    ) external override view returns (uint256) {
        require(idx < balanceOf(guy), "hd-drop-index-out-of-bounds");
        return _usrDrops[guy][idx];
    }

    function onERC721Received(
        address, address, uint256, bytes calldata
    ) external override returns(bytes4) {
        revert("hd-drop-does-not-accept-tokens");
    }

    function _isContract(address addr) private view returns (bool) {
        bytes32 codehash;
        // EIP-1052
        bytes32 accountHash =
            0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
        assembly { codehash := extcodehash(addr) }
        return (codehash != accountHash && codehash != 0x0);
    }

    function supportsInterface(
        bytes4 interfaceID
    ) external override view returns (bool) {
        return _interfaces[interfaceID];
    }

    function _addInterface(bytes4 interfaceID) private {
        _interfaces[interfaceID] = true;
    }

    function balanceOf(address guy) public override view returns (uint256) {
        require(guy != address(0), "hd-drop-invalid-address");
        return _usrDrops[guy].length;
    }

    function ownerOf(uint256 nft) external override view returns (address) {
        require(_drops[nft].guy != address(0), "hd-drop-invalid-nft");
        return _drops[nft].guy;
    }

    function safeTransferFrom(
        address src, address dst, uint256 nft, bytes calldata what
    ) external override payable {
        _safeTransfer(src, dst, nft, what);
    }

    function safeTransferFrom(
        address src, address dst, uint256 nft
    ) public override payable {
        _safeTransfer(src, dst, nft, "");
    }

    function push(address dst, uint256 nft) external {
        safeTransferFrom(msg.sender, dst, nft);
    }

    function pull(address src, uint256 nft) external {
        safeTransferFrom(src, msg.sender, nft);
    }

    function move(address src, address dst, uint256 nft) external {
        safeTransferFrom(src, dst, nft);
    }

    function _safeTransfer(
        address src, address dst, uint256 nft, bytes memory data
    ) internal {
        transferFrom(src, dst, nft);
        if (_isContract(dst)) {
            bytes4 res = ERC721TokenReceiver(dst).onERC721Received(
                msg.sender, src, nft, data
            );
            require(
                res == this.onERC721Received.selector,
                "hd-drop-invalid-token-receiver"
            );
        }
    }

    function transferFrom(
        address src, address dst, uint256 nft
    ) public override payable stoppable nod(nft) {
        require(src == _drops[nft].guy, "hd-drop-src-not-valid");
        require(
            dst != address(0) && dst != address(this),
            "hd-drop-unsafe-destination"
        );
        require(_drops[nft].guy != address(0), "hd-drop-invalid-nft");
        _upop(nft);
        _upush(dst, nft);
        _approve(address(0), nft);
        emit Transfer(src, dst, nft);
    }

    function mint(
        address guy, string memory uri, uint256 nonce, address gal, uint256 fee
    ) public auth stoppable returns (uint256 nft) {
        return _mint(guy, uri, nonce, address(gal), fee);
    }

    function _mint(
        address guy, string memory uri, uint256 nonce, address gal, uint256 fee
    ) internal returns (uint256 nft) {
        require(guy != address(0), "hd-drop-invalid-address");
        require(fee <= 10_000_000, "hd-drop-invalid-fee");

        nft = _ids++;
        require(work(nft, nonce, hard), "hd-drop-failed-work");
        hard = hard + 1;

        gal = (gal != address(0)) ? gal : guy;

        _allDrops.push(nft);
        _drops[nft] = Drop(
            _allDrops[_allDrops.length - 1],
            _usrDrops[guy].length - 1,
            guy,
            address(0),
            nonce,
            gal,
            fee
        );
        _upush(guy, nft);
        _uris[nft] = uri;

        if (fee > 0) {
            address[] memory recipients = new address[](1);
            uint[] memory bps = new uint[](1);
            recipients[0] = gal;
            bps[0] = fee / 1_000;
            emit SecondarySaleFees(nft, recipients, bps);
        }

        emit Transfer(address(0), guy, nft);
    }

    function burn(uint256 nft) public auth stoppable {
        _burn(nft);
    }

    function _burn(uint256 nft) internal {
        address guy = _drops[nft].guy;
        require(guy != address(0), "hd-drop-invalid-nft");

        uint256 _idx        = _drops[nft].pos;
        uint256 _mov        = _allDrops[_allDrops.length - 1];
        _allDrops[_idx]     = _mov;
        _drops[_mov].pos    = _idx;
        _allDrops.pop();    // Remove from All drop array
        _upop(nft);         // Remove from User drop array

        delete _drops[nft]; // Remove from drop mapping

        emit Transfer(guy, address(0), nft);
    }

    function _upush(address guy, uint256 nft) internal {
        _drops[nft].upos           = _usrDrops[guy].length;
        _usrDrops[guy].push(nft);
        _drops[nft].guy            = guy;
    }

    function _upop(uint256 nft) internal {
        uint256[] storage _udds    = _usrDrops[_drops[nft].guy];
        uint256           _uidx    = _drops[nft].upos;
        uint256           _move    = _udds[_udds.length - 1];
        _udds[_uidx]               = _move;
        _drops[_move].upos         = _uidx;
        _udds.pop();
        _usrDrops[_drops[nft].guy] = _udds;
    }

    function approve(
        address guy, uint256 nft
    ) external override payable stoppable nod(nft) {
        _approve(guy, nft);
    }

    function _approve(address guy, uint256 nft) internal {
        _drops[nft].approved = guy;
        emit Approval(msg.sender, guy, nft);
    }

    function setApprovalForAll(
        address op, bool ok
    ) external override stoppable {
        _operators[msg.sender][op] = ok;
        emit ApprovalForAll(msg.sender, op, ok);
    }

    function getApproved(uint256 nft) external override returns (address) {
        require(_drops[nft].guy != address(0), "hd-drop-invalid-nft");
        return _drops[nft].approved;
    }

    function isApprovedForAll(
        address guy, address op
    ) external override view returns (bool) {
        return _operators[guy][op];
    }

    function _lshift(
        bytes32 bits, uint256 shift
    ) internal pure returns (bytes32) {
        return bytes32(mul(uint256(bits), 2 ** shift));
    }

    function _firstn(
        bytes32 bits, uint256 num
    ) internal pure returns (bytes32) {
        bytes32 ones = bytes32(sub(2 ** num, 1));
        bytes32 mask = _lshift(ones, sub(256, num));
        return bits & mask;
    } 

    // validates a proof-of-work for a given NFT, with a supplied nonce
    // at a given difficulty level
    function work(
        uint256 id, uint256 nonce, uint8 difficulty
    ) public view returns (bool) {
        bytes32 candidate = _firstn(
            keccak256(abi.encodePacked(address(this), id, nonce)),
            difficulty
        );
        bytes32 target = _firstn(
            bytes32(uint256(address(this)) << 96),
            difficulty
        );
        return (candidate == target);
    }

    function stop() external auth {
        stopped = true;
        emit Stop();
    }

    function start() external auth {
        stopped = false;
        emit Start();
    }

    function rely(address guy) external auth {
        wards[guy] = 1;
        emit Rely(guy);
    }

    function deny(address guy) external auth {
        wards[guy] = 0;
        emit Deny(guy);
    }

    function setTokenUri(uint256 nft, string memory uri) public auth stoppable {
        _uris[nft] = uri;
    }

    function royaltyInfo(
        uint256 nft
    ) public override returns (address receiver, uint256 amount) {
        return (_drops[nft].gal, _drops[nft].fee);
    }

    function receivedRoyalties(
        address gal, address buyer, uint256 nft, address gem, uint256 fee
    ) public override {
        emit ReceivedRoyalties(gal, buyer, nft, gem, fee);
    }

    function getFeeRecipients(
        uint256 nft
    ) external view override returns (address payable[] memory) {
        address payable[] memory result = new address payable[](1);
        result[0] = payable(_drops[nft].gal);
        return result;
    }

    function getFeeBps(
        uint256 nft
    ) external view override returns (uint[] memory) {
        uint[] memory result = new uint[](1);
        result[0] = _drops[nft].fee / 1_000;
        return result;
    }

    function contractURI() public view override returns (string memory) {
        return _uri;
    }
}
设置
{
  "compilationTarget": {
    "HDDrop.sol": "HDDrop"
  },
  "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"},{"internalType":"uint8","name":"_hard","type":"uint8"},{"internalType":"string","name":"uri","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"src","type":"address"},{"indexed":true,"internalType":"address","name":"guy","type":"address"},{"indexed":false,"internalType":"uint256","name":"nft","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"guy","type":"address"},{"indexed":true,"internalType":"address","name":"op","type":"address"},{"indexed":false,"internalType":"bool","name":"ok","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"guy","type":"address"}],"name":"Deny","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_royaltyRecipient","type":"address"},{"indexed":true,"internalType":"address","name":"_buyer","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"_tokenPaid","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"ReceivedRoyalties","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"guy","type":"address"}],"name":"Rely","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address[]","name":"recipients","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"bps","type":"uint256[]"}],"name":"SecondarySaleFees","type":"event"},{"anonymous":false,"inputs":[],"name":"Start","type":"event"},{"anonymous":false,"inputs":[],"name":"Stop","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"src","type":"address"},{"indexed":true,"internalType":"address","name":"dst","type":"address"},{"indexed":false,"internalType":"uint256","name":"nft","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"guy","type":"address"},{"internalType":"uint256","name":"nft","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"guy","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nft","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"guy","type":"address"}],"name":"deny","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"nft","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"nft","type":"uint256"}],"name":"getFeeBps","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nft","type":"uint256"}],"name":"getFeeRecipients","outputs":[{"internalType":"address payable[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hard","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"guy","type":"address"},{"internalType":"address","name":"op","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"guy","type":"address"},{"internalType":"string","name":"uri","type":"string"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"gal","type":"address"},{"internalType":"uint256","name":"fee","type":"uint256"}],"name":"mint","outputs":[{"internalType":"uint256","name":"nft","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"nft","type":"uint256"}],"name":"move","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"nft","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"uint256","name":"nft","type":"uint256"}],"name":"pull","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"nft","type":"uint256"}],"name":"push","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"gal","type":"address"},{"internalType":"address","name":"buyer","type":"address"},{"internalType":"uint256","name":"nft","type":"uint256"},{"internalType":"address","name":"gem","type":"address"},{"internalType":"uint256","name":"fee","type":"uint256"}],"name":"receivedRoyalties","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guy","type":"address"}],"name":"rely","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"nft","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"nft","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"nft","type":"uint256"},{"internalType":"bytes","name":"what","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"op","type":"address"},{"internalType":"bool","name":"ok","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"nft","type":"uint256"},{"internalType":"string","name":"uri","type":"string"}],"name":"setTokenUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"start","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stopped","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"idx","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"guy","type":"address"},{"internalType":"uint256","name":"idx","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nft","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":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"nft","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"wards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint8","name":"difficulty","type":"uint8"}],"name":"work","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]