Accounts & Permissions
TRON accounts leverage the same cryptographic foundation as Ethereum — ECDSA with secp256k1 — while introducing native multi-signature permissions and an explicit activation model. This guide covers address encoding, activation requirements, and the built-in permission system for secure account management.
Address Format
Section titled “Address Format”A TRON address is derived from a private key using the same process as Ethereum, with one difference: the address bytes are prefixed with 41 before Base58Check encoding.
Every TRON address exists in two representations:
| Format | Prefix | Length | Example |
|---|---|---|---|
| Hex | 41 | 42 characters | 418840E6C55B9ADA326D211D818C34A994AECED808 |
| Base58Check | T | 34 characters | TNPeeaaFB7K9cmo4uQpcU32zGK8G1NYqeL |
Both refer to the same account. The hex format appears in raw API calls and internal ABI encoding. The Base58Check format (T-prefix) is what users see in wallets and explorers.
Derivation Steps
Section titled “Derivation Steps”# Task: Follow these steps to derive a TRON address from a private key.1. Generate a random 256-bit private key (64 hex characters)2. Derive the public key using ECDSA secp256k13. Keccak-256 hash the public key, take the last 20 bytes4. Prepend 0x415. Base58Check encode → T-prefix addressThis is identical to Ethereum key derivation except step 4 prepends 41 rather than 00.
Address Utilities (tronweb)
Section titled “Address Utilities (tronweb)”// Task: Validate, convert, and derive addresses via TronWeb.// ValidatetronWeb.isAddress('TNPeeaaFB7K9cmo4uQpcU32zGK8G1NYqeL'); // true
// Hex → Base58ChecktronWeb.address.fromHex('418840e6c55b9ada326d211d818c34a994aeced808');// → 'TNPeeaaFB7K9cmo4uQpcU32zGK8G1NYqeL'
// Base58Check → HextronWeb.address.toHex('TNPeeaaFB7K9cmo4uQpcU32zGK8G1NYqeL');// → '418840e6c55b9ada326d211d818c34a994aeced808'
// Derive address from private keytronWeb.address.fromPrivateKey(privateKey);
// Generate a new key pairconst { address, privateKey } = tronWeb.utils.accounts.generateAccount();Account Types
Section titled “Account Types”| Type | Description |
|---|---|
| EOA | Externally Owned Account. Controlled by a private key. Holds TRX, tokens, and can call contracts. |
| Contract Account | Created when a smart contract is deployed. Address is derived from the deployment transaction ID and sender address. No private key. |
Account Activation
Section titled “Account Activation”A freshly derived TRON address does not exist on-chain until it is activated. Until activation, the address can hold a valid key pair but the network has no record of it. Many operations — including receiving TRC-20 transfers for the first time — trigger or require activation.
(For Web2 developers: Unlike traditional databases where creating a new user record is free, blockchains require “activating” an account to prevent spam. Think of this as paying a tiny, one-time infrastructure fee to provision a permanent database row for a new user).
Activation Methods
Section titled “Activation Methods”Receive a TRX transfer The simplest path. When any account sends TRX to a new address, activation happens automatically. Cost: 1 TRX deducted from the sender.
CreateAccount API
# Task: Call the wallet/createaccount endpoint to activate an address.POST https://api.trongrid.io/wallet/createaccount
{ "owner_address": "TSenderAddress...", "account_address": "TNewAddress...", "visible": true}Cost: 1 TRX from owner_address.
Smart contract token transfer
If a TRC-20 contract transfers to an unactivated address, activation costs 25,000 Energy from the contract deployer. DApp deployers should budget for this when onboarding new users — see Fee Model for how to set origin_energy_limit to cover it.
Checking Activation Status
Section titled “Checking Activation Status”// Task: Determine if an address has been activated on-chain.const account = await tronWeb.trx.getAccount('TAddress...');// Unactivated address → empty object {}// Activated address → object with at least { address: '...', balance: 0 }const isActivated = Object.keys(account).length > 0;Transaction Size Limits
Section titled “Transaction Size Limits”To maintain network stability, TRON enforces strict transaction size limits:
- Account Creation: Transactions that create a new account must be strictly less than 1,000 bytes.
- General Transactions: All transactions (including contract deployment and execution results) are capped at a maximum size of 500 KB.
Permissions and Multi-Signature
Section titled “Permissions and Multi-Signature”TRON’s permission system allows an account to require multiple signers for transactions, and to restrict which operations each key can authorize. This is built into the protocol — no multisig contract is needed. (For Web2 developers: Think of this as native Role-Based Access Control (RBAC), similar to requiring multiple admin approvals before executing a critical production deployment).
Common uses:
- Exchange hot wallets requiring M-of-N approval for withdrawals
- DAO treasury requiring multiple council members to sign
- Separating operational keys (daily use) from administrative keys (rare, high-trust operations)
Three Permission Levels
Section titled “Three Permission Levels”| Permission | ID | Default | Controls |
|---|---|---|---|
| Owner | 0 | Threshold 1, account’s own key | All operations, including permission updates |
| Witness | 1 | Set only on SR accounts | Block production signing for Super Representatives |
| Active | 2–9 | Auto-created with standard operations | Day-to-day: transfers, contract calls, staking |
A new account starts with one Owner permission and one Active permission, both controlled by the account’s own key with threshold 1.
Permission Structure
Section titled “Permission Structure”Each permission defines:
- threshold — minimum total weight of signatures required
- keys — up to 5 address/weight pairs; each signer contributes their weight when they sign
- operations — a 32-byte bitmap specifying which of TRON’s 60 transaction types this permission can authorize
Setting Up a 2-of-3 Multi-Sig
Section titled “Setting Up a 2-of-3 Multi-Sig”// Task: Update account permissions to require 2 of 3 signers.const tx = await tronWeb.transactionBuilder.updateAccountPermissions( 'TOwnerAddress...', // account being configured { // owner permission — keep as single-key type: 0, threshold: 1, keys: [{ address: 'TOwnerAddress...', weight: 1 }], }, null, // witness permission (null if not an SR) [{ // active permissions — require 2 of 3 signers type: 2, threshold: 2, operations: '7fff1fc0033efb07000000000000000000000000000000000000000000000000', keys: [ { address: 'TSigner1...', weight: 1 }, { address: 'TSigner2...', weight: 1 }, { address: 'TSigner3...', weight: 1 }, ], }],);
const signed = await tronWeb.trx.sign(tx);await tronWeb.trx.sendRawTransaction(signed);Cost: 100 TRX for the permission update transaction.
Signing a Multi-Sig Transaction
Section titled “Signing a Multi-Sig Transaction”Once a multi-sig threshold is set, transactions from that account must be signed by enough key holders to meet the threshold before broadcast:
// Task: Sign a transaction sequentially with multiple private keys.// Signer 1 adds their signatureconst partialSigned = await tronWeb.trx.multiSign(unsignedTx, privateKey1);
// Signer 2 adds their signature to the same objectconst fullySigned = await tronWeb.trx.multiSign(partialSigned, privateKey2);
// Threshold met — broadcastconst result = await tronWeb.trx.sendRawTransaction(fullySigned);Each additional signer beyond the first adds 1 TRX to the transaction fee.
Operations Bitmap
Section titled “Operations Bitmap”The operations field is a 256-bit hex string where each bit controls one of TRON’s 60 contract types. The default active permission operations value:
# Task: Note the default bitmap for full active permissions.7fff1fc0033efb07000000000000000000000000000000000000000000000000This grants all common operations except AccountPermissionUpdateContract (which is reserved for Owner). If you need a restricted active permission — for example, an operator key that can only send TRX but cannot deploy contracts — you can compute a custom bitmap from the contract type index table in the TRON TIP documentation.
Account Resources at a Glance
Section titled “Account Resources at a Glance”// Task: Fetch all available and consumed resources for an account.const resources = await tronWeb.trx.getAccountResources('TAddress...');
// Energyconsole.log(resources.EnergyLimit); // total Energy available from stakingconsole.log(resources.EnergyUsed); // Energy consumed in current periodconsole.log(resources.TotalEnergyLimit); // your share of network Energy pool
// Bandwidthconsole.log(resources.NetLimit); // staked Bandwidth availableconsole.log(resources.NetUsed); // staked Bandwidth consumedconsole.log(resources.freeNetLimit); // free allocation (600/day)console.log(resources.freeNetUsed); // free Bandwidth consumed today
// TRON Power (voting weight from staking)console.log(resources.tronPowerUsed); // TP currently allocated to votesconsole.log(resources.tronPowerLimit); // total TP (= total staked TRX)For staking mechanics and how to increase these limits, see Fee Model & Delegation.