Who do you pay money to on a regular basis? Your kids, employees, landlord, whomever? And each time you send them money, do you have to send the same amount on a regular basis? That's a huge waste of time, an unnecessary amount of fees, and a drain on your mental bandwidth. What if you could just deposit some money into an account and have your people just withdraw the money they're owed, when they're owed? Thanks to smart contracts, we can easily do that! Pay Your People Algorithmically I built an smart contract called AllowanceWallet that pays my people algorithmically. That means all I have to do is fund my smart contract, add their Ethereum wallet addresses, specify how much they get per pay period (e.g., every 7 days), and they can withdraw some or all of their money whenever they want. Ethereum I can also remove people from the list of who gets paid so they no longer accrue money. But that's only possible if I transfer what they're owed directly to their wallet. Seemed fair! On top of that, the amount they're owed accrues without me doing anything. So if they don't need their money for a few weeks and they get paid every week, the smart contract keeps track of the total amount they're owed. While the idea and functionality are all pretty simple, it shows how much you can do with so little if you know how to build smart contracts. It also sets the stage for improvements later on! Why traditional banks haven't implemented this, I have NO idea. Maybe they have and I don't know about it. But thanks to blockchain technology, we can build decentralized, trustless systems that traditional banks can't compete with. Even relatively simple ones like this. How AllowanceWallet Works (Code and All!) Before I dive into the ins and outs of how AllowanceWallet works, I need to give a shoutout to the creators of the Udemy course . What I built here is an extension of a similar project I did in the course. Ethereum Blockchain Developer Bootcamp With Solidity OK let's get into it! To start out, let's take a look at the tools I used to build AllowanceWallet: - the most popular programming language to build Ethereum smart contracts Solidity - a browser-based IDE for programming in Solidity Remix - an open-source Solidity library for secure smart contract development OpenZeppelin Now when I set out to create AllowanceWallet, I wanted to make sure anyone could fund the smart contract, but only one person (i.e., the owner of the smart contract) could withdraw. } receive () external payable { emit MoneyReceived( msg . sender , msg . value ) ; This code allows anyone who interacts with the smart contract to add money. used at the end of the function gives the function permission to accept money. Without this, an exception will be raised. Payable receive() addr.transfer(amount); } } function withdraw FromWalletBalance( address payable addr , uint amount ) public onlyOwner { require(address(this).balance >= amount, "Wallet balance too low to fund withdraw" ); emit MoneySent( msg . sender , amount ) ; function withdraw AllFromWalletBalance( address payable addr ) public onlyOwner { withdraw FromWalletBalance( addr , address ( this ) .balance); This code gives the owner the ability to withdraw money saved in the smart contract. You'll notice appended to the end of the functions, which is functionality extracted from the OpenZeppelin smart contract onlyOwner Ownable.sol . import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol" ; As you can see, importing smart contracts from GitHub is very easy! So now we have a smart contract that supports deposits and withdrawals, but that's not enough. We still need to give the owner of the smart contract the ability to add and remove addresses, which will ultimately be the addresses owned by the people who'll be getting paid from the smart contract. But before we get into that, let's take a look at how we'll store this information in the first place. } struct Allowance { uint allowanceAmount ; uint allowancePeriodInDays ; uint whenLastAllowance ; uint unspentAllowance ; mapping (address => Allowance) allowances; In Solidity, and are common-place. Here you'll see that for every stored address (or allowance recipient), we have an struct. In there we store the amount of money they get paid, their payment frequency in days, their most recent allowance date, and their total unspent allowance. structs mappings Allowance With this data, the smart contract will be able to keep track of how much each address is owed at any time. Now let's see how allowances are added to the smart contract: // Initialize new allowance } function addAllowance(address addr, uint allowanceAmount, uint allowancePeriodInDays) public onlyOwner { require(allowances [addr] . allowanceAmount == 0 , "Allowance already exists" ) ; require(address(this).balance >= allowanceAmount, "Wallet balance too low to add allowance") ; Allowance memory allowance ; allowance.allowanceAmount = allowanceAmount ; allowance.allowancePeriodInDays = allowancePeriodInDays.mul( 1 days) ; allowance.whenLastAllowance = block.timestamp ; allowance.unspentAllowance = allowanceAmount ; allowances [addr] = allowance ; emit AllowanceCreated(addr, allowance) ; First off, you'll notice two statements right away. This is how we ensure the input coming from the user of the smart contract isn't going to break anything. If these functions evaluate to , the transaction fails. require false Then we allocate an struct into memory, initialize it, and store it for later use. Allowance You might've noticed the function trailing variable . This is functionality derived from OpenZeppelin's smart contract, which we import the same way we did before with . mul() allowancePeriodInDays SafeMath.sol Ownable.sol import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol" ; Alright, but what if we want to remove someone from receiving an allowance after having added them? // Payout unspent allowance } } function removeAllowance( address payable addr) public onlyOwner { require( allowances [addr].allowanceAmount != 0 , "Allowance already doesn't exist" ) ; if( allowances [addr].unspentAllowance > 0 ){ require( address ( this ).balance >= allowances[addr].unspentAllowance, "Wallet balance too low to payout unspent allowance" ) ; addr.transfer( allowances [addr].unspentAllowance) ; delete allowances[addr] ; emit MoneySent( addr , allowances[addr].unspentAllowance) ; emit AllowanceDeleted( addr ) ; At first, I just removed the allowance from the smart contract, but then I thought: "What if they still have some leftover money they didn't spend?" The second part of the function fixes this so the owner of the smart contract MUST pay out the remaining money owed to the assigned address before removing them. Otherwise, the recipient will keep racking up a balance that'll need to be paid eventually. Now, that pretty much covers the main functionality of AllowanceWallet except for one part: How do the allowance recipients get paid?! Let's get into that now. } function getPaidAllowance(uint amount) public { require(allowances [msg.sender] .allowanceAmount > 0 , "You're not a recipient of an allowance" ); require( address (this) .balance >= amount, "Wallet balance too low to pay allowance" ); // Calculate and update unspent allowance uint numAllowances = block .timestamp .sub (allowances [msg.sender] .whenLastAllowance) .div (allowances [msg.sender] .allowancePeriodInDays); allowances [msg.sender] .unspentAllowance = allowances [msg.sender] .allowanceAmount .mul (numAllowances) .add (allowances [msg.sender] .unspentAllowance); allowances [msg.sender] .whenLastAllowance = numAllowances .mul ( 1 days) .add (allowances [msg.sender] .whenLastAllowance); // Pay allowance require(allowances [msg.sender] .unspentAllowance >= amount, "You asked for more allowance than you're owed'" ); payable(msg.sender) .transfer (amount); allowances [msg.sender] .unspentAllowance = allowances [msg.sender] .unspentAllowance .sub (amount); emit MoneySent(msg .sender , amount); emit AllowanceChanged(msg .sender , allowances [msg.sender] ); Right away you'll see that only those who've been added to the smart contract by the owner can get paid and they obviously need to have money to withdraw. That's covered in the initial statements. require The next part of the code keeps track of how much the recipient is owed. For example, if you had a weekly allowance and you didn't withdraw money for 4 weeks, you'd accrue 4 weeks' worth of allowance automatically. Then once the allowance balance is updated, the requested money is transferred to the recipient as long as they don't ask for more than they're owed. And that's it! If you want to take a look at how this all fits together, you can find the code . on my GitHub What Next? I took a simple idea and expressed it by creating a simple smart contract. But there's a whole lot more that could be done to make AllowanceWallet a whole lot better. Here are a few ideas of how AllowanceWallet can be improved: Create a simple web interface using something like or . React Vue Redesign it to support multiple groups of owners and allowance recipients. Integrate it into a layer-2 ecosystem (like ) for cheaper transactions. zkSync Add functionality for streaming (i.e., continuously accruing) allowance. Allow deposited, unspent money to accrue interest by using a DeFi protocol like . yearn Reimburse withdrawal fees paid by allowance recipients through a native token ( ?). AllowanceCoin Not sure how many of these I'll actually implement, but it's fun to imagine the possibilities! Final Thoughts If you're paying your people a constant amount of money at regular intervals, you shouldn't have to think much about it. It's predictable and therefore it should be as automated as possible. And as more people start accepting crypto as a form of payment, using smart contracts to handle these types of transactions is a no-brainer. That's EXACTLY why I built . AllowanceWallet I’m Grant and I’m a freelance fintech writer! If you’re looking for engaging, informative fintech content that speaks to your audience and can grow your brand awareness and online reach, I can help. Learn more on how I can help with your fintech content creation