author

Kien Duong

May 5, 2022

Donation Smart Contract with Ethereum (Part 1)

1. Ethereum app high level architecture

donation smart contract 1

With many advantages of transparency, speed, trust,… Smart contracts have been developed and are used in a variety of fields. Using Solidity language, smart contract can be developed, compiled & deployed on an online tool Remix IDE. Besides, we will be able to develop a solidity application by using a backend programing language like NodeJS.

When a user wants to change the data on Ethereum network, user won’t connect to the backend side. Instead, the Ethereum app running on the browser will process it using web3 & Metamask. Metamask creates a transaction with user’s public & private keys and send the transaction to the Ethereum network. The transaction will need some amount of money to be processed.

 

2. Donation Smart Contract design

donation smart contract 2

2.1. Main variables:

  • manager: address The address of manager who creates & manages the contract.
  • minimumContribution: uint The minimum donation to become a contributor.
  • approvers: address[] List of contributor addresses.
  • requests: Request[] List of requests that are created by manager.
  • approversCount: uint The number of contributors.

2.2. Main functions:

  • constructor sets the minimumContribution value.
  • contribute is called when someone wants to become a contributor.
  • createRequest is called by manager to create a spending request.
  • approveRequest is called by each contributor to approve a spending request.
  • finishRequest is called by manager when a spending request has got enough approvals (>50% contributors).

 

3. Testing with Remix

Go to Remix IDE to write the logic for donation smart contract. Inside the contracts folder, create a new Donation.sol file

donation smart contract 3

    // SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract Donation {

    struct Request {
        string description;
        uint value;
        address recipient;
        bool complete;
        uint approvalsCount;
        mapping(address => bool) approvals;
    }

    address public manager;
    uint public minimumContribution;
    mapping(address => bool) public approvers;
    mapping(uint => Request) public requests;
    uint public requestsCount;
    uint public approversCount;

    modifier isManager() {
        require(msg.sender == manager);
        _;
    }

    constructor(uint minimum) {
        manager = msg.sender;
        minimumContribution = minimum;
    }

    function contribute() public payable {
        require(msg.value > minimumContribution);
        approvers[msg.sender] = true;
        approversCount++;
    }

    function createRequest(string memory description, uint value, address recipient) public isManager {
        Request storage rq = requests[requestsCount++];
        rq.description = description;
        rq.value = value;
        rq.recipient = recipient;
        rq.complete = false;
        rq.approvalsCount = 0;
    }

    function approveRequest(uint index) public {
        Request storage request = requests[index];
        require(approvers[msg.sender]);
        require(!request.approvals[msg.sender]);
        request.approvals[msg.sender] = true;
        request.approvalsCount++;
    }

    function finishRequest(uint index) public isManager {
        Request storage request = requests[index];
        require(request.approvalsCount > (approversCount / 2));
        require(!request.complete);
        payable(request.recipient).transfer(request.value);
        request.complete = true;
    }

}
  

Let’s go through the meaning of each function.

3.1. constructor

When a user deploys the smart contract, constructor function is called. The current user will be the manager of this contract, manager’s address is his address & he has to set the minimum value to allow a user to become a contributor.

3.2. contribute

Anyone wants to become the contributor of the contract, he has to call to contribute function. Via Metamask, he will send the money, if the money is greater than or equal to the minimum value, he will become a contributor and his address will be stored as an approver.

3.3. createRequest

This function can only be called by the manager. Manager will create one of many spending requests that await approvals from the contributors. The spending request contains the value & the recipient’s address.

3.4. approveRequest

Anyone who is the contributor of the contract can call this function to approve an spending request. The request will be updated the approvers information.

3.5. finishRequest

Like the createRequest function, only manager can execute this function. If a request has a number of approvers that is greater than 50% of total contributors, the money will be transfered to the recipient’s address. This request is done.

The next step, we must compile the contract first.

donation smart contract 4

Go to the deploy tab, select Javascript VM environment. Inside the list accounts, we already have 15 accounts with 100 ETH for each account. Select the first one to deploy the contract. Set the minimum value is 1 ETH means that we’re going to set the minimum value for constructor function. Click to Deploy button to deploy this contract.

donation smart contract 5

The contract has been deployed successfully. You can see that the first account (manager’s account) has been decreased some amount. It’s the gas that we have to pay when deploy a contract.

donation smart contract 6

Next step, set the manager as a contributor (optional) by calling the contribute function on the manager account. Eg. manager wants to donate 2 ETH and clicks to the contribute button. For now, the contract has the first contributor.

donation smart contract 7

Next step, still on the manager account, create a new request. In order to create a new request, user has to pass three params. Eg.

  • description: “Donate to UNICEF”
  • value: 9999 (wei)
  • recipient: 0xdD870fA1b7C4700F2BD7f44238821C26f7392148 (last one in the list accounts)

donation smart contract 8

For now, the contract already has a spending request. Switch to next two accounts and contribute. Eg. the second one donates 3 ETH, the third one donates 5ETH. The current total balance is 10ETH & 3 contributors (including 1 manager).  Go to each account and approve the first request with index. Because the contract is having only one request so the index must be zero.

donation smart contract 9

The approvalsCount is equal 3, the contributors are 3 so the first request is ready to be finished. Switch to the manager account & finish the request.

donation smart contract 10

As you can see, we’ve set the recipient’s address to be the last one account. So now, comeback to the list accounts & see the result. The last one account has been increased 9999 wei, so the request has been processed successfully.

donation smart contract 11

In this blog, we’ve created a donation contract & deployed it to the Ethereum testing network. We will go into building a smart contract project using NodeJS & ReactJS in the next blogs.

https://ai-research.dev/donation-smart-contract-with-ethereum-part-2/

Recent Blogs