简体   繁体   中英

I am trying to mint NFT using ethers.js, there seems to be a problem with my frontend code

I have tried many times to mint an NFT using ethers.js. Is something wrong with my code? I always get this error: Error: transaction failed [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ]

Also there doesn't seem to be any problem with my solidity code.

my frontend code:

const player: PlayerInterface = {
      name: "Lionel Messi",
      preferredPosition: "RWF",
      id: 1,
      age: 34,
      level: 20,
      lastUpgrade: new Date().getTime(),
      suitablePositions: ["ST", "CF", "RMF", "CAM"],
      imageURI:
        "https://bafybeicfhmevzs4aso7rqvx7l5ndb2ly7gudjyj5xjkztvohpwxw2za7iy.ipfs.dweb.link/nft.png",
    };
    const provider = new ethers.providers.Web3Provider(
      (window as any).ethereum
    );
    const signer = provider.getSigner();
    const tx = await futNFT.connect(signer).mint(player, {
      gasPrice: 30000000000,
      gasLimit: 2000000,
    });
    await tx.wait();
    console.log("minted");
    const player1 = await futNFT.getPlayer(1);
    console.log(player1);

here's my solidity smart contract:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;

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

contract FutNFT is ERC721, ERC721Enumerable, Ownable {
    /// @dev Should have logic for players with no suitable position array
    struct Player {
        string name;
        string preferredPosition;
        uint256 id;
        uint8 age;
        uint8 level;
        uint64 lastUpgrade;
        string[] suitablePositions;
        string imageURI;
    }

    struct History {
        uint256 winCount;
        uint256 lossCount;
    }

    mapping(address => History) ownerHistory;
    mapping(uint256 => Player) players;
    mapping(uint256 => address) public playerToOwner;
    mapping(uint256 => uint256) listedPlayerIndex;
    uint256[] public listedPlayers;
    uint256[] playerIds;

    event PlayerAdded(uint256 playerId);

    modifier owned(uint256 id) {
        require(getPlayerExists(id), "Player does not exist");
        require(msg.sender == ownerOf(id), "Not the owner!");
        _;
    }

    constructor() ERC721("FutNFT", "FNFT") {}

    function getListedPlayers() public view returns (uint256[] memory) {
        return listedPlayers;
    }

    function getPlayer(uint256 _id) public view returns (Player memory) {
        return players[_id];
    }

    function getPlayersByOwner(address _owner)
        public
        view
        returns (uint256[] memory)
    {
        uint256[] memory result;
        uint256 index = 0;
        for (uint256 i = 0; i < playerIds.length; i++) {
            if (playerToOwner[playerIds[i]] == _owner) {
                result[index] = playerIds[i];
                index++;
            }
        }
        return result;
    }

    function ownerOf(uint256 tokenId)
        public
        view
        override(ERC721, IERC721)
        returns (address)
    {
        return super.ownerOf(tokenId);
    }

    function getPlayerExists(uint256 _id) public view returns (bool) {
        return playerToOwner[_id] != address(0);
    }

    function mint(Player memory _player) public onlyOwner {
        require(playerToOwner[_player.id] == address(0), "Player Exists!");
        players[_player.id] = _player;
        playerIds.push(_player.id);
        playerToOwner[_player.id] = msg.sender;
        _mint(msg.sender, _player.id);
        emit PlayerAdded(_player.id);
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal override(ERC721, ERC721Enumerable) {
        super._beforeTokenTransfer(from, to, tokenId);
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721, ERC721Enumerable)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}

Please tell me if something is wrong with this. Also please ask if you need more information.

Your mint() function uses the onlyOwner modifier. In the OpenZeppelin implementation this means that the function can be only executed from the address stored in the _owner variable. If you try to execute it from a different address, it reverts.

By default (as per the OZ implementation), the _owner address is the address that deployed the contract.

So you need to execute the mint() function from the current _owner address - in your case the same address that deployed the contract. Or remove the onlyOwner modifier (and redeploy the contract) which opens the function to be executable by anyone.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM