---
updatedAt: 2026-09-30T03:41:08.000Z
agentTools:
  projectIndex: https://developers.tron.network/llms.txt
---

# Solidity on TRON

Solidity language features specific to TRON: the trx unit keyword, the trcToken type for TRC-10, msg.tokenid and msg.tokenvalue, and built-in pointers to staking and voting from contracts.

> 📘 **Prerequisites**
>
> * [TVM](https://developers.tron.network/docs/tvm)
> * [Smart contracts introduction](https://developers.tron.network/docs/smart-contracts-introduction)

TRON's Solidity compiler is a fork of the upstream Solidity compiler with a small set of TRON-specific extensions. Most upstream Solidity is supported as-is, so an Ethereum contract usually compiles unchanged. The differences fall into four categories: the `trx` unit keyword, the `trcToken` type for TRC-10, message-call extras (`msg.tokenid`, `msg.tokenvalue`), and built-in pointers for staking and voting from inside a contract.

This page is the Solidity language reference. For the full SDK that wraps Stake 2.0 in idiomatic Solidity helpers, see [Stake 2.0 Solidity SDK reference](https://developers.tron.network/docs/stake-20-solidity-api).

## TRX as a unit keyword

Upstream Solidity has unit suffixes for ether (`wei`, `gwei`, `ether`). The TRON Solidity compiler adds `trx` as the equivalent for the native token and `sun` as the smallest unit:

| Unit literal | Value                 |
| :----------- | :-------------------- |
| `1 sun`      | 1 sun (smallest unit) |
| `1 trx`      | 1,000,000 sun         |

These are usable anywhere Solidity accepts a numeric literal:

```solidity
require(msg.value >= 1 trx, "Pay at least 1 TRX");
uint256 fee = 100 sun;
```

The standard upstream `wei` / `gwei` / `ether` keywords are also available but should be avoided in TRON-specific code — `trx` and `sun` make the unit unambiguous.

## TRC-10 token built-ins

TRC-10 is the protocol-level token type that lives outside the TVM (see [TRC-10](https://developers.tron.network/docs/trc10) for the full standard). TRON Solidity exposes four built-ins that let contracts handle TRC-10 tokens.

### `trcToken` type

`trcToken` is a separate type from `uint256`, used to identify a specific TRC-10 token. Values can be cast between `trcToken` and `uint256`:

```solidity
trcToken id = 1000001;
uint256 idAsUint = uint256(id);
trcToken back = trcToken(idAsUint);
```

> 📘 Valid range
>
> A valid TRC-10 `tokenId` must be greater than 1,000,000. The compiler does not enforce this — guard with `require(id > 1000000)` when accepting `tokenId` as a parameter.

### `address.transferToken(value, tokenId)`

Send a TRC-10 token from the contract to another address, in a single Solidity call:

```solidity
function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) public {
    require(id > 1000000);
    toAddress.transferToken(tokenValue, id);
}
```

The semantics mirror `address.transfer(uint256)` for TRX: the recipient must be `payable`, and only 2,300 Energy is forwarded to the recipient's `fallback` function.

### `address.tokenBalance(tokenId)`

Query the TRC-10 balance of an address from inside a contract:

```solidity
function getTokenBalance(address account, trcToken id) public view returns (uint256) {
    return account.tokenBalance(id);
}
```

### `msg.tokenid` and `msg.tokenvalue`

When a contract function is called with attached TRC-10 tokens (using `CALLTOKEN` at the bytecode level, or the `callTokenValue` and `tokenId` parameters in `triggerSmartContract`), two extra fields are populated on the `msg` object:

```solidity
function receiveTRC10() public payable returns (trcToken, uint256) {
    trcToken id = msg.tokenid;
    uint256 amount = msg.tokenvalue;
    return (id, amount);
}
```

Both default to `0` when no TRC-10 token is attached. These extras are TRON-specific — they are not present on Ethereum.

## Staking, voting, and resource delegation

TRON exposes Stake 2.0 staking, voting, and reward-claiming features as Solidity built-ins on the contract itself. Resource delegation and some query helpers are called as built-in helper methods on `address` / `address payable`. The full reference, including all 26 helpers, is in [Stake 2.0 Solidity SDK reference](https://developers.tron.network/docs/stake-20-solidity-api).

A small selection of the most-used helpers:

```solidity
// Stake TRX to acquire Bandwidth (resourceType = 0) or Energy (resourceType = 1)
freezebalancev2(amount, resourceType);

// Begin unstaking — the getUnfreezeDelayDays chain parameter sets the waiting period
unfreezebalancev2(amount, resourceType);

// Withdraw TRX whose waiting period has elapsed
withdrawexpireunfreeze();

// Vote for a Super Representative
vote(srs, voteCounts);

// Claim accumulated voting rewards
withdrawreward();
```

## Compiler version support

TRON's Solidity compiler is maintained at [github.com/tronprotocol/solidity](https://github.com/tronprotocol/solidity). Multiple major versions are supported in the TVM:

* `0.4.x` — earliest TVM-supported series; works for legacy contracts, including `^0.4.24` and `^0.4.25`.
* `0.5.x` — historically the most common baseline; supports `^0.5.0` through `^0.5.16`.
* `0.6.x` and `0.7.x` — supported.
* `0.8.x` — current recommended baseline for new contracts. Pin a concrete patch version, for example `pragma solidity 0.8.20;` (without `^`; check the [TronBox release notes](https://github.com/tronprotocol/tronbox) for the recommended patch version).

When porting an existing Solidity contract from Ethereum, your code should compile unchanged in the matching TRON Solidity version. If you encounter version-specific issues, see [Migrating from Ethereum](https://developers.tron.network/docs/migrating-eth-contracts-to-tron).

## Differences from upstream Solidity

A few specific divergences from the standard Solidity compiler:

* `gas` keyword — accepted in source for compatibility, but the underlying TVM uses Energy. `gasleft()` returns the remaining Energy budget for the current call.
* `tx.gasprice` — returns `energyPrice` rather than a per-tx gas price.
* `block.difficulty` — always `0`. TRON does not use Proof-of-Work; it uses Delegated Proof-of-Stake (DPoS).
* `block.basefee` — returns `energyPrice`. EIP-1559 is not implemented.

For the full opcode-level differences, see [TVM vs EVM](https://developers.tron.network/docs/tvm-vs-evm).

***

## Related resources

* [Stake 2.0 Solidity SDK reference](https://developers.tron.network/docs/stake-20-solidity-api) — full helper reference for staking, delegation, and voting from contracts
* [TVM vs EVM](https://developers.tron.network/docs/tvm-vs-evm) — opcode and precompile differences
* [Opcodes](https://developers.tron.network/docs/opcodes) — full TVM opcode reference
* [Migrating from Ethereum](https://developers.tron.network/docs/migrating-eth-contracts-to-tron) — practical porting walkthrough
* [Transferring TRC-10 in smart contracts](https://developers.tron.network/docs/trc10-transfer-in-smart-contracts) — examples of the TRC-10 built-ins
* [TIP-43](https://github.com/tronprotocol/tips/blob/master/tip-43.md) — TRC-10 in smart contracts specification