Aurora: Simple on-chain governance contract with Remix and OpenZeppelin Wizard
The battle-tested set of OpenZeppelin contracts and the user-friendly contract wizard make it very easy to run through a simple on-chain governance example.
In this tutorial, you will:
- Create an ERC-20 governance token contract that you will use to cast votes on the governance proposals.
- Create a standard governor contract for your on-chain governance.
- Create a mintable ERC-20 contract that will mint new tokens on your successfully passed on-chain governance proposals.
- Run a full on-chain governance cycle.
Prerequisites
- Chainstack account to deploy an Aurora node.
- Remix IDE to compile the contracts and deploy through MetaMask.
- MetaMask to deploy the contracts through your Chainstack node and interact with the contracts.
Overview
To get from zero to the deployed contracts on the Aurora testnet, do the following:
- With Chainstack, create a public chain project.
- With Chainstack, join the Aurora testnet.
- With Chainstack, access your Aurora node credentials.
- Set up your MetaMask to work through a Chainstack node.
- Fund your account with Aurora ETH on the Aurora testnet.
- With OpenZeppelin Wizard, create your contracts.
- With Remix IDE, deploy the contracts on the Aurora testnet.
- With MetaMask, run your on-chain governance process.
Step-by-step
Create a public chain project
See Create a project.
Join the Aurora testnet
Get your Aurora node access and credentials
See View node access and credentials.
Set up MetaMask
Fund your account
You can use the Aurora faucet to fund your account, although the amount of Aurora ether dispensed will not be enough to cover the costs of this tutorial.
If you have some Goerli ether, you may bridge it from the Ethereum Goerli testnet to the Aurora testnet using the Rainbow bridge. The transfer may take up to 20 mins.
Create and deploy your ERC-20 governance token
This will be your governance token—the token that you will use to vote on proposals in the governance contract.
OpenZeppelin Wizard
- Open OpenZeppelin Wizard.
- Select ERC20.
- Provide a name and a symbol for the token. For example: GovernanceToken, GTK.
- In Premint, provide the number of tokens to issue to your account. For example: 100.
- In Feature, select Votes.
- Click Open in Remix.
Remix
- In Remix, click Compile contract.
- Click the deployment tab on your left.
- Select Environment > Injected Provider - MetaMask.
- In Contract, select your contract. For example, GovernanceToken.
- Click Deploy.
This will engage your MetaMask to deploy the contract to the Aurora testnet through your currently selected MetaMask account. Click Confirm in the MetaMask modal.
Verify the contract
To use the Aurora explorer as a web app to interact with your contracts, verify them in the explorer.
- In Remix, click Plugins > Flattener > Activate.
- Select the activated flattener plugin in your left pane and click Flatten contract.
- In the Aurora explorer, navigate to the contract that you deployed.
- Click Verify and Publish.
- In Compiler Type, select Solidity (Single file).
- In Complier version, select the compiler that you used in Remix.
- In Open Source License Type, select MIT License (MIT).
- Click Continue.
- In Optimization, select No.
- In Solidity Contract Code, provide the flattened code of your contract from Remix.
- Click Verify and Publish.
You now have the ERC-20 contract verified and your governance tokens in your account—the account that you used to deploy the contract.
Create and deploy your ERC-20 mintable token contract
This will be the contract that will be used by the governance contract to mint tokens on passing the on-chain proposal.
OpenZeppelin Wizard
- Open OpenZeppelin Wizard.
- Select ERC20.
- Provide a name and a symbol for the token. For example: MintableToken, MTK.
- In Premint, keep
0
. - In Features, select Mintable. Note that this will automatically make the contract Ownable.
- Click Open in Remix.
Remix
- In Remix, click Compile contract.
- Click the deployment tab on your left.
- Select Environment > Injected Provider - MetaMask.
- In Contract, select your contract. For example, MintableToken.
- Click Deploy.
This will engage your MetaMask to deploy the contract to the Aurora testnet through your currently selected MetaMask account. Click Confirm in the MetaMask modal.
Verify the contract similarly to the previous one.
Create and deploy your governance contract
This will be your on-chain governance contract.
OpenZeppelin Wizard
- Open OpenZeppelin Wizard.
- Select Governor.
- Provide a name and a symbol for the token. For example: MyGovernor.
- In Voting Delay, keep
1 block
. In Voting Period, put600 blocks
. In 1 block=, put1 second
. This will be about 10 minutes for a voting period. - In Quorum, switch to # and put
1
to make the quorum of 1 participating account pass the proposals. - Remove the Updatable Settings check mark.
- In Votes, select ERC20Votes.
- Remove the Timelock check mark.
- Click Open in Remix.
Remix
- In Remix, click Compile contract.
- Click the deployment tab on your left.
- Select Environment > Injected Provider - MetaMask.
- In Contract, select your contract. For example, MintableToken.
- In Deploy, provide the address of the ERC-20 governance token that you deployed as the first contract of this tutorial. This will make the deployed contract recognize the ERC-20 token as the contract's voting token.
- Click Deploy.
This will engage your MetaMask to deploy the contract to the Aurora testnet through your currently selected MetaMask account. Click Confirm in the MetaMask modal.
Verify the contract similarly to the previous one.
Delegate the votes
You have preminted the ERC-20 governance token to the account you deployed the contract with. As the governance token owner, you now need to delegate the voting power to an account.
For simplicity, you can delegate it to your account:
- In the Aurora explorer, open your verified ERC-20 governance contract.
- Click Contract > Write Contract.
- Click Connect to Web3 > MetaMask. Make sure you connect with the same account that you used to deploy the contract as this is the account that holds the preminted tokens.
- In
delegatee
, provide your account address and click Write.
This will make the provided account be able to cast votes in the governance contract.
Transfer the ERC-20 mintable contract ownership to the governance contract
The ERC-20 mintable contract is ownable. To be able to mint the tokens through the governance contract, you need to transfer the ownership of the ERC-20 contract to the governance contract.
- In the Aurora explorer, open your verified ERC-20 mintable contract.
- Click Contract > Write Contract.
- Click Connect to Web3 > MetaMask. Make sure you connect with the same account that you used to deploy the contract.
- In
transferOwnership
>newOwner
, provide the address of your governance contract. - Click Write.
This will transfer the contract ownership. Your governance contract can now mint the ERC-20 tokens.
Create a proposal
At this point, you have three contracts deployed:
- An ERC-20 governance token contract with preminted tokens assigned to your account
- An ERC-20 mintable token contract owned by the governance contract
- The governance contract to run proposals
It is now time to create your proposal.
First, get the call data that the governance contract takes as a proposal to execute. For this tutorial, the call data is minting the ERC-20 tokens to an address and an amount to mint: mint(address to, uint256 amount)
.
To get the call data:
-
Go to the online ABI encoding service.
-
In Enter your parameters manually, select:
- Function > your function >
mint
. - Argument > Address > the address to mint the tokens to.
- Argument > Uint256 > the amount of tokens to mint in 18 decimal unit. See Ethereum unit converter.
- Function > your function >
-
Copy the resulting data and precede it with
0x
. This is your call data to mint the tokens.
Now create the actual proposal.
- In the Aurora explorer, open your verified governance contract.
- Click Contract > Write Contract.
- Click Connect to Web3 > MetaMask.
- In
propose
, provide your proposal details:- In
targets
, provide the address of your ERC-20 mintable token. - In
values
, provide the amount of Aurora ether that should be deposited with the proposal. Typically, it is0
. - In
calldatas
, provide the call data that you acquired with MetaMask. - In
description
, provide any description.
- In
Once the proposal transaction is confirmed, the contract will emit an event that contains the proposal ID. You will need the proposal ID to vote for the proposal and to execute the proposal.
To get the proposal ID:
- In the Aurora explorer, open your transaction that created the proposal.
- Switch to Logs.
- In Data, copy the
proposalId
value.
Cast your vote
At this point, you have:
- A running proposal
- The proposal ID
- The voting power delegated to your account
To cast your vote:
- In the Aurora explorer, open your verified governance contract.
- Click Contract > Write Contract.
- Click Connect to Web3 > MetaMask.
- In
castVote
, provide your vote:- In
proposalId
, paste the proposal ID. - In
support
, provide your voting decision:0
is against,1
is for,2
is abstain. For the proposal to pass, vote1
.
- In
- Click Write.
This will create a transaction that casts your vote.
Execute the passed proposal
Once the proposal is voted on and the voting period reaches the deadline, the proposal is passed. You can now execute the passed proposal.
To execute:
- In the Aurora explorer, open your verified governance contract.
- Click Contract > Write Contract.
- Click Connect to Web3 > MetaMask.
- In
execute
, provide details:- In
execute
, provide0
as payable amount as you are minting ERC-20 tokens and not depositing Aurora ether. - In
targets
, provide the address of your ERC-20 mintable token. - In
values
, provide0
for the amount of Aurora ether. - In
calldatas
, provide the same call data that you generated earlier for the functionmint(address to, uint256 amount)
. - In
descriptionHash
, provide the hash of the description that you used to generate the proposal. To do this the easy way, go to an online Keccak-256 generator and paste your description text, copy the result and precede it with0x
.
- In
- Click Write.
This will execute the passed proposal and the governance contract will mint the ERC-20 mintable tokens to the account that you provided in the call data when creating the proposal.
Conclusion
This tutorial guided you through the basics of creating and deploying a set of DAO contracts to mint ERC-20 tokens through on-chain governance on the Aurora testnet through your Chainstack-deployed node.
You have also interacted with the contracts to run the full cycle governance process using the Aurora explorer as a web app and MetaMask as your interaction tool that works through your Chainstack-deployed Aurora node.
About the author
Updated 9 months ago