TRC20 tokens
TRC20 is byte-for-byte compatible with the EVM ERC20 ABI, so tronz generates the
full interface with alloy's sol! macro — no JSON ABI required. The easiest way
in is the Trc20Ext trait, which adds a .trc20() method to any provider.
use tronz::contract::Trc20Ext;Binding to a token
# async fn run(provider: impl tronz::TronProvider + Clone) -> anyhow::Result<()> {
use tronz::contract::Trc20Ext;
let usdt: tronz::Address = "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t".parse()?;
let token = provider.trc20(usdt);
# Ok(()) }provider.trc20(address) returns a Trc20Instance bound to that contract.
Reading token data
All reads are constant calls — no signer required:
# async fn run(token: tronz::contract::Trc20Instance<impl tronz::TronProvider>, who: tronz::Address) -> anyhow::Result<()> {
let name = token.name().await?; // String
let symbol = token.symbol().await?; // String
let decimals = token.decimals().await?; // u8
let supply = token.total_supply().await?; // U256
let balance = token.balance_of(who).await?; // U256
# Ok(()) }balance_of, total_supply, and allowance return raw U256 values. Apply
the token's decimals() to display them in human terms.
Transferring tokens
Writes require a signer on the provider and consume energy. transfer returns a
PendingTransaction:
use tronz::U256;
# async fn run(token: tronz::contract::Trc20Instance<impl tronz::TronProvider>, to: tronz::Address) -> anyhow::Result<()> {
let pending = token.transfer(to, U256::from(1_000_000u64)).await?;
let info = pending.get_receipt().await?;
println!("status : {:?}", info.status);
println!("contract result: {:?}", info.contract_result);
if let Some(reason) = &info.revert_reason {
println!("revert reason : {reason}");
}
# Ok(()) }Approvals
use tronz::U256;
# async fn run(token: tronz::contract::Trc20Instance<impl tronz::TronProvider>, owner: tronz::Address, spender: tronz::Address) -> anyhow::Result<()> {
// Approve a spender.
token.approve(spender, U256::from(1_000_000u64)).await?;
// Check the current allowance.
let allowed = token.allowance(owner, spender).await?;
// Move tokens you've been approved for.
token.transfer_from(owner, spender, U256::from(500_000u64)).await?;
# Ok(()) }Encoding helpers
If you need the raw calldata (e.g. to build a transaction manually or estimate
energy), the trc20 module exposes encode/decode functions and the generated
ITRC20 interface:
use tronz::contract::trc20::{encode_transfer, encode_balance_of};
use tronz::U256;
# fn run(to: tronz::Address, who: tronz::Address) {
let calldata = encode_transfer(to, U256::from(1u64));
let bal_call = encode_balance_of(who);
# }See the full runnable version in Examples → TRC20.
