We can interact with a contract that we have a sample of. To make it clear, please see how Proxy
contract interact with Name
contract in this response.
In my scenario, I want to check if the msg.sender
is the owner of an NFT. So, I'm trying to interact with any ERC721 contract using the same way instead direct contract call. Like this:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/[email protected]/token/ERC721/ERC721.sol";
import "@openzeppelin/[email protected]/token/ERC721/IERC721.sol";
contract Market {
function putOnSale(address _nftContract, uint256 _tokenId, uint256 _price) public payable {
address tokenOwner = ERC721(_nftContract).ownerOf(_tokenId); // ???
require(tokenOwner == msg.sender, 'Only owner...');
// Rest of the code...
}
}
However, I'm getting this error when I call putOnSale
method:
transact to Market.putOnSale errored: VM error: revert.
revert
The transaction has been reverted to the initial state.
Note: The called function should be payable if you send value and the value you send should be less than your current balance. Debug the transaction to get more information.
Can't I interact with another ERC721 contract using this way?
Note: I'm doing this all in Remix IDE JavaScript VM.
Thanks in advance!
Best Answer
In what little you've provided, the only thing I can see is that you're using the contract where you should be using the interface. i.e. This line:
should be:
If you're not coming from a language where you're used to working with pointers, the difference between these two likely is pretty confusing. In short, you use:
IERC721
).ERC721
).What you have written now reads like you're trying to deploy a new
ERC721
contract, with_nftContract
as the name, and then immediately ask for the owner of the given token. The problem here is that according to OpenZepplin's ERC721 API docs, this method requires that thetokenId
exists. Since you haven't minted any tokens at this point, this is going to revert the transaction.If you're still new to Solidity and aren't entirely sure of these things, I recommend avoiding any initial temptation to reduce code down to one liners. You'll find that sometimes
VM error: revert
is all the more insight that you'll get from the EVM error message. If you have multiple function calls on line, this can be harder to think through.Writing this as:
or when deploying new contracts, like this:
can make it easier to know exactly where things are going wrong, especially since you might not know if the address coming through actually is an
ERC721
.