Skip to content

Solidity Basics

Solidity is the industry-standard language for building decentralized applications on TRON’s EVM-compatible virtual machine. This primer introduces core smart contract concepts, from state variables and mappings to immutability and atomic execution, specifically tailored for developers entering the TRON ecosystem.

If you are new to blockchain development, you might be asking: Is Solidity the only smart contract language?

No, it isn’t the only one. You might hear about Rust (used on Solana), Vyper (a Pythonic alternative for EVM), or Move (used on Aptos/Sui). However, Solidity is the undisputed industry standard.

Learning Solidity is the highest-leverage skill in Web3. Because the vast majority of blockchains—including TRON, Ethereum, Polygon, Binance Smart Chain, and Avalanche—use EVM-compatible environments, writing Solidity allows your code to run on almost any major network.

If you are choosing a language to start your blockchain development journey, Solidity is unequivocally the best place to begin.


Before diving into code, it helps to understand the architecture. How does a web app actually talk to a smart contract?

  1. The Smart Contract (Backend): You write logic in Solidity. Once compiled and deployed, it lives permanently on the TRON blockchain.
  2. The ABI (The Bridge): When you compile Solidity, it generates an Application Binary Interface (ABI). This is simply a JSON file that tells your JavaScript frontend what functions exist in the contract and how to format data for them.
  3. The Wallet (Identity & Security): Users install a browser extension like TronLink. This holds their private keys and securely signs transactions without exposing their secrets to your frontend.
  4. TronWeb (The API): Your frontend uses the tronweb JavaScript library to ask the wallet to sign a transaction, which is then broadcast to the TRON network to trigger your Solidity functions.

(If you want a deep dive into the JavaScript side of things later, bookmark our tronweb SDK Guide.)


Solidity strongly resembles JavaScript, C++, and Python in its syntax, and it is statically typed (you must define the data type of every variable). However, the environment it runs in makes it fundamentally different.

If you are coming from Web2, here are the “Aha!” moments that will change how you think about coding:

When you deploy a Python script to a server, you can always SSH in and fix a bug. In Solidity, once a contract is deployed, it cannot be changed. If there is a bug, it is permanent. (Developers use advanced “proxy patterns” to upgrade contracts, but the base deployment is immutable).

In JavaScript, you create arrays and objects without a second thought. In Solidity, writing data to the blockchain’s permanent storage costs network resources. On TRON, this consumes Energy. Developers spend a lot of time optimizing data types to save users money. (Curious about how Energy works? See our Fee Model Guide.)

If a Python script hits an error halfway through a database update, you might have partially updated data. In Solidity, state changes are atomic. If a function hits an error or a require() statement fails, the entire transaction reverts. It’s as if nothing ever happened, though the user still pays the Energy cost for the failed execution.

Blockchains must be completely deterministic (every node must calculate the exact same result). Because floating-point math (0.1 + 0.2 = 0.30000000000000004) can vary slightly between CPU architectures, Solidity does not support decimals.

To represent 1.5 TRX, you represent it as a massive integer using its smallest unit (SUN): 1500000. Don’t worry about doing this math manually—your frontend will simply use tronWeb.toSun(1.5) and tronWeb.fromSun(1500000) to handle the conversions for the user.


Here are the fundamental building blocks you’ll use when writing TRON smart contracts.

State variables are permanently stored on the blockchain. Solidity also provides “Global Variables” that give you information about the blockchain and the person calling the contract.

pragma solidity ^0.8.18;
contract TypesExample {
// State variables (Stored permanently on the TRON blockchain)
uint256 public myNumber = 42; // Unsigned integer (no negatives)
address public myAddress; // TRON addresses (starts with T)
bool public isActive = true; // Boolean
string public greeting = "Hello!"; // Text
function getCallerInfo() public view returns (address, uint256) {
// Global variables available in every function
// msg.sender is injected automatically by the user's TronLink wallet
address caller = msg.sender;
uint256 timestamp = block.timestamp; // The current block time
return (caller, timestamp);
}
}

If you know Python dictionaries or JavaScript Objects, you know Mappings. They are the most gas-efficient way to store key-value data on the blockchain.

pragma solidity ^0.8.18;
contract MappingExample {
// A mapping from a TRON Address to a uint256 balance
mapping(address => uint256) public balances;
function addBalance() public {
// msg.sender is the wallet executing the transaction
balances[msg.sender] += 100;
}
}

Functions are where the actual logic happens. You can control who is allowed to call a function using modifiers. Most uniquely, functions can be marked payable, meaning they can securely receive TRX directly within the transaction.

pragma solidity ^0.8.18;
contract FunctionsExample {
address public owner;
constructor() {
// Runs once when the contract is deployed
owner = msg.sender;
}
// A modifier checks a condition before a function runs
modifier onlyOwner() {
require(msg.sender == owner, "Only the owner can do this!");
_; // Continue executing the function
}
// A state-changing function (costs Energy)
function changeOwner(address newOwner) public onlyOwner {
owner = newOwner;
}
// The 'payable' keyword allows this function to receive TRX
function deposit() public payable {
// msg.value is automatically populated with the amount of TRX (in SUN) sent by the user
require(msg.value > 0, "Must send TRX!");
}
}

Smart contracts cannot easily “talk” to the outside world. Instead, they emit Events. A frontend application (using tronweb) can listen for these events and update the user interface when they occur, which is how DApps stay synced in real-time.

pragma solidity ^0.8.18;
contract EventExample {
// Declare the event
event DataUpdated(address indexed user, uint256 newValue);
function updateData(uint256 _value) public {
// ... perform logic ...
// Broadcast the event to the network
emit DataUpdated(msg.sender, _value);
}
}

Standard Templates (Don’t Reinvent the Wheel)

Section titled “Standard Templates (Don’t Reinvent the Wheel)”

When building traditional software, you use packages and libraries. In Web3, security is paramount, so developers rely on audited standard contracts.

If you want to build a TRC-20 token, you do not write it from scratch. You import audited code from libraries like OpenZeppelin. Because TVM is EVM-compatible, OpenZeppelin’s standard Ethereum contracts work perfectly on TRON. (To learn more about TRON’s specific token mechanics, check out our Token Standards Guide.)


Solidity is a massive topic, and this page is just the beginning. As you build more complex TRON DApps, you’ll inevitably need to search for solutions, patterns, and tutorials online.

When looking for help, you don’t necessarily need to add “TRON” to your search queries. General Solidity searches work perfectly. Try searching for:

  • “Solidity mappings vs arrays”
  • “OpenZeppelin ERC-20 tutorial” (Remember, ERC-20 code is identical to TRC-20 code!)
  • “Solidity reentrancy guard example”
  • “Solidity interface and abstract contracts”

You will find that 99% of the Solidity tutorials, forums, and StackOverflow answers you find online are written for Ethereum. This is completely fine. You can copy, paste, and learn from Ethereum Solidity code directly.

However, there are a few minor differences in how TRON handles things under the hood (for example, TRON uses Energy and Bandwidth instead of Ethereum’s unified Gas system, and TRON blocks are faster).

Now that you have a grasp on the language, bookmark our Quick Reference page. It contains all the essential TRON network endpoints, chain IDs, and initialization snippets you’ll need as you start building your DApp!