Hello cryptokid !
Thank you for your reply.
I deploy the contract on mumbai testnet and the chain selected is mumbai also on moralis server.
here the contract address :
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
contract MarketPlace is ReentrancyGuard {
using Counters for Counters.Counter;
Counters.Counter private _itemIds;
Counters.Counter private _itemSold;
address public owner;
constructor() {
owner = msg.sender;
}
struct MarketItem {
uint256 itemId;
address nftContract;
uint256 tokenId;
address payable seller;
address payable owner;
uint256 price;
bool sold;
}
mapping(uint256 => MarketItem) private idToMarketItem;
event MarketItemCreated(
uint256 indexed itemId,
address indexed nftContract,
uint256 indexed tokenId,
address seller,
address owner,
uint256 price,
bool sold
);
event MarketItemSold(uint256 indexed itemId, address owner);
function createMarketItem(
address nftContract,
uint256 tokenId,
uint256 price
) public payable nonReentrant {
require(price > 0, "Price must be greater than 0");
_itemIds.increment();
uint256 itemId = _itemIds.current();
idToMarketItem[itemId] = MarketItem(
itemId,
nftContract,
tokenId,
payable(msg.sender),
payable(address(0)),
price,
false
);
IERC721(nftContract).transferFrom(msg.sender, address(this), tokenId);
emit MarketItemCreated(
itemId,
nftContract,
tokenId,
msg.sender,
address(0),
price,
false
);
}
function createMarketSale(address nftContract, uint256 itemId)
public
payable
nonReentrant
{
uint256 price = idToMarketItem[itemId].price;
uint256 tokenId = idToMarketItem[itemId].tokenId;
bool sold = idToMarketItem[itemId].sold;
require(
msg.value == price,
"Please submit the asking price in order to complete the purchase"
);
require(sold != true, "This sale has already finished");
emit MarketItemSold(itemId, msg.sender);
idToMarketItem[itemId].seller.transfer(msg.value);
IERC721(nftContract).transferFrom(address(this), msg.sender, tokenId);
idToMarketItem[itemId].owner = payable(msg.sender);
_itemSold.increment();
idToMarketItem[itemId].sold = true;
}
function fetchMarketItem() public view returns (MarketItem[] memory) {
uint256 itemCount = _itemIds.current();
uint256 unsoldItemcount = _itemIds.current() - _itemSold.current();
uint256 currentIndex = 0;
MarketItem[] memory items = new MarketItem[](unsoldItemcount);
for (uint256 i = 0; i < itemCount; i++) {
if (idToMarketItem[i + 1].owner == address(0)) {
uint256 currentId = i + 1;
MarketItem storage currentItem = idToMarketItem[currentId];
items[currentIndex] = currentItem;
currentIndex += 1;
}
}
return items;
}
}
And here the abi file import on the provider :
[
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "itemId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "nftContract",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "address",
"name": "seller",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "price",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bool",
"name": "sold",
"type": "bool"
}
],
"name": "MarketItemCreated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "itemId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"name": "MarketItemSold",
"type": "event"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function",
"constant": true
},
{
"inputs": [
{
"internalType": "address",
"name": "nftContract",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "price",
"type": "uint256"
}
],
"name": "createMarketItem",
"outputs": [],
"stateMutability": "payable",
"type": "function",
"payable": true
},
{
"inputs": [
{
"internalType": "address",
"name": "nftContract",
"type": "address"
},
{
"internalType": "uint256",
"name": "itemId",
"type": "uint256"
}
],
"name": "createMarketSale",
"outputs": [],
"stateMutability": "payable",
"type": "function",
"payable": true
},
{
"inputs": [],
"name": "fetchMarketItem",
"outputs": [
{
"components": [
{
"internalType": "uint256",
"name": "itemId",
"type": "uint256"
},
{
"internalType": "address",
"name": "nftContract",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "address payable",
"name": "seller",
"type": "address"
},
{
"internalType": "address payable",
"name": "owner",
"type": "address"
},
{
"internalType": "uint256",
"name": "price",
"type": "uint256"
},
{
"internalType": "bool",
"name": "sold",
"type": "bool"
}
],
"internalType": "struct MarketPlace.MarketItem[]",
"name": "",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function",
"constant": true
}
]
For the provider i put like this, coz got issue with this line :
const [contractABI, setContractABI] = useState (â{contract abi here}â) the â â was the issue.
import React, { useEffect, useState } from "react";
import { useMoralis } from "react-moralis";
import MoralisDappContext from "./context";
import MarketPlace from "./MarketPlace.json";
function MoralisDappProvider({ children }) {
const { web3, Moralis, user } = useMoralis();
const [walletAddress, setWalletAddress] = useState();
const [chainId, setChainId] = useState();
const [contractABI, setContractABI] = useState(MarketPlace);
const [marketAddress, setMarketAddress] = useState("0xa4826089cdcb725dE72aeB666204640593849245");
useEffect(() => {
Moralis.onChainChanged(function (chain) {
setChainId(chain);
});
Moralis.onAccountsChanged(function (address) {
setWalletAddress(address[0]);
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(() => setChainId(web3.givenProvider?.chainId));
useEffect(
() => setWalletAddress(web3.givenProvider?.selectedAddress || user?.get("ethAddress")),
[web3, user]
);
return (
<MoralisDappContext.Provider value={{ walletAddress, chainId, contractABI, setContractABI, marketAddress, setMarketAddress }}>
{children}
</MoralisDappContext.Provider>
);
}
function useMoralisDapp() {
const context = React.useContext(MoralisDappContext);
if (context === undefined) {
throw new Error("useMoralisDapp must be used within a MoralisDappProvider");
}
return context;
}
export { MoralisDappProvider, useMoralisDapp };
what do you mean by topic ?
Thanks to you ! And sorry took a while to update it.
Ah also, on the package.json, i add allow origine: * :
{
"name": "ethereum-boilerplate",
"version": "0.1.0",
"private": true,
"headers": {
"Access-Control-Allow-Origin": "*"
},