ERC721: unable to access token with ownerOf, getting "owner query for nonexistent token"
See original GitHub issueIssue
Getting Error: Returned error: VM Exception while processing transaction: revert ERC721: owner query for nonexistent token
while trying to use the ownerOf
function, which means that the ID used for ownerOf
is wrong but it doesn’t make any sense.
Steps to reproduce
- Create a project using Truffle, OpenZeppelin
truffle init
npm init
npm install @openzeppelin/contracts
- Edit
truffle-config.js
to use latest version of Solidity:
compilers: {
solc: {
version: "0.8.3", // Fetch exact version from solc-bin (default: truffle's version)
// docker: true, // Use "0.5.1" you've installed locally with docker (default: false)
// settings: { // See the solidity docs for advice about optimization and evmVersion
// optimizer: {
// enabled: false,
// runs: 200
// },
// evmVersion: "byzantium"
// }
}
},
- Create
contracts/GameItem.sol
according to OpenZeppelin documentation on ERC721
// contracts/GameItem.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
contract GameItem is ERC721URIStorage {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
constructor() ERC721("GameItem", "ITM") {}
function awardItem(address player, string memory tokenURI)
public
returns (uint256)
{
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(player, newItemId);
_setTokenURI(newItemId, tokenURI);
return newItemId;
}
}
- Create
migrations/2_deploy_contracts.js
const GameItem = artifacts.require("GameItem")
module.exports = function (deployer) {
deployer.deploy(GameItem)
}
- Create
tests/GameItem.test.js
the purpose of which is to mint a token and find its owner
const GameItem = artifacts.require("GameItem")
contract("GameItem", (accounts) => {
before(async() => {
gameItem = await GameItem.deployed()
})
it("Minting", async() => {
gameItem.awardItem(accounts[0], "meta")
let result = await gameItem.ownerOf(1)
console.log(result)
})
})
- Run
truffle test
and get the following:
Contract: GameItem
1) Minting
Events emitted during test:
---------------------------
IERC721.Transfer(
from: <indexed> 0x0000000000000000000000000000000000000000 (type: address),
to: <indexed> 0x627306090abaB3A6e1400e9345bC60c78a8BEf57 (type: address),
tokenId: <indexed> 1 (type: uint256)
)
---------------------------
0 passing (1s)
1 failing
1) Contract: GameItem
Minting:
Error: Returned error: VM Exception while processing transaction: revert ERC721: owner query for nonexistent token
at Context.<anonymous> (test/GameItem.test.js:11:37)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
What I think is happening
For some reason, 1
is an incorrect ID, even though when I transfer a token by that ID, it doesn’t throw an exception. (I used transferFrom()
, if token with ID 1 wouldn’t exist it would throw an exception since it requires _isApprovedOrOwner
, and _isApprovedOrOwner
requires _exists
. But it worked well until I decided to check the owner by ID.)
What I tried to do
- Doing the same in development mode
truffle development
migrate
gameItem = await GameItem.deployed()
gameItem.awardItem(accounts[0], "meta")
gameItem.ownerOf(1)
Works as intended, returns an address, no exceptions.
- Then I thought: maybe the ID is actually different, not
1
. So I decided to take control of it instead of usingawardItem
from docs. I added the following function toGameItem.sol
:
function mintWrapper(address player, uint256 tokenId)
public
{
_mint(player, tokenId);
}
And used that function in the GameItem.test.js
:
it("Minting", async() => {
// gameItem.awardItem(accounts[0], "meta")
gameItem.mintWrapper(accounts[0], 1)
let result = await gameItem.ownerOf(1)
console.log(result)
}
So now I control the ID of the token, I specified it to be 1, and yet gameItem.ownerOf(1)
throws an exception.
Environment
-
OS: macOS
-
Truffle version: v5.4.9
-
Solidity version: 0.8.3
-
Node.js version: v14.17.1
-
web3.js version: v1.5.2
Issue Analytics
- State:
- Created 2 years ago
- Comments:6 (2 by maintainers)
I forgot to run Ganache 😅 That’s it
You can await without putting the result in a variable