First of all, in order to make it easier to understand the problem, I will only keep the functions that are more useful for understanding the problem. This code allows creating NFTs in an array, where the first NFT has an idToken of 0. When I click the "Get data from contract" button, I want to pass parameter 0 to the readContract(tokenid) JavaScript function to display the Power value, a uint8 (randomly generated, value from 0 to 100) HTML file. Unfortunately, I encountered a bug and I tried various ways to resolve it without success. The contract and JavaScript are connected correctly (as evidenced by the connectContract() function, which is a verification of this), so the ABI and address are not part of the problem. The readContract() function is supposed to use the getNFTPower method written in the Solidity contract, but something seems to be wrong: the return value is invalid. But to me they are haha… I also tried inserting some console.log statements in the readContract() function before and after the first line of code: const power = wait window.contract.methods.getNFTPower(tokenId).call(); I don't see any console.log output after that statement, so the problem seems to occur there.
Hope someone can give me a hint..Thank you.
The following error screenshots
The following part of the code.
SOLIDITY code
contract NFTGame is ERC721, Ownable { using SafeMath for uint256; address public erc20TokenAddress; struct NFTAttributes { uint8 power; bool inArena; } NFTAttributes[] public nfts; constructor(address _erc20TokenAddress) ERC721(FightArena, FIGA) payable { erc20TokenAddress = _erc20TokenAddress; } function createNFT() external { uint8 power = uint8(uint256(keccak256(abi.encodePacked(block.timestamp, msg.sender))) % 101); Random number da 0 a 100 nfts.push(NFTAttributes(power, false)); uint256 tokenId = nfts.length - 1; _mint(msg.sender, tokenId); } function getNFTPower(uint256 tokenId) public view returns (uint8) { require(_exists(tokenId), ID del token non valido); return uint8(nfts[tokenId].power); } }
HTML/JS
... <head> ... <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/web3/1.2.7-rc.0/web3.min.js"></script> ... </head> ... <body> <button onclick="connectMetamask()">CONNECT METAMASK</button> <br> <p id="accountArea"></p> <button onclick="connectContract()">CONNECT TO CONTRACT</button> <br> <p id="contractArea"></p> <button onclick="readContract(0)">GET DATA FROM CONTRACT</button> <br> <p id="dataArea"></p> // 0 is the first NFT minted by the function createNFT() ... </body> ... <script> ... const readContract = async (tokenId) => { const power = await window.contract.methods.getNFTPower(tokenId).call(); const powerString = power.toString(); document.getElementById("dataArea").innerHTML = "Power of NFT " + tokenId + ": " + powerString; } ... </script> ...
I tried rewriting the function readContract() in various ways, but it didn't help. My goal is to click the "Get data from contract" button and display the POWER value of the tokenId of the NFT I am passing as a parameter (in the code above, the first NFT, tokenId = 0).
There are two most common reasons: