TRC-20 contract interaction

Read state and call methods on a deployed TRC-20 contract using the HTTP API, TronWeb, and Wallet-CLI.

📘

Prerequisites

This page uses the USDT contract on the Shasta testnet as an example to demonstrate how to interact with a TRC-20 contract via the Node HTTP API, TronWeb, and Wallet-CLI.

Wallet-CLI command reference

The Wallet-CLI examples below use two commands. Their parameter contracts are:

TriggerConstantContract — for view / pure (read-only) functions, no broadcast:

TriggerConstantContract [ownerAddress] [contractAddress] [method] [args] [isHex]

TriggerContract — for state-changing functions, broadcasts a transaction:

TriggerContract [ownerAddress] [contractAddress] [method] [args] [isHex] [fee_limit] [value] [token_value] [token_id]
ParameterMeaning
ownerAddressThe caller address.
contractAddressThe TRC-20 contract address.
methodThe contract function.
argsThe function parameters. Use # as the placeholder if there are no parameters.
isHexWhether the address parameter is in hex format.
fee_limitMaximum TRX consumption allowed in this call, in sun.
valueAmount of TRX to transfer to the contract during the call, in sun.
token_valueAmount of TRC-10 asset to transfer to the contract during the call.
token_idID of the TRC-10 asset to transfer to the contract during the call.

For the TronWeb examples, the same setup is reused throughout:

const { TronWeb } = require('tronweb');

const tronWeb = new TronWeb({
  fullHost: 'https://api.shasta.trongrid.io',
  // headers: { 'TRON-PRO-API-KEY': 'YOUR_API_KEY' },   // only required for Mainnet (api.trongrid.io); Shasta and Nile testnets do not require an API key
  privateKey: 'your private key'
});

const trc20ContractAddress = "TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs";
const abi = [...]; // Replace with the token's ABI.

name

Call the name function to get the name of the token.

HTTP API

# Node HTTP API: /wallet/triggerconstantcontract
# Description: Trigger the constant of the smart contract; the transaction stays off-chain.

BASE_URL=https://api.shasta.trongrid.io   # example — replace with any TRON node (TronGrid, third-party, or self-hosted)
curl -X POST ${BASE_URL}/wallet/triggerconstantcontract -d '{
  "contract_address": "TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs",
  "function_selector": "name()",
  "owner_address": "TPnBjYQEMo4Yd4866KCzXdi4a169KGd63n",
  "visible": true
}'

TronWeb

async function getName() {
    try {
        const instance = await tronWeb.contract(abi, trc20ContractAddress);
        // Use call() for pure or view methods — no broadcast, no cost.
        const result = await instance.name().call();
        console.log('result:', result);
    } catch (error) {
        console.error("TRC-20 query error", error);
    }
}

Wallet-CLI

TriggerConstantContract TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs name() # false

symbol

Call the symbol function to get the token's short symbol.

HTTP API

BASE_URL=https://api.shasta.trongrid.io   # example — replace with any TRON node (TronGrid, third-party, or self-hosted)
curl -X POST ${BASE_URL}/wallet/triggerconstantcontract -d '{
  "contract_address": "TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs",
  "function_selector": "symbol()",
  "owner_address": "TPnBjYQEMo4Yd4866KCzXdi4a169KGd63n",
  "visible": true
}'

TronWeb

async function getSymbol() {
    try {
        const instance = await tronWeb.contract(abi, trc20ContractAddress);
        const result = await instance.symbol().call();
        console.log('result:', result);
    } catch (error) {
        console.error("TRC-20 query error", error);
    }
}

Wallet-CLI

TriggerConstantContract TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs symbol() # false

decimals

Call the decimals function to get the token's precision.

HTTP API

BASE_URL=https://api.shasta.trongrid.io   # example — replace with any TRON node (TronGrid, third-party, or self-hosted)
curl -X POST ${BASE_URL}/wallet/triggerconstantcontract -d '{
  "contract_address": "TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs",
  "function_selector": "decimals()",
  "owner_address": "TPnBjYQEMo4Yd4866KCzXdi4a169KGd63n",
  "visible": true
}'

TronWeb

async function getDecimals() {
    try {
        const instance = await tronWeb.contract(abi, trc20ContractAddress);
        const result = await instance.decimals().call();
        console.log('result:', result);
    } catch (error) {
        console.error("TRC-20 query error", error);
    }
}

Wallet-CLI

TriggerConstantContract TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs decimals() # false

totalSupply

Call the totalSupply function to get the total supply of the token.

HTTP API

BASE_URL=https://api.shasta.trongrid.io   # example — replace with any TRON node (TronGrid, third-party, or self-hosted)
curl -X POST ${BASE_URL}/wallet/triggerconstantcontract -d '{
  "contract_address": "TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs",
  "function_selector": "totalSupply()",
  "owner_address": "TPnBjYQEMo4Yd4866KCzXdi4a169KGd63n",
  "visible": true
}'

TronWeb

async function getTotalSupply() {
    try {
        const instance = await tronWeb.contract(abi, trc20ContractAddress);
        const result = await instance.totalSupply().call();
        console.log('result:', result);
    } catch (error) {
        console.error("TRC-20 query error", error);
    }
}

Wallet-CLI

TriggerConstantContract TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs totalSupply() # false

balanceOf

Call the balanceOf function to get the token balance of a specified account.

HTTP API

BASE_URL=https://api.shasta.trongrid.io   # example — replace with any TRON node (TronGrid, third-party, or self-hosted)
curl -X POST ${BASE_URL}/wallet/triggerconstantcontract -d '{
  "contract_address": "TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs",
  "function_selector": "balanceOf(address)",
  "parameter": "000000000000000000000041977C20977F412C2A1AA4EF3D49FEE5EC4C31CDFB",
  "owner_address": "TPnBjYQEMo4Yd4866KCzXdi4a169KGd63n",
  "visible": true
}'

TronWeb

async function getBalanceOf() {
    try {
        const instance = await tronWeb.contract(abi, trc20ContractAddress);
        const address = "TM2TmqauSEiRf16CyFgzHV2BVxBejY9iyR";
        const result = await instance.balanceOf(address).call();
        console.log('result:', result);
    } catch (error) {
        console.error("TRC-20 query error", error);
    }
}

Wallet-CLI

TriggerConstantContract TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs balanceOf(address) "TM2TmqauSEiRf16CyFgzHV2BVxBejY9iyR" false

transfer

Call the transfer function to send tokens.

HTTP API

# Node HTTP API: /wallet/triggersmartcontract
# Description: Trigger smart contract (state-changing).

BASE_URL=https://api.shasta.trongrid.io   # example — replace with any TRON node (TronGrid, third-party, or self-hosted)
curl -X POST ${BASE_URL}/wallet/triggersmartcontract -d '{
  "contract_address": "TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs",
  "function_selector": "transfer(address,uint256)",
  "parameter": "00000000000000000000004115208EF33A926919ED270E2FA61367B2DA3753DA0000000000000000000000000000000000000000000000000000000000000032",
  "fee_limit": 100000000,
  "call_value": 0,
  "owner_address": "TPnBjYQEMo4Yd4866KCzXdi4a169KGd63n",
  "visible": true
}'

The parameter is the encoded value of address and uint256 from transfer(address,uint256). For details, see Parameter encoding and decoding.

After calling this HTTP API, you also need to call the signing and broadcasting steps.

TronWeb

async function sendTransfer() {
    try {
        const instance = await tronWeb.contract(abi, trc20ContractAddress);
        // Use send() for state-changing methods — broadcasts and consumes resources (Bandwidth and Energy).
        const result = await instance.transfer(
            "TWbcHNCYzqAGbrQteKnseKJdxfzBHyTfuh", // to address
            1000000                                // amount
        ).send({
            feeLimit: 100_000_000,
            callValue: 0,
            shouldPollResponse: true
        });
        console.log('result:', result);
    } catch (error) {
        console.error("TRC-20 transaction error", error);
    }
}

Wallet-CLI

TriggerContract TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs transfer(address,uint256) "TWbcHNCYzqAGbrQteKnseKJdxfzBHyTfuh",1000000 false 100000000 0 0 #
📘

Confirm the transaction

After broadcasting, check whether the TRC-20 transfer succeeded by querying the getTransactionInfoById API.

approve

Call the approve function to authorize another address to spend a specified amount of tokens.

HTTP API

BASE_URL=https://api.shasta.trongrid.io   # example — replace with any TRON node (TronGrid, third-party, or self-hosted)
curl -X POST ${BASE_URL}/wallet/triggersmartcontract -d '{
  "contract_address": "TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs",
  "function_selector": "approve(address,uint256)",
  "parameter": "0000000000000000000000410FB357921DFB0E32CBC9D1B30F09AAD13017F2CD0000000000000000000000000000000000000000000000000000000000000064",
  "fee_limit": 100000000,
  "call_value": 0,
  "owner_address": "TPnBjYQEMo4Yd4866KCzXdi4a169KGd63n",
  "visible": true
}'

After calling this HTTP API, you also need to call the signing and broadcasting steps.

TronWeb

// Account A approves Account B to spend 10 USDT of A: A calls approve(B, 10).
async function sendApprove() {
    try {
        const instance = await tronWeb.contract(abi, trc20ContractAddress);
        const result = await instance.approve(
            "TWbcHNCYzqAGbrQteKnseKJdxfzBHyTfuh", // address _spender
            10000000                              // amount
        ).send({
            feeLimit: 100_000_000,
            callValue: 0,
            shouldPollResponse: true
        });
        console.log('result:', result);
    } catch (error) {
        console.error("TRC-20 transaction error", error);
    }
}

Wallet-CLI

TriggerContract TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs approve(address,uint256) "TWbcHNCYzqAGbrQteKnseKJdxfzBHyTfuh",10000000 false 100000000 0 0 #
📘

Confirm the transaction

After broadcasting, check whether the approval succeeded by querying the getTransactionInfoById API.

transferFrom

The authorized address can call transferFrom to transfer tokens from the authorizer's account.

HTTP API

BASE_URL=https://api.shasta.trongrid.io   # example — replace with any TRON node (TronGrid, third-party, or self-hosted)
curl -X POST ${BASE_URL}/wallet/triggersmartcontract -d '{
  "contract_address": "TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs",
  "function_selector": "transferFrom(address,address,uint256)",
  "parameter": "00000000000000000000004109669733965A37BA3582E70CCC5302F8D254675D0000000000000000000000410FB357921DFB0E32CBC9D1B30F09AAD13017F2CD0000000000000000000000000000000000000000000000000000000000000032",
  "fee_limit": 100000000,
  "call_value": 0,
  "owner_address": "TPnBjYQEMo4Yd4866KCzXdi4a169KGd63n",
  "visible": true
}'

After calling this HTTP API, you also need to call the signing and broadcasting steps.

TronWeb

// Address B transfers 10 USDT from address A to C: B calls transferFrom(A, C, 10).
async function sendTransferFrom() {
    try {
        const instance = await tronWeb.contract(abi, trc20ContractAddress);
        const result = await instance.transferFrom(
            "TApuyuazZnGgxvbNbaGcrUijEFn1oidsAH", // address _from
            "TBQDyqoJ2ZJHTRDsrGQasyqBm4nUVLbWee", // address _to
            10000000                              // amount
        ).send({
            feeLimit: 100_000_000,
            callValue: 0,
            shouldPollResponse: true
        });
        console.log('result:', result);
    } catch (error) {
        console.error("TRC-20 transaction error", error);
    }
}

Wallet-CLI

TriggerContract TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs transferFrom(address,address,uint256) "TApuyuazZnGgxvbNbaGcrUijEFn1oidsAH","TBQDyqoJ2ZJHTRDsrGQasyqBm4nUVLbWee",10000000 false 100000000 0 0 #
📘

Confirm the transaction

After broadcasting, check whether the transfer succeeded by querying the getTransactionInfoById API.

allowance

The authorized address can call allowance to query the remaining quota from the authorizer's account.

HTTP API

BASE_URL=https://api.shasta.trongrid.io   # example — replace with any TRON node (TronGrid, third-party, or self-hosted)
curl -X POST ${BASE_URL}/wallet/triggerconstantcontract -d '{
  "contract_address": "TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs",
  "function_selector": "allowance(address,address)",
  "parameter": "00000000000000000000004109669733965A37BA3582E70CCC5302F8D254675D000000000000000000000041A245B99ECB47B18C6A90ED1D51100C5A9F0641A7",
  "owner_address": "TPnBjYQEMo4Yd4866KCzXdi4a169KGd63n",
  "visible": true
}'

TronWeb

// Query how much A has authorized B to spend: B calls allowance(A, B).
async function getAllowance() {
    try {
        const instance = await tronWeb.contract(abi, trc20ContractAddress);
        const result = await instance.allowance(
            "TApuyuazZnGgxvbNbaGcrUijEFn1oidsAH", // address _owner
            "TBQDyqoJ2ZJHTRDsrGQasyqBm4nUVLbWee"  // address _spender
        ).call();
        console.log('result:', result);
    } catch (error) {
        console.error("TRC-20 query error", error);
    }
}

Wallet-CLI

TriggerConstantContract TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs allowance(address,address) "TApuyuazZnGgxvbNbaGcrUijEFn1oidsAH","TBQDyqoJ2ZJHTRDsrGQasyqBm4nUVLbWee" false

Related resources