Solidity

如何使用外部合約向 msg.sender 發送 ERC721 代幣?

  • January 17, 2019

我有 Caller 和 ERC721 契約,就像這樣:

contract SampleToken is ERC721MetadataMintable {
   string private name;
   string private symbol;
   constructor (address _creator, string _name, string _symbol, string _tokenURI)
   ERC721MetadataMintable()
   ERC721Metadata(_name, _symbol) public {
       uint256 _tokenId = 0;
       mintWithTokenURI(_creator, _tokenId, _tokenURI);
   }
}

我希望這個來電者能夠將 NFT 轉移給msg.sender. 呼叫者的行為類似於 FRC721 合約的工廠合約。

contract Caller {
   mapping(uint256 => address) public ERC721Address;
   using Address for address;
   bytes4 constant ERC721_RECEIVED = 0xf0b9e5ba;

   struct ERCs {
       address owner;
   }

   ERCs[] public ercs;

   function create(
       string _name,
       string _symbol,
       string _tokenURI
   ) public returns(bool) {
       ERCs memory _ercs = ERCs({
           owner: msg.sender
       });
       uint256 contractId = ercs.push(_ercs) -1; 
       ERC721Address[contractId] = new SampleToken(msg.sender, _name, _symbol, _tokenURI);
       return true;
   }

   function tokenTransferTo(
       address _to,
       uint256 _contractId,
       uint256 _tokenId,
       bytes _data
   ) public {
       require(msg.sender == ownerAddress(_contractId, _tokenId), "You do not have a right to mint token.");
       SampleToken(ERC721Address[_contractId]).setApprovalForAll(msg.sender, true);
       safeTransferFrom(msg.sender, _to, _contractId, _tokenId, _data);
   }

   function ownerAddress(uint256 _contractId, uint256 _tokenId) public view returns(address) {
       return SampleToken(ERC721Address[_contractId]).ownerOf(_tokenId);
   }

   function safeTransferFrom(
       address _from,
       address _to,
       uint256 _contractId,
       uint256 _tokenId,
       bytes _data
   ) public {
       SampleToken(ERC721Address[_contractId]).transferFrom(_from, _to, _tokenId);
       // solium-disable-next-line arg-overflow
       require(checkAndCallSafeTransfer(_from, _to, _tokenId, _data));
   }

   function checkAndCallSafeTransfer(
       address _from,
       address _to,
       uint256 _tokenId,
       bytes _data
   ) internal returns (bool) {
       if (!_to.isContract()) {
         return true;
       }
       bytes4 retval = ERC721Holder(_to).onERC721Received(address(this), _from, _tokenId, _data);
       return (retval == ERC721_RECEIVED);
   }
}

每次我tokenTransferTo在呼叫create()函式後嘗試呼叫時,都會收到如下錯誤消息。有誰知道這有什麼問題?

transact to Caller.tokenTransferTo errored: VM error: revert.
revert  The transaction has been reverted to the initial state.
Note: The constructor should be payable if you send value.  Debug the transaction to get more information. 

transferFrom(msg.sender, {Caller.contractAddress}, _tokenid)我想除了實現 Dapps 層直接從 ERC721 合約端呼叫之外,目前還沒有針對這種情況的解決方案。require(_isApprovedOrOwner(msg.sender, tokenId));因為它總是在檢查零件時恢復。

https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC721/ERC721.sol

因此,您應該執行以下操作:

  1. 將代幣從msg.senderERC721 合約轉移到呼叫者合約地址。
  2. 將代幣從合約地址轉移到msg.sender所有者檢查ERC721(address).ownerOf({contractAddress})

引用自:https://ethereum.stackexchange.com/questions/65585