首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何传输ERC721令牌

如何传输ERC721令牌
EN

Stack Overflow用户
提问于 2021-10-28 08:55:34
回答 2查看 4.9K关注 0票数 0

我正在尝试传输一个ERC721令牌,但是我得到了transferToken方法的错误ERC721: transfer caller is not owner nor approved

Main.sol

代码语言:javascript
复制
import "./ERC721.sol";
import "./Counters.sol";

contract Main is ERC721 {
    using Counters for Counters.Counter;
    Counters.Counter internal _tokenIds;
    address payable internal admin; 

    constructor() ERC721("MyToken", "TOKEN") {
        admin = payable(msg.sender);
    }
}

Auction.sol

代码语言:javascript
复制
import "./Main.sol";

contract Auction is Main {
    struct AuctionInfo {
        uint256 tokenId;
        address highestBidder;
        uint highestBid;
    }

    mapping(string => AuctionInfo) private _auctionInfo;

    function createAuction(string memory id) public {
        _tokenIds.increment();

        uint256 newTokenId = _tokenIds.current();
        _mint(msg.sender, newTokenId);
        
        _auctionInfo[id].tokenId = newTokenId;
    }

    function transferToken(string memory id) public {
        require(msg.sender == _auctionInfo[id].highestBidder, "You are not the highest bidder");

        safeTransferFrom(address(this), _auctionInfo[id].highestBidder, _auctionInfo[id].tokenId);
    }

    // other methods...
}

造币合同是this,如果我没有弄错的话,令牌的所有者就是造币方法的msg.sender。在传输之前,我每次都要使用approve (或setApprovalForAll)作为this吗?我已经尝试过thispayable(this)address(this)safeTransferFrom方法,但似乎没有一种方法起作用。

例如,我尝试了以下方法,但得到了相同的还原消息:

代码语言:javascript
复制
 approve(address(this), _auctionInfo[id].tokenId);
 this.safeTransferFrom(address(this), _auctionInfo[id].highestBidder, _auctionInfo[id].tokenId);
EN

回答 2

Stack Overflow用户

发布于 2021-10-28 17:04:56

任何Blockchain背后的主要原则是,区块链网络上的任何人都不应该被信任,而且这些交易仍然应该发生愚蠢的证明,不存在任何欺骗的可能性(当然,某些黑客除外)。

如果您从Auction契约中调用msg.sender方法,那么ERC721令牌契约中的ERC721函数的msg.sender就是您的拍卖契约地址。因此,换句话说,你的拍卖合同是试图批准自己出售别人的NFT,这不是很值得信赖。

真正应该发生的是,NFT的所有者应该调用ERC721契约的ERC721方法,即您为approve函数调用发送的事务应该由NFT所有者钱包地址签名。这样,msg.sender契约中的approve函数将成为NFT的所有者。根据ERC721标准,NFT的所有者可以批准任何他们想要的东西,出售他们的NFT,因为网络中的不信任仍然存在(至少我应该能够信任自己)。在从DAPP调用approve函数之前,应该在DAPP中调用transferToken方法。

希望这解释了为什么您无法传输您的ERC721令牌。

票数 1
EN

Stack Overflow用户

发布于 2021-10-29 08:29:58

由于internalERC721._approve()函数的可见性,您可以有效地为用户执行审批。

然后您将能够从您的合同执行safeTransferFrom(tokenOwner, receiver, tokenId),因为您的合同地址被批准来操作这个特定的令牌,即使它属于tokenOwner

此代码段创建令牌,将所有权分配给msg.sender。但是,它还调用不包含任何验证的_approve()函数,并简单地将令牌的批准分配给Auction地址。

代码语言:javascript
复制
pragma solidity ^0.8;

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol";

contract Auction is ERC721 {
    
    constructor() ERC721("CollectionName", "Symbol") {}
    
    function createAuction() public {
        uint256 newTokenId = 1;

        _mint(msg.sender, newTokenId);
        _approve(address(this), newTokenId);
    }
    
}

您可以从屏幕截图中看到,所有者是0x5B... (用户地址),令牌被批准为0xd9... (契约地址)。

注意:_approve()函数是internal --它可以从ERC721契约及其派生的契约(在您的例子中是MainAuction__)调用,但是不能从外部契约或最终用户地址调用它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69751069

复制
相关文章

相似问题

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