-
Notifications
You must be signed in to change notification settings - Fork 0
Description
As a developer i would like to be able to start the mint at a predetermined time so that all buyers have a fair shot at minting the tokens.
There are a variety of ways to implement this user story and many different approaches have been tried. Sometimes folks will deploy a contract that tries to target a specific time based on the ethereum block height (the only reliable way to measure time on-chain). Sometimes it is also desirable to use state variables or a boolean flag to turn minting on or off. To keep things simple we will use another feature from open zeppelin called pauseable.
Pauseable is usually used to turn all features on or off, but for our use case it is helpful because it introduces us to three new solidity features that have not been addressed yet, multiple inheritance and function modifiers.
Solidity supports Multiple Inheritance
Function Modifiers in solidity
Solidity supports events
At this point you might have some strong opinion about multiple inheritance, but it is unavoidable in this world. The key reason is that Solidity uses a well-known function signature scheme to determine what function to call and it is therefore possible for two completely separate contracts in the dependency graph to implement two completely different functions that hash to the same 4-byte value. That forces the developers to handle multiple inheritance issues.
Following along with the OZ documentation we add the pausable dependency to the declarations at the top of the solidity file and ensure our contract inherits Pauseable. The whenNotPaused function modifier then becomes available and we can tack it on to our mint function. BOOM! we now have a way to toggle access to the function.
Check out the source code of the Pauseable contract on Github. A few things should jump out at you. First, the contract just uses a boolean state variable _paused and checks its state in the whenNotPaused modifier. Thew contract also includes internal functions to _pause and _unpause that both emit solidity events when executed.
Since they are internal functions we cannot call them publicly so we have to expose public accessors for them. Further, since the internals of Pauseable emits events, any users interested in the mint function (including your website's front-end) can listen for the events to be emitted by the contract and can react accordingly.
So now we have access control on our mint function and a way to change it, but we don't want just anyone to be able to change it. It is time to introduce access control to the entire contract by using the Ownable.sol contract.
Similar to the Pauseable.sol contract, the Ownable.sol contract is implemented as an abstract contract with events, modifiers, and state variables, etc. We can follow the same pattern here to inherit the Ownable contract, and use its members in our own contract. Now, functions marked onlyOwner will only be callable by the owner of the contract. The owner is automatically set to the contract deployer when the contract is deployed.
As always we need some tests to complete our quest!
What happens if a non-owner tries to call an owner function?
What happens when a user tries to mint when the contract is paused?
What happens if the owner tries to call the mint function while it is paused?