First Bite of Web3
Introduction
What is Web3? It means different things for different people. Even the Ethereum co-founder Gavin Wood, who coined this term in 2014 can’t give an exact definition of Web3. Loosely speaking, Web3 is an idea for a new iteration of the World Wide Web that incorporates decentralization based on blockchains.
Web1.0 refers roughly to the period from 1991 to 2004, where most websites were static webpages, and the vast majority of users were consumers, not producers, of content.
Since 2004, internet had evolved to the Web 2.0 phase, when the internet centered on the idea of “the web as platform“ , and user-created content dominated social-networking services, blogs, among other services. Web 2.0 is still considered the dominant form of internet as of today.
Specific visions for Web3 differ, but they revolve around the idea of decentralization, and often incorporate blockchain technologies, such as various cryptocurrencies and non-fungible tokens (NFTs). In recent years, decentralized finance (DeFi), and decentralized autonomous organizations (DAOs) are critical propellent of the Web3 movement.
Overview
This article is not trying to go down the rabbit hole and explain what exactly Web3 is. This article serves as an amuse-bouche for your formal Web3 dinner, and opens the Web3 world to you.
This article gives a step by step guide to develop a very simple Web3 application, which displays the Ethereum (ETH) balance of your ETH wallet, using?web3.js.
Step by Step Guide
Setup MetaMask
This application is using?MetaMask?to interact with the Ethereum blockchain. If you are new to MetaMask, follow?this page?and install MetaMask for Chrome.
After installing MetaMask and creating an account, sign in to your account.
Since this application is mainly for demo purpose, we are gonna use the Rinkeby Test Network for development, rather than Ethereum Mainnet (any operation on the Mainnet costs real money). After you sign into MetaMask, toggle the Networks menu on top of MetaMask and choose Rinkeby Test Network as shown in the following screenshot:
Deposit test ETH
After the ETH account is created in MetaMask, the default test ETH balance for the Rinkeby Test Network is 0. In order to show non zero balance in our application, we need to find a way to deposit some test ETH into our wallet.
We can use?Chainlink Faucets?to deposit test ETH into your ETH account in MetaMask as shown in the following screenshot:
In the Network section, choose Ethereum Rinkeby, and in the Testnet account address, paste the MetaMask account address that you just copy to clipboard as shown in the following screenshot:
So far you can only add 0.1 ETH to your test account per request. If you want to add more than 0.1 ETH to your test account, you could request multiple times.
By now, you already have a working ETH account with some test ETH on MetaMask. We are ready to move on to the fun part.
Install Homebrew and Node
Homebrew?is a free and open-source software package management system that simplifies the installation of software on Apple's operating system, macOS, as well as Linux. In this application, we are gonna use Homebrew to install the required libraries for our application. Assuming that you are using MacOS or Linux system for this application, paste the following in a macOS Terminal or Linux shell prompt:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
We are going to use?npm?to manage the packages required for our application. Installing?Node.js?comes with npm, which we later use to install the required packages. Run the following command:
brew install node
Create Web Application Skeleton
There are a couple of ways to create a web application skeleton. Some popular choices are?create-react-app?and?next.js. In this application, we are going to use next.js to create the skeleton of the web application. In your desired directory, run the following command:
npx create-next-app web3-demo --use-npm --example "https://github.com/vercel/next-learn/tree/master/basics/learn-starter"
Under the hood, this uses the tool called?create-next-app?, which boostraps a Next.js app for you. It uses?this template?through the?--example?flag.
Don’t be intimidated by the new?npx?command. You can think of npx as an alternative to npm. While they are performing the similar function, npx helps you to avoid npm dependencies and versioning. In most cases, npx is preferred over npm. Refer to this comparison if you want to?learn more.
Run the Development Server
You now have a new directory called?web3-demo. Let’s?cd?into it:
cd web3-demo
Then, run the following command:
npm run dev
This starts your Next.js app’s "development server" (more on this later) on port?3000.
Let’s check to see if it’s working. Open?https://localhost:3000?from your browser.
领英推荐
You should see something like this:
Integrate web3.js with Web Application
web3.js?is a collection of libraries that allow you to interact with a local or remote ethereum node using HTTP, IPC or WebSocket. In our application, we use web3.js to interact with the ETH account on MetaMask.
First you need to get web3.js into your project. This can be done using the following methods:
After that you need to create a web3 instance and set a provider.
Most Ethereum-supported browsers like MetaMask have an?EIP-1193?compliant provider available at?window.ethereum.
For web3.js, check?Web3.givenProvider.
If this property is?null?you should connect to a remote/local node.
// In Node.js use:
import Web3 from "web3";
const web3 = new Web3(Web3.givenProvider || "ws://localhost:8545");
That’s it! now you can use the?web3?object.
Main UI Components
Initial Landing Page
After the?Connect With MetaMask?button is clicked, if you have already logged in Metamask, the button text changes to?Show ETH Balance. You can clicked the?Show ETH Balance?button to see the balance of your test ETH as shown below:
If you haven’t signed in to MetaMask, After the?Connect With MetaMask?button is clicked, MetaMask will prompt you to log in, as shown below:
After you log in, the button text changes to?Show ETH Balance. You can clicked the?Show ETH Balance?button to see the balance of your test ETH.
Main Code Block
import Head from 'next/head'
import { useState } from 'react';
import Web3 from "web3";
export default function Home() {
const [metaMaskConnected, setMetaMaskConnected] = useState(false);
const [accounts, setAccounts] = useState([]);
const [showCurrentBalance, setShowCurrentBalance] = useState(false);
let web3 = new Web3();
const ethEnabled = async () => {
if (window.ethereum) {
await window.ethereum.send('eth_requestAccounts');
web3 = new Web3(window.ethereum);
return true;
}
return false;
};
const checkAccounts = async () => {
if (!await ethEnabled()) {
alert("Please install MetaMask to use this dApp!");
}
let accs = await web3.eth.getAccounts();
const newAccounts = await Promise.all(accs.map(async address => {
const balance = await web3.eth.getBalance(address);
return web3.utils.fromWei(balance, 'ether');
}));
setAccounts(newAccounts);
};
const showBalance = async () => {
await checkAccounts();
setShowCurrentBalance(true);
};
const onClickConnect = async () => {
await checkAccounts();
setMetaMaskConnected(true);
}
return (
<div className="container">
<Head>
<title>Create Next App</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<main>
<h1 className="title">
Show me the money!
</h1>
<button className="button" style={{display: metaMaskConnected ? "none" : "block"}} onClick={onClickConnect}>Connect With MetaMask</button>
<button className="button" style={{display: metaMaskConnected ? "block" : "none"}} onClick={showBalance}>Show ETH Balance</button>
<p style={{display: showCurrentBalance && accounts.length > 0 ? "block" : "none"}}>Current ETH Balance: {parseFloat(accounts[0]).toFixed(2)}</p>
<p style={{display: showCurrentBalance && accounts.length === 0 ? "block" : "none", color: "red"}}>Please connect your test account!</p>
</main>
</div>
)
}
Triggering the Log In UI of MetaMask
The critical piece of the code which triggers the Log In UI of MetaMask is?await window.ethereum.send('eth_requestAccounts'). If the MetaMask is already connected, this operation succeeds silently. Otherwise, the MetaMask Log In UI will pop up, asking for permission.
Collecting the active account and ETH balance
The piece of code which collects the active is?let accs = await web3.eth.getAccounts(). I originally thought the?getAccounts()?method will return either an empty array or an array of all the available accounts. But according to?MetaMask Doc, the?getAccounts()?method returns an array that is either empty or contains a single account address. The returned address, if any, is the address of the most recently used account that the caller is permitted to access. That seems like a security feature. Whether it will return all the available accounts in the future is TBD.
The following code records the ETH balance for the active account
const newAccounts = await Promise.all(accs.map(async address => {
const balance = await web3.eth.getBalance(address);
return web3.utils.fromWei(balance, 'ether');
}));
Toggling Between Different Accounts
It is possible that you have multiple accounts connected to your application as shown below:
You can click the “Connected“ button, and switch to the desired account. After that, you can click the?Show ETH Balance?button again to see the ETH balance of the new active account.
Conclusion
In this article, we’ve demonstrated how to create a simple web application using Next.js, web3.js, and MetaMask. You have learned how to create a MetaMask wallet, how to deposit test ETH to your wallet, how to use web3.js to show the ETH balance.
I hope you learn something very interesting and fundamental about Web3. Obviously, this web application is just a tip of the Web3 iceberg, and there is so much more you can achieve in the Web3 world.
If you find this article helpful, please follow my Twitter?@harrywangw. Let’s rock the Web3 world together.
Resources