I was fiddling with OpenZeppelin ERC721 contract and created my own contract inheriting from the ERC721.sol. I tried to change the _safeMint
method, so I copied it from the parent contract and this require
line was raising an error:
function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {
// Some extra logic here while keeping the next line exactly as in the parent contract
require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}
Error:
contracts/nft.sol:98:17: DeclarationError: Undeclared identifier.
require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); ^--------------------^
I believe this was due the _checkOnERC721Received
was defined as private
in the parent contract, and this made it unavailable to the child contract. So I decide to copy the _checkOnERC721Received
method into my contract to solve the issue. However it raised another error:
contracts/nft.sol:114:5: TypeError: Overriding function is missing "override" specifier.
function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data) ^ (Relevant source part starts here and spans across multiple lines).
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.0/contracts/token/ERC721/ERC721.sol:435:5: Overridden function is here:
function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data) ^ (Relevant source part starts here and spans across multiple lines).
And if I add the override
param I now get:
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.0/contracts/token/ERC721/ERC721.sol:435:5: TypeError: Trying to override non-virtual function.
Did you forget to add "virtual"? function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data) ^ (Relevant source part starts here and spans across multiple lines).
contracts/nft.sol:114:5: Overriding function is here:
function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data) ^ (Relevant source part starts here and spans across multiple lines).
So it seems I can't override that method?
How could I change the _safeMint
logic in an child contract, while keeping this line https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.0/contracts/token/ERC721/ERC721.sol#L318 ?
Is the only way by creating the whole contract without inheritance?
The questions is for learning purposes, I'm not trying to do anything specific.