Read ERC20 smart contract information directly on the chain with Go Ethereum

I don’t know what’s the use of this, I just feel like it’s more fun to do.

When looking at the Etherscan of Görli Testnet, such as this link:https://goerli.etherscan.io/token/0x3ffc03f05d1869f493c7dbf913e636c6280e0ff9#readContract , you can directly see some basic information of a contract, such as Decimals, Max Total Supply, etc.

So I wonder if there is any reasonable way to read these data directly from the chain (rather than creating a new API based on someone else’s API nesting doll).

Why

In fact, there are some similar articles on the Internet (you can refer to the References at the bottom of this article), but there are some problems, such as the solidity of everyone’s articles is a very ancient version:

 pragma solidity ^0.4.24;

And the contract to query ERC20 in the article wrote an interface, but later I found that for this kind of Public Interface, it can be written in OpenZeppelin, for example, ERC20 at https://github.com/OpenZeppelin/openzeppelin-contracts /blob/master/contracts/token/ERC20/ERC20.sol here.

Get Started

To solve this problem, we need the following tools:

  1. An Eth node (or an Ethereum Gateway, like Infura or Cloudflare’s free services)
  2. Go Ethernum package (including abigen or something)
  3. Solidity compiler (such as solc-js or solc)
  4. nodejs (I believe everyone has this on their computer, if not, you can go to nodesource for the whole one)

Prepare Env

Eth Node

For Eth nodes, we can just use public services directly, or if you really want to build one by yourself, you can use the docker-compose.yml to quickly start one:

 version : '3.3' services :   go-eth :     volumes :       - './ethereum:/root'     ports :       - '127.0.0.1:8545:8545'       - '127.0.0.1:8546:8546'       - '30303:30303'     image : ethereum/client-go : latest     command : --http --http.addr 0.0 . 0.0 --syncmode light --goerli --http.vhosts=* --authrpc.vhosts=* --ws --ws.addr= "127.0.0.1" --ws.origins "*"     restart : always

Go Ethernum

There seems to be no suitable package on the system I am using. Since it is a bunch of Binary, it is better to download it directly and extract it to /usr/bin :

 wget https://gethstore.blob.core.windows.net/builds/geth-alltools-linux-amd64-1.10.18-de23cf91.tar.gz tar -xvf geth-alltools-linux-amd64-1.10.18-de23cf91.tar.gz cd geth-alltools-linux-amd64-1.10.18-de23cf91 sudo mv abigen /usr/bin/ sudo mv geth /usr/bin

Solc

Here at first I followed a certain tutorial npm install solc -g and found…

The commandline options of solcjs are not compatible with solc and tools (such as geth) expecting the behaviour of solc will not work with solcjs.

It made me very angry, so in line with the principle of not looking for things for yourself if you can find Binary, I went to Binary and unzipped it to /usr/bin :

 wget https://github.com/ethereum/solidity/releases/download/v0.8.14/solc-static-linux chmod +x solc-static-linux mv solc-static-linux /usr/bin/solc

Gen ABI

Since we plan to use Go to write a whole set of things, we need to use Go Ethernum to read, and to enable Go Ethernum to read contract-related information, we need the corresponding ABI. The approximate process is as follows:

Solidity(ERC20.sol) –(solc) –> ABI(ERC20.abi) –(abigen) –> Go Package(erc20.go)

Here ERC20.sol is not rubbed by hand like some articles on the Internet, but directly provided by OpenZeppelin. A little introduction about OpenZeppelin is as follows:

A library for secure smart contract development. Build on a solid foundation of community-vetted code.

https://docs.openzeppelin.com/contracts/4.x/

To use the contract information they have written, find a blank directory, and then directly npm install @openzeppelin/contracts to get all OpenZeppelin contracts under the local node_modules , and then we under node_modules/@openzeppelin/contracts/token/ERC20 You can see the ERC20.sol file we want, this time we build abi

 solc --abi /path/to/node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol --base-path /path/to/node_modules --output-dir /path/to/

At this time, you can find an ERC20.abi file in the current directory, and then we use abigen to get the corresponding erc20.go

 abigen --abi=ERC20.abi --pkg=token --out=erc20.go

Read Contract

With the erc20.go file obtained above, we can create a read.go in the same directory to drive it, and we can write it like this:

 package main import ( "fmt" "log" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethclient" ) func main () { client , err := ethclient . Dial ( "https://goerli.knat.network" ) if err != nil { log . Fatal ( err ) } contract_address := common . HexToAddress ( "0x3ffc03f05d1869f493c7dbf913e636c6280e0ff9" ) // use erc20.go to init instance contract , err := NewToken ( contract_address , client ) decimals , err := contract . Decimals ( nil ) if err != nil { log . Fatal ( err ) } fmt . Println ( "decimals:" , decimals ) symbol , err := contract . Symbol ( & bind . CallOpts {}) if err != nil { log . Fatal ( err ) } fmt . Println ( "symbol:" , symbol ) total_supply , err := contract . TotalSupply ( nil ) if err != nil { log . Fatal ( err ) } fmt . Println ( "total_supply:" , total_supply ) }

Then we can get the information we want~

 go run . decimals: 18 symbol: TEST total_supply: 1000000000000000000000000000000001300115100103598665898811424167730937505693 

? The next step is to find a DB to write explosions?

References

  1. Query ERC20 token smart contracts
  2. Smart Contracts – Querying ERC20 Token Smart Contracts – “Developing Ethereum with Go” – 书stack.com · BookStack
  3. ERC20 tokens as Hyperledger Fabric Golang chaincode

This article is reprinted from https://nova.moe/read-smart-contract-info-from-chain/
This site is for inclusion only, and the copyright belongs to the original author.

Leave a Comment