EIP-4758 Deactivate SELFDESTRUCT
Hegota Considered for Inclusion · EVM & execution · EIP status Stagnant · created 2022-02-03
Replaces SELFDESTRUCT, the instruction that deletes a contract, with SENDALL. Only the function of sending all of the account's ether remains, the code and storage are not deleted, and the related gas refund is removed.
Why it is needed
Currently the SELFDESTRUCT instruction deletes the code and storage of a contract account entirely and sends the remaining ether to a specified address. This is an operation that changes account state significantly. Ethereum plans to hold state in a new data structure called a Verkle tree. In a Verkle tree, one account's data is stored scattered across multiple keys, and it is not visible from the outside which account those keys belong to. As a result, deleting an entire account becomes practically impossible. The source document explains that removing this instruction is a necessary condition for statelessness, where nodes do not need to hold the full state. On the other hand, there is no strong reason to need SELFDESTRUCT as it stands today, and apps that use it only to recover funds keep working after the change. So the proposal is to replace the instruction with a simple behavior that only sends ether, instead of removing it.
What changes
Today
- SELFDESTRUCT deletes all of an account's code and storage and sends the ether to a specified address
- There are gas refund rules tied to SELFDESTRUCT
- A new contract can be redeployed at the same address in the deleted spot using CREATE2
After EIP-4758
- It is renamed SENDALL and only sends the account's ether to a specified address
- The code, storage and nonce remain as they are, and all related refunds are removed
- Redeploying a contract at the same address no longer works
Who is affected
- Users: Most users see no noticeable change. Apps that use SELFDESTRUCT only to recover funds keep working after the change.
- Wallet & app developers: Contracts that use SELFDESTRUCT to redeploy at the same address with CREATE2 or as an upgrade mechanism will break. Upgrades must be switched to a delegate approach.
- Client teams: It changes consensus rules, so a hard fork is required. According to the call records it is included in the scope of bogota-devnet-2, and three clients, Nethermind, Geth and ethrex, implement it.
- Node operators and validators: The source document states that this change is a necessary condition for statelessness. It is a change tied to the Verkle tree transition.
In depth
Opcode rename and behavior change
The SELFDESTRUCT opcode is renamed SENDALL. Its new behavior is only to move all ETH in the account to the target immediately. It does not destroy code or storage and does not change the nonce. So after execution the contract stays at the same address with its code and state intact, and only the balance becomes 0. One point deserves attention. The description in the original header says funds are returned to the caller, while the Specification section says they are sent to the target. Because the original uses both expressions, the intent should be confirmed in the discussion thread when implementing.
Refund removal
All SELFDESTRUCT-related refunds are removed. Removing refunds is one of the two items in the Specification section, alongside the opcode rename. The original specification gives only this one line and does not state which refunds existed, how large they were, or what the new gas cost is. This reads as meaning that, since SENDALL does not delete code or storage, there is no basis for returning gas as a reward for reducing state. The original says nothing about changing the gas cost of the opcode itself.
Verkle trees and statelessness
SELFDESTRUCT requires a large state change that removes all of an account's code and storage. In a Verkle tree, each account is split across multiple account keys, and these keys are not clearly linked to a root account. Deleting a whole account in one operation therefore becomes impossible going forward. The Rationale section states that removing SELFDESTRUCT has been considered before, that there is no strong reason to use it now, and that disabling it is a necessary condition for statelessness. Apps that use SELFDESTRUCT only to recover funds continue to work after the change.
Backward compatibility: CREATE2 redeployment breaks
This changes consensus rules, so it requires a hard fork. The original says few apps are affected by this change. The only use case that breaks is recreating a contract at the same address with CREATE2 after SELFDESTRUCT. CREATE2 lets you fix the deployment address in advance, so it was used in a pattern of deleting a contract and then deploying different code in the same place. SENDALL does not delete code, so the code remains at that address and a contract cannot be redeployed there. Apps that used SELFDESTRUCT only to recover funds keep working as they are.
Security considerations: two use cases that become unsafe
The original lists two use cases that are no longer safe. First, using SELFDESTRUCT inside a contract to burn non-ETH token balances such as EIP-20. The authors know of no such use and consider it unlikely, since sending the tokens to a burn address achieves the same easily. Second, redeploying a contract in the same place with CREATE2. This has two branches. One is a pattern that calls SELFDESTRUCT at the end of an operation to stop the contract from being used outside a specific context. For example, in a contract where anyone can withdraw funds, it is used to prevent others from withdrawing. The original says this pattern can easily be changed so that it does not depend on SELFDESTRUCT. The other is using SELFDESTRUCT as a means of upgrading a contract. This is no longer supported, and a delegate approach should be used.
Original status and core developer call decisions
The original status is Stagnant. It was created on February 3, 2022, and the authors are Guillaume Ballet, Vitalik Buterin, and Dankrad Feist. Because it is not a finalized (Final) specification, its content may still change. It is being discussed again on core developer calls. On 10.08 ACDE #247, EIP-8360 (TCREATE) and EIP-4758 (SELFDESTRUCT deactivation) were bundled and moved to Considered for Inclusion (CFI) for Hegota, and were described as a fix for a problem introduced in Glamsterdam. On 10.22 ACDE #248, the scope of bogota-devnet-2 was fixed at four EIPs, EIP-8253, EIP-4758, EIP-8298, and EIP-8151, and it was decided to launch next week with three clients: Nethermind, Geth, and ethrex. bogota-devnet-2 is a testnet where Hegota candidate EIPs are run on a real network.