Build a Simple Shared Wallet in Solidity
A simple small shared wallet blockchain project built using Remix IDE and Solidity.
Today, we will build a shared wallet in Solidity, which will have functions like withdrawing, adding funds to different users on the wallet. We will use Openzeppelin for the ownership and other security processes.
🚀What is the project all about?
This project aims to create a shared wallet on the blockchain, and there will be an Owner and other users.
The Owner will have access to all the functions of the wallet. The Owner can add funds and withdraw ethers, while only the added users on the wallet will have access to withdraw funds. No other user can draw or add funds to their account.
Prerequisites
You can choose whatever you are familiar with as the design principle will remain the same. But in our case, we are going to use Remix IDE for running and deploying the smart contracts for Ethereum.
What is a Smart Contract?
A Smart Contract is like a digital agreement or deal between two parties. While a normal agreement takes place on paper or official documents, a Smart Contract is executed as code running in a blockchain.
Want to more about Smart Contract? Visit Ethereum.org
Solidity
We will write our whole code on Solidity, so having a basic understanding of its syntax will make things easier to understand. If you are new to Solidity, here are some excellent resources that you might want to check out.
📌List of good free solidity resources
- MASTER Solidity for Blockchain Step-By-Step (Full Course)
- Solidity 101: Introduction to smart contracts
- Solidity Crash Course
Let's Start Coding
Step 1: Set up Remix IDE
- Visit remix and start a new project by clicking on the
REMIX IDE
on the top right corner.
A new screen with a default workspace containing some folders and files on the left and a code editor on the right will appear.
Create a new file simpleSharedWallet.sol.
Step 2: Solidity version and import Openzepplin
Specify the solidity version and import Openzepplin into our code.
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol";
- Version 0.8.12 or more is used.
- Openzeppelin deals with the ownership of the contract and provides an access control mechanism.
- To know more about Openzeppelin visit here.
Step 3: Funds smart contract
- Create the
Funds
smart contract.
contract Funds is Ownable {
}
- Define a map inside the
Funds
contract that will hold the addresses and funds of the users.
contract Funds is Ownable {
mapping(address => uint) public funds;
}
- Create a public function
setFunds()
to set the funds for the different users. - The function accepts the parameters address
_who
and uint_amount
. - This function is only made accessible to the owner by using onlyOwner modifier provided by Openzepplin.
- If the requirements are met, the fund is incremented on the map.
function setFund(address _who, uint _amount) public onlyOwner {
require(funds[_who] <= address(this).balance , "Amount is more than available in the contract");
require(_amount <= address(this).balance, "Amount is too high");
funds[_who] += _amount;
}
- Next, create an
allowed()
modifier. So, what is a modifier? Modifiers are used to modify the behaviour of a function. The body of the function is inserted in the place of_;
if all the above-written requirements are met while calling this function. To know more about modifiers, visit here.
modifier allowed(uint _amount) {
require(msg.sender == owner() || funds[msg.sender] >= _amount, "You are not allowed");
_;
}
- Finally, create an internal function
reduceFunds()
that accepts address_who
and uint_amount
. This function will decrement the funds from the users in thefunds
map, every time the funds are withdrawn from the wallet.
function reduceFund(address _who, uint _amount) internal{
funds[_who] -= _amount;
}
Step 4: SharedWallet smart contract
- Create the
SharedWallet
contract.
contract SharedWallet is Ownable, Funds {
}
- Create a public function
getBalance()
that returnsuint256
. This function will return the balance of the owner(contract).
function getBalance() public view returns (uint256) {
return address(this).balance;
}
- Next, create a payable function
withdrawMoney()
that will accept anaddress
and a_amount
parameter. And for this project, we make it accessible only by the owner and the users added to thefunds
map.
function withdrawMoney(address payable _to, uint _amount) payable public allowed(_amount) {
// entered amount must < balance in the contract
require(_amount <= address(this).balance, "Contract doesn't own enough money");
// transfer funds to address entered
_to.transfer(_amount);
}
- We define the
pay()
function to initiate the transaction by the contract.
function pay() public payable {
}
Step 4: Compiling
- Select the Solidity compiler option and make sure that the compiler version matches the defined solidity version.
- Compile the solidity file.
Step 5: Deploy and run the transaction
- Select the
Environment
. For this project, choose Javascript VM. - Select an account.
- Make sure on the contract option, SimpleSharedWallet.sol file is selected.
- Then deploy.
Step 6: Testing
For testing the application, I suggest using the other available accounts in the Javascript VM account list. You can try adding them to the funds map by setFunds
. Try withdrawing with the owner account and other available accounts.
Conclusion
Blockchain technology is very new, and it is still improving. Many people are still not aware of blockchain technology as its use continues to spread. Blockchain technology can potentially bring positive changes to our lives and society, and we, the developers, should continue exploring and promoting its use.
This is a simple project done as an example to show one of the use cases of blockchain technology. It is no way near to the original application of blockchain technology but just a tiny glimpse into the world of blockchain.