The Non-Fungible Token Standard (described in EIP-721) specifies, among other things, the signature of the transferFrom()
function: function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
Besides, it says that the function "throws if _from
is not the current owner" of _tokenId
.
Now, why is the _from
argument required, at all, if it is easily deducible from _tokenId
(by passing it to the ownerOf()
function)?
Passing _from
seems redundant, and the the internal comparison of the argument to the "actual" owner of _tokenId
– wasteful.
Why not just check whether the transferFrom()
caller has been approved by the ownerOf(_tokenId)
to transfer either the _tokenId
itself (via approve()
) – or all of the owner's NFTs from the collection (via setApprovalForAll()
)?
If the caller isn't approved to transfer the NFT, it doesn't matter whether msg.sender == _ownerOf(_tokenId)
. And if they are approved, then, what is the added value of forcing the caller to also pass the _from
argument (which can be obtained by simply calling ownerOf(_tokenId)
)?
Best Answer
Great observation on the
_from
parameter! I never noticed this before.Here are the two key reasons for its inclusion in the
transferFrom()
function in ERC-721:As you know, ERC-721 is strongly inspired by ERC-20,
_from
parameter is included in both standards for the following reasons:bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd
In summary, the
_from
parameter in ERC-721 maintains consistency with other token standards like ERC-20 and simplifies working with diverse tokens for developers.It was mentioned previously that including the
_from
parameter could save gas by avoiding usingownerOf(uint256 tokenId)
. However, this function is used anyway ontransferFrom
in OpenZeppelin implementation:Considering this, I don't see any benefits in terms of gas savings by including
_from
parameter intransferFrom()
.EDIT:
Here is an Answer from the lead author of ERC-721, which provides additional insight into the reasoning behind this design choice:
Here's a simplified summary of the additional information provided:
_from
parameter) is necessary for security reasons, particularly to prevent front-running attacks.By requiring the
_from
parameter, the function ensures no ambiguity between transferring an NFT you own and one you are authorized to transfer, making the process more secure.