EVM Dapp Starter Kit
Tags: web3, dapp, tutorial
Published: 2022-11-16 10:02:48

- **What are we building**?
Using [hardhat](https://hardhat.org/), we will deploy a smart contract to the goerli testnet, this [contract](https://hardhat.org/tutorial/writing-and-compiling-contracts) creates a token and also is able to send these tokens to other address. For the frontend we will use [react](https://reactjs.org/), for the interaction with the smart contract we will use [Metamask](https://metamask.io/) and [web3-react](https://github.com/Uniswap/web3-react). Finally, for the analytics of our dapp we will be using [sumer](https://www.npmjs.com/package/sumer-sdk).

[Sumer](https://www.getsumer.com/) is building an all-in-one solution that helps dapp creators to understand and bring better usability to dapp users. We can already try the first version of [sumer](https://app.getsumer.com/) and its [SDK](https://www.npmjs.com/package/sumer-sdk)

<br>
- **What do we need**?:

1. [Node.js](https://nodejs.org/en/) and a code Editor.


### Dapp Overview:

Unlike a web application, a decentralized application or Dapp, has its backend running on a decentralized peer-to-peer network such as Ethereum. For dapps running in an EVM-based blockchain, the backend is smart contracts executed by the EVM. This means, that a dapp has the same properties as smart contracts and the blockchain network where it lives.
#### Dapp Architecture:
The architecture of dapp is still been defined and depends, like any application, on the services that the application should provide. However, there are some main components that a dapp should have:
![Dapp Architecture](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ly1n1kld4a7biqoy453o.png)


- **Frontend**: It enables the users to interact with the smart contracts through interactive graphical components such as buttons, and icons, among others. Like web applications, this user interface runs on any browser.
- **Wallet**: A wallet is a tool or software application that manages the account’s private key and addresses (public keys). Wallets don’t have custody of the account crypto assets. A wallet is only an application that enables the account owner to sign transactions, therefore, interact with the blockchain and the smart contracts living in the network.
- **Node or Node Provider**: Enables communication with the blockchain, i.e., reading data or sending transactions. A node will broadcast the transactions and miners will validate the new states that the transactions can produce. Everyone
can run a node. Nonetheless, because of the difficulty and costs that running a node could have, Dapps usually rely on a third-party service or Node provider. Every Ethereum client or Node provider implements a [JSON-RPC Specification](https://ethereum.github.io/execution-apis/api-documentation/) with a uniform set of methods.
- **The Blockchain Network**: is the base layer, where the EVM executes the dapp smart contracts and stores the new states in the blockchain.

**Let's build our dapp**
### 1.- Smart Contract Deployment / backend
To develop and deployment of our contract we will be using the [hardhat](https://hardhat.org/) development environment. Create a new folder and install hardhat:
```
mkdir my-dapp && cd my-dapp
mkdir backend && cd backend
npm init
npm install --save-dev hardhat
npm install --save-dev @nomicfoundation/hardhat-toolbox
```
Once hardhat is installed, we can create a new project with:
```
npx hardhat
```
and select: `Create an empty hardhat.config.js`

Our project structure should look like this:

![structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7vkhw6xmy2xayk9tl0q9.png)

Now let's create a folder `contracts` and inside of
it our smart contract: `Token.sol`

```
mkdir contracts && cd contracts
touch Token.sol
```
Paste the [token code](https://github.com/NomicFoundation/hardhat-boilerplate/blob/master/contracts/Token.sol) into the `Token.sol` file. The contract is full of comments that explains its functionality, kudos to hardhat team! If you wish, you can edit the `name` and `symbol` of the token.

![token info](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wr7iq5mr1u738ib3cte1.png)

We can now compile our Token contract using hardhat: 

```
npx hardhat compile
```
After compiling our contract we can deploy it to the goerli network. In order to comunicate with the blockhain we will be using the [alchemy](https://www.alchemy.com/) node provider. To sign the deploy transaction, we will need the [private key of our metamask](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-export-an-account-s-private-key#:~:text=On%20the%20account%20page%2C%20click,click%20%E2%80%9CConfirm%E2%80%9D%20to%20proceed.) wallet and some [goerli eth](https://goerlifaucet.com/).

Edit your `hardhat.config.js`:

```JS
require("@nomicfoundation/hardhat-toolbox");

// Go to https://www.alchemyapi.io, sign up, create
// a new App in its dashboard, and replace "KEY" with its key
const ALCHEMY_API_KEY = "KEY";

// Replace this private key with your Goerli account private key
// To export your private key from Metamask, open Metamask and
// go to Account Details > Export Private Key
// Beware: NEVER put real Ether into testing accounts
const GOERLI_PRIVATE_KEY = "YOUR GOERLI PRIVATE KEY";

module.exports = {
  solidity: "0.8.9",
  networks: {
    goerli: {
      url: `https://eth-goerli.alchemyapi.io/v2/${ALCHEMY_API_KEY}`,
      accounts: [GOERLI_PRIVATE_KEY]
    }
  }
};
```
_**In order to avoid exposing the api key or private key, we should use env variables, for instance [dotenv](https://www.npmjs.com/package/dotenv)**_

Now we need a script that deploys our contract. Let's create a folder `scripts`, and inside of it, a `deploy.js` file:

```JS
async function main() {
    const [deployer] = await ethers.getSigners();

    console.log("Deploying contracts with the account:", deployer.address);

    console.log("Account balance:", (await deployer.getBalance()).toString());

    const Token = await ethers.getContractFactory("Token");
    const token = await Token.deploy();

    console.log("Token address:", token.address);
}

main()
    .then(() => process.exit(0))
    .catch((error) => {
        console.error(error);
        process.exit(1);
    });
```
And now everything to deploy your contract to the goerli blockchain network should be set. If we run:

```
npx hardhat run scripts/deploy.js --network goerli
```
The following message should be displayed: 

```
Deploying contracts with the account: your wallet account
Account balance: your balance
Token address: the token contract address
```
Congratulations, you just deployed a smart contract to the goerli network!! If you copy the contract address and go to the [goerli etherscan](https://goerli.etherscan.io/), you will find your deployment there :D. Using the contract address you can also import the tokens to your metamask wallet:


![import token](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/drfa0evoxz4xyohti1ti.png)

![add_token](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zfoatl5oywm15lrjps7v.png)

### 2.- Frontend
In our project root directory create a new folder `frontend` using `create-react-app`, and inside the frontend folder install, ethers, web3-react, and the sumer-sdk.

```
npx create-react-app frontend
cd frontend
npm i ethers
npm i @web3-react/core @web3-react/injected-connector
npm i sumer-sdk
```
Our project structure should look like this:

![project_structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ru94epxel5zxxcl39bl9.png)

In `my-app/frontend/src/index.js` enable the use of web3-react and sumer-sdk:
Remember to get your key in the [sumer app](https://app.getsumer.com/)

```JS
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';

import { Web3ReactProvider } from "@web3-react/core";
import { Sumer } from "sumer-sdk";

// this is a temporary key, get yours in the sumer app 
const dappKey = '04a23d9f-1c7a-414e-b400-847658ef5cd6'

//configure web3-react
const getLibrary = (provider) => {
    const library = Sumer.init({ provider, dappKey })
    return library
};

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <Web3ReactProvider getLibrary={getLibrary}>
    <App />
  </Web3ReactProvider>
);
```
We also need our deployed contract address, and the  contract interface, generated in the compile process. For simplicity just copy `/backend/artifacts/contracts/Token.sol/Token.json` file into the `frontend/src/`

In our `frontend/src/App.js` we can start by connecting our wallet to the goerli testnet:

```JS
function ConnectMetamask() {
  const { active, account, chainId, activate, deactivate } = useWeb3React()
  if (!active) {
    return (
      <div >
        <button onClick={() => { activate(injected) }}>Connect Metamask</button>
      </div >
    )
  } else if (chainId === 5) {
    return (
      <div >User Address: {account}
        < button onClick={deactivate} > disconnect</button >
      </div >
    )
  } else {
    return (
      <div >
        {alert("please change to the göerli testnet")}
      </div >
    )
  }
}
```
We will also need a function that allows call the transfer function of our Token smart contract:

```JS
async function sendTokens(to, amount) {

    const contract = Sumer.createWrappedContract(
      CONTRACT_ADDR,
      Token.abi,
      provider.getSigner()
    );

  const tx = await contract.transfer(to, amount)
  await tx.wait()
}
```
The fully `App.js` code can be found [here](https://github.com/Wagmi-VS/my-dapp/blob/main/frontend/src/App.js)

Finally you can start your react app as usual: `npm 
 start`

![dapp](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/58n31vm0757fn2n2h8xw.png)

The whole code can be found [here](https://github.com/Wagmi-VS/my-dapp). Thanks for reading this, if you have any question, please reach us out. Happy hacking fren :D

<a href="http://getsumer.com">
    <img src="https://uploads-ssl.webflow.com/633ab0cd3a69e79d248f3b25/633abf29186753321feb30c4_sumer-logo-v1.svg" loading="lazy" width="192px" height="192px"/></a>