ETHEREAL : A Decentralized Virtual Banking system - Part I
Tags: blockchain, webdev, beginners, tutorial
Published: 2022-01-07 12:07:08

In recent times, we have all heard about **Blockchain** once or twice and it has been a hot and controversial topic ,almost in the news every other day. In the 2 parts of this article-series we have explored the various terms related to Blockchain like **Bitcoin**, **Ethereum**, **Solidity** and we have built an actual working **DApp**(a decentralized application), where we have guided you in building the project from ground zero. This project was built as part of our event **Ten Days of Code** held from **17th October 2021** to **26th October 2021**, where we mentored students all over India in building projects from scratch across various domains.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x7ixekqgghacdp2nlm64.png)

In this project, we have built a **decentralized** banking application, now decentralized here means that the central power doesn't lie in the hands of a single user but is instead **divided equally** among all the users and hence no one supervises all the account in our bank and everyone is responsible for their own account. We have implemented all the basic features that a bank can perform like deposition, withdrawal, and transfer of money.

Now, you might be wondering why **decentralized**, well great question indeed for this a simple analogy would suffice, we all hate **dictatorships** where the whole power lies with a single person and hence prefer **democracies**, well a debatable point, but let's not get there, now applying the same analogy wouldn't it be great if you and only you had the access to your account opposing the view of a **single** person having access to all the accounts, being the whole purpose of this project.

This DApp is supported using **Solidity Smart Contracts** and the frontend is built using the framework **React JS**, the application is deployed to the local blockchain network, **Ganache**. The whole project runs on an **Ethereum** supported browser, with the help of the **Metamask** extension. For building and compiling **Truffle** was used. Lastly, the frontend was connected to the solidity contract using a **web3**.

To understand all these terms and how Blockchain works do watch the video below which was a live session from our event **Ten Days of Code.**

{% youtube rnQBSH9b_Dw %}

**What is Blockchain?**
Blockchain technology is a type of distributed ledger technology (DLT) — It is an accounting system where the ledger (record of transactions) is distributed among a network of computers.
So at its core, blockchain technology is a record-keeping tool.
**Beginners guide for [Blockchain](https://medium.com/@sinafl/blockchain-101-a-beginners-guide-410d4d93d635)**

**What is a Smart Contract ?**
All of the code on the blockchain is contained in smart contracts, which are programs that run on the blockchain. All of the code on the blockchain is contained in smart contracts, which are programs that run on the blockchain. They are the building blocks of blockchain applications. We'll write a smart contract in this project to power our Banking system.
**For in-depth detail click [here](https://www.investopedia.com/terms/s/smart-contracts.asp)**

**Intro To Solidity :**
Solidity is the main programming language for writing smart contracts for the Ethereum blockchain. It is a contract-oriented language, which means that smart contracts are responsible for storing all of the programming logic that transacts with the blockchain. It's a high-level programming language that looks a lot like JavaScript, Python, and C++.
**For in-depth detail click [here](https://docs.soliditylang.org/en/v0.8.9/)**


---

## Prerequisites :

You can watch this video for setting up this project:

{% youtube P62_at1FIE4 %}

**Ganache (Local Development Blockchain)**
![Ganache](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jcdlj8az0mue4vbafee9.png)
The dependency is a **personal blockchain**, which is a local development blockchain that can be used to **mimic** the behavior of a **public blockchain**. We recommend using **[Ganache](https://www.trufflesuite.com/ganache)** as your personal blockchain for Ethereum development. It will allow you to deploy smart contracts, develop applications, and run tests. It is available on Windows, Mac, and Linux as a desktop application and a command-line tool !

**Download it by clicking [here](https://www.trufflesuite.com/ganache)** (For both Windows and Linux)

###### For Linux(Ubuntu) Users :

**Once the download is complete, go to the folder where you have downloaded the file and open the terminal and type the following to make the file executable:**


```
chmod a+x <filename.AppImage>
```


**Node.JS**
Now that you have a private blockchain running, you need to configure your environment for developing smart contracts. The first dependency you'll need is **[Node Package Manager](https://nodejs.org/en/)** , or NPM, which comes with Node.js.

**You can see if you have node already installed by going to your terminal/cmd and typing:**

```
node -v
```

If you don't have a node already installed then :

###### For Windows Users :
**Download it by clicking [here](https://nodejs.org/en/)**

**It is recommended that you download LTS version.**



###### For Linux(Ubuntu) Users :
Go to your terminal and type :
 ```
$ sudo apt install nodejs
$ sudo apt install npm
 ```
<br>

**Truffle Framework**
**Now let's install the [Truffle Framework](https://www.trufflesuite.com/docs/truffle/overview)**, 
which provides a suite of tools for developing Ethereum smart contracts with the Solidity programming language.


###### For Windows Users :
Go to your cmd and type :
```
npm install -g truffle
```
###### For Linux(Ubuntu) Users :
Go to your terminal and type :
```
$ sudo npm install -g truffle
```

**For this project, we have used React JS framework for the frontend and to get the required folder structure for our project we run the following command:**

###### For Windows Users :
Go to your cmd and type :
```
truffle unbox react 
```
###### For Linux(Ubuntu) Users :
Go to your terminal and type :
```
$ sudo npx truffle unbox react 
```

**Metamask Wallet**

For this project, we would require an **Ethereum** wallet, and here we will use the popular open-source wallet **Metamask**.

###### On Chrome/Firefox/Brave(It is recommended that you use Brave browser) :

1. Go to the extensions page of your browser and install the **Metamask plugin, click [here](https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn)**
2. On installation the user will be redirected to a setup page and the user has to choose a password and a recovery phrase.

**For in-depth detail click [here](https://docs.metamask.io/guide/)**

---

## Getting Started with the Project :

After running the command **npx truffle unbox react** you would have a folder structure of something similar to this in front of you :

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u3i3aq16bke1yisyvms7.JPG)
Let us understand what each of these means :

**node_modules** : This folder contains all the required npm packages for your project which are installed when you run **npm install**  after cloning our repository.

**src** : This folder contains all the components and pages for our React project

**public** : This is the directory where we save our images and which also contains the main HTML file **index.html** where all the components from **src** are finally rendered to give us a single page application.

The **.gitignore** file contains information-related code which you don't want to commit to **Github** .

The **package.json** and **package-lock.json** are initialized when you run **npm init** and install npm packages in your project.

**For in-depth detail about React, click [here](https://docs.soliditylang.org/en/v0.8.9/)**

{% youtube -3WA67i4WI8 %}

**For React tutorial, click [here](https://www.youtube.com/watch?v=4UZrsTqkcW4)**
###### Must watch useState (3:39:00 to 4:23:00), useEffect (4:47:27 to 5:19:24) and React Router (9:00:41 to 9:23:22)

## Part 0 : Creating a simple blockchain project: Ethereum Todo List
{% youtube OfuNQXJDnPE %}


**[Referance](https://www.youtube.com/watch?v=AiWkkj8lSTc&list=PLS5SEs8ZftgVI1LeNhgYO1Y1Gd2hhPc3F) to build this simple project:** 

## Part 1 : First Functionality - Creating a new account

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u8lcesi03c4zkzq7qkql.png)
Let us begin with the Front-end.

Navigate to your **client** folder and then to **src**.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rwygoioayn9ai8q9q21c.JPG)
We will be writing all of our frontend code in the form of various components and import them all to the final **index.js** file which will be rendered onto the HTML file present in the public folder.

Now, that you have explored all the hooks used in the project , we add some basic lines of code to every component to fetch all the details like web3, **Metamask** connected account and the solidity contract.

This code is **common** for all the components  as we need to fetch data in every component. 

The only component which won't contain this snippet is the **Navbar** because this component is only for Navigation purposes and does not require all these details , for this project purposes we create a Navbar with 2 tabs for now : **REGISTER** and **ACCOUNTS** , on clicking the **REGISTER** tab it should redirect you to the URL **"/create"** , you can change the name for this **route** if you want, we have named it "/create" and the **ACCOUNTS** tab should redirect you to the URL **"/accounts"**. You can import this Navbar in all the components you are creating to navigate to the different tabs of our application which are only 2 currently, but you will soon be creating more tabs.

The only modification is when you fetch more details or the particular function for that component from the contract you need to add this particular code snippet.

```js
 useEffect(() => {
    ​
    const getBasicDetails = async () => {
        ​
        try {

            ​ // Get network provider and web3 instance.
            ​
            const web3 = await getWeb3();

            ​ // Use web3 to get the user's accounts.
            ​
            const accounts = await web3.eth.getAccounts();

            ​ // Get the contract instance.
            ​
            const networkId = await web3.eth.net.getId();
            ​
            const deployedNetwork =
                BankingContract.networks[networkId];
            ​
            const instance = new web3.eth.Contract(

                ​BankingContract.abi, ​deployedNetwork && deployedNetwork.address
                ​);
            ​
            setWeb3(web3);​
            setAccount(accounts[0]);​
            setContract(instance);

            ​
        } catch (error) {

            ​ // Catch any errors for any of the above operations.
     ​
            alert(
                ​`Failed to load web3, accounts, or contract. Check console for details.`

                ​);
            ​
            console.error(error);​
        }​
    }​
    getBasicDetails();

}, []);

```

This is how your first **useEffect** hook looks. To go through this **useEffect** hook once would be enough as you will be using this same **useEffect** hook in every component, even if you create new components.

In this hook we have defined a function **getBasicDetails**, where we load **web3** from the **getWeb3.js**, and we get the **Metamask** connected account by using **web3**, as we have already mentioned in our intro section that web3 acts as a **connector** between our backend and frontend. 

Here we will be using **web3** for everything. For creating a **new contract**, for using the **various functions** from the backend, for loading accounts. You will soon understand that it makes everything much easier. 


Firstly, throughout the application we use web3 and whenever we use web3, it is through **asynchronous calls** and we use the **async await syntax** and basic ES7 javascript **.then, .catch** syntax to resolve promises.

**web3.eth** ( **eth** is short for **ethereum** ) is the  object which contains various functions for getting your accounts, getting your network id , creating a new contract from your **JSON file** .

Read more about the various methods of **web3 [here](https://web3js.readthedocs.io/en/v1.3.0/)**



In the **getBasicDetails** function , we use the **getAccounts()** , **net.getId()** , **Contract()** methods of **web3.eth** 

**getAccounts()** gets all the accounts connected to the Ethereum browser (here Metamask), to access the present connected account we want the very first element of this accounts array which is at the **0th index**, and we change the **state of account variable to this**   

**net.getId()** gets the network Id of the Solidity contract which is one of the two things to initiate a new contract using web3, the other one is the **abi** object present in the **Banking.json** file.

```js
new web3.eth.Contract(BankingContract.abi,deployedNetwork && deployedNetwork.address)
```

This initiates a contract from our **existing JSON file**.
We set the empty web3 variable to the loaded web3 object and the empty contract variable to the newly created contract using **useState** hook of React.

To give an example of the usage of the **useParams** hook, we have used it in the **Transactions** component.

In the **Transactions** component, we have accessed the **id** parameter from the URL and assigned it to a variable in the **Transactions component**. 

```js
const{id} =useParams(id);
```

In the input of the **useParams** hook, we refer to the exact parameter variable we used in the URL, in this case **id** .

I hope that helps you understand the **useParams** hook, for more reference visit: 

Let us briefly explore the **Routing.js** file  :

In the **Routing.js** file we import Router and Route from **'react-router-dom'** and the basic syntax of the whole Routing component is similar for every Route. 


```js
import { BrowserRouter as Router, Route } from "react-router-dom";

import ComponentName1 from "<path-to-the-component>";

import ComponentName2 from "<path-to-the-component>";

<Router>
  <Route exact path="<specify-path1-here>">
    <ComponentName1 />
  </Route>

  <Route exact path="<specify-path2-here>">
    <ComponentName2 />
  </Route>
</Router>;        

```

The first **useEffect** hook will be present in all functional components like **AccountDetails**, **DisplayAccounts** , **LoanTransaction**, **TransferMoney** and all the other components except the **Navbar** .


Let's talk about the **second** useEffect hook which you will be used in some or almost all of the components to extract the required functionality from the contract because only the creation of the contract is not enough.

We need to access the **particular functionality** from our **contract** to perform various operations for us, for example, when we are creating the CreateAccount.js component we actually don't require any additional data, but we just use the second hook to log the contract details in our **browser console** .

In this hook we run the function only when web3, contract and account are **not undefined** as we had initialized them as **undefined**, the dependency array also has web3, account, contract in it so that **useEffect** runs until all of these variables change from undefined to a **definitive value**, this is done for easy coding purposes to view the various **methods** present in the **contract** (We'll explain what are these various methods).


So, let's continue building the **createAccount.js** component, for this, we require a basic HTML form 

**PRO TIP :**  To build forms in which the data field values are stored in some variable which can be further used at different places we use the **useState** hook, this has been done in all the components so I am specifying this in the beginning for your ease. 

**EXAMPLE :**  

```js
const[name,setName]=useState("")

<input
  value={name}
  onChange={(e) => setName(e.target.value)}
  placeholder="Name"
  type="text"
/>;
```

In the above example, we initialized the **name variable** as a blank variable and then when the form input value is changed we pass the **onChange** function where the state of the name variable is updated to the **current target value**, this name can be further used any place we want, overall throughout the application we use this same syntax, so when I refer to making a **form input** with a value equal to the value of the variable "x" what I actually will mean is the above syntax.

So, now if you recall from above in the Solidity contract the function to create a new account takes 3 inputs, and among those 3 - one is the creator address which is the **account** connected to **Metamask** which we already stored in the **account state variable**, the other 2 variables are the **name** and **location** inputs which we will get from the **form** that we are creating. 

After creating the form with 2 input fields we need to create a **SUBMIT** button and we need to pass a function on the click of this button, now the syntax of this function will also be similar in every component and since this is for the first component let me give you the syntax.

**EXAMPLE:**  

We defined the **handleSubmit** function inside our **CreateAccount** component but this should be above the rendering of the JSX.

**ES7 arrow function syntax is being used here throughout the project, you may use it or may proceed with the normal function syntax**.

```js

//Function to handle the submit operation of the form

const handleSubmit = async (e) => {

        //prevents the default action that occurs when someone submits a form 

        e.preventDefault()

        //...rest of the function code ...//

    }

    <
    button type = "submit"
onClick = {
    handleSubmit
} > SUBMIT < button / >

```

This function is **asynchronous** because we need to communicate with the contract, send a request to it and wait for its response. Hence we use a similar syntax everywhere using **.then** and **.catch** to resolve the promises, **more than one** .then can also be changed as per the user requirement.       

Now in our **createAccount.js** file, the **handleSubmit** function should contain the code to access the function to create new accounts from the backend, now **how** this is done? 

Well, firstly we have already created a new contract, every contract is an object which further has an item called **methods**, now what does this methods item contain? 

It contains every public variable and function defined in the solidity contract. That's it, you can refer to the contract object in the **browser console**, you will find the **methods** item in it.

For this component, we need to access the **createAccount** method, now there are 2 ways to access a function using web3, they are call and send, the **major** differences in these two are you use call only when you want to **view data** and **not modify** anything and it **does not cost** any ether to perform this transaction but if you use the send method it costs some amount of **gas fees** and it **modifies** data, why does it cost ether though? 

Well, that is an interesting question though but as you already know that you need to send ether for any function to be executed or **written** on a **new block** and the **miners** of this block need to be **rewarded** somehow since they are securing the whole system by solving **complex algorithms** which creates new blocks for storing our executed function data, hence this is the a**mount deducted** from our account when we use the send method, which is rewarded to the **miners**.

In **createAccount.js** we are creating a new account, that is **modifying data** so we use the **send method** of **web3** rather than the **call method** (which is used to just view the data), and the syntax of a send option is such that it also accepts another object which contains details like the **from address**, **to address**, and the **value being sent**.

In, our banking application we deduct **2 ETH** from the **Metamask** account on the creation of every new account as a starting balance to the virtual account and increment the balance of the virtual account from **0** to **2** (the increment of balance is handled on the backend).

```js
await contract.methods
  .createAccount(account, name, location)
  .send({ from: account, value: web3.utils.toWei(2, "ether") })

  .then((res) => {
    console.log(res);

    window.location.href = "/accounts";
  })

  .catch((err) => {
    console.log(err);
  });

```

When you click on submit the **Metamask** will prompt you to approve the transaction with the cost of **2 ETH**, on approval your new account will be **created**. On, successful approval according to the logic of the function the page will redirect to **"/accounts"**.

----

This is an example of how to access any function from the backend passing the values and using the send method, if you just want to display values which we will see in the **DisplayAccounts.js** you just need to use the call method of web3 and spend **no ether**. 

But, always remember if you want to perform a function that updates the existing contract you need to spend some amount of ether and send it from your **Metamask** connected account, the ether is sent to the contract which will, in turn, be sent to the miner accounts. 

{% youtube VMMcbFx7TPk %}

Navigate to your **contracts** folder and open **SimpleStorage.sol** file.

```js

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

// import "github.com/Arachnid/solidity-stringutils/strings.sol";
contract Banking {
    //  using strings for *;

    uint256 public serialNumber = 0;
    uint256 public transacNum = 0;
    uint256 public bankBalance = 0;


    //Function to create account , the 2 ETH balance will be taken from your ethereum account and deposited to the banking contract
    function createAccount(
        address payable _creator,
        string memory _name,
        string memory _location
    ) public payable {
        if (_creator.balance >= 3) {
            serialNumber++;
            accounts[serialNumber] = Account(
                serialNumber,
                block.timestamp,
                _name,
                _location,
                _creator,
                2,
                true
            );
            bankBalance += 2;
            transacNum++;
            transactions[transacNum] = Transaction(
                transacNum,
                2,
                2,
                block.timestamp,
                "NewAccount",
                serialNumber
            );
            emit TransactionCompleted(
                2,
                transacNum,
                serialNumber,
                "NewAccount"
            );
        } else {
            revert("Insufficient Funds");
            // revert InsufficientFunds(serialNumber,2,_creator.balance-1,'NewAccount');
        }
    }
}

```


Now, in the **src** folder, we further have the folder structure as: 

```js
  ->components

  ->contracts

  ->App.css

  ->App.js

  ->getWeb3.js

  ->index.js

  ->Routing.js

  ->serviceWorker.js
```


Once you understand the purpose of each component you will be able to navigate easily through the code, and trust me when I say organizing your code into folders is much cleaner and accessible in the future.

The components folder contains various sub-folders for each of our components in our application, here in this application we used the **components**.

---

**->AccountDetials** (the component that gets all the account details of the current account serial number)

**->DisplayAccounts** (displays all the registered accounts connected to the particular Metamask account)

**->DisplayTransactions** (displays all the transactions that occurred in the particular account)

**->LoanTransaction** (a temporarily working function that resembles loan transactions)

**->MainSection** (the main landing page when one visits the application)

**->Navbar** (used to navigate to various components)

**->TransferMoney** (the component to transfer virtual amount)

---


By looking at the names of the components you might get a feel of the job they perform, you can edit the names of these components as you wish and once you edit them they will get edited in the files they were imported into.

The contracts folder contains the **JSON file** for the Banking contract we had deployed and we will be using and accessing this very **JSON file** to access our backend, for you full-stack developers out there you can imagine this as an **API** that can be used in your frontend application using **asynchronous** fetching.

The **App.js** contains various imports from all the components of the application and **App.css** defines the global styles for every component present in the application since all the components will be imported in **App.js**

The **getWeb3.js** is a boilerplate template generated for us by Truffle when we run the command truffle unbox react which contains a promise-based function to load **Web3**.

The **index.js** is the file where the **App.js** is finally imported and rendered onto the frontend HTML file.

The **Routing.js** is an important file that contains the various routes present in the whole application it is imported from **react-router-dom** which can be installed by running the command:



```js
npm install react-router-dom
```


Lastly, **serviceWorker.js** is not of much use for us as it is just a part of the boilerplate code that appears with React.

That was the folder structure! Now let us discuss some of the basic React hooks syntax that we have used in our application for React beginners:

Throughout this application, we have used only three React hooks and by three, I mean exactly three not more, not less all the work can be done using these three hooks. These are **useState**, **useEffect**, and **useParams**.

So, let us just get to know briefly about each of these and a little bit about the project syntax

An example for **useParams** is where we have imported the Transactions component to our **Routing.js** file and in the path URL, we have specified the parameter **id**.

In the Transactions component, we can use this id parameter to perform actions that are specific to the account with that **id**, we can access this id parameter in another component from the URL using the **useParams** hook

In the Transactions component, we have accessed the **id** parameter and assigned it to a variable in the **Transactions component**.



```js
const{id} =useParams(id);
```



In the bracket of the **useParams** hook, we refer to the exact parameter variable we used in the **URL**.

I hope that helps you understand the **useParams** hook, for more reference visit :

Let us briefly explore the **Routing.js** file  :

In the **Routing.js** file we import Router and Route from **'react-router-dom'** and the basic syntax of the whole Routing component is similar for every Route. 



```js
import { BrowserRouter as Router, Route } from "react-router-dom";

import ComponentName1 from "<path-to-the-component>";

import ComponentName2 from "<path-to-the-component>";

<Router>
  <Route exact path="<specify-path1-here>">
    <ComponentName1 />
  </Route>

  <Route exact path="<specify-path2-here>">
    <ComponentName2 />
  </Route>
</Router>;
```




Now, that was all about the first **useEffect** hook which will be present in all functional components like **AccountDetails**, **DisplayAccounts** , **LoanTransaction**, **TransferMoney** and every other component other than **Navbar** .

Let's talk about the second **useEffect** hook which you will be using in some or almost all of the components to extract the functionality from the contract because only the creation of the contract is not enough we need to access the functionality of the contract to perform various operations for us, in the first component we are creating the **CreateAccount.js** component we actually **don't** require any **additional** data, but we just use the second hook to console.log the contract details, and in this hook, we only run the function when **web3**, contract and account are not undefined as we had **initialized** them as **undefined**, the dependency array also has web3, account, contract in it so that **useEffect** runs until all of these variables change from undefined to a definitive value, this is done for easy coding purposes to view the various methods present in the contract (We'll explain what are these various methods).

So, let's continue building the **createAccount.js** component, for this, we require a basic HTML form 

**EXAMPLE :**

```js
 const [name, setName] = useState("")

    ​ < input value = {
        name
    }
onChange = {
    (e) => setName(e.target.value)
}
placeholder = "Name"
type = "text" / >

```

In the above example we initialized **name** as a blank state variable and then when the form input value is changed we pass the **onChange** function, where the state of the name variable is updated to the **current target value**, this name can be further used any place we want, overall throughout the application we use this, so when I refer to making a form input with a value equal to the value of the variable **"x"** what I actually will mean is the above syntax.


So, now if you recall in the **Solidity contract** the function to create a new account takes 3 inputs, and among those 3 -one is the creator address which is the account connected to **Metamask** which we already stored in the account state variable, the other 2 variables are the **name** and **location** inputs which we will get from the form which we are creating. 

After creating the form with 2 input fields we need to create a Submit button and we need to pass a function on click of this button, now the syntax of this function will also be similar in every component since it is the first component let us give you the format.

**EXAMPLE :** 

We defined the **handleSubmit** function inside our **CreateAccount.js** component but this should be above the rendering of the JSX 


**ES7 arrow function syntax is being used here throughout the project, you may use it or may proceed with the normal function syntax**.

```js

//Function to handle the submit operation of the form

const handleSubmit = async (e) => {

        //prevents the default action that occurs when someone submits a form 

        e.preventDefault()

        //...rest of the function code ...//

    }

    <
    button type = "submit"
onClick = {
    handleSubmit
} > SUBMIT < button / >

```


This function is **asynchronous** because we need to communicate with the contract and send a request to it and wait for its response, and hence the syntax is similar everywhere using .then and .catch to resolve the promises, more than one **.then** can also be changed as per the user requirement.       

Now in our **createAccount.js** file, the **handleSubmit** function should contain the code to access the function to create new accounts from the backend, now how this is done? 

Well, firstly we have already created a new contract, every contract is an object which further has an item called methods, now what does this methods item contain? 

It contains every public variable and function defined in the solidity contract. That's it, you can refer to the contract object in the console.log, you will find the methods item in it.

For this component we need to access the **createAccount** method, now there are 2 ways to access a function using web3, they are call and send, the major differences in these two are you use call only when you want to view data and not modify anything and it does not cost any ether to perform this transaction but if you use the send method it costs some amount of gas fees and it modifies data, why does it cost ether though? 

Well, that is an interesting question though but as you already know from the Basics module that you need to send ether for the function to be executed or written on a new block and the miners of this block need to be rewarded somehow since they are securing the whole system by solving complex algorithms which creates new blocks for storing our executed function data, hence this is the amount deducted from our account when we use the send method, which is rewarded to the miners.

For, the **createAccount.js** we are creating a new account, that is modifying data so we use the send option, and the syntax of a send option is such that it also accepts another object which contains details like the from address, to address, and the value being sent.

In, our banking application we deduct **2 ETH** from the **Metamask** connected account on the creation of every new account as a starting balance to the virtual account and increment the balance of the virtual account from 0 to 2 (the increment of balance is handled on the backend).

```js

await contract.methods
  .createAccount(account, name, location)
  .send({ from: account, value: web3.utils.toWei(2, "ether") })

  .then((res) => {
    console.log(res);

    window.location.href = "/accounts";
  })

  .catch((err) => {
    console.log(err);
  });

```

When you click on **SUBMIT**, Metamask will prompt you to approve the transaction with the cost of 2 ETH, on approval your new account will be created. On, successful approval according to the logic of the function the page will redirect to **"/accounts"**.

This is an example of how to access any function from the backend passing the values and using the send method, if you just want to display values which we will see in the **DisplayAccounts.js** in the next module you just need to use the call option and spend no ether. But, always remember if you want to perform a function you need to spend some amount of ether and send it from your **Metamask** connected account, the ether is sent to the contract which will, in turn, be sent to the miner accounts. 


## Part 2 : Displaying Accounts, Account Details and Adding Balance

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7urb4d12dcsuzmniqzor.png)

Now let us start coding the solidity component (Just navigate to **SimpleStorage.sol** file and paste this inside **contract Banking {}** ).

```js
    //Defining a struct to store the account details
    struct Account {
        uint256 serial;
        uint256 createdAt;
        string name;
        string location;
        address creator;
        //   bytes32 accountName;
        uint256 balance;
        bool doesExist;
    }

    constructor() public {
        accounts[0] = Account(
            0,
            block.timestamp,
            "Ethereal",
            "NIT Durgapur",
            address(this),
            0,
            true
        );



    //Function to get the msg.sender's ETH balance
    function getSenderBalance(address payable _account)
        external
        view
        returns (uint256)
    {
        return _account.balance;
    }

    //Function to get the contract's existing balance
    function getContractBalance() external view returns (uint256) { 
        return address(this).balance;
    }

    //Function to get the owner
    function getOwner() public view returns (address) {
        return msg.sender;
    }


    //Function to add balance to your existing acccount ,the balance will be taken from your ethereum account
    function addBalance(
        uint256 _serial,
        uint256 _amount,
        address payable _creator
    ) public payable {
        if (_creator.balance >= _amount / 1000000000000000000 + 1) {
            accounts[_serial].balance += _amount / 1000000000000000000;
            bankBalance += _amount / 1000000000000000000;
            transacNum++;

            transactions[transacNum] = Transaction(
                transacNum,
                accounts[_serial].balance,
                _amount / 1000000000000000000,
                block.timestamp,
                "AddingBalance",
                _serial
            );

            emit TransactionCompleted(
                _amount / 1000000000000000000,
                transacNum,
                serialNumber,
                "AddingBalance"
            );
        } else {
            revert("Insufficient Funds");
            // revert InsufficientFunds(_serial,_amount/1000000000000000000,_creator.balance-1,'AddingBalance');
        }
    }

```

Now, let us move on to the Front-end part.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/28i92pitlvqmcfrnm7p9.png)

The logic for this is simple, as you might have remembered we have an accounts mapping in the backend and we can access them using the **serialNumber** key which is the normal index of the account. Here we need to use the call option and call the accounts method (even mappings are part of the methods object) one by one and push it into a state variable of **bankingAccounts** if and only if the creator of the account is the same as that of the currently connected Metamask account(important check -verification condition to know that the person who created the account is the only person who can access it and perform operations in it)


The basic layout of this component is no different from the other components, but the **second** useEffect hook here has actual use since you need to call the accounts mapping (from the contract methods), and you need to call this method **serialNumber** the number of times(serialNumber is also a method from the contract methods) and check for only those accounts whose _creator address is same as that of the Metamask connected account.


In the second **useEffect** hook we need to do two things, we need to get the value of **serialNumber**, and then we need to get the various accounts connected to the Metamask address and push it to the **bankingAccounts** state array.


```js
var serial =await contract.methods.serialNumber().call()       [even public variables from the backend need to be called ]

```

Now we need to run a for loop from 1 to less than or equal to **serialNumber** and call the accounts methods with the key as the value of the iterator, the account object is pushed to the **bankingAccounts** array after it passes the check that the creator address is equal to the Metamask connected address.

```js
for (int i = 1; i <= serial; i++) {
    await contract.methods.accounts(i).call()



        //ES7 promise resolving syntax using .then and .catch 

        .then(() => {

            if (res.creator == account) {

                setBankingAccounts(bankingAccounts.push({
                    name: res.name, ...so on...
                }))

            }

        })

        .catch((err) => {

            console.log(err)
        })

}

```

The above snippet is an example where you update the state of 
 **bankingAccounts** as you are pushing each **bankingAccount** connected the that particular Metamask address.

Finally, **setLoading(false)** after the whole for loop is run.

Now you need to use one of the famous array methods mappings in the frontend to print the contents of the **bankingAccounts** array, to give you an idea of the CSS layout of this page it will only contain various account bars with the name and serial number, which after clicking on them will redirect you to the account details page of that particular account where you can find the complete account details and various operations to perform on the account.

Before printing all the accounts check for if loading is false using the ternary operator and then map the **bankingAccounts**, if the loading is still true print nothing, now you need to make these bars where you are printing clickable and they should redirect you to the specific page for that account with the parameter as **serialNumber** ( to "/accounts/:id") and here the usage of **useParams** begin as we have mentioned in the third module. Also, react throws you an error in the console that every child element must contain a key which is a unique identifier value so in this case, also you can set the key={account. serial}

**The location is changed using the window. location method**.


```js
!loading ? bankingAccounts.map((account) => {

            <div key = {
                account.serial
            }
            onClick = {
                () => {
                    window.location.href = accounts / $ {
                        serialNumber
                    }
                } >

                {account.name}

                {account.serialNumber}

                </ div >

            }): null
```


Now that was displaying all the accounts, we need to also keep updating the router and adding all the new routes we are creating to the router for example until now **"/"** route has been occupied by **createAccounts** component, and the **"/accounts"** route is occupied by `DisplayAccounts.js`, now we add the third route **"/accounts/:id"** for the `AccountDetails.js` 


Let us begin coding the **AccountDetails** component!

As usual, the two **useEffect** hooks are common like in every component.

The second **useEffect** hook, like the previous component, **DisplayAccounts** is not empty, in it the specific account pertaining to that page is called, using the id parameter from the URL, and the details are stored in a state variable, specifically, balance item of the **bankAccount** is stored in another state variable so that it can easily be updated every time the balance changes, for example when we add more balance or withdraw the balance.


```js
  const[bankAccount,setBankAccount]=useState("")

  const[balance,setBalance]=useState("")

  const{id} =useParams(id)

  const [loading,setLoading]=useState(true)

```

The function in the second useEffect hook :

```js
 await contract.methods
  .accounts(id)
  .call()

  .then((res) => {
    console.log(res);

    setBankingAccount(res);

    setBalance(res.balance);
  })

  .then(() => {
    setLoading(false);
  })

  .catch((err) => {
    console.log(err);
  });

```


Now we have the data stored in our state variables we just display it somewhere on our application. 

To, give a brief idea of the layout of the page let us divide the page into various columns, one in the extreme left to print the account details, there are various other grid boxes for each functionality that contain a simple form, for example, there is an additional balance grid box, a withdraw balance grid box, a transfer amount grid box and a box for transferring amount from one account to other, later we can add more grid boxes which contains buttons that redirect to pages for displaying transaction(last extras section) and the other one for performing loan transactions.


Now, let us move on to the second part of this article, and create a function in the backend to add virtual balance to our bank account.

We create a public payable **addBalance** function which takes inputs as the **serial** , **amount** , and the **creator address** .


**Why** these 3 inputs?

1. Serial number is required to increase the virtual balance of that particular virtual account. 

2. The amount is the amount to be passed that is **to be added**.

3. You need the creator address that is connected to **Metamask** to transfer actual ether from your **Ganache** account.



We need to increase the virtual balance by accessing the balance item of the particular account from the **serialNumber** and we also need to increase the **bankBalance** of the whole application present at the **0th index** of the **accounts mapping**.

We need to also add a check to only update the virtual balance when the **Metamask** connected **Ganache** account balance is greater than the amount entered.


**Add balance code snippet**:

```js
if(creator.balance>amount)

{

account[serialNumber].balance+=amount;

account[0].balance+=amount;

}

```


Now after displaying the account details, we start coding the add balance functionality grid box on the frontend, it should contain a form input with the state variable **balanceAdded** as we have specified in previous examples, and also a submit button which **onClick** should fire an **addBalance** function which is similar to the syntax of our previous functions and should take the 3 input values.

We use the send method here and the **from address** is from the Metamask account and the value is the balance to be added which should also be passed in the object. We need to pass this value in the send method since that amount of ether should be transferred from our **Ganache** account to the contract, if we don't specify the amount only a minimal amount of **ether** will be costed that will be the **gas amount** to perform the function from the backend.


**Adding Balance: Ether from Ganache -> Contract Address**

Virtual Balance of the account and Contract (Bank) are both increased since actual Ether flows from the Contract.

We have to also again call the accounts method with the key serial number, and then update the balance variable to instantly print the new balance in the account details grid section.

```js

const addBalance = async (e) => {
  e.preventDefault();

  `The addBalance is the state variable which we get from the addBalance form and the account is the Metamask connected account`;

  await contract.methods
    .addBalance(id, addBalance, account)
    .send({ from: account, value: addBalance })

    .then((res) => {
      console.log(res);
    })

    .then(async () => {
      await contract.methods
        .accounts(id)
        .call()

        .then((res) => {
          setBalance(res.balance);
        })

        .catch((err) => {
          console.log(err);
        });
    })

    .catch((err) => {
      console.log(err);
    });
};

```




{% youtube Y1yVd30Naac %}



We have completed the first 2 functionalities of our virtual bank, namely Creating a new account and Updating the Balance for the account in this article, in the 2nd part of this article-series we will be adding features like: **Withdrawing Balance**, **Transfering Amount** to other virtual accounts on the Bank and **Displaying Transaction history** of an account, to our virtual bank.


----


This is a 2nd Part of this article in which we will be adding features like : **Withdrawing Balance, Transfer Amount to other virtual accounts on the Bank and Displaying Transaction history** to our Project.

{% link https://dev.to/nitdgplug/ethereal-a-decentralized-virtual-banking-system-part-ii-3ppf %}

---

**You can find all the Resources required for this Project by clicking [here](https://github.com/shashank725/ETHEREAL/tree/main/resources).**

**Project Github repository :**
{% github https://github.com/deucaleon18/ETHEREAL %}

**Project collaborators :**

{% user deucaleon18 %}

{% user shashank725 %}

{% user ajp %}

<br>

**Connect with us :**
<a href="https://nitdgplug.org/"><img src="https://img.shields.io/badge/GLUG website-FFFC00?style=for-the-badge&logo=U+1F427&logoColor=white"></a>

<a href="https://www.linkedin.com/company/lugnitdgp/mycompany/"><img src="https://img.shields.io/badge/LinkedIn-0077B5?style=for-the-badge&logo=linkedin&logoColor=white" alt="linkedin"/></a>

<a href="https://www.instagram.com/nitdgplug/"><img src="https://img.shields.io/badge/Instagram-E4405F?style=for-the-badge&logo=instagram&logoColor=white"></a>

<a href="https://www.facebook.com/nitdgplug"><img src="https://img.shields.io/badge/Facebook-1877F2?style=for-the-badge&logo=facebook&logoColor=white"></a>

---

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vqsn2bupxtk6nan73cxo.JPG)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8sys3jr5g3or6enwidup.gif)