Web3 Series Tutorial for Beginners – Level 7: Building an Ethereum DApp with Ethers.js

·

Creating decentralized applications (dApps) is one of the most exciting ways to engage with blockchain technology. In this hands-on guide, you'll learn how to build a fully functional Ethereum dApp from scratch using Ethers.js, Solidity, and HTML. By the end, you’ll have a working front-end interface that interacts directly with a smart contract deployed on the Ropsten testnet.

This tutorial is designed for beginners who’ve already grasped foundational Web3 concepts such as blockchain, wallets, and smart contracts. If you're new to these topics, consider reviewing earlier levels in this series before diving in.

We’ll walk through three core stages:

Let’s get started.


Prerequisites

Before coding, ensure your development environment is set up correctly:

  1. Install MetaMask
    Download and set up the MetaMask browser extension. If you're unfamiliar with it, focus on the 1:06–4:14 segment of this introductory video.
    Once installed, switch from Ethereum Mainnet to Ropsten Testnet and copy your public wallet address.
  2. Get Test ETH
    To deploy and interact with contracts on Ropsten, you’ll need test Ether. Use a faucet like https://faucet.egorfine.com/ to request funds.
  3. Set Up a Local Server
    Install Node.js from nodejs.org, then install lite-server globally:

    npm install -g lite-server

With tools ready, we can begin building.


Step 1: Create a Basic HTML Front-End

Start by setting up a clean project folder:

mkdir my-dapp
cd my-dapp

Open the folder in your code editor (e.g., VS Code), then create index.html.

Add the basic HTML structure:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>My First dApp</title>
  <style>
    body {
      text-align: center;
      font-family: Arial, Helvetica, sans-serif;
    }
    div {
      width: 20%;
      margin: 0 auto;
      display: flex;
      flex-direction: column;
    }
    button {
      width: 100%;
      margin: 10px 0 5px 0;
    }
  </style>
</head>
<body>
  <h1>This is my dApp!</h1>
  <p>Here we can set or get the mood:</p>
  <input type="text" id="mood" placeholder="Enter your mood" />
  <div>
    <button onclick="getMood()">Get Mood</button>
    <button onclick="setMood()">Set Mood</button>
  </div>
</body>
</html>

Save and launch the server:

lite-server

Visit http://127.0.0.1:3000 in your browser. You now have a functional UI—next, let’s give it blockchain capabilities.

👉 Discover how to securely connect your wallet to a dApp


Step 2: Write and Deploy a Solidity Smart Contract

We’ll use Remix IDE, a browser-based tool, to write and deploy our contract.

  1. Go to remix.ethereum.org
  2. Enable the Solidity Compiler and Deploy & Run Transactions plugins if not visible.
  3. Create a new file named mood.sol.

Paste the following code:

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

contract MoodDiary {
    string mood;

    function setMood(string memory _mood) public {
        mood = _mood;
    }

    function getMood() public view returns (string memory) {
        return mood;
    }
}

Compile and Deploy

After deployment, note:

👉 Learn how Ethers.js simplifies blockchain interaction


Step 3: Connect Front-End to Smart Contract Using Ethers.js

Now, integrate blockchain functionality into your HTML page.

Import Ethers.js

Inside index.html, just before the closing </body> tag, add:

<script src="https://cdn.ethers.io/lib/ethers-5.2.umd.min.js" type="module"></script>
<script type="module">
  // Your JavaScript code will go here
</script>

Initialize Contract Connection

Replace placeholders with your actual contract data:

const MoodContractAddress = "YOUR_CONTRACT_ADDRESS"; // Replace with real address
const MoodContractABI = [
  {
    "inputs": [],
    "name": "getMood",
    "outputs": [
      { "internalType": "string", "name": "", "type": "string" }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      { "internalType": "string", "name": "_mood", "type": "string" }
    ],
    "name": "setMood",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  }
];

let MoodContract;
let signer;

const provider = new ethers.providers.Web3Provider(window.ethereum, "ropsten");

provider.send("eth_requestAccounts", []).then(() => {
  provider.listAccounts().then((accounts) => {
    signer = provider.getSigner(accounts[0]);
    MoodContract = new ethers.Contract(MoodContractAddress, MoodContractABI, signer);
  });
});

Add Interaction Functions

Below the initialization, add:

async function getMood() {
  const mood = await MoodContract.getMood();
  console.log("Current mood:", mood);
  alert("Mood: " + mood);
}

async function setMood() {
  const moodInput = document.getElementById("mood").value;
  const tx = await MoodContract.setMood(moodInput);
  await tx.wait();
  console.log("Mood updated!");
  alert("Mood set to: " + moodInput);
}

Your buttons are already linked via onclick attributes—no further changes needed.


Test Your dApp

  1. Ensure lite-server is running.
  2. Open http://127.0.0.1:3000
  3. Click Set Mood, enter text, and confirm the transaction in MetaMask.
  4. Wait ~15 seconds (average block time), then click Get Mood to retrieve the value from the blockchain.
  5. Verify transactions on Ropsten Etherscan using your wallet or contract address.

Open browser DevTools (Ctrl+Shift+I) to view console logs during interaction.


Frequently Asked Questions

Q: What is Ethers.js used for in dApp development?
A: Ethers.js is a lightweight JavaScript library that enables front-end apps to interact with Ethereum nodes and smart contracts, handling tasks like wallet connection, transaction signing, and contract calls.

Q: Can I build a dApp without writing a smart contract?
A: Yes! You can interact with existing contracts on Ethereum. This tutorial shows contract creation, but many dApps integrate with established protocols like Uniswap or Aave.

Q: Why use the Ropsten testnet instead of mainnet?
A: Ropsten allows testing with free test ETH, reducing risk and cost during development. Always test thoroughly before deploying to mainnet.

Q: What is an ABI, and why do I need it?
A: The ABI (Application Binary Interface) defines how your front-end communicates with a smart contract—listing functions, parameters, and return types in JSON format.

Q: How do I verify my smart contract on Etherscan?
A: After deployment, go to your contract’s Etherscan page and use the “Verify and Publish” option, providing source code and compiler settings.

Q: Is MetaMask required for every dApp?
A: While not mandatory, MetaMask is the most popular wallet for user authentication and transaction signing in Ethereum dApps.


Final Thoughts

Congratulations—you’ve built a complete Ethereum dApp that reads from and writes to the blockchain! This foundational project demonstrates key Web3 concepts:

These skills form the backbone of modern decentralized application development.

Whether you’re aiming to create DeFi platforms, NFT marketplaces, or DAO tools, mastering this stack is essential.

👉 Explore advanced Web3 development tools and resources


Core Keywords: Ethereum dApp, Ethers.js, Solidity smart contract, Web3 development, blockchain tutorial, decentralized application, Ropsten testnet