@abcoathup I have a contract based on ERC721PresetMinterPauserAutoId.
I removed ERC721Burnable
from the import and contract definition.
Now for function _beforeTokenTransfer
I get the error message
Compiling 18 files with 0.6.6
contracts/DTOParticipationNFT.sol:125:95: TypeError: Invalid contract specified in override list: "ERC721".
function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override(ERC721, ERC721Pausable) {
^------------------------------^
@openzeppelin/contracts/token/ERC721/ERC721.sol:21:1: This contract:
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {
^ (Relevant source part starts here and spans across multiple lines).
1 Like
Hi @sven.meyer,
We can just do an override (no longer need to do this for multiple inheritance)
function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override {
super._beforeTokenTransfer(from, to, tokenId);
}
See: https://docs.openzeppelin.com/contracts/3.x/extending-contracts#rules_of_hooks
I find Remix quick to check something like this out.
MyNFT.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/access/AccessControl.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/GSN/Context.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/utils/Counters.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/token/ERC721/ERC721.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/token/ERC721/ERC721Pausable.sol";
contract MyNFT is Context, AccessControl, ERC721Pausable {
using Counters for Counters.Counter;
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
Counters.Counter private _tokenIdTracker;
/**
* @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the
* account that deploys the contract.
*/
constructor(string memory name, string memory symbol, string memory baseURI) public ERC721(name, symbol) {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
_setupRole(MINTER_ROLE, _msgSender());
_setupRole(PAUSER_ROLE, _msgSender());
_setBaseURI(baseURI);
}
function mint(address to) public virtual {
require(hasRole(MINTER_ROLE, _msgSender()), "MyNFT: must have minter role to mint");
// We cannot just use balanceOf to create the new tokenId because tokens
// can be burned (destroyed), so we need a separate counter.
_mint(to, _tokenIdTracker.current());
_tokenIdTracker.increment();
}
function pause() public virtual {
require(hasRole(PAUSER_ROLE, _msgSender()), "MyNFT: must have pauser role to pause");
_pause();
}
function unpause() public virtual {
require(hasRole(PAUSER_ROLE, _msgSender()), "MyNFT: must have pauser role to unpause");
_unpause();
}
function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override {
super._beforeTokenTransfer(from, to, tokenId);
}
}
@abcoathup Thanks a lot for the quick feedback, that really helped !!
Yes, I use Remix a lot, especially to try out new stuff, because it provides a nice UI to access all functions, so avoiding to develop an UI !
Remix is now fine with my code, just in VS Code, there is a remaining warning for the constructor
constructor(string memory name, string memory symbol, string memory baseURI) public ERC721(name, symbol) {
Visibility for constructor is ignored. If you want the contract to be non-deployable,
making it "abstract" is sufficient
Should I care ?
1 Like
Hi @sven.meyer ,
In Solidity 0.7
Visibility ( public
/ external
) is not needed for constructors anymore
_From: https://docs.soliditylang.org/en/v0.8.0/070-breaking-changes.html#functions-and-events_
If you are compiling with Solidity 0.7 you can remove public
.
@abcoathup , I think it’s because I am using solc 0.6.6 atm …
thanks for the reminder !
1 Like