Bird
Raised Fist0
Blockchain / Solidityprogramming~30 mins

Web3.js vs ethers.js in Blockchain / Solidity - Hands-On Comparison

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Comparing Web3.js and ethers.js for Ethereum Interaction
📖 Scenario: You want to interact with the Ethereum blockchain to check the balance of an Ethereum address. Two popular JavaScript libraries for this are Web3.js and ethers.js. This project will help you understand how to set up and use both libraries to get the balance of the same Ethereum address.
🎯 Goal: Build a script using both Web3.js and ethers.js to fetch and display the balance of the Ethereum address 0x742d35Cc6634C0532925a3b844Bc454e4438f44e using each library.
📋 What You'll Learn
Use the exact Ethereum address 0x742d35Cc6634C0532925a3b844Bc454e4438f44e
Create a provider connected to the Ethereum mainnet using Infura
Use both Web3.js and ethers.js
Fetch the balance in wei and convert it to ether
Print the balances as strings with the labels 'Balance with Web3.js:' and 'Balance with ethers.js:'
💡 Why This Matters
🌍 Real World
Developers use Web3.js and ethers.js to build web applications that interact with Ethereum blockchain, such as wallets, decentralized apps, and analytics tools.
💼 Career
Understanding these libraries is essential for blockchain developers, smart contract engineers, and anyone working on Ethereum-based projects.
Progress0 / 4 steps
1
Setup Web3.js with Infura Provider
Create a variable called Web3 by requiring the web3 library. Then create a variable called web3 that connects to the Ethereum mainnet using the Infura URL https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID. Also, create a variable called address and set it to the string '0x742d35Cc6634C0532925a3b844Bc454e4438f44e'.
Blockchain / Solidity
Hint

Use require('web3') to import Web3.js. Then create a new Web3 instance with the Infura URL. Set the address exactly as given.

2
Setup ethers.js with Infura Provider
Create a variable called ethers by requiring the ethers library. Then create a variable called provider using new ethers.providers.JsonRpcProvider with the same Infura URL https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID.
Blockchain / Solidity
Hint

Use require('ethers') to import ethers.js. Then create a new JsonRpcProvider with the Infura URL.

3
Fetch Balance Using Both Libraries
Write an async function called getBalances. Inside it, use web3.eth.getBalance(address) to get the balance in wei and convert it to ether using web3.utils.fromWei. Also, use provider.getBalance(address) to get the balance with ethers.js and convert it to ether using ethers.utils.formatEther. Store the results in variables balanceWeb3 and balanceEthers respectively.
Blockchain / Solidity
Hint

Use await to get balances asynchronously. Convert wei to ether using the utilities from each library.

4
Print the Balances
Inside the getBalances function, print the balances with console.log using the exact format: Balance with Web3.js: {balanceWeb3} and Balance with ethers.js: {balanceEthers}. Then call the getBalances function.
Blockchain / Solidity
Hint

Use console.log with template strings to print the balances. Don't forget to call the getBalances function.

Practice

(1/5)
1. Which of the following is a key difference between Web3.js and ethers.js?
easy
A. ethers.js is a backend-only library, Web3.js is frontend-only.
B. Web3.js only works with Bitcoin, ethers.js only with Ethereum.
C. ethers.js cannot send transactions, Web3.js can.
D. Web3.js is larger and older, while ethers.js is lighter and simpler.

Solution

  1. Step 1: Understand library origins

    Web3.js is an older, larger library designed for Ethereum interaction.
  2. Step 2: Compare library features

    ethers.js is newer, designed to be lightweight and simpler to use.
  3. Final Answer:

    Web3.js is larger and older, while ethers.js is lighter and simpler. -> Option D
  4. Quick Check:

    Library size and age = A [OK]
Hint: Remember: Web3.js is big and old; ethers.js is small and new [OK]
Common Mistakes:
  • Thinking ethers.js only works on backend
  • Confusing blockchain support (Bitcoin vs Ethereum)
  • Believing ethers.js can't send transactions
2. Which of the following is the correct way to create a provider using ethers.js?
easy
A. const provider = new ethers.providers.JsonRpcProvider();
B. const provider = new Web3.providers.HttpProvider();
C. const provider = new ethers.Web3Provider();
D. const provider = new Web3.eth.JsonRpcProvider();

Solution

  1. Step 1: Recall ethers.js provider syntax

    ethers.js uses ethers.providers.JsonRpcProvider() to create a JSON RPC provider.
  2. Step 2: Identify correct syntax

    const provider = new ethers.providers.JsonRpcProvider(); matches the correct ethers.js syntax; others mix Web3.js or incorrect classes.
  3. Final Answer:

    const provider = new ethers.providers.JsonRpcProvider(); -> Option A
  4. Quick Check:

    ethers.js provider creation = D [OK]
Hint: ethers.js uses ethers.providers.JsonRpcProvider() [OK]
Common Mistakes:
  • Mixing Web3.js and ethers.js syntax
  • Using Web3 classes with ethers.js
  • Incorrect capitalization or namespaces
3. What will be the output of this ethers.js code snippet?
const ethers = require('ethers');
const provider = new ethers.providers.JsonRpcProvider();
(async () => {
  const blockNumber = await provider.getBlockNumber();
  console.log(blockNumber);
})();
medium
A. An error because getBlockNumber() is not a function.
B. Undefined because provider is not initialized.
C. The current Ethereum block number as a number.
D. A string 'blockNumber' printed to console.

Solution

  1. Step 1: Understand provider and method

    The JsonRpcProvider connects to Ethereum and getBlockNumber() returns the latest block number as a number.
  2. Step 2: Analyze async function output

    The code logs the block number to console, so output is a number representing current block.
  3. Final Answer:

    The current Ethereum block number as a number. -> Option C
  4. Quick Check:

    getBlockNumber() returns number [OK]
Hint: getBlockNumber() returns a number, not error or string [OK]
Common Mistakes:
  • Expecting a string instead of number
  • Thinking getBlockNumber() is missing
  • Assuming provider is uninitialized
4. Identify the error in this Web3.js code snippet:
const Web3 = require('web3');
const web3 = new Web3();
(async () => {
  const balance = await web3.eth.getBalance('0x123...');
  console.log(balance);
})();
medium
A. Missing provider URL when creating Web3 instance.
B. getBalance() is not an async function.
C. The address format is incorrect.
D. console.log cannot print balance.

Solution

  1. Step 1: Check Web3 instance creation

    Web3 requires a provider URL (like HTTP or WebSocket) when instantiated to connect to Ethereum.
  2. Step 2: Identify missing provider

    The code creates new Web3() without a provider, so calls like getBalance will fail.
  3. Final Answer:

    Missing provider URL when creating Web3 instance. -> Option A
  4. Quick Check:

    Web3 needs provider URL [OK]
Hint: Always pass provider URL to Web3 constructor [OK]
Common Mistakes:
  • Thinking getBalance is not async
  • Assuming address format is wrong
  • Believing console.log can't print balance
5. You want to send a transaction using ethers.js and wait for it to be mined. Which code snippet correctly does this?
hard
A. const tx = await provider.sendTransaction(txData); await tx.wait();
B. const tx = await signer.sendTransaction(txData); await tx.wait(); console.log('Mined:', tx.hash);
C. const tx = signer.sendTransaction(txData); console.log('Mined:', tx.hash);
D. const tx = await signer.send(txData); await tx.wait();

Solution

  1. Step 1: Identify correct method to send transaction

    In ethers.js, signer.sendTransaction() sends a transaction and returns a transaction response.
  2. Step 2: Wait for transaction mining

    Calling tx.wait() waits for the transaction to be mined before proceeding.
  3. Step 3: Confirm correct usage

    const tx = await signer.sendTransaction(txData; await tx.wait(); console.log('Mined:', tx.hash); correctly awaits sending, then waits for mining, then logs the hash.
  4. Final Answer:

    const tx = await signer.sendTransaction(txData); await tx.wait(); console.log('Mined:', tx.hash); -> Option B
  5. Quick Check:

    sendTransaction + wait() = C [OK]
Hint: Use sendTransaction() then wait() to confirm mining [OK]
Common Mistakes:
  • Not awaiting sendTransaction()
  • Using provider instead of signer to send
  • Calling non-existent send() method