Deploying smart contract for scholarship funding on Celo

Introduction

In today’s interconnected world, education plays a pivotal role in shaping individuals and societies. However, accessing quality education remains a challenge for many individuals, especially in developing countries. Scholarships have long been recognized as a powerful tool for bridging this gap, however the issue of ensuring that scholarship funds are utilized solely for academic purposes continues to persist, causing concerns for sponsors and hindering the growth and impact of scholarship programs. With the advent of blockchain technology, a new era of transparency, accountability, and efficiency has emerged. By leveraging the Celo blockchain’s unique features, we can establish a trustless and auditable system that ensures scholarship funds are utilized solely for academic purposes.

Prerequisites

These tutorials assume that you have some basic knowledge of solidity

Requirements

This is a list of what we’ll cover :spiral_notepad:

  • :white_check_mark: Step 1: Creating a new project
  • :white_check_mark: Step 2: Writing the smart contract
  • :white_check_mark: Step 3: Compiling and deploying the smart contract

Overview of the Challenges in Scholarship Fund Management.

Academic scholarship fund management faces several challenges, including fraud, mismanagement, and lack of transparency. These challenges can significantly impact the effectiveness and fairness of the scholarship allocation process.

  • Fraud is a significant concern in scholarship fund management, with individuals attempting to exploit the system through fraudulent applications or misrepresenting their eligibility. A decentralized and transparent solution, such as a smart contract on the Celo blockchain, can help mitigate fraud by introducing immutable records and automated verification processes. Smart contracts can enforce eligibility criteria, authenticate applicants’ identities, and ensure that funds are disbursed only to deserving recipients.

  • Mismanagement of scholarship funds can occur due to inadequate governance structures, inefficient processes, or lack of oversight. A decentralized and transparent solution can address these issues by introducing clear rules and predefined processes within the smart contract. The smart contract can automate the allocation and disbursement of funds based on predefined criteria, reducing the chances of mismanagement. Additionally, the transparency provided by the blockchain allows all stakeholders to monitor the utilization of funds in real-time, ensuring accountability and reducing the risk of mismanagement.

  • The lack of transparency in traditional scholarship fund management systems makes it difficult to track the allocation and utilization of funds. This lack of transparency can create suspicion and skepticism among applicants and stakeholders. By implementing a decentralized and transparent solution, such as a smart contract on the Celo blockchain, the entire scholarship fund management process becomes transparent and auditable. All transactions and decisions are recorded on the blockchain, allowing stakeholders to verify the fairness of the allocation process and track the utilization of funds.

Step 1: Creating a new project

  1. Open the Remix IDE

  2. Click on the File Explorer icon on the left side of the screen, then click on the burger menu and select Create New File.

  1. Chose a template for your project. For this tutorial, we will use the Basic template and name our project Scholarship Celo, then click on Ok

You will see a structur project like this.

  1. Now, we will create a new file named ScholarshipCelo.sol by right-clicking on the contracts folder and selecting New File

Step 2: Writing the smart contract

Open the ScholarshipCelo.sol file and write the following code:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";


contract Scholarship is Ownable{
    // Code goes here...
}

First, we import the Ownable contract from the OpenZeppelin library. This contract provides basic authorization control functions, which we will use to restrict access to certain functions. We also import the IERC20 interface, which we will use to interact with token contracts for the scholarship fund.

uint public scholarshipAmount;
uint public applicationDeadline;
mapping(address => bool) public applicants;
mapping(address => bool) public recipients;
IERC20 public CUSDToken;

Next, we define the state variables for our smart contract. We define the scholarshipAmount variable to store the total amount of scholarship funds available. We also define the applicationDeadline variable to store the deadline for submitting scholarship applications. We define the applicants and recipients mappings to store the addresses of applicants and recipients, respectively. Finally, we define the CUSDToken variable to store the address of the CUSD token contract.

event ApplicationSubmitted(address indexed applicant);
event ScholarshipAwarded(address indexed recipient, uint amount);

Next, we define the events for our smart contract. We define the ApplicationSubmitted event to emit when an applicant submits a scholarship application. We also define the ScholarshipAwarded event to emit when a scholarship is awarded to a recipient.

constructor(
    uint256 _scholarshipAmount,
    uint256 _applicationDeadline,
    address _CUSDTokenAddress
) {
    scholarshipAmount = _scholarshipAmount;
    applicationDeadline = _applicationDeadline;
    CUSDToken = IERC20(_CUSDTokenAddress);
}

We define the constructor for our smart contract. The constructor takes three parameters: the scholarship amount, the application deadline, and the address of the CUSD token contract. The constructor initializes the state variables with the values passed as parameters.

function applyForScholarship() public {
    require(!applicants[msg.sender], "You have already applied");
    require(
        block.timestamp <= applicationDeadline,
        "Application deadline has passed"
    );

    applicants[msg.sender] = true;
    emit ApplicationSubmitted(msg.sender);
}

Next, we define the applyForScholarship function. This function allows applicants to submit scholarship applications. The function first checks if the applicant has already applied for the scholarship. If the applicant has already applied, the function reverts with an error message. The function then checks if the application deadline has passed. If the application deadline has passed, the function reverts with an error message. If the applicant has not already applied and the application deadline has not passed, the function adds the applicant’s address to the applicants mapping and emits the ApplicationSubmitted event.

function awardScholarship(address recipient) public onlyOwner {
    require(applicants[recipient], "The recipient has not applied");
    require(
        !recipients[recipient],
        "The recipient has already been awarded the scholarship"
    );

    recipients[recipient] = true;
    require(
        CUSDToken.balanceOf(address(this)) >= scholarshipAmount,
        "Insufficient contract balance"
    );
    CUSDToken.transfer(recipient, scholarshipAmount);
    emit ScholarshipAwarded(recipient, scholarshipAmount);
}

We define the awardScholarship function. This function allows the scholarship fund manager to award scholarships to recipients. The function first checks if the recipient has applied for the scholarship. If the recipient has not applied, the function reverts with an error message. The function then checks if the recipient has already been awarded the scholarship. If the recipient has already been awarded the scholarship, the function reverts with an error message. If the recipient has applied and has not already been awarded the scholarship, the function adds the recipient’s address to the recipients mapping and emits the ScholarshipAwarded event. The function then checks if the scholarship fund has sufficient funds to award the scholarship. If the scholarship fund does not have sufficient funds, the function reverts with an error message. If the scholarship fund has sufficient funds, the function transfers the scholarship amount to the recipient and emits the ScholarshipAwarded event.

function depositTokens(uint256 amount) public onlyOwner {
    require(amount > 0, "Deposit amount must be greater than zero");
    require(
        CUSDToken.transferFrom(msg.sender, address(this), amount),
        "Token transfer failed"
    );
}

Lastly, we define the depositTokens function. This function allows the scholarship fund manager to deposit tokens into the scholarship fund. The function first checks if the deposit amount is greater than zero. If the deposit amount is not greater than zero, the function reverts with an error message. The function then transfers the deposit amount from the scholarship fund manager’s address to the scholarship fund contract.

Full code of the ScholarshipCelo.sol file:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract Scholarship is Ownable {
    uint256 public scholarshipAmount;
    uint256 public applicationDeadline;
    mapping(address => bool) public applicants;
    mapping(address => bool) public recipients;
    IERC20 public CUSDToken;

    event ApplicationSubmitted(address indexed applicant);
    event ScholarshipAwarded(address indexed recipient, uint256 amount);

    constructor(
        uint256 _scholarshipAmount,
        uint256 _applicationDeadline,
        address _CUSDTokenAddress
    ) {
        scholarshipAmount = _scholarshipAmount;
        applicationDeadline = _applicationDeadline;
        CUSDToken = IERC20(_CUSDTokenAddress);
    }

    function applyForScholarship() public {
        require(!applicants[msg.sender], "You have already applied");
        require(
            block.timestamp <= applicationDeadline,
            "Application deadline has passed"
        );

        applicants[msg.sender] = true;
        emit ApplicationSubmitted(msg.sender);
    }

    function awardScholarship(address recipient) public onlyOwner {
        require(applicants[recipient], "The recipient has not applied");
        require(
            !recipients[recipient],
            "The recipient has already been awarded the scholarship"
        );

        recipients[recipient] = true;
        require(
            CUSDToken.balanceOf(address(this)) >= scholarshipAmount,
            "Insufficient contract balance"
        );
        CUSDToken.transfer(recipient, scholarshipAmount);
        emit ScholarshipAwarded(recipient, scholarshipAmount);
    }

    function depositTokens(uint256 amount) public onlyOwner {
        require(amount > 0, "Deposit amount must be greater than zero");
        require(
            CUSDToken.transferFrom(msg.sender, address(this), amount),
            "Token transfer failed"
        );
    }
}

Step 3: Compiling and deploying the smart contract

Now, we will compile the smart contract. Open ScholarshipCelo.sol file, and look compiler icon in left side of the editor.

Choose the compiler version 0.8.15 and in the contract dropdown, choose ScholarshipCelo.sol. Then click on the compile button.

To deploy the smart contract, click on the Ethereum icon in the left sidebar of the editor.

In the environment dropdown, select Injected Web3. Then, in the contract dropdown, select ScholarshipCelo.sol, and input the constructor parameters. Then click on the Transact button.

You should see contract deployed in the Deployed Contracts section.

Now, we can interact with the smart contract using the Remix IDE UI.

Conclusion

Implementing a smart contract for scholarship funding on the Celo blockchain presents a powerful solution to address the challenges faced in scholarship fund management. Throughout this tutorial, we have explored the various aspects of designing, implementing, and integrating such a smart contract, highlighting its benefits and implications.

We began by discussing the challenges in scholarship fund management, including fraud, mismanagement, and lack of transparency. These challenges can hinder the effective distribution of funds and compromise the integrity of the scholarship process. By leveraging the Celo blockchain, we can overcome these challenges and establish a decentralized and transparent system that ensures funds are allocated to deserving recipients.

The Celo blockchain, with its key features of transparency, immutability, and programmability, aligns perfectly with the requirements of scholarship fund management. It provides a secure and tamper-resistant platform where smart contracts can be executed, ensuring the integrity and transparency of scholarship transactions.

We then delved into the process of designing and implementing the smart contract for academic scholarships on the Celo blockchain. From application for scholarship funds to award of scholarship and funding of the scholarship, we explored each step and provided detailed explanations of the Solidity code. This allowed us to create a robust and reliable system for managing scholarship funds.

Next steps.

By following this comprehensive tutorial, you now have the knowledge and tools to embark on your own journey of implementing a smart contract for scholarship funding on the Celo blockchain. Embrace this decentralized and transparent solution to empower deserving students and contribute to a fair and efficient scholarship ecosystem.

About the Author

Okoro Samuel Ogheneyole is a Web3 technical writer who has burning passion for technology and loves to share his knowledge for the benefit of other Web3 enthusiasts.

References

GithHub Repo
Solidity Documentation

5 Likes

looking forward to this

2 Likes

This topic is a proof of unlimited the Celo blockchain looking towards this

2 Likes

Thanks @Clue and @jimohyusufolatunji4. I hope to make it worth your expectations when it finally gets approved. Your support is also instrumental to getting it approved.

2 Likes

How do you think this can be scalable in terms of Adoption? Would love it if you can also share tips on this for any Dev looking to build

Love the idea though

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

2 Likes

i will review this

2 Likes

Thanks so much. I await your feedback.

3 Likes