๐ What are Event Logs in TRON?
Event Logs are a mechanism for smart contracts to emit structured data that is stored in the blockchain's transaction receipt. They allow off-chain applications to track contract activity, monitor state changes, and react to on-chain events efficiently without reading the entire contract state.
Events are defined in Solidity using the event keyword and emitted with the emit statement. When a transaction is executed, all emitted events are recorded in the receipt and can be retrieved later.
Events are the primary way for dApps and backends to be notified about what happened in a transaction. They are essential for building responsive UIs, tracking token transfers, auditing contract usage, and building analytics.
๐ฌ Log Structure & Topics
Each event log in TRON consists of several components. Understanding this structure is key to querying and decoding events:
| Component | Description | Example |
|---|---|---|
| Address | Contract address that emitted the event | 0x41... |
| Topics | Array of up to 4 32-byte values (topic0 = event signature, topics 1-3 = indexed parameters) | ["0xddf252...", "0x0000..."] |
| Data | Hex-encoded non-indexed event parameters | 0x000000000000000000000000... |
| Block Number | Block in which the log was created | 12345678 |
| Transaction Hash | Hash of the transaction that emitted the log | 0xabc... |
Example: Transfer Event Log
event Transfer(address indexed from, address indexed to, uint256 amount);
// Emitted log structure:
// topic0 = keccak256("Transfer(address,address,uint256)")
// topic1 = from address (indexed)
// topic2 = to address (indexed)
// data = amount (non-indexed, 32 bytes)
๐ท๏ธ Indexed vs. Non-Indexed Parameters
One of the most important concepts in the event system is the distinction between indexed and non-indexed parameters:
- Indexed parameters (up to 3 per event) are stored as topics and can be used for efficient filtering when querying logs. They are typically used for addresses, IDs, or other values you want to search by.
- Non-indexed parameters are stored in the data field and cannot be filtered directly. They are used for values that don't need to be searchable.
Index parameters that you will frequently filter by โ like sender address, recipient address, token ID, or order ID. Leave other parameters non-indexed to save gas and keep logs compact.
event OrderCreated(address indexed user, uint256 indexed orderId, uint256 amount, uint256 timestamp);
// Filter by user OR orderId โ efficient
๐ Querying Event Logs
There are several ways to query event logs on TRON, depending on your needs:
1. Using TronWeb
const events = await tronWeb.getEventResult(
contractAddress,
{
eventName: "Transfer",
blockNumber: "latest",
pageSize: 10
}
);
// Filter by indexed parameter (from address)
const fromEvents = await tronWeb.getEventResult(
contractAddress,
{
eventName: "Transfer",
filter: { from: "0x41..." },
blockNumber: 10000000,
pageSize: 20
}
);
2. Using TronScan API
GET https://api.tronscan.org/api/contract/events?
contract={address}&
eventName=Transfer&
limit=20&
start=0
3. Using TronGrid (Data Indexing)
For more complex queries, TronGrid provides a GraphQL interface that allows you to query events with advanced filtering, sorting, and pagination.
๐ก Listening to Events in Real-Time
TronWeb provides a powerful event listener API that lets you react to events as they happen:
const contract = await tronWeb.contract(abi, contractAddress);
// Listen to Transfer events
contract.events.Transfer()
.on('data', (event) => {
console.log('Transfer detected:', event);
console.log('From:', event.returnValues.from);
console.log('To:', event.returnValues.to);
console.log('Amount:', event.returnValues.amount);
})
.on('error', (err) => {
console.error('Event listener error:', err);
});
// Filter by from address
contract.events.Transfer({ filter: { from: '0x41...' } })
.on('data', (event) => { /* handle */ });
Event listeners rely on a persistent connection to a TRON node. For production use, consider using WebSocket connections and implementing reconnection logic. Also, be mindful of the volume of events โ use filters to reduce the data load.
๐ Common Use Cases for Events
- Token transfer tracking: Monitor USDT TRC20 or other token transfers for your application.
- Order book management: Track order creation, matching, and cancellation events in a DEX.
- Audit trails: Keep a comprehensive log of all contract interactions for compliance.
- Analytics dashboards: Build real-time dashboards showing on-chain activity.
- User notifications: Notify users when their transactions are confirmed or when specific events occur.
- Cross-chain bridges: Monitor deposit events to trigger cross-chain transfers.
๐ Best Practices for Events
- Keep events informative: Include all data needed for off-chain applications to understand the state change.
- Use indexed parameters wisely: Index the parameters you will filter by; avoid indexing large strings or arrays.
- Version your events: If you modify an event, consider adding a version number or creating a new event type to avoid breaking existing listeners.
- Test event emission: Use TronBox or Hardhat to test that events are emitted correctly in your smart contract tests.
- Monitor event sizes: Events that are too large can increase gas costs; keep the data payload minimal.
For large applications, consider using a dedicated indexing service like TronGrid or The Graph to efficiently query historical events without scanning the blockchain directly.