[英]Internal JSON-RPC error with MetaMask on Polygon Blockchain. `ERC721: transfer caller is not owner nor approved.`
I am making an NFT marketplace.我正在创建一个 NFT 市场。 When I deployed my contract on the Mumbai-testnet.
当我在 Mumbai-testnet 上部署我的合约时。 The createToken function might work cause it brings up the Metamask for the Gas Fee but after that, the Error occurs something regarding the ONWNERSHIP .
createToken function 可能会起作用,因为它会显示 Gas Fee 的 Metamask,但在那之后,会出现关于ONWNERSHIP的错误。 (Error image and text is present below.)
(错误图像和文本如下所示。)
STEPS which I follow我遵循的步骤
npm hardhat node
npm run dev
then the error occurs.然后发生错误。
Here is my NFT contract这是我的 NFT 合约
contract NFT is ERC721URIStorage {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
address contractAddress;
constructor(address marketplaceAddress) ERC721("Metaverse Tokens", "METT") {
contractAddress = marketplaceAddress;
}
function createToken(string memory tokenURI) public returns (uint256) {
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(msg.sender, newItemId);
_setTokenURI(newItemId, tokenURI);
setApprovalForAll(contractAddress, true);
return newItemId;
}}
Here is my NFTMarket contract这是我的 NFTMarket 合约
contract NFTMarket is ReentrancyGuard {
using Counters for Counters.Counter;
Counters.Counter private _itemIds;
Counters.Counter private _itemSold;
address payable owner;
uint256 listingPrice = 0.025 ether; // Here ether is denoting the MATIC
constructor() {
owner = payable(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
);
function getListingPrice() public view returns (uint256) {
return listingPrice;
}
//Function to create an NFT
function createMarketItem(
address nftContract,
uint256 tokenId,
uint256 price
) public payable nonReentrant {
//Conditions for creating the Item.
require(price > 0, "Price must be at least 1 wei");
require(
msg.value == listingPrice,
"Price must be equal to listing price"
);
_itemIds.increment();
uint256 itemId = _itemIds.current();
idToMarketItem[itemId] = MarketItem(
itemId,
nftContract,
tokenId,
payable(msg.sender),
payable(address(0)), // When new NFT is created its ownership add is set to 0.
price,
false
);
IERC721(nftContract).transferFrom(msg.sender, address(this), tokenId);
//Trigger the Event
emit MarketItemCreated(
itemId,
nftContract,
tokenId,
msg.sender,
address(0),
price,
false
);
}
//Function to Transfer the Ownership
function createMarketSale(address nftContract, uint256 itemId)
public
payable
nonReentrant
{
uint256 price = idToMarketItem[itemId].price;
uint256 tokenId = idToMarketItem[itemId].tokenId;
require(
msg.value == price,
"Please submit the asking value in order to Purchase"
);
//Will transfer the MATIC to the seller address.
idToMarketItem[itemId].seller.transfer(msg.value);
//Will transfer the ownership from the owner of this contract to the Buyer.
IERC721(nftContract).transferFrom(address(this), msg.sender, tokenId);
//Set the local value of the owner to the Buyer(msg.sender).
idToMarketItem[itemId].owner = payable(msg.sender);
//Set this NFT as sold.
idToMarketItem[itemId].sold = true;
_itemSold.increment();
payable(owner).transfer(listingPrice);
}
//Returns number of items unsold
function fetchMarketItems() 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 = idToMarketItem[i + 1].itemId;
MarketItem storage currentItem = idToMarketItem[currentId];
items[currentIndex] = currentItem;
currentIndex += 1;
}
}
return items;
}
//Returns number of Own(Created or Bought) NFTs
function fetchMyNFTs() public view returns (MarketItem[] memory) {
uint256 totalItemCount = _itemIds.current();
uint256 itemCount = 0;
uint256 currentIndex = 0;
for (uint256 i = 0; i < totalItemCount; i++) {
if (idToMarketItem[i + 1].owner == msg.sender) {
itemCount += 1;
}
}
MarketItem[] memory items = new MarketItem[](itemCount);
for (uint256 i = 0; i < totalItemCount; i++) {
if (idToMarketItem[i + 1].owner == msg.sender) {
uint256 currentId = idToMarketItem[i + 1].itemId;
MarketItem storage currentItem = idToMarketItem[currentId];
items[currentIndex] = currentItem;
currentIndex += 1;
}
}
return items;
}
//Returns the no of NFT created
function fetchItemsCreated() public view returns (MarketItem[] memory) {
uint256 totalItemCount = _itemIds.current();
uint256 itemCount = 0;
uint256 currentIndex = 0;
for (uint256 i = 0; i < totalItemCount; i++) {
if (idToMarketItem[i + 1].seller == msg.sender) {
itemCount += 1;
}
}
MarketItem[] memory items = new MarketItem[](itemCount);
for (uint256 i = 0; i < totalItemCount; i++) {
if (idToMarketItem[i + 1].seller == msg.sender) {
uint256 currentId = idToMarketItem[i + 1].itemId;
MarketItem storage currentItem = idToMarketItem[currentId];
items[currentIndex] = currentItem;
currentIndex += 1;
}
}
return items;
}}
I tried changing the RPC in the MetaMask and the configuration files and redeployed it many times with different accounts, but still, nothing changes.我尝试更改 MetaMask 和配置文件中的 RPC,并使用不同的帐户重新部署了很多次,但仍然没有任何变化。
The Error错误
MetaMask - RPC Error: Internal JSON-RPC error.
data:
code: 3
message: "execution reverted: ERC721: transfer caller is not owner nor approved"
If any other info is required please comment如果需要任何其他信息,请发表评论
You are inheriting from ERC721URIStorage
which inherits from ERC721
If you check the transferFrom
inside ERC721
:您是从继承自
ERC721URIStorage
的ERC721
继承如果您检查ERC721
内部的transferFrom
:
function transferFrom(address from,address to,uint256 tokenId
) public virtual override {
// ***** THIS REQUIRE IS NOT SATISFIED *****
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_transfer(from, to, tokenId);
}
you are getting that error, because require
statement inside transferFrom
is not satisfied.您收到该错误,因为
transferFrom
中的require
语句不满足。 So somewhere inside your contract you are calling transferFrom
and it is failing.因此,在您的合同中某处您正在调用
transferFrom
并且它失败了。 it should be written like this:它应该这样写:
// in this case transfer the ownership from the owner to the contract
IERC721(contractAddress).transferFrom(msg.sender,address(this),tokenId);
During development, every time you compile your smart contract (using something like hardhat compile..
), you have to copy the new smart contract addresses generated in your command prompt and paste them in the designated location in your source code.在开发过程中,每次编译智能合约(使用类似
hardhat compile..
之类的东西)时,都必须复制在命令提示符下生成的新智能合约地址,并将它们粘贴到源代码中的指定位置。
Thank You for your efforts.感谢你付出的努力。 I got the solution to it(After Searching for 3 days).
我得到了解决方案(搜索3天后)。
SOLUTION =>解决方案=>
There's currently a bug on Mumbai causing deployed addresses to be incorrect.孟买目前存在一个错误,导致部署的地址不正确。 This is causing the constructor of the NFT contract to approve the wrong address for NFT purchases (because it uses the address of the Market deployment for approval) — causing the annoying
"execution reverted: ERC721: approve caller is not owner nor approved for all"
error.这导致NFT合约的构造函数批准了错误的 NFT 购买地址(因为它使用 Market 部署的地址进行批准)——导致烦人的
"execution reverted: ERC721: approve caller is not owner nor approved for all"
错误。
Try using Mainnet (yes, you'll have to use real money) but it works!尝试使用主网(是的,你必须使用真钱)但它有效!
Here's a workaround deploy script that will make it work on Mumbai.这是一个解决方法部署脚本,可以让它在孟买工作。 Replace main() in deploy.js with:
将 deploy.js 中的 main() 替换为:
const hre = require("hardhat");
async function main() {
const [deployer] = await hre.ethers.getSigners();
console.log(
"Deploying contracts with the account:",
deployer.address
);
let txHash, txReceipt
const NFTMarket = await hre.ethers.getContractFactory("NFTMarket");
const nftMarket = await NFTMarket.deploy();
await nftMarket.deployed();
txHash = nftMarket.deployTransaction.hash;
txReceipt = await ethers.provider.waitForTransaction(txHash);
let nftMarketAddress = txReceipt.contractAddress
console.log("nftMarket deployed to:", nftMarketAddress);
const NFT = await hre.ethers.getContractFactory("NFT");
const nft = await NFT.deploy(nftMarketAddress);
await nft.deployed();
txHash = nft.deployTransaction.hash;
// console.log(`NFT hash: ${txHash}\nWaiting for transaction to be mined...`);
txReceipt = await ethers.provider.waitForTransaction(txHash);
let nftAddress = txReceipt.contractAddress
console.log("nft deployed to:", nftAddress);
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Redeploy the Contracts with this Script, and change the config.js
.使用此脚本重新部署合同,并更改
config.js
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.