Example: amount_math
To run this example:
- Clone the examples repository:
git clone https://github.com/throgxyz/examples.git - Run:
cargo run -p examples-queries --example amount_math
//! TRX ↔ sun conversions and amount arithmetic.
//!
//! TRON denominates all on-chain values in *sun* (`i64`), where:
//!
//! ```text
//! 1 TRX = 1_000_000 sun
//! ```
//!
//! [`Trx`] wraps `i64` sun and provides:
//!
//! - `from_sun` constructor (rejects negatives) and `as_sun` accessor
//! - exact decimal parsing via `str::parse` / `parse_trx` (no `f64`, 6 dp)
//! - fixed-precision formatting via `Display` / `format_trx`
//! - `+` / `-` operators that panic on overflow or a negative result
//! - non-panicking `checked_add` / `checked_sub`
//!
//! TRC20 token amounts use [`U256`] (256-bit unsigned) — identical to ERC-20.
//!
//! No network access required.
//!
//! ```bash
//! cargo run -p examples-queries --example amount_math
//! ```
use tronz::{
Trx, U256,
primitives::{SUN_PER_TRX, format_trx, parse_trx},
};
fn main() -> anyhow::Result<()> {
// ── TRX ↔ sun conversions ─────────────────────────────────────────────────
println!("=== TRX ↔ sun ===");
println!(" 1 TRX = {SUN_PER_TRX} sun (SUN_PER_TRX)");
// From a raw sun value (what the chain returns).
let one_trx = Trx::from_sun(1_000_000)?;
println!(" from_sun(1_000_000) = {one_trx} ({} sun)", one_trx.as_sun());
// From an exact decimal string — no floating point, up to 6 dp.
let half: Trx = "0.5".parse()?;
let two_and_half = parse_trx("2.5")?; // free-fn alias, like alloy's parse_ether
println!(" \"0.5\".parse() = {half} ({} sun)", half.as_sun());
println!(" parse_trx(\"2.5\") = {two_and_half} ({} sun)", two_and_half.as_sun());
// Display is exact and fixed to 6 fractional digits; `format_trx` is the
// free-fn equivalent (mirrors alloy's `format_ether`).
println!(" format_trx(2.5 TRX) = {}", format_trx(two_and_half));
// ── Arithmetic ────────────────────────────────────────────────────────────
//
// `+` / `-` panic on overflow or a negative result — amounts are always
// non-negative, so this surfaces logic bugs instead of silently wrapping.
println!("\n=== Arithmetic ===");
let a: Trx = "10".parse()?;
let b: Trx = "3.5".parse()?;
println!(" a = {a}");
println!(" b = {b}");
println!(" a + b = {}", a + b);
println!(" a - b = {}", a - b);
// ── Checked arithmetic ────────────────────────────────────────────────────
//
// Use the checked variants for untrusted input: they return `None` instead
// of panicking on overflow or a negative result.
println!("\n=== Checked arithmetic ===");
let x: Trx = "5".parse()?;
let y: Trx = "2".parse()?;
println!(" 5 - 2 = {:?}", x.checked_sub(y)); // Some(3)
println!(" 2 - 5 = {:?} (None = would be negative)", y.checked_sub(x));
let max = Trx::from_sun(i64::MAX)?;
println!(" MAX + 1 = {:?} (None = overflow)", max.checked_add(Trx::from_sun(1)?));
// ── Ordering ──────────────────────────────────────────────────────────────
println!("\n=== Ordering ===");
let amounts: [Trx; 4] = ["100".parse()?, "1.5".parse()?, "50".parse()?, Trx::ZERO];
let min = amounts.iter().min().copied().unwrap();
let max = amounts.iter().max().copied().unwrap();
println!(" min = {min}");
println!(" max = {max}");
// ── U256 for TRC20 tokens ─────────────────────────────────────────────────
//
// TRC20 balances and transfer amounts use U256, matching the ERC-20 ABI.
// A 6-decimal token (e.g. USDT) represents 1 unit as 1_000_000 in U256.
println!("\n=== U256 for TRC20 amounts ===");
let usdt_decimals: u32 = 6;
let one_usdt = U256::from(10u64).pow(U256::from(usdt_decimals));
println!(" 1 USDT = {one_usdt} (raw U256 with 6 decimals)");
let hundred_usdt = U256::from(100u64) * one_usdt;
println!(" 100 USDT = {hundred_usdt} (raw U256)");
// Human-readable formatting helper (divide by 10^decimals).
let whole = hundred_usdt / one_usdt;
let frac = hundred_usdt % one_usdt;
println!(" display : {whole}.{frac:0>6} USDT");
// 18-decimal token (like WETH bridged to TRON).
let weth_decimals: u32 = 18;
let one_weth = U256::from(10u64).pow(U256::from(weth_decimals));
println!("\n 1 WETH = {one_weth} (raw U256 with 18 decimals)");
Ok(())
}Find the source code on GitHub here.
