简体   繁体   English

从简单合约或工厂合约部署 erc721 合约

[英]deploy erc721 contracts from a simple or factory contract

I want to deploy erc721 contracts from a simple factory contract and i have this error when I try to upload NFT - "transfer to non ERC721Receiver implementer", "data" enter image description here我想从一个简单的工厂合约部署 erc721 合约,当我尝试上传 NFT 时出现此错误 - “transfer to non ERC721Receiver implementer”,“data” enter image description here

 // SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "./ezeynftFactory.sol"; contract ezeNFT { uint256 public tokenCounter; constructor(){ tokenCounter = 201; } function _mintNewNFT( string memory name, string memory symbol, string memory tokenUri)public{ uint256 newTokenId = tokenCounter; ezeynftFactory nfts = new ezeynftFactory(name,symbol,tokenUri,newTokenId); tokenCounter += 1; } }

 // SPDX-License-Identifier: MIT pragma experimental ABIEncoderV2; pragma solidity >=0.6.0 <0.8.0; import "../ERC721/ERC721.sol"; contract ezeynftFactory is ERC721 { constructor(string memory name, string memory symbol,string memory tokenURI,uint tokenID) ERC721(name,symbol) { _safeMint(msg.sender, tokenID); _setTokenURI(tokenID,tokenURI); } }

The OpenZeppelin _safeMint() function tries to invoke onERC721Received() on the receiver if the receiver is a contract (which your ezeNFT is). OpenZeppelin _safeMint() function 尝试在接收器上调用onERC721Received()如果接收器是合约(您的ezeNFT是)。 And reverts the transaction if it doesn't receive the expected response (which doesn't receive, so it reverts).如果它没有收到预期的响应(没有收到,所以它会还原)并还原事务。

There are two solutions to your problem.您的问题有两种解决方案。

  1. Either implement the onERC721Received() function on your ezeNFT contract (the token receiver), returning the expected response.在您的ezeNFT合约(令牌接收方)上实施onERC721Received() function,返回预期响应。 See ERC721TokenReceiver interface in the ERC-721 standard definition for more info.有关详细信息,请参阅ERC-721标准定义中的ERC721TokenReceiver接口。
contract ezeNFT {
    uint256 public tokenCounter;

    constructor(){
        tokenCounter = 201;
    }

    function _mintNewNFT( string memory name, string memory symbol, string memory tokenUri) public {
        uint256 newTokenId = tokenCounter;
        ezeynftFactory nfts = new ezeynftFactory(name,symbol,tokenUri,newTokenId);
        tokenCounter += 1;
    }

    function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes _data) external returns(bytes4) {
        // TODO validate if you want to accept tokens only from certain collections

        // return the expected response
        return bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"));
    }
}
  1. Or use the _mint() function, instead of _safeMint() , which doesn't perform the onERC721Received() call on the token receiver.或者使用_mint() function 而不是_safeMint() ,它不会对令牌接收方执行onERC721Received()调用。 So you won't have to implement it on ezeNFT .所以您不必在ezeNFT上实施它。
contract ezeynftFactory is ERC721 {
    constructor(string memory name, string memory symbol,string memory tokenURI,uint tokenID) 
     ERC721(name,symbol)
    {
        _mint(msg.sender, tokenID); // `_mint()` instead of `_safeMint()`
        _setTokenURI(tokenID,tokenURI);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM