EIP-6780 SELFDESTRUCT only in the same transaction (SELFDESTRUCT only in same transaction)
Final · EVM & execution · EIP status Final · created 2023-03-25
Reduces the functionality of the SELFDESTRUCT opcode, which removes a contract. Only when it is called in the very transaction in which the contract was created does it delete code and storage as before. Otherwise it only sends the balance to the recipient.
Why it is needed
SELFDESTRUCT is an opcode that erases all of a contract's code and storage, so it requires large changes to account state. However, in the Verkle tree structure that Ethereum plans to introduce, one account's data is stored across multiple keys that have no clear link to each other, which makes such large-scale deletion impossible. This EIP therefore chose to reduce the functionality of SELFDESTRUCT while preserving its commonly used purposes. Apps that use it only to recover a balance, and apps that call SELFDESTRUCT in the very transaction that created the contract, continue to work without modification. At the same time, it avoids the EVM implementation complexity that contract versioning would have introduced.
What changes
Today
- Whenever SELFDESTRUCT was called, the contract's code, storage and account were all deleted and the balance went to the recipient
- An upgrade pattern was possible in which a contract was redeployed at the same address with CREATE2 after SELFDESTRUCT
- Calling SELFDESTRUCT with itself as the recipient could burn ether
After EIP-6780
- When called in a transaction other than the one that created it, only the entire balance is sent to the recipient, and the code, storage and account remain
- Data is deleted as before only when it is called within the same transaction in which the contract was created
- When a contract that was already deployed sends to itself, the balance does not change and no ether is burned
Who is affected
- Contract developer: Upgrade patterns that relied on SELFDESTRUCT and CREATE2 redeployment break. They must be replaced with a proxy pattern such as ERC-2535.
- Apps used only for balance recovery: Apps that use SELFDESTRUCT only to recover funds continue to work without modification.
- Apps that depended on burning ether: The approach in which an existing contract calls SELFDESTRUCT with itself as the recipient to burn ether no longer works.
- Client teams: Because it changes consensus rules, it must be applied through a hard fork, and it reduces the burden of handling large-scale state deletion during the Verkle tree transition.
In depth
Behavior in a transaction other than the creating one
When SELFDESTRUCT is executed in a transaction other than the one in which the contract was created, the current execution frame halts and the entire account balance moves to the target. No data is deleted, including storage keys, code and the account itself. If the target is the contract that called SELFDESTRUCT, there is no net change in balance and, unlike the previous specification, ether is not burned. After EIP-3529 there is no gas refund, and the access cost rules of EIP-2929 for SELFDESTRUCT remain unchanged.
Behavior when created in the same transaction
When SELFDESTRUCT is executed in the same transaction in which the contract was created, it behaves exactly as before this EIP. The current execution frame halts, data is deleted as previously specified, the entire account balance is sent to the target, and the calling contract's balance is set to 0. In this case, if the target is the calling contract itself, ether is burned as before. The absence of a gas refund and the retention of the EIP-2929 rules are the same as in the first case.
The criterion for "creation"
A contract is considered created when the creating transaction starts, or when a CREATE-family operation (CREATE, CREATE2, and any other operation that deploys a contract in the future) begins execution. It is still treated as contract creation even if the contract's new address already holds a balance. This distinction is needed for use cases such as counterfactual accounts. Allowing deletion at contract creation time leaves no residue from accounts that have never had any state on chain other than a balance. Such accounts have no storage at all, so deleting them updates only a single account node in the trie, which is a burden on par with an ordinary ether transfer.
Relationship to Verkle trees
SELFDESTRUCT requires large changes to account state, such as removing all code and storage. In a Verkle tree, each account is stored across multiple account keys that are not clearly linked to the root account, so such deletion will become impossible in the future. Removing SELFDESTRUCT has been considered in the past, and there is currently no strong reason to use this opcode. This EIP implements behavior that preserves the common use cases while reducing the EVM implementation complexity that contract versioning would introduce.
Usage patterns that break
Two patterns are no longer safe. First, redeploying a contract in the same place with CREATE2 after SELFDESTRUCT to make it upgradeable. If the created contract does not call SELFDESTRUCT within the same transaction, this no longer works, and ERC-2535 or another kind of proxy contract must be used instead. Second, a contract that was not created in the same transaction calling SELFDESTRUCT with itself as the recipient to burn ether. If the contract existed before the transaction, ether is not burned, and if the contract was newly created within the transaction, it is burned as before.
Status and adoption
This EIP modifies consensus rules, so it requires a hard fork. The source status is Final. The SELFDESTRUCT opcode remains deprecated as specified in EIP-6049, and even given the new behavior its use in newly deployed contracts is strongly discouraged. Future EVM changes may reduce the opcode's functionality further. Test cases are in the cancun/eip6780_selfdestruct path of the Execution Spec Tests repository.