ethereum - Calling ownerOf() on an ERC-721 contract via my contract throws "Error: Transaction reverted: function retur

admin2025-04-22  1

I am building a smart contract that checks the ownership of NFTs in a very simple function call:

 function ownershipCheck(uint deployedID) public view returns (address) {
        address holder = deployedNFT.ownerOf(deployedID);
        if(_msgSender() != holder){revert InsufficientFunds();}

    }

According to hardhat, this line

        address holder = deployedNFT.ownerOf(deployedID);

is the source of the revert. I manually checked the ownership by calling the contract directly with the tokenID i am trying to check with my ownershipCheck() function and it returns the address of the expected owner. so the ERC721 contract should work correctly in terms of checking ownership (I am using the latest openzeppelin contracts).

this is the function on the interface:

interface IERC721 {
    function ownerOf(uint256 tokenId) external view returns (address owner);
}

Any idea why this might be reverting?

I am building a smart contract that checks the ownership of NFTs in a very simple function call:

 function ownershipCheck(uint deployedID) public view returns (address) {
        address holder = deployedNFT.ownerOf(deployedID);
        if(_msgSender() != holder){revert InsufficientFunds();}

    }

According to hardhat, this line

        address holder = deployedNFT.ownerOf(deployedID);

is the source of the revert. I manually checked the ownership by calling the contract directly with the tokenID i am trying to check with my ownershipCheck() function and it returns the address of the expected owner. so the ERC721 contract should work correctly in terms of checking ownership (I am using the latest openzeppelin contracts).

this is the function on the interface:

interface IERC721 {
    function ownerOf(uint256 tokenId) external view returns (address owner);
}

Any idea why this might be reverting?

Share Improve this question asked Jan 21 at 15:13 Carlton BagsCarlton Bags 31 bronze badge
Add a comment  | 

2 Answers 2

Reset to default 0

From the ERC-721 standard page:

/// @dev NFTs assigned to zero address are considered invalid, and queries
///  about them do throw.

In other words, the ownerOf() function is supposed to revert if you're querying a non-existing token ID.

You can add additional safety checks like this:

// Optional alternative method
function safeOwnershipCheck(uint deployedID) public view returns (address) {
    // Check if token exists before calling ownerOf
    if (!_tokenExists(deployedID)) {
        revert("Token does not exist");
    }
    return deployedNFT.ownerOf(deployedID);
}

// Implement this method based on your specific NFT contract
function _tokenExists(uint tokenId) internal view returns (bool) {
    // This is a placeholder - implement based on your contract's logic
    // Some contracts provide _exists() method
    // return deployedNFT._exists(tokenId);
}

Explanation:

  • The safeOwnershipCheck function ensures that you don’t call ownerOf on a non-existent token, which could save your contract from potential errors.
  • _tokenExists is a helper function that checks if a token exists. Many ERC-721 contracts provide an _exists() method, which can be used directly. If not, you'll need to implement this logic based on your contract.

Make sure to customize _tokenExists to align with your specific NFT contract's implementation.

转载请注明原文地址:http://anycun.com/QandA/1745301536a90583.html