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]| Parameter | Meaning |
|---|---|
ownerAddress | The caller address. |
contractAddress | The TRC-20 contract address. |
method | The contract function. |
args | The function parameters. Use # as the placeholder if there are no parameters. |
isHex | Whether the address parameter is in hex format. |
fee_limit | Maximum TRX consumption allowed in this call, in sun. |
value | Amount of TRX to transfer to the contract during the call, in sun. |
token_value | Amount of TRC-10 asset to transfer to the contract during the call. |
token_id | ID 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() # falsesymbol
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() # falsedecimals
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() # falsetotalSupply
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() # falsebalanceOf
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" falsetransfer
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 transactionAfter broadcasting, check whether the TRC-20 transfer succeeded by querying the
getTransactionInfoByIdAPI.
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 transactionAfter broadcasting, check whether the approval succeeded by querying the
getTransactionInfoByIdAPI.
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 transactionAfter broadcasting, check whether the transfer succeeded by querying the
getTransactionInfoByIdAPI.
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" falseRelated resources
- Parameter encoding and decoding — how to encode function selectors and arguments
- Transaction history — query past TRC-20 transfers
Updated 6 days ago