How to Inspect Smart Contract Transactions on Hedera Using… | Hedera Hedera Network Services Token Service Mint and configure tokens and accounts. Consensus Service Verifiable timestamps and ordering of events. Smart Contracts Run Solidity smart contracts. HBAR The Hedera network's native cryptocurrency. Insights How It Works Learn about Hedera from end to end. Explorers View live and historical data on Hedera. Dashboards Analyze network activity and metrics. Network Nodes Understand networks and node types. Devs Start Building Get Started Learn core concepts and build the future. Documentation Review the API and build using your favorite language. Developer Resources Integrations Plugins and microservices for Hedera. Fee Estimator Understand and estimate transaction costs. Open Source Hedera is committed to open, transparent code. Learning Center Learn about web3 and blockchain technologies. Grants Grants & accelerators for your project. Bounties Find bugs. Submit a report. Earn rewards. Ecosystem ECOSYSTEM Hedera Ecosystem Applications, developer tools, network explorers, and more. NFT Ecosystem Metrics Analyze on-chain and market NFT ecosystem metrics. CATEGORIES Web3 Applications Connect into the innovative startups decentralizing the web on Hedera. Enterprise Applications Learn about the Fortune 500 companies decentralizing the web on Hedera. Wallets & Custodians Create a Hedera account to manage HBAR, fungible tokens, and NFTs. Network Explorers Hedera mainnet and testnet graphical network explorers. Developer Tooling Third-party APIs, integrations, and plugins to build apps on Hedera. Grants & Accelerators Boost your project with support from the Hedera ecosystem. Partner Program Explore our partners to bring your vision into reality. Hedera Council Over 30 highly diversified organizations govern Hedera. Use Cases Hedera Solutions Asset Tokenization Studio Open source toolkit for tokenizing assets securely. Stablecoin Studio All-in-one toolkit for stablecoin solutions. Hedera Guardian Auditable carbon markets and traceability. Functional Use Cases Data Integrity & AI Reliable, secure, and ethically governed insights. Sustainability Enabling fair carbon markets with trust. Real-World Asset Tokenization Seamless tokenization of real-world assets and digital at scale. Consumer Engagement & Loyalty Mint, distribute, and redeem loyalty rewards. Decentralized Identity Maintain the lifecycle of credentials. Decentralized Logs Scalable, real-time timestamped events. DeFi Dapps built for the next-generation of finance. NFTs Low, fixed fees. Immutable royalties. Payments Scalable, real-time, and affordable crypto-payments. HBAR Overview Learn about Hedera's token, HBAR. Treasury Management Hedera’s report of the HBAR supply. Governance Decentralized Governance Hedera Council See the world's leading organizations that own Hedera. About Meet Hedera's Board of Directors and team. Journey Watch Hedera's journey to build an empowered digital future for all. Transparent Governance Public Policy Hedera's mission is to inform policy and regulation that impact the industry. Meeting Minutes Immutably recorded on Hedera. Roadmap Follow Hedera's roadmap in its journey to build the future. Resources Company What's New Partners Papers Careers Media Blog Technical Press Podcast Community Events Meetups Store Brand Navigation QUICKSTART How to Inspect Smart Contract Transactions on Hedera Using Mirror Nodes technical Jan 22, 2023 by Ed Marquez Head of Developer Relations by Francesco Coacci Developer Evangelist 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. index.js index.js Counter.sol CallCounter.sol console.clear(); import { Client, AccountId, PrivateKey, Hbar, ContractFunctionParameters } from "@hashgraph/sdk"; import * as queries from "./utils/queries.js"; import * as contracts from "./utils/contractOperations.js"; import counterContract from "./contracts/Counter.json" assert { type: "json" }; import counterCallerContract from "./contracts/CounterCaller.json" assert { type: "json" }; import dotenv from "dotenv"; dotenv.config(); const operatorId = AccountId.fromString(process.env.OPERATOR_ID); const operatorKey = PrivateKey.fromString(process.env.OPERATOR_PVKEY); const network = process.env.HEDERA_NETWORK; const client = Client.forNetwork(network).setOperator(operatorId, operatorKey); client.setDefaultMaxTransactionFee(new Hbar(1000)); client.setMaxQueryPayment(new Hbar(50)); async function main() { // STEP 1 =================================== console.log(`\nSTEP 1 ===================================\n`); console.log(`- Deploying contracts...\n`); // Deploy the called contract (counter) let gasLim = 8000000; const bytecode = counterContract.object; const params = []; const [calledContractId, calledContractAddress] = await contracts.deployContractFcn(bytecode, params, gasLim, client); console.log(`- Contract ID: ${calledContractId}`); console.log(`- Contract ID in Solidity address format: ${calledContractAddress}`); // Deploy the caller contract (counter caller) const bytecode1 = counterCallerContract.object; const params1 = new ContractFunctionParameters().addAddress(calledContractAddress); const [callerContractId, callerContractAddress] = await contracts.deployContractFcn(bytecode1, params1, gasLim, client); console.log(`- Contract ID: ${callerContractId}`); console.log(`- Contract ID in Solidity address format: ${callerContractAddress}`); // STEP 2 =================================== console.log(`\nSTEP 2 ===================================\n`); console.log(`- Executing the caller contract...\n`); let idx = 0; const runs = 3; const incrementRec = []; for (idx; idx < runs; idx++) { // Execute the caller contract incrementRec[idx] = await contracts.executeContractFcn(callerContractId, "counterIncrement", gasLim, client); console.log(`- Contract execution: ${incrementRec[idx].receipt.status} \n`); } // Check a Mirror Node Explorer for the last contract execution const [incrementInfo, incrementExpUrl] = await queries.mirrorTxQueryFcn(incrementRec[runs - 1], network); console.log(`- See details in mirror node explorer: \n${incrementExpUrl}`); console.log(` ==================================================== THE END - NOW JOIN: https://hedera.com/discord ====================================================\n`); } main(); // SPDX-License-Identifier: MIT pragma solidity >=0.4.22 <0.9.0; contract Counter { uint public count; event CountIncrement(address indexed _from, uint count); function increment() external { count += 1; emit CountIncrement(msg.sender, count); } } // SPDX-License-Identifier: MIT pragma solidity >=0.4.22 <0.9.0; import "./ICounter.sol"; contract CallCounter { address counterAddr; constructor (address _counter) { counterAddr = _counter; } function counterIncrement() external { return ICounter(counterAddr).increment(); } function getCount() external view returns (uint) { return ICounter(counterAddr).count(); } } 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. DeployContractFcn DeployContractFcn ExecuteContractFcn MirrorTxQueryFcn export async function deployContractFcn(bytecode, params, gasLim, client) { const contractCreateTx = new ContractCreateFlow().setBytecode(bytecode).setConstructorParameters(params).setGas(gasLim); const contractCreateSubmit = await contractCreateTx.execute(client); const contractCreateRx = await contractCreateSubmit.getReceipt(client); const contractId = contractCreateRx.contractId; const contractAddress = contractId.toSolidityAddress(); return [contractId, contractAddress]; } export async function executeContractFcn(cId, fcnName, gasLim, client) { const contractExecuteTx = new ContractExecuteTransaction().setContractId(cId).setGas(gasLim).setFunction(fcnName); const contractExecuteSubmit = await contractExecuteTx.execute(client); const contractExecuteRec = await contractExecuteSubmit.getRecord(client); return contractExecuteRec; } export async function mirrorTxQueryFcn(txRec, network) { // Query a mirror node for information about the transaction const delay = (ms) => new Promise((res) => setTimeout(res, ms)); await delay(10000); // Wait for 10 seconds before querying a mirror node to allow for info propagation const txTimestamp = txRec.consensusTimestamp; const txIdRaw = txRec.transactionId; const txIdPretty = prettify(txIdRaw.toString()); const mirrorNodeExplorerUrl = `https://hashscan.io/${network}/transaction/${txTimestamp}?tid=${txIdPretty}`; const mirrorNodeRestApi = `https://${network}.mirrornode.hedera.com/api/v1/transactions/${txIdPretty}`; let mQuery = []; try { mQuery = await axios.get(mirrorNodeRestApi); } catch {} return [mQuery, mirrorNodeExplorerUrl]; } function prettify(txIdRaw) { const a = txIdRaw.split("@"); const b = a[1].split("."); return `${a[0]}-${b[0]}-${b[1]}`; } 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. Continue Learning Open a Testnet Account Try Examples and Tutorials Join the Developer Discord Read the Learning Center Share This Back to blog What is gRPC, gRPC-Web, and Proxies? Ed Marquez Pragmatic Blockchain Design Patterns – Integrating Blockchain into Business Processes Michiel Mulders Zero Cost EthereumTransaction on Success: Hedera's New Fee Model for Relay Operators Oliver Thorn Hedera Adopts Chainlink Standard for Cross-Chain Interoperability To Accelerate Ecosystem Adoption Hedera Team Hedera Developer Highlights March 2025 Michiel Mulders Hedera Release Cycle Overview Ed Marquez View All Posts Sign up for the newsletter CONNECT WITH US Transparency Open Source Audits & Standards Sustainability Commitment Carbon Offsets Governance Hedera Council Public Policy Treasury Management Meeting Minutes LLC Agreement Node Requirements Community Events Meetups HBAR Telegram Developer Discord Twitter Community Support FAQ Network Status Developer Discord StackOverflow Brand Brand Guidelines Built on Hedera Logo Hedera Store About Team Partners Journey Roadmap Careers Contact General Inquiry Public Relations © 2018-2025 Hedera Hashgraph, LLC. All trademarks and company names are the property of their respective owners. All rights in the Deutsche Telekom mark are protected by Deutsche Telekom AG. All rights reserved. Hedera uses the third party marks with permission. Terms of Use  |  Privacy Policy