This project demonstrates a basic Governance DApp use case.
The purpose of the voting is to mint some tokens to the owner account.
The project has been implemented using HardHat framework and make use of the OpenZeppelin smart contracts:
The advantage to not implement custom Solidity smart contracts and to use the OpenZeppelin smart contracts library are several:
- The library minimize the risk of introducing bugs;
- The library is better tested;
- The library is supported by the community;
The HardHat framework make use of an API layer provided by Alchemy that interacts with the underlying blockchain network.
This project has been implemented and tested on linux machines. It may not works with other kind of OS. The following software needs to be installed on your machine:
- Node.js v20.9.0 or above;
- npm v10.1.0 or above;
After cloning the repository:
-
Install the dependencies by running
npm i
-
create a
.env
file in the root folder of the project and set the following variables:- GOERLI_URL
- PRIVATE_KEY
- ALCHEMY_API_KEY
Such variables are provided by Alchemy and you can find them in your Alchemy account.
-
use the
scripts/deploy.sh
script to deploy the 2 contracts in the Goerli test network by running:npx hardhat run scripts/deploy.js --network goerli
take note of the contracts addresses released given in output by the script.
If you want to know which are all the methods available for the contracts deployed, you can find them in the Goerli Etherscan DApp, searching by contract address.
Delegate the vote to yourself, by running the delegate script (this step can appear weird, but consider that not always who has the power of vote is the same that votes):
-
Paste your
MyToken
contract address inside thescripts/delegate.js
source file; -
run the following command:
npx hardhat run scripts/delegate.js --network goerli
Here we can make a new proposal on the governance system.
We could encode any kind of call data or value on this proposal, and we can even specify multiple targets.
In our case we're trying to mint an extra 25000 tokens to the owner.
-
Paste your
MyToken
contract address inside thescripts/proposing.js
source file; -
Paste your
MyGovernor
contract address inside thescripts/proposing.js
source file; -
Run the following command:
npx hardhat run scripts/proposing.js --network goerli
From the event
object given in output, take note of the proposalId
.
As the owner with 10000 tokens we have the executive power to push this proposal through. Let's go ahead and vote on this proposal so we can execute it.
-
Paste your
MyGovernor
contract address inside thescripts/vote.js
source file; -
Paste your
proposalId
inside thescripts/vote.js
source file; -
Run the following command:
npx hardhat run scripts/vote.js --network goerli
The transaction will cast a vote as the owner with a weight of 10000 tokens. This will be enough for the vote to be successful! Normally, the next step would be to queue this proposal in the Timelock to wait for some period before execution. In this case, we're not using a Timelock so we can go ahead and execute this proposal after the voting period has ended.
NOTE: by default the MyGovernor contract set a delay of 1 day to start voting after the proposal is deployed in the network. see OpenZeppelin MyGovernor contract wizard to change this parameter.
The execute
function looks up the proposal by hashed parameters, so we'll need to pass in our parameters here again for it to go look them up:
-
Paste your
MyToken
contract address inside thescripts/execute.js
source file; -
Paste your
MyGovernor
contract address inside thescripts/execute.js
source file; -
Run the following command:
npx hardhat run scripts/execute.js --network goerli
This will execute our proposal! If successful, the owner should now have 35000 tokens because the governance proposal will target the ERC20 token and pass in the calldata to mint 25000 tokens.