A library for secure smart contract development on TRON. A port of OpenZeppelin Contracts to the TRON Virtual Machine (TVM), adapted to TRON's standards (TIPs / TRCs) and to the ways the TVM differs from the EVM.
@openzeppelin/tron-contracts is based on OpenZeppelin Contracts — versions match upstream by major and minor (see Versioning) — and keeps its battle-tested implementations, while:
- Renaming the standards that TRON publishes under its own identifiers — for example
ERC20→TRC20,ERC165→TRC165,EIP712→TIP712— and dual-citing both the TRON (TIP / TRC) and Ethereum (EIP / ERC) specifications in the documentation. - Adapting the implementations where the TVM diverges from the EVM (e.g.
CREATE2address derivation, theblock.chainidused in EIP-712 domain separators, the TRC-721 receiver hook, and tokens such as TRON USDT whosetransferreturnsfalseon success).
Where TRON only publishes a signing or utility spec (rather than a renamable contract standard), the contract keeps its descriptive name (e.g. ECDSA, MessageHashUtils, P256) and simply references the relevant TIP.
Versions track OpenZeppelin Contracts by major and minor: each @openzeppelin/tron-contracts minor ports the feature set of the same-numbered upstream release, and new upstream features arrive only with a new matching minor. Patch numbers are independent — each library patches on its own schedule, so a given patch number does not refer to the same-numbered upstream patch (for example, this library may release a 5.6.0 while OpenZeppelin Contracts is already at 5.6.1). Upstream fixes that affect ported code are backported regardless of which upstream release carried them.
npm install @openzeppelin/tron-contracts// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {TRC20} from "@openzeppelin/tron-contracts/token/TRC20/TRC20.sol";
contract MyToken is TRC20 {
constructor() TRC20("MyToken", "MTK") {
_mint(msg.sender, 1000 * 10 ** decimals());
}
}The TVM is EVM-compatible, but TRON standardizes many interfaces under its own TIP (TRON Improvement Proposal) and TRC numbers. This library references the TRON standard and dual-cites the Ethereum equivalent where one exists.
| Domain | TRON | Ethereum | Contracts |
|---|---|---|---|
| Fungible token | TRC-20 | ERC-20 | TRC20 (+ extensions) |
| Non-fungible token | TRC-721 | ERC-721 | TRC721 (+ extensions) |
| Multi-token | TRC-1155 | ERC-1155 | TRC1155 (+ extensions) |
| Tokenized vault | TRC-4626 | ERC-4626 | TRC4626 |
| Permit (gasless approval) | TIP-2612 | ERC-2612 | TRC20Permit, ITRC20Permit |
| Interface introspection | TRC-165 | ERC-165 | TRC165, TRC165Checker, ITRC165 |
| Proxy storage slots | TRC-1967 | ERC-1967 | TRC1967Proxy, TRC1967Utils, ITRC1967 |
| Meta-transactions | TRC-2771 | ERC-2771 | TRC2771Context, TRC2771Forwarder |
| Contract signature validation | TRC-1271 | ERC-1271 | ITRC1271, SignatureChecker |
| Typed structured data | TIP-712 | EIP-712 | TIP712 |
| Domain | TRON | Ethereum | Contracts |
|---|---|---|---|
Signed data (0x19 prefix) |
TIP-191 | ERC-191 | MessageHashUtils |
| ECDSA signature encoding | TIP-120 | — | ECDSA |
| secp256r1 (P256) precompile | TIP-7951 | EIP-7951 / RIP-7212 | P256 |
| Namespaced storage layout | TIP-7201 | ERC-7201 | Initializable, SlotDerivation |
CREATE2 address derivation |
TIP-26 | EIP-1014 | Create2, Clones |
Note
Several of these carry TVM-specific behavior documented in the affected contract's NatSpec — for example: the TIP-712 domain separator masks chainId to its low four bytes (the value TRON exposes via eth_chainId); CREATE2 derives addresses with a 0x41 prefix; and TRON USDT's transfer returns false even on a successful transfer, which SafeTRC20.safeTransferChecked handles by verifying the caller's balance delta (the sender's debit).
This port adapts non-obvious differences between the TVM and the EVM, including CREATE2 / plain CREATE address derivation, the block.chainid value used in TIP-712 domain separators, the TRC-721 receiver-hook magic value, and the handling of tokens that return false on a successful transfer. Each adaptation is documented in the affected contract's NatSpec.
This library works with contract-based tokens: TRC-20, TRC-721, TRC-1155 and the other TRC standards listed above. Native TRC-10 assets, which a TRON account can hold alongside TRX, are outside its scope.
Moving a TRC-10 requires the TVM's token-aware call — address.transferToken(amount, id), compiling to CALLTOKEN. Every value-bearing path here uses an ordinary call, which carries TRX only. A TRC-10 credited to a contract built on this library therefore stays with that contract, and no supplied path forwards or withdraws it. This includes the governance executors: Governor.relay, Governor.execute and TimelockController.execute/executeBatch accept TRX through value, and their proposal and operation hashes bind targets, TRX values and calldata, with no field for a token identifier or amount.
Hold assets that contracts need to move as TRC-20 — either natively or by wrapping the TRC-10.
Important
Addresses embedded inside bytes payloads MUST use the 20-byte EVM form. During execution the TVM represents every address as the low 20 bytes, so msg.sender, address(this), and address-typed arguments are identical to the EVM. The 21-byte 0x41-prefixed and Base58Check (T…) forms that TRON tooling (TronWeb, node APIs) works with are off-chain encodings only — they never appear on-chain. When an address is carried inside a bytes argument — an ERC-7930 interoperable address, a crosschain bridge message, an ERC-7913 signer (verifier || key), or any packed calldata — it must be the raw 20-byte value. The 21-byte form is rejected where the format is self-describing (InteroperableAddress.parseEvmV1 and BridgeFungible revert on a non-20-byte address) and would otherwise be silently mis-parsed into the wrong address. Strip the 0x41 prefix at the encoding boundary (e.g. in your TronWeb integration) before placing an address in a bytes payload.
Please report any security issues responsibly via the security policy rather than opening a public issue.
OpenZeppelin Contracts for TRON is released under the MIT License.