Trigger Smart Contract on TRON: TronWeb and API Guide
Interacting with TRON smart contracts — whether transferring USDT, swapping on SunSwap, or calling your own DeFi logic — boils down to encoding function parameters, broadcasting a triggerSmartContract transaction, and paying Energy for execution.
This guide covers TronWeb's high-level API, raw HTTP triggers, read vs write calls, and production patterns.
Read vs write
| Type | Broadcast | Costs Energy | Method |
|---|---|---|---|
| Read (view/pure) | No | No | contract.method().call() |
| Write (state change) | Yes | Yes | contract.method().send() |
Reads use triggerconstantcontract — local TVM simulation.
Writes use triggersmartcontract — mined in block.
TronWeb contract instance
const TronWeb = require('tronweb');
const tronWeb = new TronWeb({
fullHost: 'https://api.trongrid.io',
privateKey: process.env.PRIVATE_KEY
});
const USDT = 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t';
const abi = [/* TRC-20 ABI fragment */];
const contract = await tronWeb.contract(abi, USDT);
If contract not found — wrong network or address. Contract not found troubleshooting.
Read balance
const balance = await contract.balanceOf('TRecipient...').call();
console.log(balance.toString()); // smallest units
Write transfer
const amount = 1_000_000; // 1 USDT (6 decimals)
const txid = await contract.transfer('TRecipient...', amount).send({
feeLimit: 100_000_000, // max TRX sun to burn for Energy
});
console.log(txid);
Full walkthrough: send USDT programmatically.
fee_limit and Energy
feeLimit caps TRX burned if Energy insufficient (in sun — 1 TRX = 1e6 sun).
Typical settings:
| Operation | feeLimit (sun) |
|---|---|
| TRC-20 transfer | 50_000_000 – 100_000_000 |
| Complex DeFi | 150_000_000 – 500_000_000 |
Account should have frozen Energy or liquid TRX. Failed txs still consume fees — transaction failed.
HTTP API: triggerSmartContract
Low-level POST to full node:
POST https://api.trongrid.io/wallet/triggersmartcontract
Body (simplified):
{
"owner_address": "41...hex",
"contract_address": "41...hex",
"function_selector": "transfer(address,uint256)",
"parameter": "0000...encoded",
"fee_limit": 100000000,
"visible": true
}
Response contains transaction object — sign locally and broadcast via broadcasttransaction.
TronWeb abstracts this. Raw HTTP useful for non-JS stacks. See TRON HTTP API reference.
triggerConstantContract (read)
POST /wallet/triggerconstantcontract
Same encoding without broadcast. Returns constant_result hex.
const result = await tronWeb.transactionBuilder.triggerConstantContract(
tronWeb.address.toHex(contractAddress),
'balanceOf(address)',
{},
[{ type: 'address', value: holderAddress }],
tronWeb.address.toHex(callerAddress)
);
Parameter encoding
Function selector = first 4 bytes of keccak256("transfer(address,uint256)").
Parameters ABI-encoded to 32-byte slots. TronWeb handles encoding when using .send() / .call().
Manual encoding error → REVERT on chain.
TronLink browser flow
Frontend dApps use TronLink injection:
const tronWeb = window.tronWeb; const contract = await tronWeb.contract().at(USDT_ADDRESS); await contract.transfer(to, amount).send();
User signs in popup — private key never in webpage. Warn users about dApp risks.
Event logs after trigger
After write, fetch receipt:
const info = await tronWeb.trx.getTransactionInfo(txid); const logs = info.log; // Transfer events for TRC-20
Event listeners for monitoring.
Common errors
| Error | Cause |
|---|---|
| REVERT | Bad params, insufficient balance/allowance |
| OUT_OF_ENERGY | Raise feeLimit or freeze TRX |
| CONTRACT_VALIDATE_ERROR | Wrong ABI or selector |
| BANDWIDTH_ERROR | Freeze for bandwidth |
Best practices
- Test on Shasta/Nile first — testnet
- Verify contract on TronScan — verify contract
- Set explicit
feeLimit— avoid defaults too low - Parse receipt
resultbefore assuming success - Idempotent retries — check txid before resend
Multi-call patterns
Routers batch swaps in one transaction. Your contracts can use internal calls — mind reentrancy and Energy limits per tx.
Related guides
FAQ
What is the difference between call and trigger on TRON?
Constant calls read state without a transaction. triggerSmartContract broadcasts state changes costing Energy.
How much Energy does a smart contract call use?
TRC-20 transfer ~65,000 Energy. Complex calls more — test on testnet.
Can I trigger without a private key?
Read calls yes. Writes require signing — TronLink or server-side key.
What does visible: true mean in API?
Addresses in request/response use Base58 T format when true, hex when false.
How do I approve then swap in two transactions?
First approve(router, amount) on token contract, then swap on router — two separate triggers. Some UIs batch via multicall contracts.
Thanks — your feedback helps us improve the docs.