Interacting with TRC-20 smart contracts on the Tron blockchain is a foundational skill for developers building decentralized applications (dApps), wallets, or token management tools. This guide walks you through calling key TRC-20 contract functions—such as name
, symbol
, decimals
, balanceOf
, transfer
, approve
, transferFrom
, and allowance
—using multiple methods: HTTP API, TronWeb, and wallet-cli.
All examples use the USDT contract on the Shasta testnet, making it easy to experiment without risking real funds. We’ll focus on both read-only (constant) and state-changing operations, ensuring you understand how to retrieve data and execute transactions securely and efficiently.
Understanding Constant vs. State-Changing Functions
Before diving into code, it's crucial to distinguish between two types of smart contract functions:
- Constant/View Functions: These do not alter blockchain state and are free to call. Examples include
name()
,symbol()
,decimals()
,totalSupply()
, andbalanceOf()
. They can be invoked off-chain using/wallet/triggerconstantcontract
. - State-Changing Functions: These modify the blockchain (e.g., transferring tokens) and require fees (bandwidth/energy). Examples include
transfer()
,approve()
, andtransferFrom()
. These use/wallet/triggersmartcontract
and must be signed and broadcast.
👉 Learn how to securely manage digital assets while interacting with smart contracts.
Querying Token Metadata
Get Token Name
Retrieve the full name of the token (e.g., "Tether USD").
HTTP API
POST /wallet/triggerconstantcontract
{
"contract_address": "419E62BE7F4F103C36507CB2A753418791B1CDC182",
"function_selector": "name()",
"owner_address": "41977C20977F412C2A1AA4EF3D49FEE5EC4C31CDFB"
}
TronWeb
const contract = await tronWeb.contract().at("TQQg4EL8o1BSeKJY4MJ8TB8XK7xufxFBvK");
const result = await contract.name().call();
console.log(result); // "Tether USD"
Wallet-cli
TriggerConstantContract TQQg4EL8o1BSeKJY4MJ8TB8XK7xufxFBvK name() # false
Get Token Symbol
Fetch the ticker symbol (e.g., "USDT").
HTTP API
{
"contract_address": "419E62BE7F4F103C36507CB2A753418791B1CDC182",
"function_selector": "symbol()",
"owner_address": "41977C20977F412C2A1AA4EF3D49FEE5EC4C31CDFB"
}
TronWeb
const result = await contract.symbol().call();
console.log(result); // "USDT"
Wallet-cli
TriggerConstantContract TQQg4EL8o1BSeKJY4MJ8TB8XK7xufxFBvK symbol() # false
Get Decimal Precision
Determine the number of decimal places the token supports (usually 6 for USDT).
HTTP API
{
"contract_address": "419E62BE7F4F103C36507CB2A753418791B1CDC182",
"function_selector": "decimals()",
"owner_address": "41977C20977F412C2A1AA4EF3D49FEE5EC4C31CDFB"
}
TronWeb
const result = await contract.decimals().call();
console.log(result); // 6
Wallet-cli
TriggerConstantContract TQQg4EL8o1BSeKJY4MJ8TB8XK7xufxFBvK decimals() # false
Get Total Supply
Check the total number of tokens issued.
HTTP API
{
"contract_address": "419E62BE7F4F103C36507CB2A753418791B1CDC182",
"function_selector": "totalSupply()",
"owner_address": "41977C20977F412C2A1AA4EF3D49FEE5EC4C31CDFB"
}
TronWeb
const result = await contract.totalSupply().call();
console.log(result); // e.g., 100000000000000
Wallet-cli
TriggerConstantContract TQQg4EL8o1BSeKJY4MJ8TB8XK7xufxFBvK totalSupply() # false
Reading and Managing Balances
Check Account Balance
Use balanceOf(address)
to get a user’s token balance.
HTTP API
{
"contract_address": "419E62BE7F4F103C36507CB2A753418791B1CDC182",
"function_selector": "balanceOf(address)",
"parameter": "000000000000000000000041977C20977F412C2A1AA4EF3D49FEE5EC4C31CDFB",
"owner_address": "41977C20977F412C2A1AA4EF3D49FEE5EC4C31CDFB"
}
TronWeb
const address = "TM2TmqauSEiRf16CyFgzHV2BVxBe...";
const result = await contract.balanceOf(address).call();
console.log(tronWeb.fromSun(result)); // Convert from Sun if needed
Wallet-cli
TriggerConstantContract TQQg4EL8o1BSeKJY4MJ8TB8XK7xufxFBvK balanceOf(address) "TM2TmqauSEiRf16CyFgzHV2BVxBejY9iyR" false
Executing Token Transfers
Transfer Tokens
Send tokens from one address to another using transfer(to, amount)
.
⚠️ Requires transaction fee and broadcasting.
HTTP API
POST /wallet/triggersmartcontract
{
"contract_address": "419E62BE7F4F103C36507CB2A753418791B1CDC182",
"function_selector": "transfer(address,uint256)",
"parameter": "0000000000000000000000...encoded params...",
"fee_limit": 100000000,
"call_value": 0,
"owner_address": "41977C20977F412C2A1AA4EF3D49FEE5EC4C31CDFB"
}
Note: Parameters must be ABI-encoded. Refer to Tron’s official documentation for encoding details.
TronWeb
await contract.transfer("TVDGp...", 1000000).send({
feeLimit: 1000000
});
Wallet-cli
TriggerContract TQQg4EL8o1BSeKJY4MJ8TB8XK7xufxFBvK transfer(address,uint256) "TBQDyqoJ2ZJHTRDsrGQasyqBm4nUVLbWee",100 false 100000000 0 0 #
👉 Discover secure ways to interact with blockchain contracts using trusted platforms.
Approve Third-Party Spending
Allow another address to spend tokens on your behalf using approve(spender, amount)
.
TronWeb
await contract.approve("TA1g2WQiXbU...", 10000000).send({
feeLimit: 100000000
});
Wallet-cli
TriggerContract TQQg4EL8o1BSeKJY4MJ8TB8XK7xufxFBvK approve(address,uint256) "TBQDyqoJ2ZJHTRDsrGQasyqBm4nUVLbWee",100 false 100000000 0 0 #
Transfer On Behalf of Another (transferFrom)
After approval, a third party can call transferFrom(owner, to, amount)
.
TronWeb
await contract.transferFrom("TM2TmqauSEiRf...", "TVDGpn...", 100000).send({
feeLimit: 10_00_0_ });
Wallet-cli
TriggerContract TQQg4EL8o1BSeKJY4MJ8TB8XK7xufxFBvK transferFrom(address,address,uint256) "TApuyuazZnGgxvbNbaGcrUijEFn1oidsAH","TBQDyqoJ2ZJHTRDsrGQasyqBm4nUVLbWee",50 false 100_
Check Allowance
Query how many tokens one address can spend from another using allowance(owner, spender)
.
TronWeb
const value = await contract.allowance("TM2TmqauSEiRf...", "TA1g2WQiXbU...").call();
console.log(value);
Wallet-cli
TriggerConstantContract TQQg4EL8o1BSeKJY4MJ8TB8XK7xufxFBvK allowance(address,address) "TApuyuazZnGgxvbNbaGcrUijEFn1oidsAH","TQmDzierQxEFJm1dT5YXnTXqVAfdN9HtXj" false
Transaction Confirmation
After executing a state-changing transaction, verify success using:
getTransactionInfoById <tx_id>
Check the result
field:
"result": true
→ successful execution."result": false
→ failed (check logs for reason).
Core Keywords
- TRC-20 contract interaction
- TronWeb tutorial
- Smart contract function call
- USDT on Tron
- TriggerConstantContract
- Transfer TRC-20 tokens
- Approve allowance Tron
- Blockchain development guide
Frequently Asked Questions (FAQ)
What is the difference between triggerconstantcontract
and triggersmartcontract
?
triggerconstantcontract
is used for read-only functions like name()
or balanceOf()
that don’t change blockchain state and don’t cost fees. triggersmartcontract
is for write operations like transfer()
that modify data and require fees and transaction broadcasting.
Why do I need to encode parameters manually in HTTP API calls?
The Tron network requires ABI-encoded parameters for function inputs. Tools like the Tron Convert Tool help encode addresses and integers into hexadecimal format expected by the smart contract.
Can I test these commands on the mainnet?
Yes, but always test on Shasta or Nile testnets first. Replace the contract address and node URLs accordingly. Never expose private keys in production environments.
How do I handle errors when calling smart contracts?
Always wrap contract calls in try-catch blocks. Common issues include insufficient bandwidth/energy, incorrect parameter encoding, or invalid addresses. Use getTransactionInfoById
to debug failed transactions.
Is it safe to use wallet-cli for token transfers?
Wallet-cli is secure if used locally with proper key management. Avoid running it on public or shared systems. For dApps, prefer TronWeb or backend SDKs with secure key storage.
Do I need to pay TRX for every TRC-20 transfer?
Yes. Every state-changing operation consumes bandwidth or energy, which may require freezing TRX or paying in Sun if resources are depleted.
👉 Access advanced tools for blockchain interaction and token management today.
This guide equips developers with practical knowledge to interact with TRC-20 contracts confidently across different environments. Whether you're querying balances or enabling decentralized exchanges, mastering these patterns is essential for building robust Tron-based applications.