I am trying to build an dApp that allows users to transfer their ERC721 token to my smart contract, and then at a later time, send to another user. Here is my contract code:

contract HoldNFT is ERC721, IERC721Receiver, ERC721Holder, Ownable{
    using Counters for Counters.Counter;
    Counters.Counter public _tokenIDs;
    constructor() ERC721("HoldNFT", "HOLDNFT") {
    function send(IERC721 tokenAddress, uint256 tokenId) public {
        uint256 current = _tokenIDs.current();
        tokenAddress.safeTransferFrom(msg.sender, address(this), tokenId); 
        _safeMint(recipient, current);

When I call on this function, I get the errow message "Revert ERC721: transfer caller is not owner or approved". My understanding is that this occurs because I am calling the safeTransferFrom function from a smart contract, so the msg.sender in the IERC721 contract (tokenAddress argument) is my smart contract instead of the user, who actually owns the token. I want to know if there is a way around this. I know that you can call the safeTransferFrom function or approve function from JavaScript so the msg.sender is the user. However, I don't think this will work in my particular case because the tokenAddress is arbitary (decided by the user) so I do not have access to the ABI in development. What should I do?

P.S. The template I used for this project was from a dApp called nftysanta (0x1f4E4eF54dB90934DE8fB2d68438C68660099Ad4). It seems to use the same implementation as far as I can see? And I assumed that it works because it's a verified contract on mainnet.

1 Answer 1


Call approve(yourContractAddress, tokenId) function first with your user, then your contract will be able to transfer the token himself.

  • I cannot call this function from JavaScript because I do not have the ABI. (There might be a way to manually write part of the ABI since ERC721 all have the same safetransferfrom function as far as I know?). Or do you mean to call it from the contract? Because I think that faces the same issue?
    – Xing Li
    Commented Sep 19, 2022 at 2:17
  • Yes, you should be able to make the abi since the contract must have implemented ERC721 interface, as far as I remember, you can pass some part of the abi rather than a complete one. You can't call from your contract on behalf of your user account though. Commented Sep 19, 2022 at 2:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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