'Transaction fails with CALL_EXCEPTION whenever I try to mint an NFT using ethers.js
I am using ethers.js to call the mint function in my smart contract but it fails with this error:
Error: transaction failed [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ].
I am able to call the view functions this error only occurs when I call functions which make transactions. So, I know that I have connected to the same network as the contract.
My smart contract:
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 {
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;
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 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;
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);
}
}
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);
Solution 1:[1]
This line checks if a player is address(0) which is always false
require(playerToOwner[_player.id] == address(0), "Player Exists!");
it should be
require(playerToOwner[_player.id] != address(0), "Player Exists!");
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Peter |
