首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SetApprovalForAll:既不拥有也不批准

SetApprovalForAll:既不拥有也不批准
EN

Stack Overflow用户
提问于 2022-03-19 14:57:15
回答 1查看 1.1K关注 0票数 0

大家好,我的合同中有一个问题,我不知道如何解决it...Is一个Nft,这个问题发生在第二次销售中,我的意思是,如果我创建了一个令牌,然后在市场中导入令牌并将它从A卖到B是working....but,如果我试图从B卖到C,我会收到错误"Caller不所有者也不批准“。

代码语言:javascript
复制
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Counters.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol";


pragma solidity ^0.8.0;


contract NFTS is ERC721URIStorage, Ownable{
    using Counters for Counters.Counter;
    Counters.Counter private _tokenId;

    address contractOwner;
    address marketPlace;

    constructor(address _marketplace)ERC721("AAA", "BBB"){
        marketPlace = _marketplace;
        contractOwner = msg.sender;
    }

    mapping(uint=>address) public tokenCreator;

    function createNFT(string memory _uri)external returns(uint){
        _tokenId.increment();
        uint newId = _tokenId.current();
        _safeMint(msg.sender, newId);
        _setTokenURI(newId, _uri);
        setApprovalForAll(marketPlace, true);
        tokenCreator[newId] = msg.sender;
        return newId;
    }
}





contract Marketplace is Ownable, ReentrancyGuard{
    using Counters for Counters.Counter;
    Counters.Counter private _itemId;

    address payable contractOwner;
    uint listingPrice = 1 wei;
    uint delistingPrice = 1 wei;

    constructor(){
        contractOwner = payable(msg.sender);
    }


    struct importItemInMarketplace{
        address _nftContract;
        address payable contractOwner;
        address payable tokenCreator;
        address payable tokenOwner;
        address payable buyer;
        uint tokenId;
        uint price;
        uint royalties;
    }

    mapping(uint=>importItemInMarketplace) public idItemImportedInMarketplace;

    event successImported(
        address _nftContract,
        address payable contractOwner,
        address payable tokenCreator,
        address payable tokenOwner,
        address payable buyer,
        uint tokenId,
        uint price,
        uint royalties
    );


    struct itemForRoyalties{
        address payable contractOwner;
        address payable tokenCreator;
        uint price;
        uint royalties;
    }

    mapping(uint=>itemForRoyalties) public tokenIdRoyalties;


    function itemInMarketplace(
        address _nftContract,
        uint _tokenId,
        uint _price,
        uint _royalties
    )external payable nonReentrant{
        address tokenOwner = NFTS(_nftContract).ownerOf(_tokenId);
        address tokenCreator = NFTS(_nftContract).tokenCreator(_tokenId);
        
        require(_price > 0, "Cannot set a price less or equal to 0!");
        require(msg.value == listingPrice, "You have to pay 1 wei to list your token!");
        require(msg.sender == tokenOwner, "Cannot list a token if is not yours!" );
        require(_royalties > 5 && _royalties < 20, "You can set royalties between 5% and 20 % !");
        
        _itemId.increment();
        uint newId = _itemId.current();
        
        
        
        idItemImportedInMarketplace[newId] = importItemInMarketplace(
            _nftContract,
            payable(contractOwner),
            payable(tokenCreator),
            payable(tokenOwner),
            payable(address(0)),
            _tokenId,
            _price,
            _royalties  
        );
        
        
        tokenIdRoyalties[_tokenId] = itemForRoyalties(
            payable(contractOwner),
            payable(tokenCreator),
            _price,
            _royalties
        );

    }

    function getDataRoyalties(uint _tokenId)public view returns(
        address, address, uint, uint
    ){
        return (tokenIdRoyalties[_tokenId].contractOwner, tokenIdRoyalties[_tokenId].tokenCreator, tokenIdRoyalties[_tokenId].price, tokenIdRoyalties[_tokenId].royalties);
    }



    struct ItemSold{
        address _nftContract;
        address payable contractOwner;
        address payable tokenCreator;
        address payable prevTokenOwner;
        address payable buyer;
        uint tokenId;
        uint price;
        uint royalties;
    }

    mapping(uint=>ItemSold)public soldedItemTokenId;


    event SoldSuccess(
        address _nftContract,
        address payable contractOwner,
        address payable tokenCreator,
        address payable prevTokenOwner,
        address payable buyer,
        uint tokenId,
        uint price,
        uint royalties
    );



    function purchase(address _nftContract, uint _itemIds)external payable nonReentrant{
        address payable _contractOwner = idItemImportedInMarketplace[_itemIds].contractOwner;
        address payable _tokenOwner = idItemImportedInMarketplace[_itemIds].tokenOwner;
        address payable _tokenCreator = idItemImportedInMarketplace[_itemIds].tokenCreator;
        address payable _prevTokenOwner = _tokenOwner;
        address payable _buyer = idItemImportedInMarketplace[_itemIds].buyer;
        uint _tokenId = idItemImportedInMarketplace[_itemIds].tokenId;
        uint _price = idItemImportedInMarketplace[_itemIds].price;
        uint _royalties = idItemImportedInMarketplace[_itemIds].royalties;
        
        require(msg.sender != _contractOwner && msg.sender != _tokenOwner, "Admin or tokenOwner cannot buy this Item!");
        require(msg.value == _price, "Set the right price to buy it!");

        payable(_contractOwner).transfer(listingPrice);
        _tokenOwner = payable(msg.sender);
        payable(_prevTokenOwner).transfer(_price);
        _buyer = payable(_tokenOwner);
        NFTS(_nftContract).transferFrom(_prevTokenOwner, _buyer, _tokenId);
        delete(idItemImportedInMarketplace[_itemIds]);
        _itemId.decrement();

        soldedItemTokenId[_tokenId] = ItemSold(
            _nftContract,
            payable(_contractOwner),
            payable(_tokenCreator),
            payable(_prevTokenOwner),
            payable(_buyer),
            _tokenId,
            _price,
            _royalties
        );


        emit SoldSuccess(
            _nftContract,
            payable(_contractOwner),
            payable(_tokenCreator),
            payable(_prevTokenOwner),
            payable(_buyer),
            _tokenId,
            _price,
            _royalties
        );
    }

现在我不明白为什么我会收到这个错误,因为在第二次出售时,B帐户可以列出令牌,而通过列出函数,只有令牌所有者可以列出令牌。任何帮助都是appreciate...thanks,祝您一天愉快

EN

回答 1

Stack Overflow用户

发布于 2022-06-08 04:02:57

当用户在NFTS合同中调用SetApprovalForAll(marketplace, true)时,他允许市场交换使用该合同创建的任何

现在,当A将NFT转移到B时,市场代表A执行订单,因为A在创建令牌时调用了SetApprovalForAll,因此市场拥有转让A的令牌的权限,因此没有任何问题。

现在,当B试图将NFT传输到C时,B还没有允许市场传输他的令牌。因此,在您的购买函数中,代码的这一部分抛出错误“调用者不所有者也不批准”。

代码语言:javascript
复制
NFTS(_nftContract).transferFrom(_prevTokenOwner, _buyer, _tokenId);

因此,要解决这个问题,必须找到B从前端调用SetApprovalForAll的方法。当B注册到您的网站或在令牌转移发生之前,您可以这样做。

使用ethers.js,它看起来如下所示

代码语言:javascript
复制
const contract = new ethers.Contract(nftAddress, NFT.abi, signer)  //signer is B
const isApprovedForAll = await contract.isApprovedForAll(signerAddress, marketplaceAddress)
if(!isApprovedForAll){
    await contract.setApprovalForAll(maketplaceAddress, true)
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71539232

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档