How to estimate required STEP
It is important to set a proper stepLimit
value in your transaction to make the submitted transaction executed successfully. This document explains how to systemically estimate the required Step.
Intended Audience
Anyone who sends transactions to the ICON Network
Purpose
To learn how to estimate the required Step for their transactions using ICON SDKs, T-Bears CLI or JSON-RPC API calls.
Prerequisite
- Understand how ICON JSON-RPC APIs work.
- Need to know how to submit a transaction to the ICON Network using various tools.
How-To
The mechanism of requesting Step estimation is very similar to sending transactions.
Request and Response
Transaction Request
The following example is a transaction request message that will invoke the transfer
method on the IRC2 token contract.
{
"jsonrpc": "2.0",
"method": "icx_sendTransaction",
"id": 1234,
"params": {
"version": "0x3",
"from": "hxcced4d83a03098f5976b5ed339b0cab3e51ca1f9",
"to": "cx65fc79aa09e867fd51d0c8361f42cb38bc1f08f3",
"stepLimit": "0x30d40",
"timestamp": "0x583f58f62eae0",
"nid": "0x3",
"nonce": "0x1",
"dataType": "call",
"data": {
"method": "transfer",
"params": {
"_to": "hx25cd4028f055457b8fbdae1dbd8b5fe465248e55",
"_value": "0x8ac7230489e80000"
}
},
"signature": "rBaH0U6y85y1CWp/JbalUbzLVGjtGYG+hut/G5o30vBxhWoxPYtSYBQu6X0Tak1SdcnlZSCJL7DeOeKmI4y+5wE="
}
}
Step Estimate Request
The step estimation request is the same as the above example except the stepLimit
and signature
. The stepLimit
and signature
fields are unnecessary because the step estimation process does not verify the sender, nor limit the execution until the cumulative step reaches the stepLimit
.
The following example is the Step estimation request for the above token transfer transaction. You can simply remove the stepLimit
and signature
fields from the original transaction request.
{
"jsonrpc": "2.0",
"method": "debug_estimateStep",
"id": 1234,
"params": {
"version": "0x3",
"from": "hxcced4d83a03098f5976b5ed339b0cab3e51ca1f9",
"to": "cx65fc79aa09e867fd51d0c8361f42cb38bc1f08f3",
"timestamp": "0x583f58f62eae0",
"nid": "0x3",
"nonce": "0x1",
"dataType": "call",
"data": {
"method": "transfer",
"params": {
"_to": "hx25cd4028f055457b8fbdae1dbd8b5fe465248e55",
"_value": "0x8ac7230489e80000"
}
}
}
}
Response - Success
If there are no exceptions, the response will return the estimated Step usage as follows.
{
"jsonrpc": "2.0",
"id": 1234,
"result": "0x23f8c"
}
Response - Fail
If there is an exception, the response will show the error message.
{
"jsonrpc": "2.0",
"id": 1234,
"error": {
"code": -32602,
"message": "JSON schema validation error: 'version' is a required property"
}
}
JSON-RPC API call
Debug API Endpoint : :///api/debug/v3
You can make a step estimation request using curl from the CLI as follows. Note that in the below command example, stepEstimationRequest.json
is the file that contains the request message.
$ curl -H "Content-Type: application/json" -d @stepEstimationRequest.json https://bicon.net.solidwallet.io/api/debug/v3
{"jsonrpc": "2.0", "result": "0x23f8c", "id": 1234}
Java
Below is a code snippet for Java. For the detailed ICON Java SDK usage guideline, please read Java SDK ↗ (opens in a new tab).
// make a raw transaction without the stepLimit
Transaction transaction = TransactionBuilder.newBuilder()
.nid(networkId)
.from(fromAddress)
.to(toAddress)
.nonce(BigInteger.valueOf(1))
.call("transfer")
.params(params)
.build();
// get an estimated step value
BigInteger estimatedStep = iconService.estimateStep(transaction).execute();
// set some margin
BigInteger margin = BigInteger.valueOf(10000);
// make a signed transaction with the same raw transaction and the estimated step
SignedTransaction signedTransaction = new SignedTransaction(transaction, wallet, estimatedStep.add(margin));
Bytes txHash = iconService.sendTransaction(signedTransaction).execute();
...
Python
Step estimation code snippet for Python. For the detailed ICON Python SDK usage guideline, please read Python SDK ↗ (opens in a new tab).
# Generates a raw transaction without the stepLimit
transaction = TransactionBuilder()\
.from_(wallet.get_address())\
.to("cx00...02")\
.value(150000000)\
.nid(3)\
.nonce(100)\
.build()
# Returns an estimated step value
estimate_step = icon_service.estimate_step(transaction)
# Adds some margin to the estimated step
step_limit = estimate_step + 10000
# Returns the signed transaction object having a signature with the same raw transaction and the estimated step
signed_transaction = SignedTransaction(transaction, wallet, step_limit)
# Sends the transaction
tx_hash = icon_service.send_transaction(signed_transaction)
Summary
With the debug_estimateStep
JSON-RPC API, developers can estimate how much Step will be required for a particular transaction under the current block state. Using various ICON SDKs, you can integrate the functionality in your DApp.
Please be aware that the returned value is just an ESTIMATION. The block state may not remain the same between the Step estimation and the actual transaction execution time. The required Step can be different if the block state changes.