Here is the _safeMint from ERc721.sol the implementation of ERC-721
function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {
_mint(to, tokenId);
require(
_checkOnERC721Received(address(0), to, tokenId, _data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}
I understand it is calling the _mint and then checking the condition of onERC721Received. My question is why don't you check the condition first and then call the _mint()? Any reason for checking the condition after calling?
It don't really matter at the end of the day. Any failure will revert the whole transaction. And it makes logic sense that a token is minted to the recipient first and check second if the receiving end meets the requirement.
on this particular case, the call to _checkOnERC721Received needs to come after the mint/safeTransfer call (check the function code for reference) because it checks if the receiver is a contract and calls the function onERC721Received on that contract. Logically you can only 'tell' the contract it has received a token after it is minted/transfered