TLDR:
Celo is an open-source blockchain ecosystem that makes decentralized financial (DeFi) tools and services accessible to anyone with a smartphone. It is designed to support financial inclusion and provide a platform for decentralized applications (DApps) with a particular emphasis on mobile usability.
Not for production (NFP) obviously. Feel free to take the source and modify to your needs.
We assume no responsibility for the code. Moreover, this is a very rough unaudited contract.
In this tutorial, we’ll build a simple voting DApp on the Celo blockchain. The project involves deploying a smart contract using Foundry and creating a simple user interface with Next.js and web3.js to interact with MetaMask.
Start for free and get your app to production levels immediately. No credit card required.
You can sign up with your GitHub, X, Google, or Microsoft account.
Use Foundry to develop, compile, and deploy a simple voting smart contract.
Install Foundry on your machine; you can follow the instructions in the Foundry book.
Once installed, create a new directory for your project and initialize a Foundry project.
This will create a Foundry project with the following layout:
In the src
directory, rename the sample smart contract to Voting.sol
and paste the following contract:
This Solidity smart contract is provided as an educational example and is not intended for production use. The code is simplified for clarity and lacks several critical features required for a secure and efficient production-grade application.
Follow the comments in the smart contract to understand the implementation; here is a quick breakdown.
This Solidity smart contract implements a simple voting system. Here’s a concise breakdown:
Contract Name: Voting
Key Components:
Candidate Struct: Represents a candidate with a name
and voteCount
.
Mappings:
candidates
: Maps a candidate ID to a Candidate
struct.voters
: Maps an address to a boolean indicating if the address has voted.State Variables:
candidatesCount
: Tracks the number of candidates.Events:
CandidateAdded
: Emitted when a new candidate is added.Voted
: Emitted when a vote is cast.Constructor:
Functions:
addCandidate
:
candidatesCount
and updates the candidates
mapping.CandidateAdded
event.vote
:
voters
mapping to mark the address as having voted.voteCount
.Voted
event.getCandidate
:
addCandidate
function, which is called in the constructor to add initial candidates.This smart contract is designed for a simple voting scenario where users vote for pre-defined candidates, and the results are publicly accessible.
Now that we have a contract let’s implement a simple test script within Foundry. In the test
directory, rename the current sample script to Voting.t.sol
and paste the following script:
This basic test script checks that an address cannot vote twice and that a user cannot vote for a candidate not on the list. Note how this contract lacks any real Sybil protection; this is an improvement you can add.
Move your terminal within the Foundry project and run the test command.
This will run the test script and you should see all the tests pass.
We have a tested smart contract; let’s deploy it on Celo using Foundry and your Chainstack node. If you haven’t yet, ensure you have some Celo tokens.
Let’s compile the smart contract:
Then, we can deploy the contract in one single command using forge create
:
Make sure to add your RPC url and your private key to the command editing YOUR_CELO_CHAINSTACK_RPC
and YOUR_PRIVATE_KEY
.
Also note that this is a quick way to deploy and test, but exposing endpoints and private keys in your terminal is not a good security practice; ensure the wallet is used for testing only.
This will deploy the smart contract on Celo.
The transaction can be seen on the Celo explorer; the link will show you an example of this contract deployment.
We’ll need the contract ABI and the address where it was deployed for the front end. You can find the ABI in the Foundry project inout/Voting.sol/Voting.json
. If you didn’t make any edits to the contract, you’ll find the proper ABI already implemented in the front-end code we’ll review in the next section.
Now that we have deployed the smart contract, we can create a simple front end so that users can interact with it and vote. Let’s initiate a Next.js project. You can do this in a different directory.
You can initialize the project with the following options
Then, move into that directory:
And install the web3.js package:
Then in the Next project, go in src/app/page.js
and paste the following:
Remember to add your node URL and smart contract address in:
Also note that exposing your endpoint in the front end like this is not good security practice, but it works for a prototype.
This React component implements a frontend interface for a simple voting application that interacts with a Celo blockchain smart contract. Here’s a concise breakdown:
Dependencies:
Web3
library for blockchain interaction.useEffect
, useState
) for managing state and side effects.Key Variables:
nodeUrl
: URL of the Celo blockchain node.chainId
: Chain ID for the Celo Mainnet.contractAddress
: Address of the deployed voting smart contract.contractAbi
: ABI (Application Binary Interface) of the smart contract.State Variables:
candidates
: Array to store candidate details.account
: Stores the user’s blockchain account address.isCorrectNetwork
: Boolean indicating if the user is connected to the correct blockchain network.loading
: Boolean indicating if candidate data is being loaded.error
: String for storing error messages.Lifecycle Hooks:
useEffect
: Loads the user’s account on the component mount and checks the network status. If the user is connected to the correct network, it loads candidates.Functions:
checkNetwork
: Checks if the user is connected to the correct blockchain network and switches networks if necessary.switchNetwork
: Switches the user’s MetaMask network to the Celo Mainnet.loadAccount
: Requests the user’s account address from MetaMask and checks the network status.disconnectAccount
: Resets the account and network status.loadCandidates
: Loads candidate details from the smart contract and updates the state.vote
: The user can vote for a candidate by using the smart contract.UI Elements:
This frontend code provides a user interface for interacting with the voting smart contract, enabling users to connect their MetaMask accounts, vote for candidates, and view current voting results.
All the pieces are together now. If you do not change the contract, the ABI in the front end will work. Otherwise, you’ll need to add the updated ABI. Run the project with:
Your front end will be available on http://localhost:3000
:
Click on the Login with MetaMask button to connect your wallet to the DApp. Then, you can vote for a candidate by signing a transaction.
Congratulations! You have successfully built a simple voting DApp on the Celo blockchain. Following this tutorial, you’ve learned how to develop, test, and deploy a smart contract using Foundry and create a frontend interface with Next.js and web3.js to interact with the contract. This project is a foundational example of getting you started with blockchain development on Celo. Remember to enhance and secure your DApp before deploying it to a production environment.
TLDR:
Celo is an open-source blockchain ecosystem that makes decentralized financial (DeFi) tools and services accessible to anyone with a smartphone. It is designed to support financial inclusion and provide a platform for decentralized applications (DApps) with a particular emphasis on mobile usability.
Not for production (NFP) obviously. Feel free to take the source and modify to your needs.
We assume no responsibility for the code. Moreover, this is a very rough unaudited contract.
In this tutorial, we’ll build a simple voting DApp on the Celo blockchain. The project involves deploying a smart contract using Foundry and creating a simple user interface with Next.js and web3.js to interact with MetaMask.
Start for free and get your app to production levels immediately. No credit card required.
You can sign up with your GitHub, X, Google, or Microsoft account.
Use Foundry to develop, compile, and deploy a simple voting smart contract.
Install Foundry on your machine; you can follow the instructions in the Foundry book.
Once installed, create a new directory for your project and initialize a Foundry project.
This will create a Foundry project with the following layout:
In the src
directory, rename the sample smart contract to Voting.sol
and paste the following contract:
This Solidity smart contract is provided as an educational example and is not intended for production use. The code is simplified for clarity and lacks several critical features required for a secure and efficient production-grade application.
Follow the comments in the smart contract to understand the implementation; here is a quick breakdown.
This Solidity smart contract implements a simple voting system. Here’s a concise breakdown:
Contract Name: Voting
Key Components:
Candidate Struct: Represents a candidate with a name
and voteCount
.
Mappings:
candidates
: Maps a candidate ID to a Candidate
struct.voters
: Maps an address to a boolean indicating if the address has voted.State Variables:
candidatesCount
: Tracks the number of candidates.Events:
CandidateAdded
: Emitted when a new candidate is added.Voted
: Emitted when a vote is cast.Constructor:
Functions:
addCandidate
:
candidatesCount
and updates the candidates
mapping.CandidateAdded
event.vote
:
voters
mapping to mark the address as having voted.voteCount
.Voted
event.getCandidate
:
addCandidate
function, which is called in the constructor to add initial candidates.This smart contract is designed for a simple voting scenario where users vote for pre-defined candidates, and the results are publicly accessible.
Now that we have a contract let’s implement a simple test script within Foundry. In the test
directory, rename the current sample script to Voting.t.sol
and paste the following script:
This basic test script checks that an address cannot vote twice and that a user cannot vote for a candidate not on the list. Note how this contract lacks any real Sybil protection; this is an improvement you can add.
Move your terminal within the Foundry project and run the test command.
This will run the test script and you should see all the tests pass.
We have a tested smart contract; let’s deploy it on Celo using Foundry and your Chainstack node. If you haven’t yet, ensure you have some Celo tokens.
Let’s compile the smart contract:
Then, we can deploy the contract in one single command using forge create
:
Make sure to add your RPC url and your private key to the command editing YOUR_CELO_CHAINSTACK_RPC
and YOUR_PRIVATE_KEY
.
Also note that this is a quick way to deploy and test, but exposing endpoints and private keys in your terminal is not a good security practice; ensure the wallet is used for testing only.
This will deploy the smart contract on Celo.
The transaction can be seen on the Celo explorer; the link will show you an example of this contract deployment.
We’ll need the contract ABI and the address where it was deployed for the front end. You can find the ABI in the Foundry project inout/Voting.sol/Voting.json
. If you didn’t make any edits to the contract, you’ll find the proper ABI already implemented in the front-end code we’ll review in the next section.
Now that we have deployed the smart contract, we can create a simple front end so that users can interact with it and vote. Let’s initiate a Next.js project. You can do this in a different directory.
You can initialize the project with the following options
Then, move into that directory:
And install the web3.js package:
Then in the Next project, go in src/app/page.js
and paste the following:
Remember to add your node URL and smart contract address in:
Also note that exposing your endpoint in the front end like this is not good security practice, but it works for a prototype.
This React component implements a frontend interface for a simple voting application that interacts with a Celo blockchain smart contract. Here’s a concise breakdown:
Dependencies:
Web3
library for blockchain interaction.useEffect
, useState
) for managing state and side effects.Key Variables:
nodeUrl
: URL of the Celo blockchain node.chainId
: Chain ID for the Celo Mainnet.contractAddress
: Address of the deployed voting smart contract.contractAbi
: ABI (Application Binary Interface) of the smart contract.State Variables:
candidates
: Array to store candidate details.account
: Stores the user’s blockchain account address.isCorrectNetwork
: Boolean indicating if the user is connected to the correct blockchain network.loading
: Boolean indicating if candidate data is being loaded.error
: String for storing error messages.Lifecycle Hooks:
useEffect
: Loads the user’s account on the component mount and checks the network status. If the user is connected to the correct network, it loads candidates.Functions:
checkNetwork
: Checks if the user is connected to the correct blockchain network and switches networks if necessary.switchNetwork
: Switches the user’s MetaMask network to the Celo Mainnet.loadAccount
: Requests the user’s account address from MetaMask and checks the network status.disconnectAccount
: Resets the account and network status.loadCandidates
: Loads candidate details from the smart contract and updates the state.vote
: The user can vote for a candidate by using the smart contract.UI Elements:
This frontend code provides a user interface for interacting with the voting smart contract, enabling users to connect their MetaMask accounts, vote for candidates, and view current voting results.
All the pieces are together now. If you do not change the contract, the ABI in the front end will work. Otherwise, you’ll need to add the updated ABI. Run the project with:
Your front end will be available on http://localhost:3000
:
Click on the Login with MetaMask button to connect your wallet to the DApp. Then, you can vote for a candidate by signing a transaction.
Congratulations! You have successfully built a simple voting DApp on the Celo blockchain. Following this tutorial, you’ve learned how to develop, test, and deploy a smart contract using Foundry and create a frontend interface with Next.js and web3.js to interact with the contract. This project is a foundational example of getting you started with blockchain development on Celo. Remember to enhance and secure your DApp before deploying it to a production environment.