How does one configure the ‘Constructor’ when calling from multiple OpenZepplin contracts, for example, ‘ERC20Capped’ and ‘ERC20Detailed’
Can you please list an example, complete noob here, but trying
Great product and forum BTW
Many thanks, Josh
How does one configure the ‘Constructor’ when calling from multiple OpenZepplin contracts, for example, ‘ERC20Capped’ and ‘ERC20Detailed’
Can you please list an example, complete noob here, but trying
Great product and forum BTW
Many thanks, Josh
Hi @Josh_Read,
Welcome to smart contract development. Everyone was new once. (What are your top three recommendations for a new developer in the space?)
Using the ERC20 Preset as a guide, ERC20PresetMinterPauser.sol, the following token can be minted, paused, burnt and has a cap on minting.
The constructor should call constructors of the base contracts (if they take parameters). See the Solidity documentation for more details: https://docs.soliditylang.org/en/v0.7.4/contracts.html#arguments-for-base-constructors
Please note, ERC20Capped
also overrides _beforeTokenTransfer
.
To learn more about hooks, head to Using Hooks.
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/GSN/Context.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20Capped.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20Burnable.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20Pausable.sol";
/**
* @dev {ERC20} token, including:
*
* - ability for holders to burn (destroy) their tokens
* - a minter role that allows for token minting (creation)
* - a pauser role that allows to stop all token transfers
*
* This contract uses {AccessControl} to lock permissioned functions using the
* different roles - head to its documentation for details.
*
* The account that deploys the contract will be granted the minter and pauser
* roles, as well as the default admin role, which will let it grant both minter
* and pauser roles to other accounts.
*/
contract MyToken is Context, AccessControl, ERC20Capped, ERC20Burnable, ERC20Pausable {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
/**
* @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the
* account that deploys the contract.
*
* See {ERC20-constructor}.
*/
constructor(string memory name, string memory symbol, uint256 cap) public ERC20(name, symbol) ERC20Capped(cap) {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
_setupRole(MINTER_ROLE, _msgSender());
_setupRole(PAUSER_ROLE, _msgSender());
}
/**
* @dev Creates `amount` new tokens for `to`.
*
* See {ERC20-_mint}.
*
* Requirements:
*
* - the caller must have the `MINTER_ROLE`.
*/
function mint(address to, uint256 amount) public virtual {
require(hasRole(MINTER_ROLE, _msgSender()), "MyToken: must have minter role to mint");
_mint(to, amount);
}
/**
* @dev Pauses all token transfers.
*
* See {ERC20Pausable} and {Pausable-_pause}.
*
* Requirements:
*
* - the caller must have the `PAUSER_ROLE`.
*/
function pause() public virtual {
require(hasRole(PAUSER_ROLE, _msgSender()), "MyToken: must have pauser role to pause");
_pause();
}
/**
* @dev Unpauses all token transfers.
*
* See {ERC20Pausable} and {Pausable-_unpause}.
*
* Requirements:
*
* - the caller must have the `PAUSER_ROLE`.
*/
function unpause() public virtual {
require(hasRole(PAUSER_ROLE, _msgSender()), "MyToken: must have pauser role to unpause");
_unpause();
}
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override(ERC20, ERC20Capped, ERC20Pausable) {
super._beforeTokenTransfer(from, to, amount);
}
}
Please note: ERC20Detailed
is from OpenZeppelin Contracts 2.x and this was included in ERC20
in OpenZeppelin Contracts 3.x.
Hi @Josh_Read,
I wanted to check if you needed more information?