3

I am using ERC721 implementation for NFT tokens.

I am testing the transfer functionalities in ERC721.

 `transferFrom(address _from, address _to, uint256 _tokenId)`    
 `safeTransferFrom(address _from, address _to, uint256 _tokenId)`
 `safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data)`

I have tried the token transfer scenario with _to address as account address.

I am trying to do the token transfer scenarios with _to address as contract address.

I have written a receiver contract for testing the functionality.

  pragma solidity ^0.4.22;

  import "./standard/ERC721TokenReceiver.sol";

  contract ValidReceiver is ERC721TokenReceiver {

      event  LOGTokenFallBack(address from,bytes4 value);

      function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes _data) external returns(bytes4 value) {
            emit LOGTokenFallBack(_from, bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")));
            return 0x150b7a02;

     } 
} 

Updated the safeTranferFrom functionality also as follows:-

   function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) public  {
    transferFrom(_from, _to, _tokenId);

    //Get size of "_to" address, if 0 it's a wallet
    uint32 size;
    assembly {
        size := extcodesize(_to)
    }
    if(size > 0){
       ERC721TokenReceiver receiver = ERC721TokenReceiver(_to);
       require(receiver.onERC721Received(msg.sender,_from,_tokenId,data) == bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")));

    }

It seems to be that the transfer gets reverted.

I have updated the ERC721TokenReceiver by removing the return type as follows.

   function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes _data) external ;

And updated ValidReceiver as follows.

contract ValidReceiver is ERC721TokenReceiver {

      event  LOGTokenFallBack(address from,bytes4 value);

      function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes _data) external  {
            emit LOGTokenFallBack(_from, bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")));


     } 
} 

And it seems to be a successful transfer by emitting the LOGTokenFallBack event.

I have tried various ways to do the transfer by return type in receiver contract.

Did anyone face the issue similar to the one mentioned?

Any help is appreciated.

  • There seems no issue with the contract or the implementation. Maybe the transfer fn at transferFrom(_from, _to, _tokenId); reverts. I have tested the same contracts and it worked perfect, emitted events. – Prashant Prabhakar Singh Aug 2 at 11:48
  • @PrashantPrabhakarSingh I have tried the same using mocha test scripts as well as using the truffle console. I am still facing the issue while calling the receiver contract function having return type. receiver.onERC721Received(msg.sender,_from,_tokenId,data). This call gets reverted, and I didn't get the bytes value as response. – Crissi Mariam Robert Aug 5 at 4:55
  • @PrashantPrabhakarSingh I have changed the return type to bool instead of bytes. And it has the same issue.It seems to be working,if I remove the return type from both my receiver interface and contract. – Crissi Mariam Robert Aug 5 at 5:48
1

Try our official ERC721 implementation. Here is also a working example described in our test case. See also a link to the ERC721 receiver mock and a direct link to the safeTransferFrom implementation.

Btw, things can become much simpler with the 0xcert Framework. It hides the complexity, you don't have to write Solidity at all, you just use Javascript methods.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.