Event subscription
Four ways to receive TRON on-chain events — TronGrid HTTPS, TronWeb, the Fullnode's built-in ZeroMQ publisher, or self-hosted plugins (Kafka / MongoDB) — plus the V1.0 / V2.0 event service framework and the seven event trigger types.
Prerequisites
- Deploy a node — only required for the self-hosted methods
A TRON Fullnode produces a continuous stream of on-chain activity — every block, every transaction, every smart-contract log. Event subscription is the mechanism by which an application receives that stream. There are multiple ways to access it, depending on how much infrastructure you want to operate and whether you need historical backfill in addition to real-time push.
How to access events
| Method | Best for | Operates locally? | Historical backfill |
|---|---|---|---|
| TronGrid (hosted HTTPS query) | Front-ends, lightweight integrations | No — managed service | Yes (queryable by tx / block) |
| TronWeb (JavaScript SDK) | Browser and Node.js apps | No — wraps TronGrid | Yes (Mainnet + testnets; private chains not supported) |
| Built-in ZeroMQ (Fullnode publisher) | Dev work, a single in-network consumer | Yes — needs a Fullnode | No — real-time only |
| Self-hosted plugin (Kafka / MongoDB) | Indexers, analytics pipelines, durable streams | Yes — needs a Fullnode + plugin + storage | Yes (with V2.0 framework) |
The first two require no infrastructure beyond what your application already runs. The last two require operating a TRON Fullnode but give you direct access to the event stream without provider rate limits.
- TronGrid — see Get events by transaction ID and TronGrid V1 API overview. TronGrid formats event-plugin data as extension APIs and exposes them through hosted HTTPS endpoints.
- TronWeb — JavaScript SDK with built-in event helpers. See the TronWeb event API. Works on Mainnet and testnets; not available for private chains.
- Built-in ZeroMQ — TRON Fullnodes ship a built-in ZeroMQ publisher (TIP-28), so no plugin install is needed. See ZeroMQ event plugin.
- Self-hosted plugins — durable transports backed by Kafka or MongoDB. The rest of this page focuses on these.
Event service framework
When you run a self-hosted plugin, the Fullnode's event service framework is what fetches events from the chain, wraps them, queues them, and pushes them into your plugin for asynchronous storage. Two framework versions exist; the choice affects whether historical backfill is available.
| Version | Real-time pushes | Historical backfill | Default |
|---|---|---|---|
| V1.0 | Yes — events fire as new blocks are processed | No — only events produced from the moment the node starts | Yes (when event.subscribe.version is unset) |
| V2.0 | Yes | Yes — events from a configured starting height are replayed before the live stream | Opt-in via event.subscribe.version = 1 |
V2.0 was introduced to let indexers bootstrap from a specific historical block rather than only follow the chain head. For deeper background and version-selection guidance, see the Event service framework V2.0 introduction.
Migrating V1.0 → V2.0
Both versions use the same plugin binaries and the same subscription configuration; migration is mostly a one-line config flip.
-
Update the plugin. V2.0 historical sync can produce high-volume bursts; older plugin builds may run out of memory. Download the latest from event-plugin releases or build from source:
git clone https://github.com/tronprotocol/event-plugin.git cd event-plugin ./gradlew build -
Enable V2.0 in
config.conf:event.subscribe.version = 1 -
Keep your subscription configuration unchanged. The
topics,filter,path,server, anddbconfigblocks all carry over from V1.0. -
(Optional) Configure historical backfill start height:
event.subscribe.startSyncBlockNum = <block_height>startSyncBlockNum <= 0— backfill disabled; behavior matches V1.0 real-time.startSyncBlockNum > 0— backfill enabled; events from that height are replayed before the live stream starts.
-
Restart the Fullnode with
--es. Historical events replay first, then the live stream takes over.
VerifystartSyncBlockNumbefore restart.A height below your consumer's last-seen point produces duplicates; a height above produces gaps. This is the most common source of post-migration data inconsistencies.
Event types
A Fullnode emits seven trigger types. Each can be independently enabled in the plugin's topics block. The triggerName values are fixed identifiers; only the consumer-side topic name (Kafka topic or MongoDB collection) is customizable.
triggerName | Carries | Typical use |
|---|---|---|
block | Newly produced block headers | Block-height monitors, head trackers |
transaction | Transactions in newly produced blocks | Transaction indexers, mempool analyzers |
contractevent | Decoded contract events (parsed against ABI) | Application back-ends consuming events as structured records |
contractlog | Raw contract logs (topics + data) | DeFi indexers, NFT trackers handling raw logs |
solidity | Solidified block headers (≥19-SR confirmed) | Exchanges, bridges — anything needing finality before acting |
solidityevent | Decoded contract events on solidified blocks | Same as contractevent but post-finality |
soliditylog | Raw contract logs on solidified blocks | Same as contractlog but post-finality |
Event subscription resource costSubscribing to many trigger types simultaneously raises the Fullnode's CPU and memory cost. Pick the smallest set that meets your application's needs — for most use cases, one or two.
Trigger payloads
The payloads carry these fields:
Block / Solidity trigger
timeStamp block timestamp
triggerName "blockTrigger" or "solidityTrigger"
blockNumber block height
blockHash block ID
transactionSize number of transactions in the block
latestSolidifiedBlockNumber most recent solidified height
transactionList list of transaction hashesTransaction trigger
blockHash block ID
blockNumber block height
energyUsage total Energy consumed by the transaction
energyFee TRX burned to cover Energy
originEnergyUsage Energy paid by the contract deployer
energyUsageTotal total Energy (caller + deployer + burn)Contract event trigger / solidityevent
transactionId transaction hash
contractAddress contract address
callerAddress address that invoked the contract
blockNumber containing block height
blockTimestamp block timestamp
eventSignature Solidity event signature
topicMap map of indexed topics (name → value)
data non-indexed event data (Solidity representation)
removed true if log was removed (reorg)Contract log trigger / soliditylog
transactionId transaction hash
contractAddress contract address
callerAddress address that invoked the contract
blockNumber containing block height
blockTimestamp block timestamp
contractTopics list of raw 32-byte topics
data raw event data
removed true if log was removed (reorg)For the canonical specification, see TIP-12 — Event subscription.
Filter syntax
The filter block narrows contract-event and contract-log streams. It does not apply to block / transaction triggers.
| Field | Meaning |
|---|---|
fromblock | "", "earliest", or a specific height; lower bound (inclusive) |
toblock | "", "latest", or a specific height; upper bound (inclusive) |
contractAddress | List of contract addresses; empty list matches all |
contractTopic | List of event topic hashes; empty list matches all |
Self-hosted plugin architecture
For the self-hosted path, the Fullnode loads a plugin (a Java JAR) at start-up; the plugin handles the transport to your chosen message system or storage.
┌────────────────┐ events ┌──────────────┐ transport ┌──────────────┐
│ TRON Fullnode │ ───────────────▶ │ Plugin │ ────────────────▶ │ Consumer │
│ (java-tron) │ (in-process) │ (.jar) │ (ZMQ/Kafka/Mongo) │ (your app) │
└────────────────┘ └──────────────┘ └──────────────┘Two plugin implementations ship as reference:
| Plugin | Transport | Best for | Doc |
|---|---|---|---|
| Kafka | Apache Kafka topics | Durable streams, multiple consumers, replay by offset | Kafka plugin |
| MongoDB | MongoDB collections | Indexed event storage, ad-hoc queries | MongoDB plugin |
The Fullnode's built-in ZeroMQ publisher serves the same role for cases where you don't want to operate a separate plugin or storage layer — see ZeroMQ event plugin.
You can write your own plugin against the java-tron event SPI — the entry point is the org.tron.common.logsfilter.IPluginEventListener interface. Kafka and MongoDB are reference implementations; the event-plugin source is the template.
Choosing a plugin
- ZeroMQ — lowest setup cost; no persistence; best for development or a single in-network consumer.
- Kafka — durable; supports replay by offset; multiple downstream consumers; best when you already operate Kafka.
- MongoDB — indexed storage; pairs with the optional TRON Event Query HTTP service for ad-hoc lookups.
Enabling event subscription
Same flow regardless of plugin:
- Build or download the plugin JAR (or the latest event-plugin release).
- Place the JAR somewhere readable by the Fullnode.
- Add the
event.subscribeblock toconfig.conf— setpathto the JAR,serverto the transport endpoint, andtopics/filterto your subscription. - Restart the Fullnode with
--es.
Per-plugin specifics (Kafka topic creation, MongoDB account provisioning, etc.) live in the per-plugin docs.
Resource cost.Event subscription adds CPU and memory load to the Fullnode. For high-throughput SR nodes, consider running event subscription on a separate dedicated Fullnode that syncs the same chain, so event processing does not compete with the consensus thread.
Related resources
- TronGrid V1 API overview — query on-chain events through hosted HTTPS APIs
- TronWeb event API — JavaScript SDK helpers
- ZeroMQ event plugin — Built-in pub-sub
- Kafka event plugin — Durable streams with replay
- MongoDB event plugin — Indexed event storage
- Event service framework V2.0 introduction — Background on V2.0
- TIP-12 — Event subscription — Canonical specification
- event-plugin source — Reference implementations and SPI template
- Listen to contract events — Application-level recipe
Updated 5 days ago