TriportRPC

Why a TRC-20 balanceOf call returns zero

Last updated:

At a glance

Symptom details
PropertyValue
Methodwallet/triggerconstantcontract with function_selector balanceOf(address)
parameter32-byte hex: 12 zero bytes + 20-byte address, no 41 prefix
Hex address42 hex characters including the 41 prefix
Base58 address34 characters starting with T

What you see

A wallet holds USDT on TRON, but your triggerconstantcontract call for balanceOf returns a constant result of all zeros. The same call in an explorer shows the balance.

Why this happens

TRON's TRC-20 guide builds the call from owner_address (the caller), contract_address (the token), function_selector "balanceOf(address)" and parameter — the address argument ABI-encoded as 32-byte hex, shown in the guide as 000000000000000000000000 followed by the 20-byte address "without the TRON address prefix". A TRON hex address has 42 hex characters "including the 41 prefix", and its Base58 form is 34 characters starting with T. Putting the 41-prefixed or Base58 form into parameter does not encode the holder's 20-byte address the way the guide shows, so the contract can read a different address — one with no balance. The request's visible flag concerns the form of the addresses the request carries, and must be set as the method's reference describes.

What to do

  1. Encode the holder address for parameter as 12 zero bytes plus the 20 address bytes — the hex address without the 41 prefix — 64 hex characters in total.
  2. Send owner_address and contract_address in one form, and set visible as the method's reference describes for that form.
  3. Decode the constant result as a uint256 and divide by the token's decimals.
  4. Confirm the contract address is the token on the network you are querying (Mainnet, Shasta and Nile are separate).

When this is not our problem

Address encoding and ABI parameters are defined by TRON and the token's ABI, identically on every full node, whoever operates it, Triport included. Only the request encoding can be fixed.

FAQ

Why does my TRC-20 balanceOf return 0 on TRON?
Usually the address in parameter is encoded wrongly — with the 41 prefix or in Base58 — so the contract looks up a different address. Use 32-byte hex without the prefix.
What does visible mean in TRON API requests?
It concerns the form of the addresses in the request; check the method's reference for the value that matches the form you send.

Sources