Key takeaways
- "A token transfer" on TRON is three different machines: a native TRX move, a protocol-native TRC-10 move, and a TRC-20 smart-contract call.
- The standard decides whether a transfer can activate a new account, which resource it burns, and whether the recipient is a readable field or buried in call data.
- TRX and TRC-10 run no code; TRC-20 is a contract execution — so only the native two can stand up an account, and only TRC-20 burns Energy.
- For attribution: a wallet funded only by USDT could not have been created by that USDT, which is why token-only funding is a weak attribution signal for anyone reading it on-chain.
“A token transfer” on TRON isn’t one thing. The chain carries three distinct kinds of value on entirely different plumbing. A TRX transfer is a native protocol operation. A TRC-10 transfer is also native — the protocol understands the token directly, with no code running. A TRC-20 transfer is the odd one out: a smart contract executing, the same machinery that runs a DeFi swap.
For an investigator, which standard a transfer uses isn’t a detail. It tells you whether the transfer could have brought a new account into existence, which resource it consumed, and whether the recipient is sitting in plain sight or waiting to be decoded.
TRX: the native coin
TRX is the base layer everything else sits on — “the most important cryptocurrency on the TRON network.” It pays for resources when an account’s Bandwidth or Energy runs short, is staked to obtain those resources and voting rights, and serves as collateral in DeFi lending.
Its smallest unit is the SUN, where 1 TRX = 1,000,000 SUN. Raw transaction data is denominated in SUN, which is why a one-TRX transfer shows an amount of 1000000.
Moving TRX is its own protocol transaction type — TransferContract (type 1), which “transfers TRX from one account to another.” Sender, recipient, and amount ride as top-level fields. No code runs; the protocol moves the balance directly.
TRC-10: a token the protocol understands natively
TRC-10 is where TRON diverges most sharply from Ethereum. It’s “a native token standard supported by the TRON network. Unlike TRC-20 tokens, it does not rely on the TRON Virtual Machine (TVM) but is implemented directly at the blockchain protocol level.” The chain itself knows what a TRC-10 token is — issuing or transferring one runs no contract code.
Issuance is a transaction type, not a deployment. Any account can issue a TRC-10 token through AssetIssueContract (type 6), “limited to one issuance per account — with a creation fee of 1024 TRX” (a network parameter rather than a fixed constant). No Solidity, no bytecode — the token’s name, supply, and precision are fields in a transaction the protocol records directly. Transfers get their own type too: TransferAssetContract (type 2), introduced “to transfer tokens from one account address to another,” which exposes the token, sender, recipient, and amount as readable top-level fields.
The TVM was even extended to handle TRC-10. Dedicated opcodes — CALLTOKEN and TOKENBALANCE, whose own description names the “trc10 token” — let a contract attach and read TRC-10 value. Those opcodes exist precisely because the protocol treats TRC-10 as first-class, and they’re covered alongside the rest of the TVM in Smart Contracts and the TVM. TRC-20 gets no such native support, because a TRC-20 token isn’t a protocol object at all.
TRC-20: a token that is really a smart contract
TRC-20 is “a set of contract standards for the issuance of token assets” — not a protocol primitive but a smart contract implementing a standard interface on the TVM. TRON’s glossary puts it plainly: “a technical standard used for smart contracts on the TRON blockchain for implementing tokens with the TRON Virtual Machine.”
The standard is defined by TIP-20 (status: Final), adapted from Ethereum’s ERC-20 — possible because the TVM is EVM-compatible. It fixes the interface every compliant token exposes:
| Function | What it does |
|---|---|
totalSupply() | Total tokens in existence |
balanceOf(address) | An address’s balance |
transfer(to, value) | Move tokens from the caller |
transferFrom(from, to, value) | Move tokens the caller was approved to spend |
approve(spender, value) | Authorize another address to spend the caller’s tokens |
allowance(owner, spender) | Remaining approved amount |
Two events round it out — Transfer and Approval — emitted so off-chain readers can follow token movement through logs.
[!NOTE] The
approve/allowancepair is where a lot of TRON risk lives.approve()authorizes “a third party (like a DApp smart contract) to transfer the token from the token owner’s account.” A wallet that has approved a malicious contract for an unlimited allowance can be drained later without signing anything further — the approval already granted the permission. Reading a wallet’s outstanding approvals is its own investigative step.
So a TRC-20 transfer is a TriggerSmartContract invoking transfer(address,uint256) — a contract call, behaving nothing like a native transfer. That gap drives everything below.
Resources: why TRC-20 costs more to send
Every transaction consumes Bandwidth, measured by its byte size, and each account gets 600 free Bandwidth per day — the full resource model lives in Stake 2.0. Energy is different: it “measures the amount of computation required by the TRON Virtual Machine,” and only contract execution burns it. A TRX or TRC-10 transfer runs no code, so it spends Bandwidth alone. A TRC-20 transfer is code, so it consumes Energy on top of the Bandwidth for its bytes.
What the distinction signals on-chain
Only native transfers can activate an account. A TRX or TRC-10 transfer to an uninitialized address creates and activates it; a TRC-20 transfer can’t — a point developed in Account Activation. The attribution consequence is direct: a wallet holding nothing but USDT may have been activated by someone else entirely, because the USDT funding it could never have brought it into existence. That’s why a token-only funding history is a weak attribution signal for any analyst — a TRC-20 inflow tells you less about who stood up an address than a native one does.
The recipient is readable for native transfers and hidden for TRC-20. A TransferContract or TransferAssetContract records the recipient as a real to_address. A TriggerSmartContract doesn’t: its top-level contract_address is the token contract, and the actual recipient and amount are ABI-encoded inside the call data. Reading TRC-20 flow means decoding that data, and the mechanics belong to Smart Contracts and the TVM. The dominant TRC-20 on the network, and the one most of this matters for, is USDT — its story is USDT on TRON.
Sources
- TRON Developer Hub — TRX — TRX as the native coin, the SUN unit (
1 TRX = 1,000,000 SUN), andTransferContractas the TRX transfer type. - TRON Developer Hub — TRC-10 — TRC-10 as a native, non-TVM token standard implemented at the protocol level;
AssetIssueContract, the 1024 TRX issuance fee and one-per-account limit, andTransferAssetContract. - TRON Developer Hub — TRC-20 — TRC-20 as a smart-contract token standard, the function interface, and the
approve()/allowance()authorization model. - TIP-20 — TRC-20 Token Standard — the canonical standard (status: Final), its ERC-20 derivation, and the function signatures.
- TRON Developer Hub — Glossary — the native-vs-TVM contrast between TRC-10 and TRC-20 stated directly.
- TRON Developer Hub — Resource Model — Bandwidth as the per-byte resource every transaction consumes (600 free per day) and Energy as the TVM-computation resource.
- TRON Developer Hub — Opcodes — the native TVM opcodes for TRC-10 (
CALLTOKEN,TOKENBALANCE), evidence that TRC-10 is a protocol-native asset class. - tronprotocol/protocol —
core/Tron.proto— theContractTypeenum giving the numeric transaction types (TransferContract1,TransferAssetContract2,AssetIssueContract6,TriggerSmartContract31).