🐹
ChainRPC
  • Welcome to Chain-RPC Docs
  • Getting started
  • Networks
    • Ethereum
      • Concepts
        • Transaction types
        • Filters and subscriptions
      • How to
        • Authenticate requests
        • Make requests
        • Make batch requests
        • Choose a network
        • Subscribe to events
        • Interact with ERC-20 tokens
        • Add a network add-on
        • Secure a project
          • API key
          • API key secret
          • JWTs
          • Rate limits
          • Allowlists
        • Avoid rate limiting
      • JSON-RPC methods
        • eth_accounts
        • eth_blockNumber
        • eth_call
        • eth_chainId
        • eth_coinbase
        • eth_estimateGas
        • eth_feeHistory
        • eth_getBalance
        • eth_gasPrice
        • eth_getBlockByHash
        • eth_getBlockByNumber
        • eth_getBlockTransactionCountByHash
        • eth_getBlockTransactionCountByNumber
        • eth_getCode
        • eth_getLogs
        • eth_getStorageAt
        • eth_getTransactionByBlockHashAndIndex
        • eth_getTransactionByBlockNumberAndIndex
        • eth_getTransactionByHash
        • eth_getTransactionCount
        • eth_getTransactionReceipt
        • eth_getUncleByBlockHashAndIndex
        • eth_getUncleByBlockNumberAndIndex
        • eth_getUncleCountByBlockHash
        • eth_getUncleCountByBlockNumber
        • eth_getWork
        • eth_mining
        • eth_hashrate
        • eth_protocolVersion
        • eth_sendRawTransaction
        • eth_sendTransaction
        • eth_sign
        • eth_submitWork
        • eth_syncing
        • net_listening
        • net_peerCount
        • net_version
        • web3_clientVersion
        • Filter methods
          • eth_newFilter
          • eth_newBlockFilter
          • eth_newPendingTransactionFilter
          • eth_getFilterLogs
          • eth_getFilterChanges
          • eth_uninstallFilter
        • Subscription methods
          • eth_subscribe
          • eth_unsubscribe
    • Arbitrum
      • How to
        • Authenticate requests
        • Make requests
        • Choose a network
        • Secure a project
        • Get testnet ETH
      • JSON-RPC API methods
    • Aurora
      • How to
      • JSON-RPC API methods
    • Avalanche (C-Chain)
      • How to
      • JSON-RPC API methods
    • BNB Chain
      • How to
      • JSON-RPC API methods
    • Celo
      • How to
      • JSON-RPC API methods
    • Cube
      • How to
      • JSON-RPC API methods
    • Fantom
      • How to
      • JSON-RPC API methods
    • Gnosis
      • How to
      • JSON-RPC API methods
    • Heco
      • How to
      • JSON-RPC API methods
    • Klaytn
      • How to
      • JSON-RPC API methods
    • Optimism
      • How to
      • JSON-RPC API methods
    • OEC Chain
      • How to
      • JSON-RPC API methods
    • Polygon PoS
      • How to
      • JSON-RPC API methods
  • Custom APIs
    • Wellat SDK
    • DeX SDK
    • NFT SDK
Powered by GitBook
On this page
  • ERC-20 token functions and events
  • Send transactions
  • Observe logs of mined transactions
  • Topics
  • Data
  1. Networks
  2. Ethereum
  3. How to

Interact with ERC-20 tokens

PreviousSubscribe to eventsNextAdd a network add-on

Last updated 2 years ago

is a simple token standard and the most common contract type on Ethereum.

You can:

  • using eth_sendRawTransaction.

  • using eth_getLogs.

  • Follow this tutorial to retrieve the balance of ERC-20 tokens.

  • Follow this tutorial to track ERC-20 token transfers.

ERC-20 token functions and events

An ERC-20 token must implement the following functions:

  • totalSupply() - Returns the total token supply.

  • balanceOf(owner) - Returns the account balance of another account with address owner.

  • allowance(owner, spender) - Returns the amount which spender is still allowed to withdraw from owner.

  • transfer(to, value) - Transfers value amount of tokens to address to.

  • approve(spender, value) - Allows spender to withdraw from your account multiple times, up to the value amount.

  • transferFrom(from, to, value) - Transfers value amount of tokens from address from to address to.

At certain times, an ERC-20 token also must emit the following events:

  • Transfer(from, to, value) - Must trigger when tokens are transferred, including zero value transfers.

  • Approval(owner, spender, value) - Must trigger on any successful call to approve(spender, value).

Send transactions

Use eth_sendRawTransaction to send ERC-20 token transactions.

web3.sha3('Transfer(address,address,uint256)')[0..4]
0x70a08231

The first four bytes of this hash comprise its four-byte signature. Take this four-byte signature, pad it with zeros, and package this information into a data string. Then sign the transaction and send it using eth_sendRawTransaction:

curl https://eth.chainrpc.io/v3/YOUR-API-KEY \
    -X POST \
    -H "Content-Type: application/json" \
    -d '{"jsonrpc":"2.0","method":"eth_sendRawTransaction","params": ["0xf869018203e882520894f17f52151ebef6c7334fad080c5704d77216b732881bc16d674ec80000801ba02da1c48b670996dcb1f447ef9ef00b33033c48a4fe938f420bec3e56bfd24071a062e0aa78a81bf0290afbc3a9d8e9a068e6d74caa66c5e0fa8a46deaae96b0833"],"id":1}'
{
    "id": 1,
    "jsonrpc": "2.0",
    "result": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331"
}

Observe logs of mined transactions

When a transaction is mined, event logs are published for public viewing.

Once the event logs are published, you can execute eth_getLogs to investigate what changed relative to the events that you care about, and react to them.

For example, an event ticketing service that wants to issue off-chain tickets based on crypto payments can use eth_getLogs to find payments to their address, and react to these events by processing some logic in their backend servers to issue tickets to users.

curl https://eth.chainrpc.io/v3/YOUR-API-KEY \
    -X POST \
    -H "Content-Type: application/json" \
    -d {"jsonrpc":"2.0","method":"eth_getLogs","id":1,"params":[{"fromBlock":"Ox91F37C","toBlock":"0x91F37C","topics":[ "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "0x000000000000000000000000ee25e1ba53c225d250861c8e5a9a3e0fe19c790e", "0x000000000000000000000000dfbaf3e4c7496dad574a1b842bc85b402bdc298d" ],"address":"0x6B175474E89094C44Da98b954EedeAC495271d0F"}]}
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": [
    {
      "address": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
      "topics": [
        "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
        "0x000000000000000000000000ee25e1ba53c2250250861c8e5a9a3e0fe19c790e",
        "0x000000000000000000000000dfbaf3e4c7496dad574a1b842bc85b402bdc298d"
      ],
      "data": "0x00000000000000000000000000000000000000000000041f900d25d6693623a6",
      "blockNumbern": "0x91F37C"
    }
  ]
}

In this example request, the parameters fromBlock and toBlock specify the hexadecimal block number to retrieve logs from.

If fromBlock and toBlock are omitted, eth_getLogs returns the entire chain history by default. Infura has a cap on requests of 10,000 events per query. We recommend requesting a single block, as in this example, and to do that for each mined block.

This request tells the blockchain to retrieve event logs related to address 0x6B175474E89094C44Da98b954EedeAC495271d0F emitted in block 0x91F37C that matches topics 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef, 0x000000000000000000000000ee25e1ba53c225d250861c8e5a9a3e0fe19c790e and 0x000000000000000000000000dfbaf3e4c7496dad574a1b842bc85b402bdc298d.

The response returned for this request is an array of events. In this example, only one event for one address matches the specified topics.

Topics

event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
event Transfer(address indexed from, address indexed to, uint tokens);
web3.sha3('Approval(address,address,uint256)')
0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925

The resulting hash doesn’t match the hash provided in the initial request response. Now let’s try the event on line 95 of the contract:

web3.sha3('Transfer(address,address,uint256)')
0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef

The resulting hash matches the hash provided in the initial request response. Now you know that 0xddf25 is the transfer event in this example.

Data

The data field in the request response refers to all the "non-indexed stuff" captured in the events. In this example, for the transfer topic, data represents the number of tokens that were transferred. That is, 0x41f900d25d6693623a6 or 19471.6949921 DAI tokens were transferred from ee25e1ba53c225d250861c8e5a9a3e0fe19c790e to dfbaf3e4c7496dad574a1b842bc85b402bdc298d.

View for more details about how these functions work and when to emit these events.

The JSON-RPC format expects eth_sendRawTransaction to have a specific data field format that requires normalizing the Transfer function to a short . To do this, set the parameters for the function and run it through Ethereum’s :

The following example uses eth_getLogs on the DAI ERC-20 Solidity contract :

Topics are events emitted by smart contracts. Looking at the source code of the original contract used in this example, there are two event signatures that could be associated with it on lines 94 and 95:

To find out which topic (event) it actually was, create the of the event and take the of it. Let’s try the event on line 94:

ERC-20
Send ERC-20 transactions
Observe event logs of mined ERC-20 transactions
EIP-20
function selector
sha3 keccak hash
0x6B175474E89094C44Da98b954EedeAC495271d0F
0x6B175474E89094C44Da98b954EedeAC495271d0F
function selector
sha3 keccak hash