Introduction
Blockchain technology has transformed various industries, and decentralized applications (dApps) have emerged as a powerful tool in leveraging its potential. In this comprehensive guide, we will explore the process of building a sophisticated dApp on the Celo blockchain using the Web3.js library. Web3.js provides a suite of JavaScript libraries that enable developers to interact with Celo and Ethereum-based blockchains, making it an ideal choice for dApp development.
Prerequisites
Before delving into the development of a Celo dApp with Web3.js, ensure that you have the following prerequisites in place:
- Fundamental knowledge of JavaScript and web development.
- Familiarity with Solidity, the programming language for writing smart contracts on Ethereum-based blockchains.
- Node.js installed on your machine for executing JavaScript code.
- Metamask browser extension for account management and connecting to the Celo network.
- Hardhat development environment for compiling, testing, and deploying smart contracts.
Setting Up the Development Environment
To begin, follow these steps to set up your development environment:
-
Install Node.js: Visit the official Node.js website (https://nodejs.org) and download the latest LTS version suitable for your operating system. Follow the installation instructions to complete the setup.
-
Install Metamask: Metamask is a browser extension that facilitates Ethereum account management and connectivity to the Celo network. Install Metamask in your preferred web browser and configure it to connect to the Celo network by referring to the Celo documentation.
-
Install Hardhat: Hardhat is a powerful development environment for Ethereum-based projects. Open your terminal or command prompt and run the following command to install Hardhat globally:
npm install --save-dev hardhat
This command installs Hardhat, making it accessible from any project.
-
Set up a new project: Create a new directory for your Celo dApp project and navigate to it using the terminal. Initialize a new npm project by running the following command:
npm init -y
This command generates a
package.json
file in your project directory. -
Install Web3.js: While still in your project directory, install the Web3.js library by executing the following command:
npm install web3
This command installs Web3.js as a dependency for your project.
Smart Contract Development
With the development environment set up, let’s proceed with creating a complex smart contract for our Celo dApp.
-
Create a new directory named
contracts
in your project directory. Inside thecontracts
directory, create a new file namedCrowdfunding.sol
. This file will contain the Solidity code for our smart contract. -
Open the
Crowdfunding.sol
file in your preferred code editor and define the smart contract. For example, let’s create a crowdfunding contract that allows users to contribute funds and receive rewards based on their contribution:// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract Crowdfunding { struct Project { address creator; string title; string description; uint256 goalAmount; uint256 currentAmount; uint256 deadline; mapping(address => uint256) contributions; mapping(address => bool) hasClaimedReward; } mapping(uint256 => Project) public projects; uint256 public numProjects; function createProject( string memory _title, string memory _description, uint256 _goalAmount, uint256 _deadline ) external { projects[numProjects] = Project( msg.sender, _title, _description, _goalAmount, 0, block.timestamp + _deadline, 0 ); numProjects++; } function contribute(uint256 _projectId) external payable { Project storage project = projects[_projectId]; require(block.timestamp < project.deadline, "Deadline exceeded"); require(msg.value > 0, "Contribution amount must be greater than 0"); project.contributions[msg.sender] += msg.value; project.currentAmount += msg.value; } function claimReward(uint256 _projectId) external { Project storage project = projects[_projectId]; require( block.timestamp > project.deadline, "Deadline has not been reached" ); require( project.contributions[msg.sender] > 0, "No contribution found" ); require( !project.hasClaimedReward[msg.sender], "Reward already claimed" ); uint256 rewardAmount = (project.contributions[msg.sender] * project.goalAmount) / project.currentAmount; payable(msg.sender).transfer(rewardAmount); project.hasClaimedReward[msg.sender] = true; } }
This contract defines a
Crowdfunding
contract that enables the creation of crowdfunding projects. Each project has various properties such as the creator’s address, title, description, goal amount, current amount, deadline, and mappings to track contributions and reward claims.The contract also includes functions to create a new project, contribute funds to a project, and claim rewards after the project deadline.
Compiling and Deploying Smart Contracts
Now that we have defined the smart contract, let’s compile and deploy it to the Celo network.
-
In your project directory, create a new directory named
scripts
. Inside thescripts
directory, create a new file nameddeploy.js
. This file will contain the deployment script for our smart contract. -
Open the
deploy.js
file in your code editor and add the following code:const { ethers } = require("hardhat"); async function main() { const Crowdfunding = await ethers.getContractFactory("Crowdfunding"); const crowdfunding = await Crowdfunding.deploy(); await crowdfunding.deployed(); console.log("Crowdfunding contract deployed to:", crowdfunding.address); } main() .then(() => process.exit(0)) .catch((error) => { console.error(error); process.exit(1); });
This script imports the required
ethers
package from Hardhat. Themain
function, defined as an asynchronous function, handles the deployment process. It retrieves the contract factory forCrowdfunding
usingethers.getContractFactory
and deploys it usingcrowdfunding.deploy()
. Theawait crowdfunding.deployed()
ensures that the deployment is completed successfully. Finally, the script logs the deployed contract address to the console. Error handling and process exit are also implemented. -
Save the changes to
deploy.js
. In your terminal or command prompt, execute the following command to compile and deploy the smart contract:npx hardhat run scripts/deploy.js --network <network-name>
Replace
<network-name>
with the name of the Celo network you configured in Metamask, such asceloalfajores
orcelobaklava
.Hardhat will compile the smart contract and deploy it to the specified Celo network. After a successful deployment, the contract address will be logged in the console.
Interacting with the Smart Contract Using Web3.js
Now that our smart contract is deployed,
let’s interact with it using Web3.js.
-
Create a new file named
app.js
in your project directory. This file will contain the JavaScript code for interacting with the smart contract. -
Open the
app.js
file in your code editor and add the following code:const Web3 = require("web3"); // Create a Web3 instance connected to the Celo network const web3 = new Web3("<Celo-RPC-URL>"); // Set the default account to use for transactions web3.eth.defaultAccount = "<your-account-address>"; // Load the contract ABI and address const contractABI = require("./artifacts/contracts/Crowdfunding.sol/Crowdfunding.json") .abi; const contractAddress = "<contract-address>"; // Create a contract instance const crowdfundingContract = new web3.eth.Contract( contractABI, contractAddress ); // Interact with the contract async function interactWithContract() { const projectCount = await crowdfundingContract.methods.numProjects().call(); console.log("Number of projects:", projectCount); const projectId = 0; // Assuming the first project const project = await crowdfundingContract.methods.projects(projectId).call(); console.log("Project details:", project); await crowdfundingContract.methods .contribute(projectId) .send({ from: web3.eth.defaultAccount, value: 1000000000000000000 }); console.log("Contribution successful"); await crowdfundingContract.methods.claimReward(projectId).send({ from: web3.eth.defaultAccount, }); console.log("Reward claimed"); } interactWithContract().catch(console.error);
This code block requires the
web3
package. It creates a Web3 instance connected to the Celo network using the specified<Celo-RPC-URL>
. The default account for transactions is set to<your-account-address>
. The contract ABI and address are loaded from the compiled artifacts of the smart contract. ThecrowdfundingContract
variable represents an instance of the smart contract created using the contract ABI and address.The
interactWithContract
function, defined as an asynchronous function, performs interactions with the contract. It first calls thenumProjects
method to retrieve the number of projects and logs it to the console. Then, assuming the first project, it retrieves the details of the project using theprojects
method and logs them to the console.Next, it calls the
contribute
method to contribute funds to the project, specifying the project ID and the value in wei. Thesend
method is used to send the transaction, and thefrom
field is set to the default account address. It logs a message indicating a successful contribution.Finally, it calls the
claimReward
method to claim the reward for the project, specifying the project ID. Again, thesend
method is used to send the transaction, and thefrom
field is set to the default account address. It logs a message indicating that the reward has been claimed. -
Save the changes to
app.js
. In your terminal or command prompt, execute the following command to run the script:node app.js
The script connects to the Celo network, interacts with the deployed smart contract, and logs the number of projects, project details, and the success of contributions and reward claims to the console.
Conclusion
This guide has provided comprehensive instructions for smart contract development, compilation, deployment, and interaction using Web3.js.
By understanding each block of code, you can effectively develop complex dApps on the Celo blockchain, contributing to the growth and adoption of blockchain technology.
Continue expanding your knowledge and exploring the extensive capabilities of Celo and Web3.js to create innovative and impactful decentralized applications.
About the Author
Aborode Prime Olusegun is a Growth Marketer and Data Analyst. He’s got a huge interest in Web3 and the decentralisation that it offers. Twitter