The popularity of blockchain technology continues to increase over time, especially with the emergence of Web3, which promises decentralization and transparency. For web developers, JavaScript has become one of the programming languages used to interact with blockchain. This article will discuss in detail how JavaScript can interact with blockchain through Web3, and provide a simple implementation example using the ethers.js library. Before that, we will discuss the definition of Web3 and the reasons why JavaScript is the primary choice for implementing Web3.
What is Web3?
Web3, often referred to as the “decentralized internet,” is a vision for the future of the internet built on blockchain technology. Blockchains such as Ethereum, Binance Smart Chain, or Polygon form the foundation of Web3. This concept was first popularized by Gavin Wood, one of the co-founders of Ethereum, in 2014. Web3 promises an internet that gives users full control over their data, identity, and digital assets.
Unlike Web 2.0, where large platforms like Google, Facebook, and Amazon dominate and control user data, Web3 embraces the principle of decentralization.
Why is JavaScript the Top Choice for Web3 Implementation?
JavaScript has become the primary programming language for developing decentralized applications (DApps). This is not a coincidence, but rather the result of various strategic and technical factors that make it the top choice for Web3 developers. Here are the reasons:
- JavaScript Ecosystem
JavaScript has been the standard language in web development for more than two decades. When Web3 arrived as an evolution of Web 2.0, developers didn't have to start from scratch. The mature JavaScript ecosystem, with millions of packages and libraries on npm, stable frameworks, and advanced tooling, provides a strong foundation for building Web3 applications.
- Direct Integration Between Browsers and Wallets
One of the reasons JavaScript truly excels is its ability to integrate directly with browser extensions like MetaMask. In Web3, users often interact with the blockchain through their wallets, and JavaScript allows provider “injection” through the window.ethereum
object. This means that dApps can request transaction approvals in real time without the need for an intermediary server, in line with the decentralization principle of Web3.
- Asynchronous Programming Model
Web3 development relies heavily on asynchronous processes such as communicating with the blockchain, waiting for transaction confirmations, and interacting with smart contracts. JavaScript, with its event-driven model and promise-based programming, is the right choice for handling these processes.
- Event-Driven Architecture
Blockchain is an event-driven system, which is a mechanism where the program flow runs based on certain events. In the context of blockchain, smart contracts can trigger events, each transaction generates a log, and state changes must be monitored in real-time. Due to the event-driven nature of JavaScript with the use of callbacks and asynchronous patterns, this language is very suitable for this paradigm.
Basic Concepts of Blockchain
Before diving deeper, let's understand the basic concepts of blockchain:
- Blockchain: A decentralized, secure, and immutable chain of data blocks. Each block contains transactions that are validated by network nodes.
- Smart Contracts: Program code that runs automatically on the blockchain, such as smart contracts on Ethereum written in Solidity.
- Wallet: A tool for storing crypto assets and interacting with the blockchain, such as the MetaMask wallet that supports JavaScript injection.
- Node Provider: Services such as Infura or Alchemy that provide APIs to connect to the blockchain without running your own node.
Preparation
Before we begin implementation, there are several tools we need to prepare:
- VS Code
- Chrome Browser
- Browser with Metamask Extension Installed
- JavaScript
Create Scaffolding Project
First, we need to create a scaffolding project with the npm create
command as shown below.
npm create vite@latest js-web3-dapp -- --template vanilla
Install ethers.js
Enter the js-web3-app
folder that we created, then paste the command below to install the library.
npm install ethers
Implementation
Code in the index.html
file.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Interact Web3 with Javascript</title>
</head>
<body>
<h1>Simple Web3 App</h1>
<button id="connectButton">Connect MetaMask</button>
<button id="checkBalanceButton" disabled>Check Balance</button>
<p id="walletAddress"></p>
<p id="balance"></p>
<script type="module" src="/src/main.js"></script>
</body>
</html>
After that, open the main.js
file and paste the code below.
import { ethers } from 'ethers';
let walletState = { provider: null, signer: null, address: null };
async function connectWallet() {
if (window.ethereum) {
try {
const provider = new ethers.BrowserProvider(window.ethereum);
await provider.send("eth_requestAccounts", []);
const signer = await provider.getSigner();
const address = await signer.getAddress();
console.log("Connected wallet:", address);
document.getElementById("walletAddress").innerText = `Connected Wallet Address: ${address}`;
document.getElementById("checkBalanceButton").disabled = false;
walletState = { provider, signer, address };
return walletState;
} catch (error) {
console.error("Error connecting wallet:", error);
document.getElementById("balance").innerText = `Error: ${error.message}`;
}
} else {
console.error("MetaMask not installed");
document.getElementById("balance").innerText = "Error: Please install MetaMask";
}
return {};
}
async function checkBalance(provider, address) {
try {
const balance = await provider.getBalance(address);
const balanceInEth = ethers.formatEther(balance);
document.getElementById("balance").innerText = `Balance: ${balanceInEth} ETH`;
} catch (error) {
console.error("Error checking balance:", error);
document.getElementById("balance").innerText = `Error: ${error.message}`;
document.getElementById("balance").className = "error";
}
}
document.getElementById("connectButton").addEventListener("click", async () => {
const { signer } = await connectWallet() || {};
if (signer) {
const address = await signer.getAddress();
document.getElementById("walletAddress").innerText = `Connected Wallet Address: ${address}`;
}
});
document.getElementById("checkBalanceButton").addEventListener("click", async () => {
if (walletState.provider && walletState.address) {
await checkBalance(walletState.provider, walletState.address);
}
});
Testing
Open a new terminal, then type the command below to run the local server.
npm run dev
After that, open your browser with the provided host http://localhost:5173/
.
Click the “Connect MetaMask” button, then a pop-up from the MetaMask wallet will appear. Click the connect button on the extension pop-up.
NOTE: If you have not previously created a MetaMask account, you will be directed to create a MetaMask wallet first.
The MetaMask wallet has successfully connected to our application.
Next, let's click the “Check Balance” button, which will check the balance on the Ethereum blockchain.
Conclusion
JavaScript makes it easier for developers to interact with Blockchain technology. With the help of libraries such as ethers.js, reading data and executing transactions becomes much simpler. If you are interested, you can start with a simple setup and then practice directly on the testnet to understand the flow.
Thank you.