More CLI commands
get_transaction
To get transaction information run the following:
starknet get_transaction --hash TRANSACTION_HASH
The output should resemble:
{
"block_hash": "0x0",
"block_number": 0,
"status": "ACCEPTED_ON_L2",
"transaction": {
"calldata": [
"0x1",
"$[INTRO_CONTRACT_ADDRESS_TRIMMED]",
"0x362398bec32bc0ebb411203221a35a0301193a96f317ebe5e40be9f60d15320",
"0x0",
"0x1",
"0x1",
"0x4d2"
],
"contract_address": "$[ACCOUNT_ADDRESS_TRIMMED]",
"max_fee": "0x0",
"nonce": "0x3",
"signature": [
"0x26ee1f973def2e6d5c7f32aaad96c84dab32df6a62ee0e8b530a72bc5478fe6",
"0x502b15e440cc2a8a1966f0c973015096715e366fde36a4659c56f84249688e"
],
"transaction_hash": "0x69d743891f69d758928e163eff1e3d7256752f549f134974d4aa8d26d5d7da8",
"type": "INVOKE_FUNCTION",
"version": "0x1"
},
"transaction_index": 1
}
The result contains:
-
transaction_hash
– The hash of the transaction. -
status
– The status of the transaction. For a detailed list of supported transaction statuses, refer to the tx_status usage example. -
transaction
– The transaction data.
It may also include each of the following optional fields (according to the transaction’s status):
-
block_hash
– The hash of the block containing the transaction. -
block_number
– The sequence number of the block containing the transaction. -
transaction_index
– The index of the transaction within the block containing it. -
transaction_failure_reason
– The reason for the transaction failure.
get_transaction_receipt
Transaction receipt contains execution information, such as L1<->L2 interaction and consumed
resources, in addition to its block information, similar to get_transaction
. To get the
transaction’s receipt, run the following:
starknet get_transaction_receipt --hash TRANSACTION_HASH
The output should resemble:
{
"actual_fee": "0x0",
"block_hash": "0x0",
"block_number": 0,
"events": [],
"execution_resources": {
"builtin_instance_counter": {
"pedersen_builtin": 2,
"range_check_builtin": 10
},
"n_memory_holes": 25,
"n_steps": 309
},
"l2_to_l1_messages": [
{
"from_address": "0x7dacca7a41e893630664a61f4d8ec05550ca1a212849c62417cb3ecf4bad863",
"payload": [
"0x0",
"0xbc614e",
"0x3e8"
],
"to_address": "0x9E4c14403d7d9A8A782044E86a93CAE09D7B2ac9"
}
],
"status": "ACCEPTED_ON_L2",
"transaction_hash": "0x7797c6673a1a0aeebbcb1c726702e263e5138123124ddef7edd85cd925b11ec",
"transaction_index": 2
}
The result contains (in addition to get_transaction
fields):
-
l2_to_l1_messages
– Messages sent from L2 to L1. -
l1_to_l2_consumed_message
– The consumed message, in case the transaction was sent from L1. -
execution_resources
– Resources consumed by the transaction execution.
get_transaction_trace
Transaction trace contains execution information in a nested structure of calls; every call, starting from the external transaction, contains a list of inner calls, ordered chronologically. For each such call, the trace holds the following: caller/callee addresses, selector, calldata along with execution information such as its return value, emitted events, and sent messages.
To get the transaction’s trace, run the following:
starknet get_transaction_trace --hash TRANSACTION_HASH
The output should resemble:
{
"function_invocation": {
"call_type": "CALL",
"calldata": [
"0x1",
"$[INTRO_CONTRACT_ADDRESS_TRIMMED]",
"0x15511cc3694f64379908437d6d64458dc76d02482052bfb8a5b33a72c054c77",
"0x0",
"0x2",
"0x2",
"0xbc614e",
"0x3e8"
],
"caller_address": "0x0",
"class_hash": "0x74acbf20e655c80c4fa16e3574489073e0093fd8b386d9614ab2d6cf5b866bf",
"contract_address": "0x78d796e87cfa496bffad27be9ed42f2709bd6e32a6366f842fdf38664a1412d",
"entry_point_type": "EXTERNAL",
"events": [],
"execution_resources": {
"builtin_instance_counter": {
"pedersen_builtin": 2,
"range_check_builtin": 10
},
"n_memory_holes": 25,
"n_steps": 309
},
"internal_calls": [
...
],
"messages": [],
"result": [],
"selector": "0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad"
},
"signature": [
"0x6e4606a3c0f3bd0eac37ddfbf2645f62c04474e5eac51a2f6225ee7702996a",
"0x389d0bae9be71ceb3b6092dda9b76279543bc2bfe271c3d05a812c3dbeffeb7"
],
"validate_invocation": {
"call_type": "CALL",
"calldata": [
"0x1",
"0x39564c4f6d9f45a963a6dc8cf32737f0d51a08e446304626173fd838bd70e1c",
"0x15511cc3694f64379908437d6d64458dc76d02482052bfb8a5b33a72c054c77",
"0x0",
"0x2",
"0x2",
"0xbc614e",
"0x3e8"
],
"caller_address": "0x0",
"class_hash": "0x74acbf20e655c80c4fa16e3574489073e0093fd8b386d9614ab2d6cf5b866bf",
"contract_address": "0x78d796e87cfa496bffad27be9ed42f2709bd6e32a6366f842fdf38664a1412d",
"entry_point_type": "EXTERNAL",
"events": [],
"execution_resources": {
"builtin_instance_counter": {
"ecdsa_builtin": 1,
"range_check_builtin": 2
},
"n_memory_holes": 0,
"n_steps": 89
},
"internal_calls": [],
"messages": [],
"result": [],
"selector": "0x162da33a4585851fe8d3af3c2a9c60b557814e221e0d4f30ff0b2189d9c7775"
}
}
Estimate fee
You can estimate the fee of a given transaction before executing it by adding the --estimate_fee
flag to the invoke
or declare
commands. This will simulate the transaction and return the
estimated fee associated with it.
You can read more about the fee mechanism
here. The result is presented in WEI and ETH,
as shown below.
Note that with the --estimate_fee
flag, the state of the contracts does not change. For example,
the following code will not affect the balance stored in BALANCE_CONTRACT
.
To estimate the fee of a given transaction run the following:
starknet invoke \
--address ${CONTRACT_ADDRESS} \
--abi contract_abi.json \
--function increase_balance \
--inputs 1234 \
--estimate_fee
The output should resemble:
The estimated fee is: 756800000000000 WEI (0.000757 ETH).
Gas usage: 7568
Gas price: 100000000000 WEI
Simulate transaction
The --simulate
flag is similar to --estimate_fee
, except that it also returns the trace produced
by executing the transaction.
Note that with the --simulate
flag, as with --estimate_fee
, the state of the contracts does not
change. For example, the command below will not affect the balance stored in BALANCE_CONTRACT
.
To simulate the execution of a given transaction run the following:
starknet invoke \
--address ${CONTRACT_ADDRESS} \
--abi contract_abi.json \
--function increase_balance \
--inputs 1234 \
--simulate
The output should resemble:
The estimated fee is: 756800000000000 WEI (0.000757 ETH).
Gas usage: 7568
Gas price: 100000000000 WEI
{
"function_invocation": {
"call_type": "CALL",
"calldata": [
"0x1",
"$[INTRO_CONTRACT_ADDRESS_TRIMMED]",
"0x362398bec32bc0ebb411203221a35a0301193a96f317ebe5e40be9f60d15320",
"0x0",
"0x1",
"0x1",
"0x4d2"
],
"caller_address": "0x0",
"class_hash": "$[ACCOUNT_CLASS_HASH]",
"contract_address": "$[ACCOUNT_ADDRESS_TRIMMED]",
"entry_point_type": "EXTERNAL",
"events": [],
"execution_resources": {
"builtin_instance_counter": {
"range_check_builtin": 2
},
"n_memory_holes": 3,
"n_steps": 206
},
"internal_calls": [
...
],
"messages": [],
"result": [],
"selector": "0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad"
},
"signature": [
"0x6501fcc88705e138910cf5d8f88cedbc7b6ffde47da5562a94dbc834ce92f4e",
"0x52371924f8c82221dd895d705eac391f7faefb57b9c55293ede92990355e086"
],
"validate_invocation": {
"call_type": "CALL",
"calldata": [
"0x1",
"$[INTRO_CONTRACT_ADDRESS_TRIMMED]",
"0x362398bec32bc0ebb411203221a35a0301193a96f317ebe5e40be9f60d15320",
"0x0",
"0x1",
"0x1",
"0x4d2"
],
"caller_address": "0x0",
"class_hash": "$[ACCOUNT_CLASS_HASH]",
"contract_address": "$[ACCOUNT_ADDRESS_TRIMMED]",
"entry_point_type": "EXTERNAL",
"events": [],
"execution_resources": {
"builtin_instance_counter": {
"ecdsa_builtin": 1,
"range_check_builtin": 2
},
"n_memory_holes": 0,
"n_steps": 89
},
"internal_calls": [],
"messages": [],
"result": [],
"selector": "0x162da33a4585851fe8d3af3c2a9c60b557814e221e0d4f30ff0b2189d9c7775"
}
}
get_code
Once the deploy
transaction is accepted on-chain, you will be able to see the code of the contract
you have just deployed. The output consists of a list of bytecodes, rather than the source code. This
is because the Starknet network gets the contract after compilation.
To get the contract at a specific address, run the following command:
starknet get_code --contract_address ${CONTRACT_ADDRESS}
The output should resemble:
{
"abi": [
{
"inputs": [
{
"name": "amount",
"type": "felt"
}
],
"name": "increase_balance",
"outputs": [],
"type": "function"
},
...
"0x48127ffb7fff8000",
"0x48127ffb7fff8000",
"0x48127ffb7fff8000",
"0x208b7fff7fff7ffe"
]
}
get_class_by_hash
To get the full class compatible with a specific hash, run the following command:
starknet get_class_by_hash --class_hash CLASS_HASH
The output should resemble:
{
"abi": [
{
"inputs": [
{
"name": "amount",
"type": "felt"
}
],
"name": "increase_balance",
"outputs": [],
"type": "function"
},
...
}
}
get_full_contract
To get the full contract class of a contract at a specific address, run the following command:
starknet get_full_contract --contract_address ${CONTRACT_ADDRESS}
The output should resemble:
{
"abi": [
{
"inputs": [
{
"name": "amount",
"type": "felt"
}
],
"name": "increase_balance",
"outputs": [],
"type": "function"
},
...
}
}
get_class_hash_at
To get the hash of a contract at a specific address, run the following command:
starknet get_class_hash_at --contract_address ${CONTRACT_ADDRESS}
The output should resemble:
0x2951dd06d31f492e8ed1e91da115dbcd3ffd7c688f39b4878db99d86995e4c
get_block
Instead of querying a specific contract or transaction, you may want to query an entire block and examine the transactions contained within it. To do this, run the following:
starknet get_block --number BLOCK_NUMBER
The output should resemble:
{
"block_hash": "0x15344d9ce0bd1aa5d7577885c0bef948494ac926a9b7080c45ef2754bb2a59a",
"block_number": 0,
"gas_price": "0x174876e800",
"parent_block_hash": "0x19bbfaf06c332eda3d6a0f3bf45583d4312707435e8df265a02524853c7491e",
"sequencer_address": "0x310959e4d55cfe4712291a5f9787893fb392d1ffb96905aba549b21e91e9fc9",
"starknet_version": "$[VERSION]",
"state_root": "079354de0075c5c1f2a6af40c7dd70a92dc93c68b54ecc327b61c8426fea177c",
"status": "ACCEPTED_ON_L2",
"timestamp": 105,
"transaction_receipts": [
{
"actual_fee": "0x0",
"events": [],
"execution_resources": {
"builtin_instance_counter": {},
"n_memory_holes": 0,
"n_steps": 41
},
"l2_to_l1_messages": [],
"transaction_hash": "0x7f00beb6bd9ee1cb5bc6eaf824d0be2f2d5b3580955085c99ff0fc7228dcc07",
"transaction_index": 0
}
],
"transactions": [
{
"class_hash": "0x1fac3074c9d5282f0acc5c69a4781a1c711efea5e73c550c5d9fb253cf7fd3d",
"constructor_calldata": [
"0x5e797f7945a9a34ad6ab316302b5e752645e07e6d9dcc494fd4bb05da849520"
],
"contract_address": "0x4c16242a45b33e2bf7517a2b757ceba7021d31d0f18b675e3670163ebbafec",
"contract_address_salt": "0x5d0a87ee7d3b7c70f8683a9f13c12f2fa36c83bbe2b0fa85f6dc9256faf6a",
"max_fee": "0x0",
"nonce": "0x0",
"signature": [
"0x3216167b64f5daf104c820d7dfe5df93df158464b10cf5537ed898b2c5ddee7",
"0x76a7d396f5ac4275c97461763e4737829d81ce767aa4cf16d53f0a9ee89bcfc"
],
"transaction_hash": "0x7f00beb6bd9ee1cb5bc6eaf824d0be2f2d5b3580955085c99ff0fc7228dcc07",
"type": "DEPLOY_ACCOUNT",
"version": "0x1"
}
]
}
The result contains:
-
block_hash
– The block hash, a unique identifier of the block. -
parent_block_hash
– The block hash of the parent block. -
block_number
– The sequence number of the block, which is the number of blocks prior to this block. -
state_root
– The root of a commitment tree representing the Starknet’s state after the given block. -
status
– The status of the block (for example,ACCEPTED_ON_L2
, which means that the block was created but has not been accepted on-chain yet). -
timestamp
– A timestamp representing the time this block was created. -
transaction_receipts
– Information about the transaction status and the corresponding L1<->L2 interaction, for every transaction included in the block. -
transactions
– A mapping of the transactions included in the block, according to their transaction hashes. Note that these are the same hashes used in thetransaction_receipts
mapping.
To query the pending block, simply pass --number=pending
. To query a block by hash, use --hash
instead. Note that at most one of these arguments can be given.
get_nonce
You can retrieve the nonce of a contract (usually, an account contract) using the following command:
starknet get_nonce --contract_address ${ACCOUNT_ADDRESS}
Note that the nonce returned by this command is advanced only once the transaction reaches the pending (or later) state.
get_block_traces
Instead of querying a specific transaction, you may want to query an entire block and examine the
traces of all the transactions contained within it (see get_transaction_trace
above). To do this,
run the following:
starknet get_block_traces --number BLOCK_NUMBER
The output should resemble:
{
"traces": [
{
"function_invocation": {
"call_type": "CALL",
"calldata": [
"0x7a9e2c42b232648a4f974495cad18734c7d06c70b28f257715bf1d051d7ef38"
],
"caller_address": "0x0",
"class_hash": "0x1fac3074c9d5282f0acc5c69a4781a1c711efea5e73c550c5d9fb253cf7fd3d",
"contract_address": "0x1271fa9e5d66cfb372e81591ccfa7107d6adfd4eea65a0023ced14be367a5d2",
"entry_point_type": "CONSTRUCTOR",
"events": [],
"execution_resources": {
"builtin_instance_counter": {},
"n_memory_holes": 0,
"n_steps": 41
},
"internal_calls": [],
"messages": [],
"result": [],
"selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194"
},
"signature": [
"0x3216167b64f5daf104c820d7dfe5df93df158464b10cf5537ed898b2c5ddee7",
"0x76a7d396f5ac4275c97461763e4737829d81ce767aa4cf16d53f0a9ee89bcfc"
],
"transaction_hash": "0x43507ba264f550a20f1957b0e63a8f55bff2648ced17e46f9724ef47c26472e",
"validate_invocation": {
"call_type": "CALL",
"calldata": [
"0x1fac3074c9d5282f0acc5c69a4781a1c711efea5e73c550c5d9fb253cf7fd3d",
"0x4f508479b71268536367e6225a9afbba484c753706df0c00bd11b2380e8ce9f",
"0xf00de10171648ba2d82921388340bf47c83fe18921a7e71f4ded556099b5a5"
],
"caller_address": "0x0",
"class_hash": "0x1fac3074c9d5282f0acc5c69a4781a1c711efea5e73c550c5d9fb253cf7fd3d",
"contract_address": "0x65fced1e7b6b3cf219cda7611966f72068780ad9b514d9bc4e60226f3c30d28",
"entry_point_type": "EXTERNAL",
"events": [],
"execution_resources": {
"builtin_instance_counter": {
"ecdsa_builtin": 1
},
"n_memory_holes": 0,
"n_steps": 75
},
"internal_calls": [],
"messages": [],
"result": [],
"selector": "0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895"
}
}
]
}
get_state_update
You can use the following command to get the state changes in a specific block (for example, what storage cells have changed):
starknet get_state_update --block_number BLOCK_NUMBER
The output should resemble:
{
"block_hash": "0x703fad93522cd338891ce4e009ca3d71ff742a31fcf87c46d8a5f644e77fbe3",
"new_root": "0714e01d3a891f71aeaea0dc1af25958fdb71aa0566773e9e208c8ea1adfd3ab",
"old_root": "02e5810fb9ecbb8d561bcb54b03cfcc3f1b88eda7043148291e2eb974e5ba16c",
"state_diff": {
"declared_contracts": [],
"deployed_contracts": [
{
"address": "0x3a0c6f9001e69edf3c5750475455010ad36eecc6084ebe9ed2c0aa45d029281",
"class_hash": "0x1fac3074c9d5282f0acc5c69a4781a1c711efea5e73c550c5d9fb253cf7fd3d"
}
],
"nonces": {},
"storage_diffs": {
"0x304a44f9c5a902743a96071794c89959bf2435bd8ebb24ee88bf55ed2b02c04": [
{
"key": "0x3b28019ccfdbd30ffc65951d94bb85c9e2b8434111a000b5afd533ce65f57a4",
"value": "0x64e10e4399a5760d8db27ea20311380c2cb02063dbd34da731a083b3074c34e"
}
]
}
}
}
The result contains:
-
block_hash
– The block hash, a unique identifier of the block. -
new_root
– The root of a commitment tree representing the Starknet’s state after the given block. -
old_root
– The root of a commitment tree representing the Starknet’s state before the given block. -
state_diff
– The changes in the state applied in this block, given as a mapping of addresses to the new values and/or new contracts.
To query the last block, simply remove the --block_number
argument. To query a block by hash,
use --block_hash
instead. Note that at most one of these arguments can be given.
get_storage_at
Other than querying the contract’s code, you may also want to query the contract’s storage at a specific key. To do so, you first need to understand which key is of interest to you. As you saw before, Starknet introduces a new primitive, which is storage variables. Each storage variable is mapped to a storage key (a field element). To compute this key, run the following Python code:
from starkware.starknet.public.abi import get_storage_var_address
balance_key = get_storage_var_address('balance')
print(f'Balance key: {balance_key}')
You should get:
Balance key: 916907772491729262376534102982219947830828984996257231353398618781993312401
Now, you can query the balance using:
starknet get_storage_at \
--contract_address ${CONTRACT_ADDRESS} \
--key 916907772491729262376534102982219947830828984996257231353398618781993312401
Using the same contract we have used so far, you should get:
0x4d2
Note that this is the same result obtained by the call to get_balance
.
Later on, at the user authentication section, you will see a generalization of storage variables, which allows, for example, having a balance variable for each user. This will require minor adjustments to the code above, which we will review in the relevant section.
Block-specific queries
Some of the aforementioned CLI functions have an additional argument, --block_hash
, which applies
the given query to a specific block. For example, you may want to query the balance variable at some
specific point in time.
To find out whether a CLI function can be executed as a block-specific query, simply use the --help
argument to see if --block_hash
is part of the optional arguments for that function. In case you do
not use the --block_hash
argument, the query will be applied to the last block.