Solidity
如何在 ER721 的子合約中更改 _safeMint 方法的邏輯?
我正在擺弄 OpenZeppelin ERC721 合約,並創建了我自己的繼承自ERC721.sol的合約。我試圖改變
_safeMint
方法,所以我從父契約中複製了它,這一require
行引發了一個錯誤: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"); }
錯誤:
contracts/nft.sol:98:17: DeclarationError: Undeclared identifier. require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); ^--------------------^
我相信這是由於在父契約
_checkOnERC721Received
中定義private
的,這使得子契約無法使用。所以我決定把這個_checkOnERC721Received
方法複製到我的契約中來解決這個問題。但是它引發了另一個錯誤: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).
如果我添加
override
參數,我現在得到: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).
所以看來我不能覆蓋那個方法?我如何更改
_safeMint
子契約中的邏輯,同時保留此行https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.0/contracts/token/ERC721/ERC721.sol#L318?是通過創建整個契約而不繼承的唯一方法嗎?這些問題是出於學習目的,我不想做任何具體的事情。
你可以做兩件事改變
_safeMint
行為
- 覆蓋
_safeMint
並呼叫其父級contract MyToken is ERC721 { function _safeMint(address to, uint256 tokenId, bytes memory _data) internal override { /* Can do something here and modify input parameters */ super._safeMint(to, tokenId, _data); /* Can do something else here */ } }
- 覆蓋
_mint
,在目前實現中_safeMint
只呼叫_mint
contract MyToken is ERC721 { function _mint(address to, uint256 tokenId) internal override { /* Can do something here and modify input parameters */ super.mint(to, tokenId); /* Can do something else here */ } }