Deploying Smart Contracts to Tron
Tron is not EVM in the conventional sense, although it supports Solidity. TVM (Tron Virtual Machine) is compatible with EVM at the bytecode level, but gas model, addressing, native token handling and tooling are fundamentally different. A developer coming from Ethereum will step on several rakes before the first contract deploys correctly.
Key Differences Between Tron and Ethereum
Addresses and Conversion
Tron uses Base58Check addresses (T...), not hex. One account has two representations:
- Tron address:
TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE - Hex address:
0x41d64a4e1d7af3bc84a5dd6d5b6d86bd1e45ef0ab
In smart contracts and working with ABI via TronWeb, hex form is used. For user display — Base58. TronWeb.address.toHex() and TronWeb.address.fromHex() for conversion.
Energy and Bandwidth — Not Gas
Tron does not use gas in Ethereum understanding. Instead:
- Bandwidth: cost of storing transaction bytes. Spent on any transactions. Recovers over time (1 bandwidth = 1 byte).
- Energy: analog of gas, spent when executing smart contracts. Costs TRX or TRX frozen to obtain energy.
Freezing TRX gives energy without burning — more economical for active users. For one-time operations, energy is bought directly.
Limits: when deploying contract you need sufficient energy. Standard simple contract — 50,000-200,000 energy. Without sufficient energy — transaction fails with OUT_OF_ENERGY.
Development Tools
TronBox — Truffle for Tron
npm install -g tronbox
tronbox init
tronbox.js configuration:
const { TRON_PRIVATE_KEY } = process.env
module.exports = {
networks: {
shasta: { // Testnet
privateKey: TRON_PRIVATE_KEY,
userFeePercentage: 100, // 100% fees paid by caller
feeLimit: 1_000_000_000, // max TRX (in sun) per transaction
fullHost: "https://api.shasta.trongrid.io",
network_id: "*"
},
mainnet: {
privateKey: TRON_PRIVATE_KEY,
userFeePercentage: 100,
feeLimit: 1_000_000_000,
fullHost: "https://api.trongrid.io",
network_id: "*"
}
},
compilers: {
solc: {
version: "0.8.6" // Tron TVM has limitations on Solidity versions
}
}
}
Important on Solidity versions: TVM does not always support the latest Solidity versions. At the time of writing, versions up to 0.8.18 work stably. Check compatibility on official Tron documentation before deployment.
Hardhat + tronbox-provider
Alternative if project is already on Hardhat:
npm install @tronbox/hardhat-tron
// hardhat.config.ts
import "@tronbox/hardhat-tron"
const config = {
networks: {
tron: {
url: "https://api.trongrid.io",
accounts: [process.env.TRON_PRIVATE_KEY!]
}
}
}
TronGrid API Key
TronGrid — official Tron API provider. Free plan has limits, production needs API key. Register at trondao.org.
Without API key in request headers: public rate limit is very low, unrealistic for production.
Deployment via TronBox
# Compilation
tronbox compile
# Deploy to Shasta testnet
tronbox migrate --network shasta
# Deploy to mainnet
tronbox migrate --network mainnet
Migration script migrations/2_deploy_contract.js:
const MyContract = artifacts.require("MyContract")
module.exports = function(deployer) {
deployer.deploy(
MyContract,
"constructor_arg_1",
"constructor_arg_2",
{
feeLimit: 1_000_000_000,
callValue: 0, // TRX sent on deployment (in sun, 1 TRX = 1,000,000 sun)
userFeePercentage: 100
}
)
}
TronWeb for Contract Interaction
const TronWeb = require("tronweb")
const tronWeb = new TronWeb({
fullHost: "https://api.trongrid.io",
headers: { "TRON-PRO-API-KEY": process.env.TRONGRID_API_KEY },
privateKey: process.env.TRON_PRIVATE_KEY
})
// Contract interaction
const contract = await tronWeb.contract().at(CONTRACT_ADDRESS)
// Call view function
const result = await contract.balanceOf(address).call()
// Send transaction
const tx = await contract.transfer(recipientAddress, amount).send({
feeLimit: 100_000_000,
callValue: 0
})
TRC-20 vs ERC-20
TRC-20 is Tron analog of ERC-20. ABI is identical, but:
- No
msg.valuein conventional sense for native TRX — usecallValuein transaction parameters -
address(this).balancereturns balance in sun (1 TRX = 1,000,000 sun) - For TRX transfer between contracts:
address payable target = address(uint160(hexAddress))— conversion from Tron address needed
Popular TRC-20: USDT on Tron handles huge stablecoin transaction volume in Asia — frequent integration task.
Verification on TronScan
TronScan (tronscan.org) is Tron blockchain explorer. Contract verification via UI: upload source code, specify compiler version and optimization settings. No CLI tool like hardhat-verify.
Timeline
Deploying ready EVM contract to Tron Shasta testnet: 4-8 hours (TVM adaptation, TronBox setup, getting testnet TRX via faucet). Mainnet deployment with verification: up to 2 days including testing with real energy and TRC-20 compatibility check.







