Forem

Cover image for How to Build a dApp with React, Solidity, and MetaMask
Raji moshood
Raji moshood

Posted on

How to Build a dApp with React, Solidity, and MetaMask

Introduction

Decentralized applications (dApps) run on blockchain networks, enabling trustless, transparent, and censorship-resistant functionality. In this guide, we’ll build a dApp using React, Solidity, and MetaMask, integrating Web3.js and Ethers.js for blockchain interactions.

What You'll Learn:

✔ Writing smart contracts in Solidity
✔ Deploying contracts on Ethereum testnet
✔ Connecting a dApp to MetaMask using Web3.js & Ethers.js
✔ Executing blockchain transactions from React

  1. Setting Up the Development Environment

Prerequisites

Ensure you have the following installed:

Node.js (v16 or later)

MetaMask browser extension

Hardhat (Ethereum development environment)

Step 1: Initialize a Hardhat Project

mkdir my-dapp && cd my-dapp
npm init -y
npm install --save-dev hardhat
npx hardhat
Enter fullscreen mode Exit fullscreen mode

Select “Create a basic sample project” and install dependencies when prompted.

  1. Writing a Smart Contract in Solidity

Step 1: Create a Solidity Contract

Inside contracts/, create a file named MyContract.sol:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

contract MyContract {
    uint256 public counter;

    function increment() public {
        counter++;
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Compile the Contract

npx hardhat compile
Enter fullscreen mode Exit fullscreen mode

Step 3: Deploy the Contract

Modify scripts/deploy.js:

const hre = require("hardhat");

async function main() {
  const Contract = await hre.ethers.getContractFactory("MyContract");
  const contract = await Contract.deploy();
  await contract.deployed();
  console.log("Contract deployed to:", contract.address);
}

main().catch((error) => {
  console.error(error);
  process.exit(1);
});
Enter fullscreen mode Exit fullscreen mode

Run the deployment script:

npx hardhat run 
Enter fullscreen mode Exit fullscreen mode
scripts/deploy.js --network localhost
Enter fullscreen mode Exit fullscreen mode
  1. Connecting the dApp to MetaMask with Web3.js & Ethers.js

Step 1: Install Web3.js & Ethers.js

npm install web3 ethers
Enter fullscreen mode Exit fullscreen mode

Step 2: Connect React to MetaMask

In App.js, set up MetaMask connection:

import { useState } from "react";
import { ethers } from "ethers";

function App() {
  const [account, setAccount] = useState("");

  async function connectWallet() {
    if (window.ethereum) {
      const provider = new ethers.providers.Web3Provider(window.ethereum);
      const accounts = await provider.send("eth_requestAccounts", []);
      setAccount(accounts[0]);
    } else {
      alert("MetaMask not found");
    }
  }

  return (
    <div>
      <button onClick={connectWallet}>Connect Wallet</button>
      <p>Connected Account: {account}</p>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode
  1. Interacting with the Smart Contract

Step 1: Load the Contract in React

Create contractABI.js with ABI (after deployment, copy from artifacts/contracts/MyContract.json):

const contractABI = [
  {
    "inputs": [],
    "name": "increment",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "counter",
    "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}],
    "stateMutability": "view",
    "type": "function"
  }
];

export default contractABI;
Enter fullscreen mode Exit fullscreen mode

Step 2: Fetch Contract Data in React

Modify App.js:

import { useState, useEffect } from "react";
import { ethers } from "ethers";
import contractABI from "./contractABI";

const contractAddress = "YOUR_DEPLOYED_CONTRACT_ADDRESS";

function App() {
  const [account, setAccount] = useState("");
  const [contract, setContract] = useState(null);
  const [counter, setCounter] = useState(0);

  async function connectWallet() {
    if (window.ethereum) {
      const provider = new ethers.providers.Web3Provider(window.ethereum);
      const signer = provider.getSigner();
      const accounts = await provider.send("eth_requestAccounts", []);
      setAccount(accounts[0]);

      const contractInstance = new ethers.Contract(contractAddress, contractABI, signer);
      setContract(contractInstance);
      fetchCounter(contractInstance);
    } else {
      alert("MetaMask not found");
    }
  }

  async function fetchCounter(contractInstance) {
    const count = await contractInstance.counter();
    setCounter(count.toNumber());
  }

  async function incrementCounter() {
    if (contract) {
      const tx = await contract.increment();
      await tx.wait();
      fetchCounter(contract);
    }
  }

  useEffect(() => {
    if (contract) fetchCounter(contract);
  }, [contract]);

  return (
    <div>
      <button onClick={connectWallet}>Connect Wallet</button>
      <p>Connected Account: {account}</p>
      <p>Counter Value: {counter}</p>
      <button onClick={incrementCounter}>Increment Counter</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

export default App;

  1. Testing the dApp on a Testnet

Step 1: Get Testnet Funds

  1. Open MetaMask.

  2. Switch to Goerli or Sepolia Testnet.

  3. Get test ETH from a faucet (https://goerlifaucet.com).

Step 2: Deploy to Testnet

Modify hardhat.config.js:

module.exports = {
  solidity: "0.8.19",
  networks: {
    goerli: {
      url: "https://eth-goerli.alchemyapi.io/v2/YOUR_ALCHEMY_API_KEY",
      accounts: ["YOUR_PRIVATE_KEY"]
    }
  }
};
Enter fullscreen mode Exit fullscreen mode

Deploy:

npx hardhat run scripts/deploy.js --network goerli
Enter fullscreen mode Exit fullscreen mode
  1. Enhancing the dApp

✔ Use IPFS or Arweave for decentralized file storage.
✔ Add WalletConnect to support multiple wallets.
✔ Use Moralis API for indexing blockchain data.
✔ Deploy front-end on Vercel or Netlify for easy hosting.

Conclusion

In this guide, we built a React + Solidity dApp that connects to MetaMask, interacts with smart contracts, and runs transactions on Ethereum.

✔ Wrote and deployed a Solidity contract
✔ Connected React with MetaMask using Ethers.js
✔ Interacted with smart contracts from the front end

I am open to collaboration on projects and work. Let's transform ideas into digital reality.

Web3 #Ethereum #Solidity #React #MetaMask #dApps

Top comments (0)