[Ethereum] Web3js & Web3.py ERC20 Name, Symbol, & Decimals call(): Results in Web3.exceptions & OverflowError for Some But Not All Existing Contracts

abierc-20web3.pyweb3js

I'm building simple Javascript & Python 3 scripts using the Web3 module to output ERC20 token names, symbols, and decimals from any given contract address.
The standard ERC20_ABI json file was copied directly from the Ethereum ERC20-ABI Github page found below, and is imported into my main code:

https://github.com/ethereum/wiki/wiki/Contract-ERC20-ABI

This script successfully outputs token data from the majority of contracts, however, fails with a handful on both Javascript & Python… including but not limited to ERC20 tokens that were later swapped to their own mainnet chains. The problem here appears to be contract related, as I'd assumed the standard ABI file would be able to pull what I needed.

Does anyone have any idea how to successfully retrieve this data for every ERC20 token available, without having to pull from Etherscan?

Below are scenarios, specifically with Python 3 for simplicity-sake.


Scenario #1:

Attempt at retrieving the 'Token Decimals' for High Performance Blockchain (HPB), a token still traded as an ERC20, results in the following error:

from web3 import Web3
import ERC20_ABI
import json

web3 = Web3(Web3.IPCProvider('/data/ethereum/geth/mainnet/geth.ipc'))

# Contract Address for High Performance Blockchain (HPB)
contract = '0x38c6A68304cdEfb9BEc48BbFaABA5C5B47818bb2'

token_info = web3.eth.contract(web3.toChecksumAddress(contract), abi=ERC20_ABI.ERC20_ABI)
token_decimals = token_info.functions.decimals().call()
print(token_decimals)

Python3 Error:

web3.exceptions.BadFunctionCallOutput: Could not decode contract
function call decimals return data b'' for output_types ['uint8']


Scenario #2:

Attempt at retrieving the 'Token Name' for ICON (ICX), a token swapped to its mainnet chain in 2018, results in the following error:

from web3 import Web3
import ERC20_ABI
import json

web3 = Web3(Web3.IPCProvider('/data/ethereum/geth/mainnet/geth.ipc'))

# Contract Address for ICON (ICX)
contract = '0xb5a5f22694352c15b00323844ad545abb2b11028'

token_info = web3.eth.contract(web3.toChecksumAddress(contract), abi=ERC20_ABI.ERC20_ABI)
token_name = web3.toText(token_info.functions.name().call())
print(token_name)

Python3 Error:

web3.exceptions.BadFunctionCallOutput: Could not decode contract
function call name return data b'' for output_types ['string']


Scenario #3:

Attempt at retrieving the 'Token Symbol' for EOS, a token swapped to its mainnet chain in 2018, results in the following error:

from web3 import Web3
import ERC20_ABI
import json

web3 = Web3(Web3.IPCProvider('/data/ethereum/geth/mainnet/geth.ipc'))

# Contract Address for EOS
contract = '0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0'

token_info = web3.eth.contract(web3.toChecksumAddress(contract), abi=ERC20_ABI.ERC20_ABI)
token_symbol = web3.toText(token_info.functions.symbol().call())
print(token_symbol)

OverflowError: Python int too large to convert to C ssize_t

Best Answer

name, symbol, and decimals are marked as OPTIONAL within the ERC20 Token Standard. Each of the examples you have referenced do not include them (or includes them differently from how they are specified in your abi).

  1. The High Performance Blockchain contract specifies the number of decimals as DECIMALS in all caps, rather than the expected decimals

  2. The Icon contract does not include a name function

  3. The EOS contract returns symbol as bytes32 instead of string

Related Topic