# EVM cost relationships
## Motivation
To establish the granular steps of complex instructions on the EVM. These steps can then be applied across multiple instructions, providing a better base for repricing and discussions.
The complex instructions here are those outside of computation and memory: storage, state and transaction/call frame instructions.
**Question: are cost determined based on purely the specification, purely an optimised client, or some combination of both?**
**Question: are cost determined based on worst-case, best-case or avg-case? If avg-case, are there some overhead charges added for worst-case?**
## Background
Based on Istanbul.
Current costs (from YP):
```
Zero = 0, // 0, Zero
Base, // 2, Quick
VeryLow, // 3, Fastest
Low, // 5, Fast
Mid, // 8, Mid
High, // 10, Slow
```
Current costs (from Solidity's libevmasm):
```
extCodeGas: 700
balanceGas: 700
sloadGas: 800
sstoreSetGas: 20000
sstoreResetGas: 5000
sstoreRefundGas: 15000
createGas: 32000
callGas: 700
callStipendGas: 2300
callValueTransferGas: 9000
callNewAccountGas: 25000
selfdestructGas: 5000
selfdestructRefundGas: 24000
memoryGas: 3
copyGas: 3
createDataGas: 200
txGas: 21000
txCreateGas: 53000
txDataZeroGas: 4
txDataNonZeroGas: 16
keccak256Gas: 30
keccak256WordGas: 6
```
## Cost primitives
`QUERY_TX` = 2 <small>(As currently.)</small>
`QUERY_CONSTANT_FRAME` = 2 <small>(As currently.)</small>
`QUERY_FRAME` = 2 <small>(As currently.)</small>
`LOAD_ACCOUNT` = 700 <small>(As currently.)</small>
`LOAD_CODE` = 200 <small>**(Newly introduced.)**</small>
`COPY_PER_WORD` = 3 <small>(As currently.)</small>
`CREATE_CALLFRAME` = 100 <small>**(Newly introduced.)**</small>
`CALL_STIPEND` = 2300 <small>(As currently.)</small>
`CREATE_ACCOUNT` = 25000 <small>(As currently, `callNewAccountGas` above.)</small>
`CODE_STORE_PER_WORD` = 200 <small>(As currently, `createDataGas` above.)</small>
`MODIFY_ACCOUNT` = 5000 <small>**(Newly introduced.)**</small>
We define the following helpers:
1. `memoryExtension(offset)` -- calculates the memory extension cost
2. `copyPerWord(size)`: `ceil(len / 32) * COPY_PER_WORD`
## Instructions
### Complex
#### KECCAK256
Cost: `keccak256Gas + ceil(len / 32) * keccak256WordGas`
### Transaction/blocks state
#### ORIGIN
Cost: `QUERY_TX`
#### GASPRICE
Cost: `QUERY_TX`
#### BLOCKHASH
TBD
#### COINBASE
Cost: `QUERY_TX`
#### TIMESTAMP
Cost: `QUERY_TX`
#### NUMBER
Cost: `QUERY_TX`
#### DIFFICULTY
Cost: `QUERY_TX`
#### GASLIMIT
Cost: `QUERY_TX`
#### CHAINID
Cost: `QUERY_TX`
### Call frame state (constants)
#### CALLER
Cost: `QUERY_CONSTANT_FRAME`
#### CALLVALUE
Cost: `QUERY_CONSTANT_FRAME`
#### CALLDATALOAD
Cost: `QUERY_CONSTANT_FRAME`
*Currently this is set at "verylow" or 3 gas.*
#### CALLDATASIZE
Cost: `QUERY_CONSTANT_FRAME`
#### CALLDATACOPY
Cost: `QUERY_CONSTANT_FRAME (+ COPY_PER_WORD + MEM_EXTENSION)`
*Currently this is set at "verylow" or 3 gas.*
#### RETURNDATASIZE
Cost: `QUERY_CONSTANT_FRAME`
#### RETURNDATACOPY
Cost: `QUERY_CONSTANT_FRAME (+ COPY_PER_WORD + MEM_EXTENSION)`
*Currently this is set at "verylow" or 3 gas.*
#### CODESIZE
Cost: `QUERY_CONSTANT_FRAME`
#### CODECOPY
Cost: `QUERY_CONSTANT_FRAME (+ COPY_PER_WORD + MEM_EXTENSION)`
*Currently this is set at "verylow" or 3 gas.*
### Call frame state (ephemeral)
#### MSIZE
Cost: `QUERY_FRAME`
#### GAS
Cost: `QUERY_FRAME`
#### SELFBALANCE
Cost: `QUERY_FRAME`
*Currently this is set at "low" or 5 gas.*
### Other account state
#### EXTBALANCE
Cost: `LOAD_ACCOUNT`
Rationale: the account contains the balance.
#### EXTCODESIZE
Cost: `LOAD_ACCOUNT + LOAD_CODE`
Rationale: the account contains the code hash, but the code needs to be located from its own trie.
#### EXTCODECOPY(address, dst, src, len)
Cost: `LOAD_ACCOUNT + LOAD_CODE + copyPerWord(len) + memoryExtension(dst + len)`
#### EXTCODEHASH
Cost: `LOAD_ACCOUNT`
Rationale: the account contains the code hash.
#### CREATE
Cost: `calculateAddress() + CREATE_ACCOUNT + CREATE_CALLFRAME + len(code) * CODE_STORE_PER_BYTE`, where
1. `calculateAddress` is defined as `keccak256Gas + keccak256WordGas`, since the address calculation is optimistically a single word and we ignore the overhead of RLP,
2. `CREATE_CALLFRAME` is here to account for execution of the initcode,
3. `code` refers to the code returned by executing `initcode`, where `initcode` refers to the code passed to `CREATE`.
*Note: address calculation is `keccak256(rlp(sender, nonce))[:20]`*
*Currently this is charge at a fixed value of `createGas`.*
#### CREATE2
The same rules apply here as in `CREATE`, with the only exception that `calculateAddress` is as follows: `keccak256WordGas * (ceil(len(initcode) / 32) + 3)`.
*Note: The extra 3 words are for the final round of hashing, which is not accounted for in EIP-1014. The EIP also omits `keccak256Gas`.*
#### CALL
Call has four different variants depending on input and account state:
1. Destination exists, no value passed: `LOAD_ACCOUNT + LOAD_CODE + CREATE_CALLFRAME`
2. Destination exists, value passed: `LOAD_ACCOUNT + LOAD_CODE + CALL_STIPEND + MODIFY_ACCOUNT + CREATE_CALLFRAME`
3. Destination does not exists, no value passed: `LOAD_ACCOUNT` (isn't this a noop ("only" a tree lookup) since the account is not presisted?)
4. Destination does not exists, value passed: `LOAD_ACCOUNT + CREATE_ACCOUNT + CALL_STIPEND + CREATE_CALLFRAME`
*Currently this is set callGas + !!exists * callNewAccountGas + !!value * callValueTransferGas*
*Currently in order to persist an account, need to send value, e.g. the total cost is callGas + callNewAccountGas + callValueTransferGas (34000).*
#### CALLCODE
Cost: `LOAD_ACCOUNT + LOAD_CODE + CREATE_CALLFRAME`
TBD
**Also consider value sending.**
#### DELEGATECALL
Cost: `LOAD_ACCOUNT + LOAD_CODE + CREATE_CALLFRAME`
TBD
If account does not exists, only `LOAD_ACCOUNT` is charged.
#### STATICCALL
Cost: `LOAD_ACCOUNT + LOAD_CODE + CREATE_CALLFRAME`
TBD
If account does not exists, only `LOAD_ACCOUNT` is charged.
Special case: if destination is a precompile, `LOAD_CODE` doesn't need to apply. (EIP-2046)
#### SELFDESTRUCT
TBD
### Storage trie
#### SSTORE
~~Cost: `SSTORE_COST + STATE_COST_PER_WORD`~~
See EIP-142.
TBD
#### SLOAD
~~Cost: `SLOAD_COST`~~
TBD
### Precompile (subset)
#### SHA256
Cost: `sha256Gas + ceil(len(input)/32) * sha256WordGas`, where `sha256Gas` = 60 and `sha256WordGas` = 12.
#### RIPEMD160
Cost: `ripemd160Gas + ceil(len(input)/32) * ripemd160WordGas`, where `ripemd160Gas` = 600 and `ripemd160WordGas` = 120.
#### Identity
Cost: `identityGas + ceil(len(input)/32) * identityWordGas`, where `identityGas` = 15 and `identityWordGas` = 3.
## Takeaways
1. `CREATE` is not accounting for the RLP and hashing.
2. `CREATE2` is not accounting for the final round of hashing.
3. `CALL` is too complex.
4. It seems that "call frame state" copying instructions have a 1 gas cost in addition to reading the state (3 gas vs 2 gas.) plus the per word cost. In comparison, the identity precompile has a base cost of 15 gas plus 3 per word.
5. Should `LOAD_ACCOUNT` charge for the avg-case or the worst-case?
## Appendix: Feedback
`LOAD_CODE` has not been a significant factor due to the way the account trie and the code storage is handled.
## Appendix: Cost comparison
**Numbers are not on sync with the formulas**
Unfinished. (Assumes `LOAD_CODE` is 700, and `CREATE_CALLFRAME` is 200)
| Opcodes | Istanbul | Proposed |
|----------------------------|----------|----------|
| EXTBALANCE | 700 | 700 |
| CREATE (0 codesize) | 32000 | 25236 |
| CREATE (max codesize) | 4947200 | 4940436 |
| CREATE2 (0 codesize) | 32000 | 25248 |
| CREATE2 (max codesize) | 4951838 | 4945056 |
| CALL | 700 | 1500 |
| CALL (new account) | 25700 | 26500 |
| CALL (with value) | 9700 | 3800 |
| CALL (new account + value) | 34700 | 28800 |
| CALL (to self, EIP1380) | 700 | 100 |
| STATICCALL (to precompile, EIP2046) | 700 | 100 |
| SELFDESTRUCT | 5000 | |