I have been working on a project. Following is the NFT contract on ERC721 as parent:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
/**
* The NFT contract keeps a note of NFT ipfs client
*/
contract NFT is ERC721URIStorage {
uint public tokenCount;
constructor() ERC721("Art timeline NFT", "ARTN") {}
function mint (string memory _tokenURI) external returns(uint) {
tokenCount ++;
_safeMint(msg.sender, tokenCount);
_setTokenURI(tokenCount, _tokenURI);
return(tokenCount);
}
}
And the following marketplace is:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
/**
* The NFTProject contract keeps a note of the list of all nfts
* The given contract is specifically for the project creation with timelines
*/
contract NFTProjectMarketplace is ReentrancyGuard {
address payable public immutable feeAccount;
uint public feePercent;
bool public completed = false;
uint256 public sellTimeDelay;
struct NFTItem {
uint itemId;
IERC721 nft;
uint tokenId;
uint256 uploadTime;
uint projectId;
}
mapping(uint => NFTItem) public projectNfts;
uint public totalNoOfNfts;
struct Project {
uint projectId;
string name;
string description;
// mapping(uint => NFTItem) nfts;
// uint noOfNfts;
// mapping(uint => Bid) bids;
// uint noOfBids;
bool sold;
address payable creator;
uint lastBid;
bool completed;
uint256 projectStartTime;
uint256 projectCompleteTime;
}
uint256 public projectCount;
mapping(uint => Project) public projects;
constructor(uint _feePercent, uint _sellTimeDelay) {
feePercent = _feePercent;
feeAccount = payable(msg.sender);
sellTimeDelay = _sellTimeDelay;
}
function getCurrentTimeInEpoch() internal view returns(uint256) {
return(block.timestamp * 1000);
}
/*
** The given method is to initialize a project with a given NFT. It instantiates a normal project
* with the given NFT, and places an initial bid as decided by the creator
*/
function makeProject(IERC721 _nft, uint _tokenId, uint _basePrice, string memory _projectName, string memory _projectDescription) external nonReentrant {
require(_basePrice > 0, "Price must be greater than 0");
uint256 currentTime = getCurrentTimeInEpoch();
_nft.transferFrom(msg.sender, address(this), _tokenId);
projectCount ++;
totalNoOfNfts ++;
projects[projectCount] = Project(projectCount, _projectName, _projectDescription, false, payable(msg.sender), _basePrice, false, currentTime, 0);
projectNfts[totalNoOfNfts] = NFTItem(totalNoOfNfts, _nft, _tokenId, currentTime, projectCount);
}
/*
** Add new timeline NFT to the project
*/
function addNFTToProject(IERC721 _nft, uint _tokenId, uint _projectId) external nonReentrant {
Project storage proj = projects[_projectId];
require(msg.sender == proj.creator, "Only the creator can add nfts to the project");
uint256 currentTime = getCurrentTimeInEpoch();
_nft.transferFrom(msg.sender, address(this), _tokenId);
totalNoOfNfts ++;
projectNfts[totalNoOfNfts] = NFTItem(totalNoOfNfts, _nft, _tokenId, currentTime, _projectId);
}
}
The goal is to add nfts to projects as made by the user. Following is the error that I am getting when running addNFTToProject
method:
ProviderError: Error: VM Exception while processing transaction: reverted with reason string 'ERC721: operator query for nonexistent token'
at HttpProvider.request (node_modules/hardhat/src/internal/core/providers/http.ts:49:19)
at GanacheGasMultiplierProvider.request (node_modules/hardhat/src/internal/core/providers/gas-providers.ts:312:34)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (node:internal/process/task_queues:96:5)