solidity – How to Make a Payable transferFrom Function in an OpenZeppelin ERC721 Contract

ethereumjsolidity

I have just finished the crypto zombies tutorial https://cryptozombies.io/ and wanted to get it working locally but also using a solc 0.8.0. Compilation has thrown me lots of errors, many of which I just had to change external to public in my overrides and also add the override modifier. There is one issue, however, that I am unsure how to resolve. The contract inherits from the @openzeppelin/contracts version of ERC721. The two functions I am having issues with use the payable modifier.

  function transferFrom(address _from, address _to, uint256 _tokenId) public payable override {
    require (zombieToOwner[_tokenId] == msg.sender || zombieApprovals[_tokenId] == msg.sender);
    _transfer(_from, _to, _tokenId);
  }

  function approve(address _approved, uint256 _tokenId) public payable override onlyOwnerOf(_tokenId) {
    zombieApprovals[_tokenId] = _approved;
    emit Approval(msg.sender, _approved, _tokenId);
  }

I get an error during compilation..

TypeError: Overriding function changes state mutability from "nonpayable" to "payable".

So I find that in the ERC721 contract, neither of these functions is marked as payable.

So my question is do I remove the payable modifiers in my function overrides? I thought that this would mean the function/tx cannot carry an ether value. Or do I add the modifiers to the functions in the contracts I am inheriting from? Why do the functions lack these modifiers if (from what I have read) solidity expects them to be present in these two functions? Or am I missing something? I am unsure how to proceed so any help would be massively appreciated!

Best Answer

Only use payable when you're explicitly sending WETH. Sending tokens or NFTs does not inheritably cost WETH (only gas). If the transfer function calls another function it will inherit payable from the called function.