I'm creating a Dapp that let's a user mint an NFt then list it for sell.this is my ERC721 contract
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
// Uncomment this line to use console.log
// import "hardhat/console.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
contract Collections is ERC721, ERC721URIStorage,ERC721Enumerable {
uint256 public _nextTokenId;
constructor()
ERC721("Colletcion", "CCC")
{}
function safeMint(address to, string memory uri) public{
uint256 tokenId = _nextTokenId++;
_safeMint(to, tokenId);
_setTokenURI(tokenId, uri);
}
// The following functions are overrides required by Solidity.
function tokenURI(uint256 tokenId)
public
view
override(ERC721, ERC721URIStorage)
returns (string memory)
{
return super.tokenURI(tokenId);
}
// The following functions are overrides required by Solidity.
function _update(address to, uint256 tokenId, address auth)
internal
override(ERC721, ERC721Enumerable)
returns (address)
{
return super._update(to, tokenId, auth);
}
function _increaseBalance(address account, uint128 value)
internal
override(ERC721, ERC721Enumerable)
{
super._increaseBalance(account, value);
}
function supportsInterface(bytes4 interfaceId)
public
view
override(ERC721, ERC721URIStorage, ERC721Enumerable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}
And here is my Market.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "hardhat/console.sol";
interface IERC721 {
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function transferFrom(address from, address to, uint256 tokenId) external;
function ownerOf(uint256 tokenId) external view returns (address);
}
contract Marketplace {
IERC721 public token;
address public admin;
event NFTListed(uint256 indexed tokenId, address indexed owner, uint256 price);
event NFTSold(uint256 indexed tokenId, address indexed buyer, uint256 price);
event NFTCanceled(uint256 indexed tokenId, address indexed owner);
constructor(address _nftAddress, address _admin) {
require(_nftAddress != address(0), "Invalid NFT address");
require(_admin != address(0), "Invalid admin address");
token = IERC721(_nftAddress);
admin = _admin;
}
struct NFT {
address owner;
uint256 price;
bool sold;
}
mapping(uint256 => NFT) public nfts;
bool private locked = false;
modifier onlyOwner(uint256 _tokenId) {
require(token.ownerOf(_tokenId) == msg.sender, "Not the owner");
_;
}
modifier onlyAdmin() {
require(msg.sender == admin, "Not the admin");
_;
}
modifier nonReentrant() {
require(!locked, "Reentrant call");
locked = true;
_;
locked = false;
}
function listNFT(uint256 _tokenId, uint256 _price) external onlyOwner(_tokenId) {
require(_price > 0, "Price must be greater than zero");
// Transfer the NFT from the owner to the marketplace contract
token.transferFrom(msg.sender, address(this), _tokenId);
// List the NFT
nfts[_tokenId] = NFT(msg.sender, _price, false);
emit NFTListed(_tokenId, msg.sender, _price);
}
function buyNFT(uint256 _tokenId) external payable nonReentrant {
NFT storage nft = nfts[_tokenId];
require(!nft.sold, "NFT already sold");
require(nft.price == msg.value, "Incorrect price");
require(nft.owner != msg.sender, "Cannot buy your own NFT");
nft.sold = true;
address seller = nft.owner;
// Transfer the NFT from the marketplace contract to the buyer
token.safeTransferFrom(address(this), msg.sender, _tokenId);
// Transfer the payment to the seller
payable(seller).transfer(msg.value);
emit NFTSold(_tokenId, msg.sender, msg.value);
// Remove the NFT from the listings
delete nfts[_tokenId];
}
function cancelNFT(uint256 _tokenId) external onlyAdmin {
NFT storage nft = nfts[_tokenId];
require(!nft.sold, "NFT already sold");
// Transfer the NFT back to the owner
token.safeTransferFrom(address(this), nft.owner, _tokenId);
emit NFTCanceled(_tokenId, nft.owner);
// Remove the NFT from the listings
delete nfts[_tokenId];
}
function getNFT(uint256 _tokenId) external view returns (NFT memory) {
return nfts[_tokenId];
}
}
And that is how i'm calling it in my frontend
const list = async (id: string, price: string) => {
try {
const signer = await provider.getSigner();
const nftContract = contract.connect(signer);
const marketContract = market.connect(signer);
const marketplaceAddress = import.meta.env
.VITE_MARKETPLACE_CONTRACT_ADDRESS;
const tokenId = id;
const priceInWei = price;
// Check if the NFT is already approved for the marketplace contract
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
const currentApproval = await nftContract.getApproved(tokenId);
if (currentApproval.toLowerCase() !== marketplaceAddress.toLowerCase()) {
// Approve the marketplace contract to transfer the NFT
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
const approvalTx = await nftContract.approve(
marketplaceAddress,
tokenId
);
await approvalTx.wait(1);
}
// List the NFT on the marketplace
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
const listTx = await marketContract.listNFT(tokenId, priceInWei);
console.log("NFT listing transaction:", listTx.hash);
} catch (error) {
console.error("Error listing NFT:", error);
}
};
I'm getting these errors
MetaMask - RPC Error: Internal JSON-RPC error.
data
:
{hash: null, programCounter: 2492, result: '0x', reason: null, message: 'revert'}
message
:
"VM Exception while processing transaction: revert"
name
:
"RuntimeError"
stack
:
"RuntimeError: VM Exception while processing transaction: revert\n at exactimate (C:\\Program Files\\WindowsApps\\GanacheUI_2.7.1.0_x64__rb4352f0jd4m2\\app\\resources\\static\\node\\node_modules\\ganache\\dist\\node\\1.js:2:182136)"
[[Prototype]]
:
Object
message
:
"Internal JSON-RPC error."
And this one
Table.tsx:103 Error listing NFT:
Error: missing revert data (action="estimateGas", data=null, reason=null, transaction={ "data": "0x94383f1400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000013", "from": "0xE8495F857774bB61647f280e0FB87987B3A18e3B", "to": "0x453BEF367C09Bd01c6411c747058b1955338B135" }, invocation=null, revert=null, code=CALL_EXCEPTION, version=6.13.0)
at makeError (ethers.js?v=f8fb06fb:325:15)
at getBuiltinCallException (ethers.js?v=f8fb06fb:11863:10)
at _AbiCoder.getBuiltinCallException (ethers.js?v=f8fb06fb:11934:12)
at BrowserProvider.getRpcError (ethers.js?v=f8fb06fb:19084:26)
at BrowserProvider.getRpcError (ethers.js?v=f8fb06fb:21502:18)
at ethers.js?v=f8fb06fb:19272:27
Why am i getting these errors
first i was testing using hardhat network with metamask i tried to switch to ganache that didn't work
The mistake that led to this error was that I was deploying the marketplace contract with parameters misplaced