The goal of this tutorial is to help smart contract developers understand the traceability information for contract transactions that is provided by the mirror nodes. Specifically, you will learn how to view contract
actions, state changes, and logs. Understanding this information and knowing where to get it can simplify the process of inspecting and debugging smart contracts on Hedera.
For detailed information about the development and implementation of this traceability information, check out HIP-513: Smart Contract Traceability Extension and HIP-435: Record Stream V6.
Try It Yourself
- Get a Hedera testnet account
- This portal acts like a faucet, giving you 10,000 test HBAR every 24 hours
- If you’re new to Hedera, check out these steps to setup your development environment
- Use this Codesandbox to try the example
- Fork the sandbox
- Remember to provide testnet account credentials in the .env file
- Open a new terminal to execute index.js
- Get the example code from GitHub
You Will Use These Tools
- Hedera JavaScript SDK (Documentation)
- Solidity (Documentation)
- Mirror node REST API (Learn More)
- Mirror node explorer (HashScan)
Let’s Inspect an Example: The Client Calls a Contract that Calls Another Contract
There are three entities in this scenario: Operator and two smart contracts.
Your testnet credentials from the Hedera portal should be used for the operator variables, which are used to initialize the Hedera client that submits transactions to the network and gets confirmations.
- The code in index.js initializes a Hedera client (Operator). It also deploys and executes the two contracts
- The contract Counter.sol has a function named increment() that increases the state variable count
and emits an event when called - The contract CallCounter.sol has a state variable that stores the address of the counter contract (counterAddr). It also has the functions, counterIncrement() and getCount(). These functions use an interface (ICounter.sol) to call increment()
and read the value of count in Counter.sol
The expected behavior with this setup is that Operator
executes the counterIncrement() function in CallCounter.sol, which in turn executes the increment() function in Counter.sol, which in turn increases the state variable count and emits an event. You will then view information related to all those activities from the mirror nodes.
A for loop is used to make this chain of calls occur three times every time index.js executes.
This is the console output of index.js:
STEP 1 =================================== - Deploying contracts... - Contract ID: 0.0.2505 - Contract ID in Solidity address format: 00000000000000000000000000000000000009c9
- Contract ID: 0.0.2507 - Contract ID in Solidity address format: 00000000000000000000000000000000000009cb STEP 2 =================================== - Executing the caller contract... - Contract execution: SUCCESS - Contract execution: SUCCESS - Contract execution: SUCCESS - See details in mirror node explorer: https://hashscan.io/previewnet/transaction/1674246551.782213192?tid=0.0.1132-1674246540-672254772 ==================================================== THE END - NOW JOIN: https://hedera.com/discord ====================================================
Each tab below shows the helper functions used to deploy and execute the contracts (contracts.deployContractFcn and contracts.executeContractFcn) and to query the information about the 3rd transaction from the mirror nodes (queries.mirrorTxQueryFcn). These functions are reusable in case you need to perform those activities in the future.
After deployment and execution, we can see information for all these entities and transactions in HashScan. Keep in mind that previewnet and testnet are periodically reset for maintenance purposes, so you may not see these same exact entries in the future – screenshots are included for reference.
- Counter Contract: https://hashscan.io/previewnet/contract/0.0.2505
- Caller Contract: https://hashscan.io/previewnet/contract/0.0.2507
- Operator: https://hashscan.io/previewnet/account/0.0.1132
- Last Transaction (out of three contract executions): https://hashscan.io/previewnet/transaction/1674246551.782213192?tid=0.0.1132-1674246540-672254772
Contract Results
The contract results section provides summary information of whether the transaction completed successfully or not, the entities involved, gas values, and more.
Contract Results in HashScan:
Mirror Node REST API for Results:
https://previewnet.mirrornode.hedera.com/api/v1/contracts/0.0.2507/results
Contract Actions
The Actions section (Call Trace in HashScan) highlights all the interactions from entity to entity (account calls contract, contract calls contract, etc.) This can help you understand the sequence of calls and operations in your application. In HashScan, you can expand all the calls involved in a transaction to see details like entity IDs, gas values, HBAR transferred, and more.
In our example, you can see that the account 0.0.1132 calls the contract 0.0.2507 (CallCounter.sol), which then calls the contract 0.0.2505 (Counter.sol)
Contract Actions in HashScan:
Mirror Node REST API for Actions: https://previewnet.mirrornode.hedera.com/api/v1/contracts/results/0xb739e3c90b8cf9dcc823aff3175bd61efa2167c7072c1103cde0aad3f2295815/actions
State Changes
State changes can also be inspected with mirror nodes. In HashScan, you can see the values read and written to state for a given address.
In our example, for the third contract execution, you see that the value of 3 is written to the state of contract 0.0.2505 (Counter.sol) and the contract 0.0.2507 reads the address of the counter contract.
Contract State in HashScan:
Mirror Node REST API for State:
https://previewnet.mirrornode.hedera.com/api/v1/contracts/0.0.2505/state
https://previewnet.mirrornode.hedera.com/api/v1/contracts/0.0.2507/state
Logs
Mirror nodes also provide information about events, which is captured in the logs section.
As a refresher, when an event is emitted, it stores the arguments in a special on-chain data structure called the transaction log. Logs are composed of topics and data.
For a detailed explanation of how to access event information from smart contracts, be sure to read the tutorial How to Get Event Information from Hedera Smart Contracts.
Contract Logs on HashScan:
Mirror Node REST API for Logs:
https://previewnet.mirrornode.hedera.com/api/v1/contracts/0.0.2505/results/logs
Summary
Now you know how to inspect smart contract transactions using the traceability information provided by the mirror nodes. You can try this example with the other officially supported SDKs for Java, Go, and Swift.