Interacting With your Smart Contract using Web3.js

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:

  1. Fundamental knowledge of JavaScript and web development.
  2. Familiarity with Solidity, the programming language for writing smart contracts on Ethereum-based blockchains.
  3. Node.js installed on your machine for executing JavaScript code.
  4. Metamask browser extension for account management and connecting to the Celo network.
  5. 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:

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  1. Create a new directory named contracts in your project directory. Inside the contracts directory, create a new file named Crowdfunding.sol. This file will contain the Solidity code for our smart contract.

  2. 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.

  1. In your project directory, create a new directory named scripts. Inside the scripts directory, create a new file named deploy.js. This file will contain the deployment script for our smart contract.

  2. 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. The main function, defined as an asynchronous function, handles the deployment process. It retrieves the contract factory for Crowdfunding using ethers.getContractFactory and deploys it using crowdfunding.deploy(). The await 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.

  3. 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 as celoalfajores or celobaklava.

    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.

  1. Create a new file named app.js in your project directory. This file will contain the JavaScript code for interacting with the smart contract.

  2. 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. The crowdfundingContract 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 the numProjects 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 the projects 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. The send method is used to send the transaction, and the from 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, the send method is used to send the transaction, and the from field is set to the default account address. It logs a message indicating that the reward has been claimed.

  3. 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

Source Code

6 Likes

Amazing idea of topic. Looking forward to how it turns out

3 Likes

Looking forward to this piece :innocent:

3 Likes

Though there has been some similar tutorials in this area. I believe you will do justice to the grey areas to make the coding journey of beginners much easier. I look forward to the outcome when it finally gets approved

4 Likes

Looking forward to this😎

3 Likes

Yeah. But this focuses on dApps and tries to explain it better and more straightforward. Hopefully I do justice to it

5 Likes

Thank you

3 Likes

Thank you my friend

4 Likes

Fantastic news! Your proposal has landed in this week’s top voted list. As you begin your project journey, remember to align with our community and technical guidelines, ensuring a high quality platform for our developers. Congratulations! :mortar_board: :seedling:

3 Likes

I’ll be reviewing this @olusegun

1 Like

Thank you jorshimayor

1 Like

Thank you Jorshimayor

1 Like