I have been relearning solidity recently to solidify some of the details and to create a "WTF Solidity Crash Course" for beginners (advanced programmers can seek other tutorials). New lectures will be updated every week, ranging from 1 to 3.
Twitter: @0xAA_Science
Discord: WTF Academy
All codes and tutorials are open-sourced on Github: github.com/AmazingAng/WTF-Solidity
In this lecture, we'll introduce the payment-splitting contract, which allows the transfer of ETH
to a group of accounts according to their respective weights for payment-splitting purposes. The code section is a simplification of the PaymentSplitter contract provided by the OpenZeppelin library, which can be found on Github.
Payment Split
Payment split is the act of dividing money according to a certain ratio. In real life, it is common to encounter situations where the spoils are not divided equally. However, in the world of blockchain, Code is Law
, we can write the proportion that each person should get in the smart contract in advance, and let the smart contract handle the split of income.

Payment Split Contract
The Payment Split contract (PaymentSplit
) has the following features:
- When creating the contract, the beneficiaries
payees
and their shareshares
are predetermined. - The shares can be equal or in any other proportion.
- From all the ETH that the contract receives, each beneficiary can withdraw the amount proportional to their allocated share.
- The Payment Split contract follows the
Pull Payment
pattern, where payments are not automatically transferred to the account but are kept in the contract. Beneficiaries trigger the actual transfer by calling therelease()
function.
Events
There are a total of 3
events in the Splitter Contract:
PayeeAdded
: Event for adding a payee.PaymentReleased
: Event for payee withdrawing funds.PaymentReceived
: Event for Splitter Contract receiving funds.
State Variables
There are 5
state variables in the revenue-splitting contract, used to record beneficiary addresses, shares, and paid-out ETH
:
totalShares
: Total shares, which is the sum ofshares
.totalReleased
: The amount ofETH
paid out from the revenue splitting contract to beneficiaries, which is the sum ofreleased
.payees
: Anaddress
array that records the addresses of beneficiaries.shares
: Anaddress
touint256
mapping that records the shares of each beneficiary.released
: Anaddress
touint256
mapping that records the amount paid to each beneficiary by the revenue splitting contract.
Functions
There are 6
functions in the revenue-sharing contract:
- Constructor: initializes the beneficiary array
_payees
and the revenue sharing array_shares
, where the length of both arrays must not be 0 and their lengths must be equal. Elements of the _shares array must be greater than 0, and the addresses in the _payees array can't be the zero address and can't have a duplicate address. receive()
: callback function, releases thePaymentReceived
event when the revenue sharing contract receivesETH
.release()
: revenue sharing function, distributes the correspondingETH
to the valid beneficiary address_account
. Anyone can trigger this function, but theETH
will be transferred to the beneficiary address_account
. Calls the releasable() function.releasable()
: calculates the amount ofETH
that a beneficiary address should receive. Calls thependingPayment()
function.pendingPayment()
: calculates the amount ofETH
that the beneficiary should receive based on their address_account
, the revenue sharing contract's total income_totalReceived
, and the money they have already received_alreadyReleased
._addPayee()
: function to add a new beneficiary and their sharing percentage. It is called during the initialization of the contract and cannot be modified afterwards.
Remix Demo
1. Deploy the PaymentSplit
contract and transfer 1 ETH
In the constructor, enter two beneficiary addresses with shares of 1
and 3
.

2. View beneficiary addresses, shares, and ETH
to be distributed


3. Call the release
function to claim ETH

4. View overall expenses, beneficiary balances, and changes in ETH
to be distributed

Summary
In this lecture, we introduced the revenue-sharing contract. In the world of blockchain, Code is Law
, we can write the proportion that each person should receive in the smart contract beforehand. After receiving revenue, the smart contract will handle revenue sharing to avoid the issue of "unequal distribution of shares" afterwards.