starknet_estimateFee
endpoint, and interfaces for fee estimations are also exposed by the various Starknet SDKs.
overall_fee
to decide on the L1 gas bounds.You can find more details in the Starknet v0.13.1 prerelease notes.max_amount
and max_price_per_unit
for each of the three fee unit. A necessary condition for a transaction to enter a block is that max_price_per_unit
is greater than or equal to the block’s corresponding price for each resource, but if included sequencers are then enforced by the Starknet OS (and as such, enforced by a proof) to charge no more than the max price specified by the transaction.
v3
transactions already provide these bounds (as part of the resource_bounds
dictionary), while previous versions only provide a WEI-denominated overall max_fee
.Sequencers usually charges less than the max price specified in the transaction, as charges are in accordance with the formula for determining a transaction’s fee.CairoResourceFeeWeights
vector (see VM resources for more information)
replace_class
syscall
DECLARE
and 0 otherwise, as declare transactions need to post on L1 the new class hash and compiled class hash which are added to the state
l1_gas_price
, l2_gas_price
, and l1_data_gas_price
.
l1_gas_price
and l1_data_price
are computed by taking the average of the last 60 L1 base gas or data gas prices sampled every 60 seconds by the sequencer, plus 1 Gwei. For l1_data_gas_price
, this number is then multiplied by a scaling factor of 0.135 that approximate for the average rate compression achieved from posting the data to Ethereum.
l2_gas_price
is currently a fixed amount denominated in WEI (the price in FRI is only dependent on the WEI to FRI ratio). Starknet version 0.14.0 will introduce a fee market for l2_gas
similar to Ethereum’s EIP 1559, computing l2_gas_price
as follows:
where:
l2_gas_price
l2_gas_price
won’t change
l2_gas_price
will respectively decrease or increase by at most
l2_gas_price
will be equal to
u8_add
is a libfunc).
The Cairo compiler defines a libfunc costs table, which is measured in “Sierra gas” and has a 1-1 ratio with L2 gas (i.e., a libfunc which costs 500 Sierra gas adds 500 to a transaction’s overall L2 gas)
Builtin | Sierra gas cost |
---|---|
Range check | 70 |
Pedersen | 4,050 |
Poseidon | 491 |
Bitwise | 583 |
ECDSA | 10,561 |
EC_OP | 4,085 |
Keccak | 136,189 |
ADD_MOD | 230 |
MUL_MOD | 604 |
versioned constants.json
files in the sequencer’s resources directory.withdraw_gas
libfunc. For functions with neither branching nor recursion, the Cairo→Sierra compiler adds a single withdraw_gas(C)
call in the beginning of the function, where C
is the sum over the costs of the libfuncs included in the function. For functions with branching, the compiler adds a call to withdraw_gas(C)
before the actual branching, where C
is the maximal branch cost.
redeposit_gas(C)
on the cheaper branches, where C
is unused gas on that branch.withdraw_gas
instruction after every libfunc, but since withdraw_gas
itself has some cost (decreasing a counter and handling the insufficient gas case) this would incur a large burden on the program. Instead, the compiler constructs the call graph induced by the program, and asserts that every cycle includes a withdraw_gas(X)
instruction, where X
should cover the cost of a single run through the cycle, greatly reducing the overhead compared to the naive mechanism.
Up to 500M Cairo steps | Up to 20M Pedersen hashes | Up to 4M signature verifications | Up to 10M range checks |
CairoResourceUsage
, that contains the following:
CairoResourceFeeWeights
vector, a predefined weights vector in accordance with the proof parameters, in which each resource type has an entry that specifies the relative gas cost of that component in the proof. The sequencer then charges only according to the limiting factor, making the final fee defined by:
where enumerates the Cairo resource components. Going back to the above example, if the cost of submitting a proof with 20M Pedersen hashes is roughly 5M gas, then the weight of the Pedersen builtin is 5,000,000/20,000,0000 = 25 gas per application.
DEPLOY
transaction (since we need to specify the deployed contract’s class hash)
replace_class
syscall.
DECLARE
and 0 otherwise. Declare transactions need to post on L1 the new class hash and compiled class hash which are added to the state.
send_message_to_l1
syscall is included in a state update, the following data reaches L1:
LogMessageToL1
event
LogMessageToL1
event with two topics and a two-word data array, resulting in a total ofINVOKE
transactions or L1_HANDLER
), constructor calldata (in the case of DEPLOY_ACCOUNT
transactions), and signatures
DECLARE
transactions (only relevant for DECLARE
transactions of version ≥ 2)
DECLARE
transactions, where in version < 2 this refers to the compiled class)
DECLARE
transactions of version ≥ 2)
Resource | L2 Gas cost |
---|---|
Event key | 10,240 gas/felt |
Event data | 5,120 gas/felt |
Calldata | 5,120 gas/felt |
CASM bytecode | 40,000 gas/felt |
Sierra bytecode | 40,000 gas/felt |
ABI | 1,280 gas/character |