You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Discussion: Add input and output fields to InternalTransactions #816
This proposal adds input (call data) and output (return data) fields to InternalTransactions in the TRON protocol.
The Problem
TRON currently does not persist these specific fields in its database. As a result, indexers and explorers cannot fetch critical information regarding internal actions, such as:
Function call parameters within contract-to-contract interactions.
Deployment data for contracts created via factory patterns (internal CREATE/CREATE2).
The Solution
By capturing and storing these fields, TRON will provide complete execution traces (similar to EVM standards). This will:
Improve Transparency: Provide full visibility into nested contract execution.
Enable Better Indexing: Allow tools to accurately track internal state changes and factory deployments.
Enhance Developer Experience: Simplify debugging by exposing return values from internal calls.
@roseshahar
Could you clarify the concrete use cases and consumers for this data, and whether
full persistence is required versus trace-based or optional solutions?
@lxcmyf This change only affects nodes that use saveInternalTx
Example use cases:
Data indexers - currently no one can index what an internal transaction did (sighash, output, etc...). For example you can see that Allium's TRON contracts table is very partial.
Contract deployments via factories - Contract constructors cannot be found. Also, the only way currently to get the bytecode of a contract that was deployed via a factory is by using an external node call GetContract / eth_getCode, and can't be found via block endpoints. This means you can't fully index these contracts the same as normal deployments
@waynercheung The data will not be accessible historical because it does not exist in the database currently. However, if you will re-sync a node from Genesis after this change, that data will be available
@roseshahar If input/output is added, the node database may expand, especially for transactions with frequent internal calls. It is suggested to introduce configuration options that allow users to configure on their own whether to enable the addition of input/output. Also, evaluate the average field size (input may be hundreds of bytes) and test the impact on node synchronization time.
@roseshahar
Since the agreement of internal transactions does not participate in consensus, it is recommended to customize and develop fullnode and add these two fields to meet your needs.
This change makes a lot of sense - being able to see input and output data from internal transactions will really help developers understand what’s actually happening under the hood. Right now a lot of important context (like contract call params and return values) is basically invisible, which makes debugging and building tooling harder than it needs to be. Capturing these fields would bring TRON’s execution traces closer to what developers are used to on EVM-style chains, and I’d love to see this move forward.
@lxcmyf
Thanks for suggesting the custom fullnode development as an option. I think this is a solid alternative since internal tx don't affect consensus, making it low-risk and quick to implement for those who need it right away. It avoids bloating the core protocol and lets users fork java-tron to add input/output fields locally, similar to how some Ethereum nodes handle custom tracing.
First of all, you can read about how custom tracers work on Geth here. The Geth team developed a solid API where you can just "drop-in" your tracer file, and it has access to a very defined set of input. In this case, the data is not saved, it can not be accessed even if you gave a plugin API.
When you say "just run a custom node" you are just inviting builders to the mess of merge-conflicts, running your own node which is not that simple on TRON, and getting your database conflicting with upstream changes.
Second, this is not bloating, this is a must have for supporting builders on your chain. If you have access to Allium's tables you can see that most of the Contracts table is empty because they just don't have the data. Adding the input and output is not bloating since the InternalTransaction is already feature-flagged.
@lxcmyf Since one of the most active issues on TRON is an archive node I think that any step in this direction does help the consensus, even if the people who upvoted are not active here.
@roseshahar
Adding input/output fields may not be necessary for all developers, so having saveInternalTx automatically include input/output data isn't an optimal approach.
It would be better to provide a separate configuration flag allowing developers to choose whether to store this data.
@roseshahar
I think the archive node is not a good idea. Due to the large amount of data generated by archive node snapshots, Tron currently does not support providing snapshots of archive nodes.
@waynercheung , in my opinion having an extra new flag is not optimal as it will be confusing for developers and data platforms and indexers. Enabling saveInternalTx should be enough to store ALL Internal Txns data.
Most of the RPC providers does not support saveInternalTx flag by default nowadays, making @roseshahar suggestion a separate flag will just add unnecessary friction/complexity for RPC and Indexers.
This will be a great feature for On-chain analysis and debugging on TRON :)
@simbadMarino , thanks for sharing your thoughts—I agree that keeping things simple under one flag could reduce confusion and make it easier for indexers/RPCs to get full data when they enable saveInternalTx. The potential for better on-chain analysis and debugging is definitely a big win for TRON.
However, I still think a separate flag (e.g., saveInternalTxDetails defaulting to off) could offer valuable flexibility without much added complexity. Not all nodes need the extra storage for input/output, especially resource-light setups or those just wanting basic internal tx tracking.
Technically, it's straightforward to implement in java-tron (just a conditional in the storage logic), and it could encourage more providers to enable the base feature without committing to full overhead.
What do you think about benchmarking the storage impact first, or maybe making it configurable via a sub-flag? Would love to hear from others on real-world RPC experiences!
Token Terminal supports adding input (call data) and output (return data) to TRON InternalTransactions, as proposed in this issue.
Why this matters
On EVM chains, indexers rely on execution traces to decode function selectors/parameters and return data for nested contract calls, especially when protocols don’t emit complete events. TRON nodes can return internal transactions (e.g., via gettransactioninfobyid when internal tx storage is enabled), but the internal tx objects lack input/output, which blocks reliable function-level decoding.
Impact for onchain data analysis
Enables accurate analytics for protocols where events are incomplete or absent (For example, Sky’s financial metrics couldn’t be captured on Ethereum without input/output fields on traces)
Improves visibility into contract-to-contract interactions and factory deployments
Brings TRON closer to the “full trace” baseline indexers expect from EVM chains
Summary
┌────────────────────────────────┬────────┐
│ Metric │ Value │
├────────────────────────────────┼────────┤
│ Average transactions per block │ 336.98 │
├────────────────────────────────┼────────┤
│ Average traces per block │ 345.28 │
├────────────────────────────────┼────────┤
│ Average traces per transaction │ 1.02 │
└────────────────────────────────┴────────┘
Transaction Stats
┌─────────────────────────────┬───────┐
│ Metric │ Value │
├─────────────────────────────┼───────┤
│ Min transactions in a block │ 222 │
├─────────────────────────────┼───────┤
│ Max transactions in a block │ 494 │
└─────────────────────────────┴───────┘
Trace Stats
┌───────────────────────┬───────┐
│ Metric │ Value │
├───────────────────────┼───────┤
│ Min traces in a block │ 223 │
├───────────────────────┼───────┤
│ Max traces in a block │ 510 │
└───────────────────────┴───────┘
Trace Input Size
┌───────────────────┬─────────────┐
│ Metric │ Value │
├───────────────────┼─────────────┤
│ Average per trace │ 29.66 bytes │
└───────────────────┴─────────────┘
Trace Output Size
┌────────────────────┬────────────┐
│ Metric │ Value │
├────────────────────┼────────────┤
│ Average per trace │ 7.86 bytes │
└────────────────────┴────────────┘
In my opinion this is a pretty tiny amount of added data relative to the total transaction size, and has huge impact on the usability of TRON
Thanks for the analysis, but I have concerns about the methodology, to make the discussion even stronger, could you share more about the methodology and source?
For example:
What dataset or blocks did you sample (e.g., recent blocks from TronScan or a node replay)?
How many blocks/transactions were analyzed, and over what time period?
How were "traces" defined and counted (e.g., internal calls/CREATEs via TVM execution)?
Any specifics on how input/output sizes were measured?
Having those details would help the community and other developers verify/reproduce it and address any edge cases (e.g., outliers with very long inputs in complex DeFi calls).
If it's based on a public query or script, linking it could be super helpful for others to build on.
Overall, this kind of quantitative backing is exactly what helps move the TIP forward—great work!
Curious if you've run any node-level benchmarks with the PR changes to see real-world DB growth?
@waynercheung I've ran this analysis on the latest 100~ blocks on TRON at the time of sending the message.
For measuring this I had to run a custom node that can export traces, as this data is not available in any way possible other than running a patched node.
It's possible that the block range you selected happened to be during a specific low-activity period, so it's recommended to expand the block range, such as 200K blocks(~ one week).
Expected in 200K blocks: ~32,000 CREATEs
Time: ~6-8 hours
Could you perform this verification, as it would provide more sample data for developers to discuss and further validate?
Thanks
From a storage perspective, an extra ~40 bytes per trace seems manageable on modern hardware, but the CREATE operation discrepancy (missing 97% of deployments) suggests the current sample may underestimate real-world usage.
Agree that the 200K-block validation is necessary before moving forward. If the larger sample confirms <200GB/year overhead, the benefits likely outweigh costs; if it scales to 1TB+ or significantly impacts sync, the optional-flag approach becomes more appropriate.
Let's wait for the comprehensive data before deciding.
I support improving internal transaction trace completeness, but the storage/indexing boundary needs to be explicit.
The next useful artifact would be the larger 200k-block sample with separate estimates for CALL, CREATE, and CREATE2, because deployment data appears to be where the current trace format loses the most information. I would also define whether input/output are consensus data, full-node database fields, event plugin/indexer fields, or API-only derived fields. That distinction matters for pruning, historical backfill, and backward compatibility with existing explorer/indexer APIs.
The main open item is still the storage and performance validation. The earlier 50k-block analysis was affected by a trace collection bug that missed most contract creations, and no corrected 200k-block dataset has been published yet.
Before moving forward, it would be useful to provide:
separate statistics for CALL, CREATE, and CREATE2;
P50/P90/P99/max input and output sizes;
estimated annual database growth;
node synchronization and query-performance benchmarks;
clarification on whether the fields are FullNode database data, plugin/indexer data, or API-derived traces;
a decision on whether storage is controlled by saveInternalTx or a separate optional flag.
The feature remains valuable for indexers, factory deployments, debugging, and security analysis, but the corrected benchmark is still needed to evaluate its operational cost.
Activity
roseshahar commentedon Jan 16, 2026
Related Pull Request: #817
lxcmyf commentedon Jan 16, 2026
@roseshahar
Could you clarify the concrete use cases and consumers for this data, and whether
full persistence is required versus trace-based or optional solutions?
roseshahar commentedon Jan 16, 2026
@lxcmyf This change only affects nodes that use
saveInternalTxExample use cases:
GetContract/eth_getCode, and can't be found viablockendpoints. This means you can't fully index these contracts the same as normal deploymentswaynercheung commentedon Jan 16, 2026
@roseshahar Will input/output data for historical transactions be accessible? If yes, through what mechanism?
roseshahar commentedon Jan 16, 2026
@waynercheung The data will not be accessible historical because it does not exist in the database currently. However, if you will re-sync a node from Genesis after this change, that data will be available
waynercheung commentedon Jan 17, 2026
@roseshahar If input/output is added, the node database may expand, especially for transactions with frequent internal calls. It is suggested to introduce configuration options that allow users to configure on their own whether to enable the addition of input/output. Also, evaluate the average field size (input may be hundreds of bytes) and test the impact on node synchronization time.
lxcmyf commentedon Jan 18, 2026
@roseshahar
Since the agreement of internal transactions does not participate in consensus, it is recommended to customize and develop fullnode and add these two fields to meet your needs.
yuval99g commentedon Jan 18, 2026
This change makes a lot of sense - being able to see input and output data from internal transactions will really help developers understand what’s actually happening under the hood. Right now a lot of important context (like contract call params and return values) is basically invisible, which makes debugging and building tooling harder than it needs to be. Capturing these fields would bring TRON’s execution traces closer to what developers are used to on EVM-style chains, and I’d love to see this move forward.
waynercheung commentedon Jan 18, 2026
@lxcmyf
Thanks for suggesting the custom fullnode development as an option. I think this is a solid alternative since internal tx don't affect consensus, making it low-risk and quick to implement for those who need it right away. It avoids bloating the core protocol and lets users fork java-tron to add input/output fields locally, similar to how some Ethereum nodes handle custom tracing.
roseshahar commentedon Jan 19, 2026
@waynercheung This is absolutely not the case.
First of all, you can read about how custom tracers work on Geth here. The Geth team developed a solid API where you can just "drop-in" your tracer file, and it has access to a very defined set of input. In this case, the data is not saved, it can not be accessed even if you gave a plugin API.
When you say "just run a custom node" you are just inviting builders to the mess of merge-conflicts, running your own node which is not that simple on TRON, and getting your database conflicting with upstream changes.
Second, this is not bloating, this is a must have for supporting builders on your chain. If you have access to Allium's tables you can see that most of the
Contractstable is empty because they just don't have the data. Adding theinputandoutputis not bloating since theInternalTransactionis already feature-flagged.roseshahar commentedon Jan 19, 2026
@lxcmyf Since one of the most active issues on TRON is an archive node I think that any step in this direction does help the consensus, even if the people who upvoted are not active here.
317787106 commentedon Jan 19, 2026
@roseshahar It seems useful. Have you estamated the volume size of these input and output? Data is constantly expanding, this is a big problem.
waynercheung commentedon Jan 20, 2026
@roseshahar
Adding input/output fields may not be necessary for all developers, so having
saveInternalTxautomatically include input/output data isn't an optimal approach.It would be better to provide a separate configuration flag allowing developers to choose whether to store this data.
lxcmyf commentedon Jan 20, 2026
@roseshahar
I think the archive node is not a good idea. Due to the large amount of data generated by archive node snapshots, Tron currently does not support providing snapshots of archive nodes.
simbadMarino commentedon Jan 21, 2026
@waynercheung , in my opinion having an extra new flag is not optimal as it will be confusing for developers and data platforms and indexers. Enabling
saveInternalTxshould be enough to store ALL Internal Txns data.Most of the RPC providers does not support
saveInternalTxflag by default nowadays, making @roseshahar suggestion a separate flag will just add unnecessary friction/complexity for RPC and Indexers.This will be a great feature for On-chain analysis and debugging on TRON :)
waynercheung commentedon Jan 21, 2026
@simbadMarino , thanks for sharing your thoughts—I agree that keeping things simple under one flag could reduce confusion and make it easier for indexers/RPCs to get full data when they enable saveInternalTx. The potential for better on-chain analysis and debugging is definitely a big win for TRON.
However, I still think a separate flag (e.g., saveInternalTxDetails defaulting to off) could offer valuable flexibility without much added complexity. Not all nodes need the extra storage for input/output, especially resource-light setups or those just wanting basic internal tx tracking.
Technically, it's straightforward to implement in java-tron (just a conditional in the storage logic), and it could encourage more providers to enable the base feature without committing to full overhead.
What do you think about benchmarking the storage impact first, or maybe making it configurable via a sub-flag? Would love to hear from others on real-world RPC experiences!
Sami-Mannila commentedon Jan 26, 2026
Support for TIP #816 from Token Terminal
Token Terminal supports adding input (call data) and output (return data) to TRON
InternalTransactions, as proposed in this issue.Why this matters
On EVM chains, indexers rely on execution traces to decode function selectors/parameters and return data for nested contract calls, especially when protocols don’t emit complete events. TRON nodes can return internal transactions (e.g., via
gettransactioninfobyidwhen internal tx storage is enabled), but the internal tx objects lack input/output, which blocks reliable function-level decoding.Impact for onchain data analysis
roseshahar commentedon Jan 27, 2026
Hey @317787106 @waynercheung
Here is the analysis I did:
In my opinion this is a pretty tiny amount of added data relative to the total transaction size, and has huge impact on the usability of TRON
waynercheung commentedon Jan 28, 2026
@roseshahar
Thanks for the analysis, but I have concerns about the methodology, to make the discussion even stronger, could you share more about the methodology and source?
For example:
Having those details would help the community and other developers verify/reproduce it and address any edge cases (e.g., outliers with very long inputs in complex DeFi calls).
If it's based on a public query or script, linking it could be super helpful for others to build on.
Overall, this kind of quantitative backing is exactly what helps move the TIP forward—great work!
Curious if you've run any node-level benchmarks with the PR changes to see real-world DB growth?
roseshahar commentedon Jan 28, 2026
@waynercheung I've ran this analysis on the latest 100~ blocks on TRON at the time of sending the message.
For measuring this I had to run a custom node that can export traces, as this data is not available in any way possible other than running a patched node.
Traces is a well defined term - https://www.alchemy.com/docs/reference/what-are-evm-traces
Input and output are bytes
waynercheung commentedon Jan 29, 2026
@roseshahar Thanks for running the custom node—that's real work!
That said, a few things stand out that could strengthen the argument further:
Firstly, 100 blocks = ~5 minutes of TRON activity. This may miss:
For statistical significance, blockchain analysis typically uses:
Your 34,500 traces = 0.001% of TRON's annual activity.
Beside,
How many CREATE/CREATE2 operations were in your 100 blocks?
What's the distribution, not just average?
Could you run this on 1,000 or 10,000 blocks ?
Can you share the script?
If we underestimate:
Not trying to be difficult—just want accurate data to support this TIP properly!
Would extending to 1K-10K blocks be feasible?
roseshahar commentedon Jan 31, 2026
@waynercheung Here is data based on 50,000 blocks: 79619000 to 79669000 (I had a few blocks failing though)
waynercheung commentedon Feb 2, 2026
@roseshahar Great work on 50K blocks, but I found a critical issue validating your 50K-block data:
Your CREATEs: 112 in 1.74 days (64/day)
Actual TRON (2025): 4,000 CREATE/day average
You're missing ~97% of CREATE operations.
This means:
Request: Run 200,000 blocks (1 week) to validate:
Real TRON data by month (2025):
It's possible that the block range you selected happened to be during a specific low-activity period, so it's recommended to expand the block range, such as 200K blocks(~ one week).
Expected in 200K blocks: ~32,000 CREATEs
Time: ~6-8 hours
Could you perform this verification, as it would provide more sample data for developers to discuss and further validate?
Thanks
roseshahar commentedon Feb 5, 2026
Hey @waynercheung , it seems you are correct. I just fixed a bug in my custom node that caused this a few days ago.
Unfortunately, since there is no other way to gather this data I will have to wait some until I have more data exported.
simbadMarino commentedon Feb 23, 2026
hi @roseshahar , just checking wether you have now some data to share
warku123 commentedon Feb 27, 2026
From a storage perspective, an extra ~40 bytes per trace seems manageable on modern hardware, but the CREATE operation discrepancy (missing 97% of deployments) suggests the current sample may underestimate real-world usage.
Agree that the 200K-block validation is necessary before moving forward. If the larger sample confirms <200GB/year overhead, the benefits likely outweigh costs; if it scales to 1TB+ or significantly impacts sync, the optional-flag approach becomes more appropriate.
Let's wait for the comprehensive data before deciding.
lvs0075 commentedon Apr 16, 2026
@roseshahar What is the current status of this? Is there any data you can share?
Redchar1992 commentedon Jun 5, 2026
I support improving internal transaction trace completeness, but the storage/indexing boundary needs to be explicit.
The next useful artifact would be the larger 200k-block sample with separate estimates for
CALL,CREATE, andCREATE2, because deployment data appears to be where the current trace format loses the most information. I would also define whetherinput/outputare consensus data, full-node database fields, event plugin/indexer fields, or API-only derived fields. That distinction matters for pruning, historical backfill, and backward compatibility with existing explorer/indexer APIs.aiden3885 commentedon Sep 15, 2026
The main open item is still the storage and performance validation. The earlier 50k-block analysis was affected by a trace collection bug that missed most contract creations, and no corrected 200k-block dataset has been published yet.
Before moving forward, it would be useful to provide:
CALL,CREATE, andCREATE2;saveInternalTxor a separate optional flag.The feature remains valuable for indexers, factory deployments, debugging, and security analysis, but the corrected benchmark is still needed to evaluate its operational cost.