How to Code a Fantastic Batch Payment Function With Solidity: A Must Know Technique

Introduction

Let’s face it, as long as you are using solidity to develop smart contracts, you will be faced with the challenge of processing bulky transactions. You need the level up your payment processing skills with solidity and you need to do that fast.

\
In this tutorial, you will learn a very crucial smart contract skill for disbursing money (Ethers) to multiple accounts with a click of a button.

\
By the way, if you are looking for a personal tutor to speed you up with web3 development please book a session with me.

\
If you are fired up like I am, let’s jump into this tutorial…

Why you must master batch payment processing in Solidity

Solidity is a specific programming language for handling payment processing between accounts. This is a rare trait among the programming languages on the web. Solidity was built with the intent of managing transactions with the Ethereum digital currency eliminating the need for middlemen and big corporations.

\
With Solidity smart contract programming, you don’t need a bank or any bank lady to process your payment, all your payments will be processed in the network.

\
But the mere fact that solidity gives you the power to make digital transactions faster, secured, and at a large scale does not mean that you can do this perfectly without learning.

\
In as much that this financial network has provided us with a way to move money between points fast, secured, and limitless, It has also attracted the predatory eyes of thieves known as (hackers).

\
Yes, they watch out for weakness in your system specifically how money is moved in your smart contract. When they find a way to exploit such weakness, they will plunder your system and render your business dysfunctional.

\
For that not to happen, you must understand how to process batch payments with your smart contracts.

Batch Payment Smart Contract Example

I want to illustrate this to you through an example smart contract I’ve created named Payroll. Below is the full smart contract code…

\

//SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;

contract Payroll {
    address public companyAcc;
    uint256 public companyBal;
    uint256 public totalWorkers = 0;
    uint256 public totalSalary = 0;
    uint256 public totalPayment = 0;

    mapping(address => bool) isWorker;

    event Paid(
        uint256 id,
        address from,
        uint256 totalSalary,
        uint256 timestamp
    );

    struct PaymentStruct {
        uint256 id;
        address worker;
        uint256 salary;
        uint256 timestamp;
    }

    PaymentStruct[] employees;

    modifier ownerOnly(){
        require(msg.sender == companyAcc, "Owner reserved only");
        _;
    }

    constructor() {
        companyAcc = msg.sender;
    }

    function addWorker(
        address worker,
        uint256 salary
    ) external ownerOnly returns (bool) {
        require(salary > 0 ether, "Salary cannot be zero!");
        require(!isWorker[worker], "Record already existing!");

        totalWorkers++;
        totalSalary += salary;
        isWorker[worker] = true;

        employees.push(
            PaymentStruct(
                totalWorkers,
                worker,
                salary,
                block.timestamp
            )
        );

        return true;
    }

    function payWorkers() payable external ownerOnly returns (bool) {
        require(msg.value >= totalSalary, "Ethers too small");
        require(totalSalary <= companyBal, "Insufficient balance");

        for(uint i = 0; i < employees.length; i++) {
            payTo(employees[i].worker, employees[i].salary);
        }

        totalPayment++;
        companyBal -= msg.value;

        emit Paid(
            totalPayment,
            companyAcc,
            totalSalary,
            block.timestamp
        );

        return true;
    }

    function fundCompanyAcc() payable external returns (bool) {
        require(companyAcc != msg.sender, "You can't fund yourself!");
        payTo(companyAcc, msg.value);
        companyBal += msg.value;
        return true;
    }

    function getWorkers() external view returns (PaymentStruct[] memory) {
        return employees;
    }

    function payTo(
        address to, 
        uint256 amount
    ) internal returns (bool) {
        (bool success,) = payable(to).call{value: amount}("");
        require(success, "Payment failed");
        return true;
    }
}

\
Great, above is a smart contract for paying a company’s employees according to their salaries. Let’s take a look at how we accomplish this smart contract step by step.

\
Step 1:
In this first step, we are setting up our smart contract structure. We are using the MIT license identifier and the compiler range of 0.7.0 to 0.9.0. Next, we defined the smart contract with a name called Payroll.

\

//SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;
contract Payroll {
  // Codes goes here...
}

\
Step 2:
Here we are defining the essential state variables for our smart contract. The companyAcc specifies the deployment account or address. CompanyBal holds all the fund that comes into the company. We then specified some variables to keep track of the total workers, salaries, and payments in our smart contract.

\

address public companyAcc; // Owner's account
uint256 public companyBal; // Companies fund
uint256 public totalWorkers = 0;
uint256 public totalSalary = 0;
uint256 public totalPayment = 0;
mapping(address => bool) isWorker; // Identifies workers

\
Step 3:
This step specifies the smart contract event log. We want some vital data logged out on each successful payout. The data to be logged out here include the payout Id, the payer, the total salary paid, and the time of payment.

\

event Paid(
    uint256 id,
    address from,
    uint256 totalSalary,
    uint256 timestamp
);

\
Step 4:
This specifies the payment structure. Struct is a solidity keyword denoting structure. We want each employee to have the following records:

\

  • Id which must be an unsigned integer.
  • A wallet address indicated as worker.
  • A specified salary.
  • A timestamp representing the time of joining the company.

\

struct PaymentStruct {
  uint256 id;
  address worker;
  uint256 salary;
  uint256 timestamp;
}
PaymentStruct[] employees; //An array of employees

\
Step 5:
In this step, we created a modifier called ownerOnly. Its sole purpose is to guard a function against unauthorized access. Whichever function we include this modifier into will only permit access to the owner of the company which in this case is the deployer of the smart contract.

\

modifier ownerOnly(){
    require(msg.sender == companyAcc, "Owner reserved only");
    _;
}

\
Step 6:
Here we set up the deployer address to be the company’s account.

constructor() {
    companyAcc = msg.sender;
}

\
Step 7:
This function is responsible for adding a new worker to the employee records. It can only be operated by the deployer of the smart contract which is the company’s account.

\

function addWorker(
    address worker,
    uint256 salary
) external ownerOnly returns (bool) {
    // Checks for salary and work's existence...
    require(salary > 0 ether, "Salary cannot be zero!");
    require(!isWorker[worker], "Record already existing!");

    // Performs essential computations...
    totalWorkers++;
    totalSalary += salary;
    isWorker[worker] = true;

    // Includes worker in the employees array...
    employees.push(
        PaymentStruct(
            totalWorkers,
            worker,
            salary,
            block.timestamp
        )
    );

    return true;
}

\
Step 8:
This function is responsible for paying the company’s workers. This is the function performing the bulk transactions. You should pay good attention to it.

\

function payWorkers() payable external ownerOnly returns (bool) {
    // Ensures that salary can be paid...
    require(msg.value >= totalSalary, "Ethers too small");
    require(totalSalary <= companyBal, "Insufficient balance");

    // Performs recursive payment to each employee...
    for(uint i = 0; i < employees.length; i++) {
        payTo(employees[i].worker, employees[i].salary);
    }

    // Performs essential computations...
    totalPayment++;
    companyBal -= msg.value;

    // Emits payment event...
    emit Paid(
        totalPayment,
        companyAcc,
        totalSalary,
        block.timestamp
    );

    return true;
}

\
The secret to processing batch payment is to put it in a loop construct and have the loop call the secured payment function over and over again until all cases are worked on.

\
Step 9:
This function receives payments from the outside and funds the company’s account.

\

function fundCompanyAcc() payable external returns (bool) {
    require(companyAcc != msg.sender, "You can't fund yourself!");
    payTo(companyAcc, msg.value);
    companyBal += msg.value;
    return true;
}

\
Step 10:
This function simply returns the list of employees now part of the company.

\

function getWorkers() external view returns (PaymentStruct[] memory) {
    return employees;
}

\
Step 10:
This function is responsible for sending money from one address to another. It was repetitively called during the batch payment to the workers.

\

function payTo(
    address to, 
    uint256 amount
) internal returns (bool) {
    (bool success,) = payable(to).call{value: amount}("");
    require(success, "Payment failed");
    return true;
}

Caution about Batch Payment Processing

Please note that batch payment processing is an autonomous activity put into action, hence, it is wise to do some checking before processing. Here are some tips to take note of.

\
Verify Data
Make sure that you verify the correctness of data before processing payments. Using the required functions and special modifiers such as adminOnly to ensure that only accurate records are input into the system.

\
Process Payment
Make sure you charge the account first before changing the state variables. This will help guard against reentrancy attacks.

\
Recalibrate Record
Update the state variables only after you’ve done the above activities. For example, if a malicious user intends on attacking your payment function by sending multiple requests at a time. He will be compelled to pay twice, and with each request, payment has to be made before the state variables are updated.

Conclusion

Payment processing is a must-have skill if you are serious about being a web3 developer. It’s also important to know how to be defensive against attacks such as reentrancy.

\
That’s all for this tutorial, hope this information was valuable to you. I’m still doing private tutoring classes for those who want to jump into the web3 space. If you’re interested, please book me up on my website.

\
Hoping to see you in the next one, till then, have a great day!

About the Author

Gospel Darlington kick-started his journey as a software engineer in 2016. Over the years, he has grown full-blown skills in JavaScript stacks such as React, ReactNative, NextJs, and now blockchain.

\
He is currently freelancing, building apps for clients, and writing technical tutorials teaching others how to do what he does.

\
Gospel Darlington is open and available to hear from you. You can reach him on LinkedIn, Facebook, Github, or on his website.

Leave a Reply

Your email address will not be published. Required fields are marked *

Instagram

Why do People Say: "Developers are Lazy"?
The saying “work smart, not hard” is applicable for programmers.
.
https://hackernoon.com/why-do-people-say-developers-are-lazy

.
Author: Aga Wozniak
.
.
.
.
.
#blog #100Daysofcode #javascript #vuejs #datascientist #peoplewhocode #learntocode #coding #developerlife #frontenddeveloper #backenddeveloper #fullstackdeveloper #developer #webdeveloper #thedevlife #phpdeveloper #computerscience #programmer #programmingisfun #codingdays
...

Mitigating the DDOS Threats Facing Banks and Fintechs
As much as digitization and cyber simplified banking, the Fintech sector has left digital payment activity exposed to malicious and suspicious activity.
.
https://hackernoon.com/mitigating-the-ddos-threats-facing-banks-and-fintechs

.
Author: Josh Horowitz
.
.
.
.
.
#blog #100Daysofcode #javascript #vuejs #datascientist #peoplewhocode #learntocode #coding #developerlife #frontenddeveloper #backenddeveloper #fullstackdeveloper #developer #webdeveloper #thedevlife #phpdeveloper #computerscience #programmer #programmingisfun #codingdays
...

24 Best JavaScript Blogs and Websites
In this overview, we have compiled a list of popular sites, as well as JS blogs that are worth reading and keeping in your bookmarks.
.
https://hackernoon.com/24-best-javascript-blogs-and-websites

.
Author: natashatsybliyenko
.
.
.
.
.
#blog #100Daysofcode #javascript #vuejs #datascientist #peoplewhocode #learntocode #coding #developerlife #frontenddeveloper #backenddeveloper #fullstackdeveloper #developer #webdeveloper #thedevlife #phpdeveloper #computerscience #programmer #programmingisfun #codingdays
...

The Projects Working to Lower Ethereum Gas Fees
As more investors try their hand at DeFi, gas fees are shooting over the roof, making engaging with decentralized apps uneconomical for most users.
.
https://hackernoon.com/ethereum-gas-fees-are-there-any-projects-working-to-optimize-eth-gas-fees

.
Author: CryptoVirally SLR
.
.
.
.
.
#blog #100Daysofcode #javascript #vuejs #datascientist #peoplewhocode #learntocode #coding #developerlife #frontenddeveloper #backenddeveloper #fullstackdeveloper #developer #webdeveloper #thedevlife #phpdeveloper #computerscience #programmer #programmingisfun #codingdays
...

On the Edge of a New Year: IT Predictions for 2022
The single biggest cause of network errors are people.
.
https://hackernoon.com/an-interview-with-uplogix-ceo-lisa-frankovitch

.
Author: Mignonette Garnier
.
.
.
.
.
#blog #100Daysofcode #javascript #vuejs #datascientist #peoplewhocode #learntocode #coding #developerlife #frontenddeveloper #backenddeveloper #fullstackdeveloper #developer #webdeveloper #thedevlife #phpdeveloper #computerscience #programmer #programmingisfun #codingdays
...

How to Modernize IBM i Applications
If you’re like most IBM i users, you know how much value your IBM i data and applications bring to your business. Your end-users, however, may not. In today’s world of rich user experience, fast-paced application development, and constantly evolving customer expectations, IBM i applications are unde…
.
https://hackernoon.com/how-to-modernize-ibm-i-applications

.
Author: Lansa
.
.
.
.
.
#blog #100Daysofcode #javascript #vuejs #datascientist #peoplewhocode #learntocode #coding #developerlife #frontenddeveloper #backenddeveloper #fullstackdeveloper #developer #webdeveloper #thedevlife #phpdeveloper #computerscience #programmer #programmingisfun #codingdays
...