EIP-6780: Reduced SELFDESTRUCT Functionality
SELFDESTRUCT originally:
- Destroyed the contract's bytecode and storage.
- Forwarded the contract's ETH balance to a designated recipient.
- Refunded gas to the caller (incentive to clean up unused contracts).
This created multiple footguns: re-deploying via CREATE2 to the same address with different code (because storage was wiped), unintended data loss in proxy contracts when the implementation called selfdestruct, MEV opportunities around "refund the gas" mechanics.
EIP-6780 (Cancun) reduced SELFDESTRUCT to:
- If called in the same transaction as the contract was created: full original behavior (destroy + forward funds + refund gas).
- Otherwise: only forward the balance. The bytecode and storage stay intact.
In effect, SELFDESTRUCT is now a balance-sweep opcode for already-deployed contracts, not a destruction primitive.
Neo Equivalent
Neo's ContractManagement.Destroy() has always been:
- An explicit method call (no opcode).
- Authorized by the contract's witness.
- Removes the contract's storage and manifest.
- Has no automatic fund-forwarding or gas refund.
The "destroy" path is intentionally narrow: contracts must explicitly opt in by implementing a callable destroy method, witnesses must check, and any token balances held at the contract address must be transferred out beforehand by contract logic — there's no implicit sweep.
Live on Neo TestNet
Both implementations are deployed on Neo N3 TestNet (network magic 894710606).
| Implementation | Contract Hash | Deploy Tx |
|---|---|---|
Solidity (neo-solc) | 0x67a59c179448a3769d5559a691a4c118c7de9930 | 0x35d83590…980e4e |
Neo C# (nccs) | 0x8acf52e9a1f696965480cd40046c9c3de020f8eb | 0x5bf67208…6d1473 |
Cross-implementation invocations match on isArmed. Source pairs under docs/standards-mirror/deployments/eip-6780/.
