-
Notifications
You must be signed in to change notification settings - Fork 5.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Disable SELFDESTRUCT EIP #2751
Disable SELFDESTRUCT EIP #2751
Conversation
An alternative to POP semantics would be to turn its semantics into a TRANSFER. Side effect free tranfers is a legitimate use case of SELFDESTRUCT imo |
In practice, you cannot remove any complexity already introduced. The future complexity of EVM may be reduced, but all EVMs have to support past block executions, so they will still have the complexity.
I think a better semantic to fix this would be to just leave a marker on-chain but keep everything else of
As @MrChico said, otherwise you'd risk breaking those time-lock contract that relies on |
FYI in case you missed it, the discussion forum is: https://ethereum-magicians.org/t/eip-for-disabling-selfdestruct-opcode/4382 |
You can, if you change the architecture of the client implementation. It is possible to construct the implementation that only uses EVM (simpler) for the current rule set, and special historical EVM (more complex) to re-trace historical transactions, as I mentioned here: https://ethereum-magicians.org/t/backwards-forwards-sync-of-ethereum-clients/2258 And yes, this discussion will disappear when PR is merged, so better discussed on the FEM link |
Is this actually true? Why can't a future ethereum client just refuse to support blocks older than block N, with its mainnet config pretending that block N is the genesis? There are things that removing the SELFDESTRUCT refund will break; particularly, the CREATE -> do stuff -> SELFDESTRUCT workflow for combining multiple operations into one transaction. That said, that may be fine as there are other EIPs to more "naturally" support such functionality. |
<!--The motivation is critical for EIPs that want to change the Ethereum protocol. It should clearly explain why the existing protocol specification is inadequate to address the problem that the EIP solves. EIP submissions without sufficient motivation may be rejected outright.--> | ||
Operation `SELFDESTRUCT` (formerly `SUICIDE`) was in the EVM from the beginning, and its purpose was to incentivise clearing the state, by giving the | ||
caller gas refund. In practice, this incentivisation turned out to be very limited, and the designed purpose was not archieved. However, `SELFDESTRUCT` | ||
brings significant amount of complexity to the EVM. It is responsible for some of the most arcane edge cases in the EVM semantics. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strongly agree on this. In particular, the existence of this opcode significantly increases the complexity of many forms of caching, as SELFDESTRUCT can potentially delete an unbounded number of storage slots.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If selfdestruct did not delete those storage slots it would empower a new kind of upgrade pattern (create2 reincarnations) while reducing SELFDESTRUCT complexity.
I don't think geth ever clears those storage slots from the state trie; it checks if there was a recent self-destruct. A reincarnation could fork the network if not enough nodes remain aware of the selfdestruct and reference a quantum storage slot.
After certain block number, the semantics of `SELFDESTRUCT` becomes the same as the combination of `POP` followed by `STOP`. Gas cost is the same as the gas cost | ||
of `POP`, which is 2 gas. No value transfer occurs and no gas refund is given. | ||
After certain block number, the semantics of `SELFDESTRUCT` becomes the same as the combination of `POP`, followed by transferring remaining ETH | ||
to the address popped from the stack, followed by `STOP`. Gas cost is the same as the gas cost of non-zero value transfer, which is 9000 gas. No gas refund is given. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This gas scheme will make it cheaper to create new account via SELFDESTRUCT
(which costs 30000 right now). Better either:
- Keep the current
SELFDESTRUCT
gas cost:5000 + 25000 if new account
. - Or, increase the base to
9000
like this but also with the 25000 new account penalty:9000 + 25000 if new account
.
Also note that 9000
comes from CALL
opcode, but SELFDESTRUCT
is not exactly the same as CALL
transfer because the former will never execute the target if it's a contract.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's currently cheapest to create an account using a regular 21000 transfer
I'm merely speaking as an eth1.x client implementor when talking about this complexity. Practically, right now, we cannot remove any past complexity under the assumption that we want to support all past block executions. Re-defining genesis or like Alexey proposed doing the backwards-forwards sync works around this, of course, but that does mean we drop support for past block execution. However, putting off the hat of an Ethereum client implementor, I do agree with you and I believe this problem is already solved nicely. For example, in Substrate, all runtime execution logic is written in wasm and recorded on-chain. So client can re-define logic and remove any accidental complexity at will while still being able to execute all past blocks. I believe there's something similar in eth2 EEs, but I'm not really familiar with that. |
As a gastoken whale I'm strongly opposed. We provide stability to the gasprice and provide more space when blocks are full. Removing the SELFDESTRUCT refund would force us to use SSTORE, which is less-efficient. You would see larger swings in the gasPrice and we would consume more gas overall. |
Really happy people are finally taking this seriously. Been shouting this for 6 months now. How can I help as a Comms person? |
If you were to break tokenized refunds, you should also fork the state to cleanup every contract they have created and compensate tokenholders at some "fair" gasPrice to limit migratory congestion. I'm aware of the following refund contract creators, but there may be more.
|
|
||
## Security Considerations | ||
<!--All EIPs must contain a section that discusses the security implications/considerations relevant to the proposed change. Include information that might be important for security discussions, surfaces risks and can be used throughout the life cycle of the proposal. E.g. include security-relevant design decisions, concerns, important discussions, implementation-specific guidance and pitfalls, an outline of threats and risks and how they are being addressed. EIP submissions missing the "Security Considerations" section will be rejected. An EIP cannot proceed to status "Final" without a Security Considerations discussion deemed sufficient by the reviewers.--> | ||
At this point, author of this EIP is not aware of any class of smart contracts that rely on `SELFDESTRUCT` for their functionality and security, with the exception of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some projects are using a ephemeral contracts
pattern to generate payment accounts, to withdraw from such accounts a contract is deployed on them (using CREATE2), the withdrawal takes place and the contract it's self-destruct.
Because of the ephemeral
nature of those accounts, authentication can be skipped (either the transaction fails and the account is never created, or the transaction success and the account is emptied). This would still be a safe pattern as long as the project never reuses those addresses, but it would endanger funds otherwise.
A good example of this pattern can be found on UniswapEX (https://github.com/UniswapEx/exchange/blob/master/contracts/libs/Fabric.sol), I think that UniswapEX is not affected, because those accounts are never re-used, but we would need to check if other projects are using the same pattern while re-using accounts.
I wonder if a built-in gasToken could act as an alternative to EIP-1556, it could mimic the behaviour of GasToken without actually storing anything on the state (only mimic the refunds), so we would get the "gas stabiliser" effect of GasToken without bloating the storage. |
|
||
## Abstract | ||
<!--A short (~200 word) description of the technical issue being addressed.--> | ||
Althouth `SELFDESTRUCT` originally came with EVM to help clean up the state, we learnt that in practice it did not achieve this objective on |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Althouth
should read although
## Specification | ||
<!--The technical specification should describe the syntax and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations for any of the current Ethereum platforms (go-ethereum, parity, cpp-ethereum, ethereumj, ethereumjs, and [others](https://github.com/ethereum/wiki/wiki/Clients)).--> | ||
After certain block number, the semantics of `SELFDESTRUCT` becomes the same as the combination of `POP`, followed by transferring remaining ETH | ||
to the address popped from the stack, followed by `STOP`. Gas cost is the same as the gas cost of non-zero value transfer, which is 9000 gas. No gas refund is given. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the address popped from the stack, followed by
STOP
.
This suggests selfdestruct can be executed multiple times. Is that the goal?
## Specification | ||
<!--The technical specification should describe the syntax and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations for any of the current Ethereum platforms (go-ethereum, parity, cpp-ethereum, ethereumj, ethereumjs, and [others](https://github.com/ethereum/wiki/wiki/Clients)).--> | ||
After certain block number, the semantics of `SELFDESTRUCT` becomes the same as the combination of `POP`, followed by transferring remaining ETH | ||
to the address popped from the stack, followed by `STOP`. Gas cost is the same as the gas cost of non-zero value transfer, which is 9000 gas. No gas refund is given. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think there's any point introducing new pricing here, if the specification is that SELFDESTRUCT
is replaced with CALL(<addr>, <value>, gas=0, ..
) and STOP
, then just state that and apply the gas rules of those two.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This operation should be cheaper than CALL because it doesn't need to load code or create an execution context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because it doesn't need to load code or create an execution context.
This EIP is changing the semantics of SELFDESTRUCT. From the current description it is not clear whether it turns into a non-executing transfer or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, turning it into an executing transfer would be a nice EVM unification/simplification. SELFDESTRUCT
is currently one of the "sneakiest" ways to add funds to an address; a capability that people often forget about.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@carver Developers only "forget" about it because of deceptive Solidity syntax. Nobody should assume their contract is "nonpayable". This does not change that because miners can still break that assumption via coinbase.
The convenience of the storage overhead is that we free the space when the network is congested, so in exchange for the additional gas we free more storage than the additional usage fills. By outbidding low-priority transactions in low congestion, we consume less space than usage that would not zero-out, thereby smoothing the growth of the state trie. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few spelling errors were keeping this PR from passing CI, I've noted them in the this review. Additionally, you should be good to assign this EIP as 2751
and update the filename to eip-2751
. After that, it should be mergeable and we can avoid losing any valuable discussion in this PR!
caller gas refund. In practice, this incentivisation turned out to be very limited, and the designed purpose was not archieved. However, `SELFDESTRUCT` | ||
brings significant amount of complexity to the EVM. It is responsible for some of the most arcane edge cases in the EVM semantics. | ||
It is also used as a vehicle to run an efficient arbitrage of gas prices (GasToken2), which | ||
ironically lead to the increase use of the state. Introduction of `CREATE2` opcode in Constantinople upgrade created a new phenomenom of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ironically lead to the increase use of the state. Introduction of `CREATE2` opcode in Constantinople upgrade created a new phenomenom of | |
ironically lead to the increase use of the state. Introduction of `CREATE2` opcode in Constantinople upgrade created a new phenomenon of |
|
||
## Backwards Compatibility | ||
<!--All EIPs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The EIP must explain how the author proposes to deal with these incompatibilities. EIP submissions without a sufficient backwards compatibility treatise may be rejected outright.--> | ||
Backwards incompatible and requres a hard fork. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Backwards incompatible and requres a hard fork. | |
Backwards incompatible and requires a hard fork. |
|
||
## Abstract | ||
<!--A short (~200 word) description of the technical issue being addressed.--> | ||
Althouth `SELFDESTRUCT` originally came with EVM to help clean up the state, we learnt that in practice it did not achieve this objective on |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Althouth `SELFDESTRUCT` originally came with EVM to help clean up the state, we learnt that in practice it did not achieve this objective on | |
Although `SELFDESTRUCT` originally came with EVM to help clean up the state, we learnt that in practice it did not achieve this objective on |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ooh, how did you do this @lightclient?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be a plus/minus button as part of the comment interface :) (something like in #6 here https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request)
Polymorphic contracts are the superior upgrade model. If you have thousands of token balances and allowances it's much cheaper to upgrade the code in-place than to migrate to a new contract. If it's too much work for the evm to ensure all of the storage slots are cleared, just don't do it; it would save me the trouble of resetting all contract state. Most self-destructs are for contracts without state; very few contracts self-destruct with remaining state. Instead you could incentivize other contracts to clear it out of the trie manually. A new opcode could point out external storage corresponding to an account without code and clear it for a gas refund. |
There has been no activity on this pull request for two months. It will be closed in a week if no further activity occurs. If you would like to move this EIP forward, please respond to any outstanding feedback or add a comment indicating that you have addressed all required feedback and are ready for a review. |
This pull request was closed due to inactivity. If you are still pursuing it, feel free to reopen it and respond to any feedback or request a review in a comment. |
Make
SELFDESTRUCT
EVM operation no-op (effectively disable). Contracts will not be able to delete themselves.