How to Send an XRC20 Transaction on the XDC Network Using ethers.js

Use Ethers.js to send XRC20 tokens over the XDC network

🧭 Table of contents

📰 Overview

Ethers.js is a library written in Javascript which simplifies blockchain interactions.

What you will learn

In this tutorial, you will learn how to import ethers.js, transact an XRC20 token, and set gas prices appropriately.

What you will do

  • Import ethers.js

  • Transfer an XRC20 token

  • Verify Transaction

📰 About XRC20 Tokens

XRC20 is a set of rules to standardize assets on the XDC network. Every XRC20 Token must be able to execute the following methods:

  • totalSupply()

  • balanceOf(address account)

  • allowance(address owner, address spender)

  • transfer(address recipient, uint amount)

  • approve(address spender, uint amount)

  • transferFrom(address sender, address recipient, uint amount)

These are the minimum required methods that allow an asset on the XDC network to be called an XRC20 token. Also, a XRC20 token must be able to emit the following Events on the blockchain:

  • Approval(address indexed tokenOwner, address indexed spender, uint tokens)

  • Transfer(address indexed from, address indexed to, uint tokens)

Events are helpers that come in handy in the exhaustive labor of indexing state changes, and they are essential to off-chain applications to find relevant data on the blockchain. By mapping all Transfer events, for example, we can fetch all the historic data on token transfers more easily.

Last but not least, a few contract constants that are public that are also very important to have are:

  • name

  • symbol

  • decimals

Without these public constants, it would be impossible to label tokens on block explorers, for example. In this tutorial we will deploy a XRC20 token that have all the Methods, Events and Constants mentioned above.

🚀 Setting up the development environment

There are a few technical requirements before you start. Please install the following:

⚒ Starting a new NPM Project and Installing Dependencies

Start by setting up your folder. As we are creating a project called XRC20, you should create a new XRC20 folder by running on terminal.

mkdir XRC20 && cd XRC20

Initialize the new project in that folder:

npm init

Tip: to generate project without any questions you can use npm init -y

Install the necessary dependencies:

npm install ethers dotenv

💵 Transacting an XRC20 token contract on the XDC Network with ethers

Before sending actual transactions, we have to do some preparations.

💵 Add funds to wallet using Apothem Faucet

If you don't have an XDC address yet, you can create new wallet using XDCPay

💵 What is an XDC transaction

An XDC transaction is a set of instructions one account sends to another. Transactions can be used to transfer native XDC token or for interactions with smart contracts.

💵 Setting up env file

You can use .env.example as a template.

Your .env file should look like this:

XINFIN_NETWORK_URL=https://erpc.xinfin.network
XINFIN_PRIVATE_KEY=0xyourprivatekey
APOTHEM_NETWORK_URL=https://erpc.apothem.network
APOTHEM_PRIVATE_KEY=0xyourprivatekey
XRC20_TOKEN_ADDRESS=0xyourtokenaddress

Tip: never commit files containing your seed phrase or private key to a git

❕ Keep in mind that you need to replace xdc prefix in your token address with 0x. So token address xdcfc1b5137a6c8dffcf816857463afbb4672d462f3 will become 0xfc1b5137a6c8dffcf816857463afbb4672d462f3.

If you don't have any XRC20 tokens, you can follow one of those tutorials to create one:

💵 Using ethers to transact XRC20

Create a file named send_token.js in your project with following content:

require('dotenv').config()
const ethers = require('ethers')
const XRC20ABI = require('./XRC20.json')

const testnetProvider = new ethers.providers.JsonRpcProvider(process.env.APOTHEM_NETWORK_URL)
const wallet = new ethers.Wallet(process.env.APOTHEM_PRIVATE_KEY, testnetProvider)
const walletSigner = wallet.connect(testnetProvider)

// we are using our address as a recipient, but you can use any address you want
const recipient_address = wallet.address
const your_xrc20_token_address = process.env.XRC20_TOKEN_ADDRESS
const number_of_tokens = ethers.utils.parseUnits('10', 18)

async function main() {
  const contract = new ethers.Contract(
    your_xrc20_token_address,
    XRC20ABI,
    walletSigner
  )

  const receipt = await contract.transfer(recipient_address, number_of_tokens)

  console.log(receipt.hash)
}

main()

Now lets go through each line:

const XRC20ABI = require('./XRC20.json')

In order to interact with the contract, you need to provide an ABI or application binary interface. This is basically just list of functions and events which explains how to interact with smart contract. You can copy ABI from here XRC20 ABI

const testnetProvider = new ethers.providers.JsonRpcProvider(process.env.APOTHEM_NETWORK_URL)

You will create an rpc provider to be able to send and receive messages from blockchain.

const wallet = new ethers.Wallet(process.env.APOTHEM_PRIVATE_KEY, testnetProvider)
const walletSigner = wallet.connect(testnetProvider)

This is your wallet which is used to sign transactions. You must connect it to your rpc provider.

const recipient_address = wallet.address
const your_xrc20_token_address = process.env.XRC20_TOKEN_ADDRESS
const decimals = 18
const number_of_tokens = ethers.utils.parseUnits('10', decimals)

recipient_address is the recipient we want send tokens to, your_xrc20_token_address is XRC20 token we will transfer, and decimals is decimals value for your token and number_of_tokens is amount of tokens we will send.

const recipient_address = "0x585dd46bfa516cc4325d877c614321f22ec7ce5e"
const your_xrc20_token_address = process.env.XRC20_TOKEN_ADDRESS
const decimals = 18
const number_of_tokens = ethers.utils.parseUnits('10', decimals)

If you would like to send the tokens to a different recipient_address simply replacewallet.address with the XDC address you would like to send the tokens to, being sure to replace the "xdc" prefix with "0x".

const contract = new ethers.Contract(
  your_xrc20_token_address,
  XRC20ABI,
  walletSigner
)

We create a contract instance which we use to interact with our XRC20 contract on blockchain. First argument is token address, second is ABI, and the third is our wallet to sign transaction.

const receipt = await contract.transfer(recipient_address, number_of_tokens)
console.log(receipt.hash)

Now lets run it!

node send_token.js

Next, wait few seconds and you should see something like this:

0xabf5957a25f943dfb1b71c6d9fc041c7c419b6440af4661f8aab21fc185bd134

🔍 Verifying transaction via Apothem network explorer

After running our script, you should have received a transaction hash. You can use this hash to check transaction on a blockchain. To do this, go to https://explorer.apothem.network and paste your transaction hash in search field.


For more information about ether.js check out ethers.js github repo and ethers.js documentation website. For more information about the XDC Network, Please Visit XDC Network Documentation on GitBook. You can find resources used for this tutorial here example-xrc20-transfer.

Last updated