EVMC
EVM Storage Change Status

The description of evmc_storage_status enum design and its relation to the specification in EIP-2200 and others.

Specification

‍This is the EIP-2200 specification with modifications:

  • the clause tree has been converted to ordered lists to be referenceable,
  • the cost constant names has been replaced with matching Yellow Paper names.
  1. If gasleft is less than or equal to gas stipend, fail the current call frame with 'out of gas' exception.
  2. If current value equals new value (this is a no-op), Gwarmaccess is deducted.
  3. If current value does not equal new value
    1. If original value equals current value (this storage slot has not been changed by the current execution context)
      1. If original value is 0, Gsset is deducted.
      2. Otherwise, Gsreset gas is deducted.
        1. If new value is 0, add Rsclear gas to refund counter.
    2. If original value does not equal current value (this storage slot is dirty), Gwarmaccess gas is deducted. Apply both of the following clauses.
      1. If original value is not 0
        1. If current value is 0 (also means that new value is not 0), remove Rsclear gas from refund counter.
        2. If new value is 0 (also means that current value is not 0), add Rsclear gas to refund counter.
      2. If original value equals new value (this storage slot is reset)
        1. If original value is 0, add Gsset - Gwarmaccess to refund counter.
        2. Otherwise, add Gsreset - Gwarmaccess gas to refund counter.

Cost constants

Yellow Paper EIP-2200 EIP-2200 Value EIP-2929 Value
Gwarmaccess SLOAD_GAS 800 100
Gsset SSTORE_SET_GAS 20000 20000
Gsreset SSTORE_RESET_GAS 5000 2900
Rsclear SSTORE_CLEARS_SCHEDULE 15000 15000

Storage change statuses

  • 0 - zero value
  • X - non-zero value
  • Y - non-zero value different from X
  • Z - non-zero value different form X and Y
  • o - original value
  • c - current value
  • v - new value
name o c v dirty restored clause gas cost gas refund
ASSIGNED 000 no yes 2 Gwarmaccess 0
X00 yes no 2
0YY yes no 2
XYY yes no 2
YYY no yes 2
0YZ yes no 3.2
XYZ yes no 3.2
ADDED 00Z no no 3.1.1 Gsset 0
DELETED XX0 no no 3.1.2.1 Gsreset Rsclear
MODIFIED XXZ no no 3.1.2 Gsreset 0
DELETED_ADDED X0Z yes no 3.2.1.1 Gwarmaccess -Rsclear
MODIFIED_DELETED XY0 yes no 3.2.1.2 Gwarmaccess Rsclear
DELETED_RESTORED X0X yes yes 3.2.1.1 + 3.2.2.2 Gwarmaccess -Rsclear + Gsreset - Gwarmaccess
ADDED_DELETED 0Y0 yes yes 3.2.2.1 Gwarmaccess Gsset - Gwarmaccess
MODIFIED_RESTORED XYX yes yes 3.2.2.2 Gwarmaccess Gsreset - Gwarmaccess

Efficient implementation

All distinctive storage change statuses can be unambiguously selected by combination of the 4 following checks:

  • o ≠ c, i.e. original != current (dirty),
  • o = v, i.e original == new (restored),
  • c ≠ 0, i.e current != 0,
  • v ≠ 0, i.e new != 0.
name o c v o ≠ c o = v c ≠ 0 v ≠ 0 checksum proof
ASSIGNED 000 0100 4 (0b0100)
X00 1000 8 (0b1000)
0YY 1011 11 (0b1011)
XYY 1011 11 (0b1011)
YYY 0111 7 (0b0111)
0YZ 1011 11 (0b1011)
XYZ 1011 11 (0b1011)
ADDED 00Z 0001 1 (0b0001)
DELETED XX0 0010 2 (0b0010)
MODIFIED XXZ 0011 3 (0b0011)
DELETED_ADDED X0Z 1001 9 (0b1001)
MODIFIED_DELETED XY0 1010 10 (0b1010)
DELETED_RESTORED X0X 1101 13 (0b1101)
ADDED_DELETED 0Y0 1110 14 (0b1110)
MODIFIED_RESTORED XYX 1111 15 (0b1111)
impossible 0000 0 (0b0000) o=c ∧ o≠v ∧ c=0 ⇒ v≠0
0101 5 (0b0101) o=c ∧ o=v ∧ c=0 ⇒ v=0
0110 6 (0b0110) o=c ∧ o=v ∧ c≠0 ⇒ v≠0
1100 12 (0b1100) o≠c ∧ o=v ∧ c=0 ⇒ v≠0