Libraries
So far we have looked at reading blockchain data directly from the blockchain by calling RPC nodes using HTTP requests. We've also seen how to decode responses. Much of this can be abstracted away.
Ethers.js
Ethers.js is a library which abstracts away many of the complexities associated with interacting with EVM blockchains.
Here we will run through the eth_call example in two different ways, this time using ethers.js.
First, we need to install ethers into our project.
Installation
Simply install ethers using node package manager (npm):
npm install ethersSetup
Create a new script named 'ethers_call.ts' and open it.
We begin by importing ethers into our script. It is easiest to import everything from ethers to begin with. This is done with the line:
import { ethers } from "ethers";From here, we need to connect to the RPC node (ethers still needs to know where to get the information we need from). This introduces the idea of a provider. A Provider is a read-only connection to the blockchain. Ethers also has another object, the Sigher, which uses an RPC node along with a private key to allow write access to the blockchain. We will cover this later.
We create a provider instance with the line:
const provider = new ethers.JsonRpcProvider("https://rpc.adiri.tel");This establishes the connection to the RPC node and gives us an object on which we can call ethers functions.
Simple use
A simple function to start is just getting the block number. If we write the script:
and run it, we should print the current block number to the console. Note it prints a decimal integer value, rather than the hexadecimal we got when calling the node using HTTP requests. Ethers handles the conversion automatically.
Using call()
Our eth_call example becomes slightly simpler too:
This, when run should give the response:
0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b54656c636f696e20415544000000000000000000000000000000000000000000 as before.
Directly calling functions
There is, however, an alternative approach to getting the name of the token, or calling any other read function on a given contract. This involves creating an ethers Contract instance, which requires a contract address, a provider and the contract Application Binary Interface (ABI). We have the first two, and the third is available here. The ABI provides ethers with important context relating to a contract's functionality and how to interact with it.
Handling the ABI
In your project's root folder, create a file named 'ABI.json' and copy and paste the ABI from the documentation link. The ABI is produced by the solidity compiler and is derived from the solidity smart contract code.
We can then import this information to our script using the built in fs (File System) and path modules:
In the above 3 lines we:
create the string representing the path to the ABI.json file
Read the data stored within the ABI.json file
convert the read data to JSON format for use with ethers.
Creating the Contract Object
We now have all the components required to create an ethers Contract object which we can do in the following way:
Here we have provided the contract address, ABI and provider to create a new instance of a Contract object which we save to the variable named contract. More information can be found in the relevant section of the documentation.
All that is left is for us to use the contract. We can do this easily by calling the function names as they appear on the smart contract. In our case, we know the token inherits from the ERC 20 token standard. It will therefore have a getter function named name() (this is the one we have been calling up to now). To get the name of the token we write:
Building the Script
Putting all of these elements together might give us something like:
Feel free to overwrite the previous code from the 'Using call()' section.
Running the Script
We run this with:
which compiles our typescript scripts to JavaScript, followed by:
Response
The script should return:
Note the string has been automatically converted from hexadecimal.
Reading Decimals
It is also very easy to call other functions on the contract - we just change the function name. For example, we can now easily query how many decimals this contract uses, by replacing:
with:
recompiling and rerunning the script gives:
Contract Name: 6n
Showing the contract uses 6 decimals. This is correct.
Conclusion
Hopefully this series of tutorials has demonstrated how to query a blockchain, and the advantages of using libraries to gather data rather than raw HTTP requests. This should serve as useful context as you continue to learn about Telcoin Network!
Last updated