Ethereum API method that returns traces for all the transactions within a specific block. Developers can use the trace_block
method to gain insight into the behavior of smart contracts within a block, analyze gas usage, and optimize their contracts accordingly. This method is only available on an Erigon instance.
Get you own node endpoint today
Start for free and get your app to production levels immediately. No credit card required.
You can sign up with your GitHub, X, Google, or Microsoft account.
Enable the Erigon client on your elastic Ethereum node
Available on the Business subscription plan and higher.
Once you have joined a public network, do the following:
- Select the project with the network.
- Select the network.
- Click Add node.
- Provide a node name.
- Under Type, select Elastic.
- Under Mode, select Archive. With an archive node, you will be able to query historical states for the entire chain.
- Under Debug and trace APIs, select On.
- Under Hosting, select Chainstack.
- For Chainstack hosting, select a cloud provider and a region.
- Review your changes and click Add node.
Once deployed, the node status will change from Pending to Running. You will also see the Debug and trace tag next to the node name.
Enable the Erigon client on your dedicated Ethereum node
Available on the Growth subscription plan and higher.
Once you have joined a public network, do the following:
- Select the project with the network.
- Select the network.
- Click Add node.
- Provide a node name.
- Under Type, select Dedicated.
- Under Mode, select Archive. With an archive node, you will be able to query historical states for the entire chain.
- Under Hosting, select Chainstack. See Supported hosting options.
- For Chainstack hosting, select a cloud provider and a region.
- Under Client, select Erigon.
- Review your changes and click Send request.
The Chainstack Sales team will reach out to your shortly.
Parameters
-
quantity or tag
— the integer of a block encoded as hexadecimal or the string with:-
latest
— the most recent block in the blockchain and the current state of the blockchain at the most recent block. A chain reorganization is to be expected. -
safe
— the block that received justification from the beacon chain. Although this block could be involved in a chain reorganization, it would necessitate either a coordinated attack by the majority of validators or an instance of severe propagation latency. -
finalized
— the block accepted as canonical by more than 2/3 of the validators. A chain reorganization is extremely unlikely, and it would require at least 1/3 of the staked ETH to be burned. -
earliest
— the earliest available or genesis block -
pending
— the pending state and transactions block. The current state of transactions that have been broadcast to the network but have not yet been included in a block.See the default block parameter and How The Merge Impacts Ethereum’s Application Layer.
-
Response
result
— an object containing the traces of all of the transactions in the block:action
— an object that describes the action taken by the transaction:from
— the address of the sender who initiated the transaction.callType
— the type of call,call
ordelegatecall
, two ways to invoke a function in a smart contract.call
creates a new environment for the function to work in, so changes made in that function won't affect the environment where the function was called.delegatecall
doesn't create a new environment. Instead, it runs the function within the environment of the caller, so changes made in that function will affect the caller's environment.gas
— the units of gas included in the transaction by the sender.input
— the optional input data sent with the transaction, usually used to interact with smart contracts.to
— the address of the recipient of the transaction if it was a transaction to an address. For contract creation transactions, this field is null.value
— the value of the native token transferred along with the transaction, in Wei.blockHash
— the hash of the block in which the transaction was included.blockNumber
— the number of the block in which the transaction was included.error
— a string that indicates whether the transaction was successful or not.null
if successful,Reverted
if not.result
— an object that contains additional data about the execution of the transaction:gasUsed
— the total used gas by the call, encoded as hexadecimal.output
— the return value of the call, encoded as a hexadecimal string.
subtraces
— the number of sub-traces created during execution. When a transaction is executed on the EVM, it may trigger additional sub-executions, such as when a smart contract calls another smart contract or when an external account is accessed.traceAddress
— an array that indicates the position of the transaction in the trace.transactionHash
— the hash of the transaction.transactionPosition
— the position of the transaction in the block.type
— the type of action taken by the transaction,call
orcreate
.call
is the most common type of trace and occurs when a smart contract invokes another contract's function.create
represents the creation of a new smart contract. This type of trace occurs when a smart contract is deployed to the blockchain.
trace_block
code examples
trace_block
code examplesLearn more about the
ChainstackProvider
inethers.js
: ethers ChainstackProvider Documentation.
const ethers = require("ethers");
// Create a ChainstackProvider instance for Ethereum mainnet
const chainstack = new ethers.ChainstackProvider("mainnet");
const traceBlock = async (block) => {
const traces = await chainstack.send("trace_block", [block]);
console.log(traces);
};
traceBlock("latest");
const { Web3, Web3PluginBase } = require("web3");
const NODE_URL = "CHAINSTACK_NODE_URL";
const web3 = new Web3(NODE_URL);
// Define the TraceBlockPlugin class
class TraceBlockPlugin extends Web3PluginBase {
pluginNamespace = 'erigon';
async traceBlock(blockId) {
return this.requestManager.send({
method: 'trace_block',
params: [blockId],
});
}
}
// Register the plugin
web3.registerPlugin(new TraceBlockPlugin());
async function traceBlock(block) {
const result = await web3.erigon.traceBlock(block);
console.log(result);
}
traceBlock("latest");
from web3 import Web3
node_url = "CHAINSTACK_NODE_URL"
web3 = Web3.HTTPProvider(node_url)
block = "latest"
traces = web3.provider.make_request('trace_block', [block])
print(traces)
Use case
A practical use case for the trace_block
method on Ethereum can be to conduct an analysis of the most recent block on the network. For example, by examining the amount of gas supplied by all the transactions and the actual amount of gas utilized, developers can gain valuable insights into the block's behavior. This can be the first step to developing a chain explorer.
The following code is an implementation of this idea using web3.js:
const { Web3, Web3PluginBase } = require("web3");
const NODE_URL = "CHAINSTACK_NODE_URL";
const web3 = new Web3(NODE_URL);
// Define the TraceBlockPlugin class
class TraceBlockPlugin extends Web3PluginBase {
pluginNamespace = 'erigon';
async traceBlock(blockId) {
return this.requestManager.send({
method: 'trace_block',
params: [blockId],
});
}
}
// Register the plugin
web3.registerPlugin(new TraceBlockPlugin());
// A function that returns an array of result and gas fields for each transaction in a block
async function traceBlock(block) {
try {
const traces = await web3.erigon.traceBlock(block);
const resultFields = [];
const gasFields = [];
for (const { result, action } of traces) {
resultFields.push(result);
gasFields.push(action.gas);
}
return [resultFields, gasFields];
} catch (error) {
console.error(`Error while tracing block: ${error}`);
throw error;
}
}
// A function that calculates the total gas used by all transactions in a block
function returnGasUsed(results) {
const totalGasUsed = results.reduce((total, result) => {
if (result !== null && result.gasUsed !== undefined) {
const decimalValue = web3.utils.hexToNumberString(result.gasUsed);
total += Number(decimalValue);
}
return total;
}, 0);
return totalGasUsed;
}
// A function that calculates the total gas supplied to a block
function returnTotalGas(gasArray) {
const totalGas = gasArray.reduce((total, gas) => {
if (gas !== undefined) {
const decimalValue = web3.utils.hexToNumberString(gas);
total += Number(decimalValue);
}
return total;
}, 0);
return totalGas;
}
// The main function that runs the gas analysis
async function main() {
try {
const block = 'latest';
const [results, gas] = await traceBlock(block);
const gasUsed = returnGasUsed(results);
const totalGas = returnTotalGas(gas);
console.log('===== Gas analysis =====');
console.log(`Total gas supplied: ${totalGas}`);
console.log(`Gas used: ${gasUsed}`);
console.log(`Unused gas: ${totalGas - gasUsed}`);
const gasUsedPercentage = (gasUsed / totalGas) * 100;
console.log(`Percentage of gas used: ${gasUsedPercentage.toFixed(2)} %`);
} catch (error) {
console.error(`Error while running gas analysis: ${error}`);
}
}
// Call the main function to start the program
main();
The traceBlock
function takes a block number or tag as an input parameter and returns an array of two elements. The first element is an array of the results of each transaction in the block, which contains the gasUsed
field, and the second element is an array of the gas
field used by each call.
The returnGasUsed
function calculates the total gas used by all transactions in a block by iterating over the results array and summing up the gasUsed
fields of each non-null element.
The returnTotalGas
function calculates the total gas supplied to a block by iterating over the gasArray
array and summing up the non-undefined elements.
The main function calls the traceBlock
function with the block number or tag calculates the gas used and total gas supplied using the returnGasUsed
and returnTotalGas
functions, and outputs the results to the console.
The main
function is wrapped in a try-catch
block to handle any errors that may occur during execution.
Finally, the main
function is called at the end of the script to run the gas analysis.
Try the trace_block
RPC method yourself
trace_block
RPC method yourself