Transactions
Overview
Transactions are cryptographically signed instructions from accounts that update the state of the Starknet network. Starknet supports only three types of transactions, with each type going through the same lifecycle to receive its execution and finality statuses. Every transaction that was executed successfully is issued a receipt, which includes its statuses, as well as other information about it.
-
Transaction fields and hash calculations reference in Resources
-
starknet_api_openrpc.json
in thestarknet-specs
GitHub repository
Transaction types
Starknet supports the following types of transactions:
DECLARE
|
Introduces a new contract class to Starknet, enabling other contracts to either deploy instances of it or use it via a library call
|
||
INVOKE
|
Invokes a function in an existing contract instance, undergoing validation and execution initiated by the caller account’s
|
||
DEPLOY_ACCOUNT
|
Deploys a new account contract to Starknet.
|
The The |
Each transaction type is versioned, with versions increasing when the fields that comprise the transaction change, either with the addition of a new field or the removal of an existing field. The following table summarizes the current, deprecated, and unsupported versions of each transaction type:
Type | Current version | Deprecated versions | Unsupported versions |
---|---|---|---|
|
v3 |
None |
v1, v0 |
|
v3 |
None |
v2, v1, v0 |
|
v3 |
None |
v1 |
Do not submit a transaction that uses an unsupported transaction type, as it cannot be included in a proof, and therefore cannot become part of a Starknet block. Sending transaction that use deprecated versions is still supported, but support will be removed in an upcoming Starknet release. |
Transaction lifecycle
The high-level steps in the Starknet transaction lifecycle are as follows:
-
Transaction submission: A transaction is submitted to a sequencer by a full node.
-
Mempool validation: The sequencer’s mempool performs preliminary validation of the transaction, such as ensuring that its invoker’s balance exceeds the transaction’s
max_fee
value, assuring the transaction’s calldata length is within the legal limit, and more. If the transaction is invalid, it does not proceed. -
Sequencer validation: The sequencer performs preliminary validation of the transaction before executing it to ensure that the transaction is still valid. If the transaction is invalid, it does not proceed.
-
Execution: The sequencer batches all transactions that passed the preliminary validation into a block, and applies them to the state sequentially. If a transaction fails during execution, it is included in the block with as reverted.
-
Proof generation and verification: The prover uses the Starknet operating system to computes the proof for the correct execution of all transactions in the block, and transmits it to the L1 verifier, which verifies it. At this point, the L1 state is updated to include the transaction.
Mempools
Up to and including Starknet v0.13.5, transactions were received and ordered by the sequencer in a first-in-first-out (FIFO) fashion. Starting from Starknet v0.14.0, each sequencer will instead maintain a mempool, decouping the transaction order of arrival from the transaction ordering in blocks, for which they are can decide their own policy.
The introduction of mempools will have the following implications on how transactions are processed:
-
Nonces: Transactions with a nonce greater than the sender’s current nonce + \(x\) will be rejected by the mempool, where:
-
A sender’s current nonce is the sender’s nonce in the latest finalized state at the time the transaction is received
-
\(50 \leq x \leq 100\) is still TBD for
INVOKE
andDEPLOY_ACCOUNT
transactions and \(x = 0\) forDECLARE
transactions (i.e., no declares with future nonces)
-
-
Fee escalation: A transaction in the mempool can be replaced by a transaction sent from the same account with the same nonce and both
tip
andmax_l2_gas_price
increased by at least 10%There are unlikely edge cases in which a transaction is not replaced despite submitting a valid transaction to replace it, such as the existing transaction entering a block while the new one is still processed in the gateway.
-
Transaction time-to-live (TTL): Transactions that cannot be included in a block and have exceeded their TTL, currently configured to be 5 mins, are periodically evicted from the mempool
-
DECLARE
transactions time-to-mature (TTM): Before being inserted into the mempool,DECLARE
transactions are sent to a "waiting room" until they exceed their TTM, where TTM < TTL but is still TBD. While in the "waiting room",DECLARE
transactions can’t be replaced, and transactions sent with the same nonce as a transaction in the "waiting room" by the same account are rejected
Transaction statuses
A transaction’s state is represented by the following finality and execution statuses:
Type | Status | Description | ||
---|---|---|---|---|
Finality |
|
The transaction is not yet known to the sequencer. |
||
|
The transaction was received by the mempool. The transaction is now either executed successfully, rejected, or reverted. |
|||
|
The transaction was received by the mempool but failed the validation by the sequencer. Such transactions are not included in a block.
|
|||
|
The transaction was executed and included in a block. |
|||
|
The transaction was accepted on Ethereum. |
|||
Execution |
|
The transaction passed validation but failed during the execution by the sequencer, and is included in a block as reverted.
|
||
|
The transaction was successfully executed by the sequencer and is included in a block. |
Starting from Starknet version 0.14.0, these statuses will change to the following:
Type | Status | Description | ||
---|---|---|---|---|
Finality |
|
The transaction is not yet known to any sequencer. |
||
|
A full node has successfully submitted the transaction to a sequencer.
|
|||
|
The transaction was written to the feeder gateway’s storage by a sequencer.
|
|||
|
The transaction was successfully executed by a sequencer and its receipt was written to the feeder gateway’s storage. |
|||
|
The transaction was included in a block finalized by the consensus protocol. |
|||
|
The Starknet state on L1 moved to a block height which is greater than or equal to the height of the block containing the transaction. |
|||
Execution |
|
The transaction failed during execution by a sequencer, and was included in a block as reverted.
|
||
|
The transaction was successfully executed by a sequencer and is included in a block. |
State implications of reverted transactions
When a transaction is marked as REVERTED
, the following state implications occur:
Nonce increases |
The nonce value for the account of the failed transaction iterates despite the failure. |
||
Fee charge |
The sequencer charges a fee for the execution of the transaction up to the point of failure, and a respective |
||
Partial reversion |
All changes that occurred during the validation stage are not reverted. However, all changes that occurred during the execution stage are reverted, including all messages to L1 or any events that were emitted during this stage. Events might still be emitted from the validation stage or the fee charge stage. |
||
Fee calculation |
The fee charged for
|
Transaction receipt
A transaction receipt can be obtained by using the Starknet API’s starknet_getTransactionReceipt
endpoint and contains the following fields:
transaction_hash
|
The hash of the transaction. |
actual_fee
|
The actual fee paid for the transaction. |
finality_status
|
The finality status of the transaction. |
execution_status
|
The execution status of the transaction. |
block_hash
|
The hash of the block that includes the transaction |
block_number
|
The sequential number of the block that includes the transaction |
messages_sent
|
A list of messages sent to L1. |
events
|
The events emitted. |
execution_resource
|
A summary of the execution resources used by the transaction. |
type
|
The type of the transaction. |
The following is an example of a transaction receipt:
{
"jsonrpc": "2.0",
"result": {
"actual_fee": "0x221db5dbf6db",
"block_hash": "0x301fc0d09c5810600af7bb9610be10596ad6f4e6d28a60d397dd148f0962a88",
"block_number": 906096,
"events": [
{
"data": [
"0x181de8b0cd32999a5cc962c5f724bc0f6a322f02957b80e1d5fef49a87588b7",
"0x0",
"0x9184e72a000",
"0x0"
],
"from_address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7",
"keys": [
"0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9"
]
},
{
"data": [
"0x764da020183e28a48ee38a9474f84e7e5ff13194",
"0x9184e72a000",
"0x0",
"0x181de8b0cd32999a5cc962c5f724bc0f6a322f02957b80e1d5fef49a87588b7"
],
"from_address": "0x73314940630fd6dcda0d772d4c972c4e0a9946bef9dabf4ef84eda8ef542b82",
"keys": [
"0x194fc63c49b0f07c8e7a78476844837255213824bd6cb81e0ccfb949921aad1"
]
},
{
"data": [
"0x181de8b0cd32999a5cc962c5f724bc0f6a322f02957b80e1d5fef49a87588b7",
"0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8",
"0x221db5dbf6db",
"0x0"
],
"from_address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7",
"keys": [
"0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9"
]
}
],
"execution_status": "SUCCEEDED",
"finality_status": "ACCEPTED_ON_L2",
"messages_sent": [
{
"from_address": "0x73314940630fd6dcda0d772d4c972c4e0a9946bef9dabf4ef84eda8ef542b82",
"payload": [
"0x0",
"0x764da020183e28a48ee38a9474f84e7e5ff13194",
"0x9184e72a000",
"0x0"
],
"to_address": "0xc3511006c04ef1d78af4c8e0e74ec18a6e64ff9e"
}
],
"transaction_hash": "0xdeadbeef",
"type": "INVOKE"
},
"id": 1
}