Build a Shared Wallet in Solidity
Tags: solidity, blockchain, web3
Published: 2022-03-30 07:42:35

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](https://openzeppelin.com/) 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](https://remix-project.org/) 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](https://ethereum.org/en/developers/docs/smart-contracts/)

### 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)](https://www.youtube.com/watch?v=YJ-D1RMI0T0)
- [Solidity 101: Introduction to smart contracts](https://www.defi-academy.com/courses/introduction-to-smart-contracts)
- [Solidity Crash Course](https://blog.finxter.com/solidity/)


## Let's Start Coding

### Step 1: Set up Remix IDE
- Visit [remix](https://remix-project.org/) and start a new project by clicking on the `REMIX IDE` on the top right corner.

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1647081084647/5-TvtsHPR.png)

- 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**. 

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1647081476849/hGKeoAgwp.png)

### 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](https://docs.openzeppelin.com/contracts/2.x/api/ownership).

 
### 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](https://www.tutorialspoint.com/solidity/solidity_function_modifiers.htm).

```
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 the `funds` 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 returns `uint256`. 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 an `address` and a `_amount` parameter. And for this project, we make it accessible only by the owner and the users added to the `funds` 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.

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1647181443138/j37Wa5xSA.png)

- Compile the solidity file.

### Step 5: Deploy and run the transaction

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1647181619466/LAHSexR4D.png)

- 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. 

---

🌎Explore, 🎓Learn, 👷‍♂️Build. Happy Coding💛