One of the presiding JavaScript libraries for interacting with the Ethereum blockchain is ether.js
.
The ether.js
library, only 88 KB compressed in size, is remarkably smaller than the web3.js
library. Because of that, web apps load more quickly if you use the ether.js
API. This constantly improving library has already been popular among developers for its developer-friendly modules.
Today we will see how ether.js
interacts with the blockchain and the smart contract. We will not go for the theoretical explanation of ether.js
.
Instead, we will deal with some practical use cases of ether.js
.
Interacting with the Blockchain
Connecting to blockchain:
We need to connect to a node first to interact with the blockchain.
Today we will use Infura, a powerful suite of high-availability blockchain APIs and developer tools. If you still need to make an account in Infura, then just sign up.
After signing in, click the “create new key
” button to create a new project. Select the network as web3 API and enter the project name as you wish. A new page will open, and you need to move to the “get started with the web3 Ethereum
” option. Just copy the main net link from there.
Then move to the visual studio code. Make a new folder and install node modules and ether.js
.
npm init -y npm install –-save ethers
Create a new javascript file for writing our codes. I am naming it as “etherBlockchain.js
”.
Now import ether.js
inside the javascript file.
const { ethers } = require("ethers");
Now to read data from the blockchain, we need to fix the provider.
const provider = new ethers.providers.JsonRpcProvider( "https://mainnet.infura.io/v3/3148ece387d84a40b4a8c883b07c33c0" );
We have pasted the Infura URL as the parameter for JSON RPC provider. This will connect us with the Infura node.
Get the current block:
Using the Infura mainnet, we can get the current block number with the help of ether.js
provider.
const interactBlockchain = async () => { const currentBlock = await provider.getBlockNumber(); console.log("You are using the block: ", currentBlock); };
We have created an async await
function to identify the block number. getBlockNumber()
method of the provider will help us to get the block number. In the vscode terminal, run the script.
node etherBlockchain.js
If everything runs fine, you should get the block number on the screen. Now to verify if it is genuine, visit the etherscan.io
website. The current block number must be displayed under the Latest Blocks
section.
Get the Balance:
To get the balance, we will use the provider.getBalance()
method of ether.js
. You need to put the address of any Ethereum account to get the balance of that account.
const balance = await provider.getBalance( "0xF977814e90dA44bFA03b6295A0616a897441aceC" ); console.log(“Account Balance: ”, balance);
All the codes should be kept inside the async await
function.
When you run the script, you will get a BigNumber
object as a return. Ethereum runs many operations on numbers outside the range of safe values to use in javascript.
💡 A BigNumber
is an object which safely allows mathematical operations on numbers of any magnitude.
Reference: https://docs.ethers.org/v5/api/utils/bignumber/
You need to convert this big number object to a readable format to get the balance of the account.
We will use the formatEther
method of the utils library of the ether.js
to get the balance in ether.
const balanceInEther = ethers.utils.formatEther(balance); console.log("Account balance in ether:", balanceInEther);
Now, if you run the script, you should get the account balance in ether.
This utils library of the ether.js
is a vast one. You can do so many things with that.
Reference: https://docs.ethers.org/v5/api/utils/
Now to convert the balance in wei again, we will use this utils
library.
const balanceInWei = ethers.utils.parseEther(balanceInEther); console.log("Account balance in wei:", balanceInWei);
When you run the script, You will get the balance in wei.
In this way, you can run any query on the blockchain by using the methods of ether.js
. We need to see how we can interact with a smart contract using ether.js
.
Interacting with Smart Contracts
We have our simple smart contract ready for deployment on the Remix IDE.
I have made a simple Counter
contract that will increase the count by ten whenever you call the increment
function.
The getCount()
method will return the count whenever you call the getCount()
method. We will call those methods from the node terminal of vscode.
pragma solidity >= 0.5.0 < 0.9.0; contract Counter { uint count = 0; function setCount(uint _count) public { count=_count; } function increment() public { count = count + 10; } function getCount() public view returns (uint) { return count; } }
We need to deploy the smart contract in a blockchain.
We will use the Goerli testnet to deploy the contract, and the Metamask will be used to establish communication with the testnet.
We need some money on the goerli account to bear the Gas fee cost for the smart contract deployment. If you need to learn how to add the goerli test network on the Meatamask wallet and how to add some free goerli eth on the Metamask wallet, then watch some videos on youtube. It is very easy to add some free eth through the goerli faucet.
Now back to Remix IDE. After doing the compilation, you move to the “DEPLOY AND RUN TRANSACTIONS” section of the Remix IDE. Select the environment as “Injected Provider-Metamask”.
Now click on the deploy
button. Metamask will pop up and ask to confirm the transaction. You can even check the transaction on the etherscan if you want.
We need the smart contract address and ABI afterward to create an instance of the smart contract on the node terminal.
For this part, we need to use React as the frontend. This frontend will establish a connection with Metamask. Open the command prompt and type the following to initiate a react app in your directory.
👉 Recommended: Learn to Build Smart Contracts in React with web3.js: Here’s How!
npx create-react-app ether_smart_contract
A react app on localhost:3000
must be running on your browser. Now, move to the app.js
on vscode, clear the code, and import ether.js
first.
import { ethers } from "ethers";
We need to use useEffect()
hook of the react. Inside the useEffect
, create an async await
function to write the codes to call the smart contract.
Now again, call the provider; in this case, our provider would be Metamask.
const provider = new ethers.providers.Web3Provider(window.ethereum);
The test goerli network on our Metamask is using the Infura node. Hence, we don’t need to connect to the Infura network manually.
This is one of the privileges of using Metamask. With Metamask wallet, you can connect to different networks easily.
Difference between provider and signer:
We need to introduce a signer for our contract. What is the difference between the provider and the signer?
The provider is required whenever you are reading any data from blockchain or smart contract, but you are not changing the state of something on the smart contract; whenever you are changing the state of something on the smart contract, you need to use the signer.
Actually, when you write something on the smart contract, you are changing the state of something. Whenever you bring some change to the smart contract, you have to bear a cost for the transaction.
The signer will sign a transaction on your behalf to validate the transaction. Every time you click the confirm transaction button on the Metamask, a signer automatically signs a transaction on the backend and validates the transaction.
const signer = provider.getSigner();
Create two variables for the contract ABI and the contract address.
ContractAddress = “Input the contract address”; ContractABI = “Input the contract ABI”;
Now we can create an instance of the smart contract with the help of contractABI
and contractAddress
.
const contract = new ethers.Contract( contractAddress, contractABI, signer );
This ethers. The contract method requires the contract address, contract ABI, and the signer as a parameter to create an instance of the smart contract.
Calling the constant methods:
Now our contract instance is ready. Using the contract instance, we can call the readable methods from the smart contracts.
const count = await contract.getCount(); console.log(count);
We have called the getCount()
function of the smart contract, which returns a big number. We need to convert it to string. For that,
console.log("Current count is:", String(count));
Calling the non-constant methods:
Now we should get the count in a readable format. We can set the count as we desire by calling the setCount()
method from the smart contract.
await contract.setCount(20);
The count must be set as 20. You can call the getCount()
methods again to check the count.
Now, if we want to increment the count by ten, then we can call the increment()
function with the help of contract.current()
method.
const tx = await contract.connect(signer).increment(); await tx.wait();
As we change the blockchain state, we need to connect the signer to approve the transaction. We did it here.
The transaction will take some time to be mined on the blockchain. So, you have to wait a bit to see the count increase.
If you call the getCount()
method again after some time, I hope you will see the count has increased by 10.
So that are some ways you can connect to a blockchain and query data from it. You have also seen the way smart contract interacts with ether.js
. That’s all for today. Thanks for the reading.