When attempting to send a token from an account to a marketplace in ERC721, the transfer caller must either be the owner

Currently, I am in the process of transferring my NFT to a marketplace

pragma solidity ^0.8.7;

import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

import "hardhat/console.sol";

contract NFT is ERC721URIStorage {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    address contractAddress;

    constructor(address marketplaceAddress) ERC721("Heliopolis NFT", "HNFT") {
        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;
    }

    function transferToken(address from, address to, uint256 tokenId) external {
        require(ownerOf(tokenId) == from, "From address must be token owner");
        _transfer(from, to, tokenId);
    }

    function getContractAddress() public view returns (address) {
        return contractAddress;
    }
}

As part of my implementation using web3modal:

import { ethers } from 'ethers';
import Web3Modal from 'web3modal';

import { nftMarketplaceAddress, nftAddress } from 'utils/contracts';

import { nftMarketplaceAbi } from 'utils/nftMarketplaceAbi';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const resellNft = async (nft: any) => {
    try{
        const web3Modal = new Web3Modal();
        const connection = await web3Modal.connect();
        const provider = new ethers.providers.Web3Provider(connection);
        const signer = provider.getSigner();
        const contract = new ethers.Contract(nftMarketplaceAddress, nftMarketplaceAbi, signer);
        
        // putItemToResell invokes the transferToken(*) method mentioned above
        const transaction = await contract.putItemToResell(nftAddress, nft.tokenId, nft.price,
            {
                gasLimit: 1000000,
                gasPrice: ethers.utils.parseUnits("10", "gwei"),
                value: ethers.utils.parseUnits("0.001", "ether"),

            }
        );
        const response = await transaction.wait();
        console.log(response);
    }catch (e:any){
        throw e;
    }

}

If an error such as

ERC721: transfer caller is not owner nor approved
shows up, refers to this thread (ERC721: transfer caller is not owner nor approved) suggesting granting approval to the marketplace for invoking transferFrom() on your behalf. It's worth noting that the NFT contract includes the approve method inherited from its super class. Is there a way around this issue?

Answer №1

Indeed, your assumption is accurate. When you wish for another contract to handle the transfer of an NFT on your behalf, you must grant approval to that specific contract.

The function responsible for this task is:

function setApprovalForAll(address _operator, bool _approved) external;

This function is a key component of the ERC721 standard.

Therefore, if you want a marketplace to facilitate the transfer of user-owned NFTs upon sale, you need to initiate the following action first:

yourNftContract.setApprovalForAll(marketplaceContractAddress, true)

A similar process applies when trying to list an NFT for sale on platforms like Opensea – you must perform the approval transaction to authorize the respective contract.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Turn off browser image caching

In order to provide users with fresh weather updates, my Earth weather web application receives new weather maps every six hours as images. I want to prevent the browser from caching these images to ensure that the user always sees the most current data, r ...

Having Trouble with Angular Route (6) Configuration

I've been experiencing some unusual issues with the Angular 6 router, but this particular one is really frustrating. Here are the routes that I have defined in routing-app.module.ts: export const routes: Routes = [ { path: 'login&a ...

Is it acceptable to have an empty dependency array in React.useEffect?

Within my child React component, I receive an itemList prop from the parent component. This prop is an array of objects that contain data fetched from an endpoint. My goal in the child component is to enhance each object in the itemList array by adding mo ...

Using React to make an API call without utilizing hooks

Hello, I am currently working on developing a webpart using SharePoint and React. However, I am facing some issues with fetching data from a simple API. export default class Testing100 extends React.Component<ITesting100Props, {}> { constructor(p ...

I'm having trouble asynchronously adding a row to a table using the @angular/material:table schematic

Having trouble asynchronously adding rows using the @angular/material:table schematic. Despite calling this.table.renderRows(), the new rows are not displayed correctly. The "works" part is added to the table, reflecting in the paginator, but the asynchron ...

Toggle the visibility of an input field based on a checkbox's onchange event

I am facing a challenge where I need to display or hide an Input/Text field based on the state of a Checkbox. When the Checkbox is checked, I want to show the TextField, and when it is unchecked, I want to hide it. Below is the code snippet for this compon ...

Unable to designate data types for a React Higher Order Component

In order to enhance a component with flattened props, I am working on creating a Higher Order Component (HOC). The goal is to take a component and return a new one that accepts flattened props using the flat package, then apply these unflattened props to t ...

Error message: Conflicting type declarations across multiple files

I am facing a challenge with my TypeScript 'snippets' project. It seems that multiple .ts files contain type names (like Foo) that are the same. //file-a.ts type Foo = { } //file-b.ts type Foo = { } When attempting to compile, I encounter ...

A different approach to handling multiple constructors in Angular 4

Angular 4 does not support having multiple constructors, so I need to find a cleaner way to instantiate my object. This is what my model looks like: export class SrcFilter { constructor(public firstList?: Array<String>, public secondList?: Arra ...

Join our mailing list for exclusive updates on Angular 6

ingredients : Array additionalIngredients : Array In my code, I have two different methods for subscribing: this.ingredients.valueChanges.subscribe(val=> { console.log(val); } this.additionalIngredients.valueChanges.subscribe(val2=> { console.lo ...

Testing the integration of socket.io with Angular through unit tests

Currently, I am in the process of unit testing an angular service within my application that is responsible for creating a socket.io client. The structure of my service can be seen below: export class SocketService { private name: string; private host ...

Why do callbacks in Typescript fail to compile when their arguments don't match?

In my current project, I encountered a scenario where a React callback led to a contrived example. interface A { a: string b: string } interface B { a: string b: string c: string } function foo(fn: (a: A) => void, a: A) { fn( ...

What is the overlay feature in Material-UI dialogs?

I recently started using the React-Redux Material-UI package found at http://www.material-ui.com/#/components/dialog My goal is to implement a grey overlay that blankets the entire dialog element, complete with a circular loading indicator after the user ...

JavaScript Equivalent of Declaration in TypeScript

In my Next JS application, I encountered a situation where a line of code relies on a variable from a script src in the app.tsx page. Here's how it looks: app.tsx: <script src="https://js.stripe.com/v3/"></script> config.ts: de ...

Struggling to comprehend the intricacies of these generic declarations, particularly when it comes to Type Argument Lists

I'm currently reviewing the code snippet from the TypeScript definitions of fastify. I am struggling to understand these definitions. Although I am familiar with angle brackets used for generics, most TypeScript tutorials focus on simple types like Ar ...

Issues resolving the signature of a parameter in a Typescript decorator within vscode

I encountered an error while attempting to decorate a class in my NestJS service. The Typescript code compiles without any issues, but I am facing this problem only in VSCode. Unable to resolve signature of parameter decorator when called as an expression ...

The Google Maps feature encountered an error (ReferenceError: google is not defined)

Utilizing the Google Maps API on my website to display multiple locations has been successful so far. However, an issue arises when attempting to determine the distance between two sets of latitude and longitude coordinates - resulting in an error message ...

Tips for saving metadata about properties within a class

I am looking to add metadata to properties within classes, specifically using abbreviations for property names. By using annotations like @shortName(abbreviated), you can label each property as follows: function shortName(shortName: string){ return fu ...

Guide on showing the content of an uploaded file as an object in JavaScript using file reader

When using the file upload function to upload a json file and read its contents, I am encountering an issue where the result is in string format instead of object. How can I display it as an object? Here is my code: .html <div class="form-group"> ...

Having trouble with obtaining precise mouseup and mousedown coordinates

Currently, I am working with react and typescript for my project. I have implemented a canvas element where I am attempting to draw a rectangle based on mouseup and mousedown events. However, the issue I am facing is that the rectangles are being drawn in ...