# DEACTIVATE (aka SELFDESTRUCT) with old-storage shadowing Following up on [EIP-6046 Replacing SELFDESTRUCT with DEACTIVATE](https://eips.ethereum.org/EIPS/eip-6046). Concerns were raised that reactivating accounts with existing storage keys could a) result in failures for unprepared accounts; b) be misused by malicious actors. Below is an option to avoid that by recording the reactivation count and hashing storage keys with that, so that old keys remain hidden. ### Specification 1. We reserve 2^64-1 as a special nonce value, therefore further restricting [EIP-2681](https://eips.ethereum.org/EIPS/eip-2681)'s rules: - Consider any transaction invalid, where the nonce exceeds or equals to 2^64-2. - The `CREATE` and `CREATE2` instructions’ execution ends with the result 0 pushed on stack, where the `creator_account.nonce` is 2^64-2. 2. `SELFDESTRUCT` - Costs 5000 gas. - Gives no gas refund. - Transfers account balance (`target_account.balance += account.balance`) - Sets `account.nonce` to 2^64-1. - Sets `account.balance` to 0. - This means that targeting self eventually destroys the balance. 3. During account execution (triggered both via external transactions or `CALL*`), if `account.nonce` equals `2^64-1`, behave as if the account does not exists. - Value transfers can be received. - A `CALL*` returns empty value. 4. `CREATE2` is modified that it allows account creation if `target_account.nonce` equals `2^64-1`. In this case a reactivation is taking place: - The account's state entry is extended from `(balance, nonce, code_hash, storage_hash)` to `(balance, nonce, code_hash, storage_hash, incarnation_count)`. - The `target_account.nonce` is reset to `0`. - The `target_account.incarnation_count` is increased. *(See rationale about account changes below.)* 5. If the `account.incarnation_count` is non-zero, the behaviour of `SLOAD` and `SSTORE` is modified: - The hashing of the key is changed from `keccak256(key)` to `keccak256(incarnation_count || key)`, where `||` means concatenation. 6. Rename the `SELFDESTRUCT` instruction to `DEACTIVATE`, to more clearly signal its behaviour. ### Rationale / Comments #### Shadowing ("waste") With the modified hashing keys created in previous incarnation are inaccessible forever. This means they can't be deleted. #### Storage costs The cost `SLOAD` and `SSTORE` is not increased, because hashing of the key already takes place. Given the round input size of Keccak-256 is 136-bytes and we currently feed in 32-bytes, there is enough space to feed in the `incarnation_count` without causing an extra round of hashing. #### Limit of `incarnation_count` It would make sense specifying a limit, such as `2^32`, which is unlikely to be hit, but gives a guarantee on pricing (see previous section). #### Cost of de/reactivation Since storage waste is left behind, it would make sense increasing the cost of `DEACTIVATE` or `CREATE2` (if it caused a reactivation). #### Alternate options to extending the account Extending the account entry (which is RLP serialised) with a new field is a significant change we have avoided until now. The alternative options are not enticing however, such as splitting the nonce space into incarnation buckets and tracking the nonce within. **Given one of the major drivers of change is the move to Verkle trees, it likely would make sense to enable this change the same time as Verkle trees are introduced, where the `incarnation_count` would become another "metadata"-key. This avoids the change of state object.** #### Observability of deactivated accounts If we want external observability of *deactivated* accounts, perhaps an [`EXTNONCE` opcode](https://ethereum-magicians.org/t/eip-4672-nonce-opcode/8171) would be useful with returning the special 2^64-1 value.