EIP-6913: SETCODE instruction

Allowing during DELEGATECALL was the original specification. I’m open to either way. But the benefit is for static analysis to be able to detect whether an account has mutable code, whereas it is a much harder question when you can SETCODE within DELEGATECALL. The current specification, which I am calling belongs-to in this forum thread, would have another benefit that any code observed within an unreverted context to be immutable will always be immutable, allowing on-chain static analysis.

All of the confusion raised in the ACDE meeting by @MariusVanDerWijden was pretty muffled but everything I could hear is already addressed by the EIP. I plan to attend the next meeting to directly confront your confusion but as always it would be better to discuss it async here.


We already have a way to do it, via SELFDESTRUCT and CREATE2

The mechanism is broken by eip-6780 and should be replaced with a new opcode.

You also say there are ambiguities but these behaviors are specified. The general rule under the current “belongs-to” spec is that SETCODE is allowed when the executing code belongs to the current account. There was a simpler original spec that allowed SETCODE inside DELEGATECALL and multiple-SETCODE but it had the drawback that it was harder for static analysis to determine if code was immutable. The “belongs-to” specification also enables on-chain static analysis because code immutability cannot be faked.

Setting code within a contract that just got SETCODE

Allowed in the original spec. Disallowed in the current “belongs-to” spec.

Doing SETCODE in a loop

Allowed in the original spec. Disallowed in the current “belongs-to” spec. However it is possible to loop SETCODE by calling into the modified code.

Doing SETCODE recursively

Newly modified code can be called into and can therein SETCODE again. But if your context has not yet SETCODE, a child context can prevent you from doing so by modifying the code of the account you are executing.

It doesn’t play well with verkle

It was designed to play well with Verkle. Please elaborate.

An alternative approach, described by Vitalik:

This code_address design would be acceptable for me. It would mean that older code versions remain in the state, but it would enable sharing code. With the code_address design we would want an opcode for reading an account’s code_address and an opcode for creating a new account with another account’s code address, and also opcodes for reading the immutable code at that code address if it does not match the account’s code (eg CODECOPY, EXTCODECOPY, ACCOUNTCODECOPY). So code_address is a more complex design than SETCODE that requires more opcodes but accomplishes the same objectives.

I have simplified the belongs-to specification by changing the general rule to not being able to execute SETCODE if the executing code does not match the account’s code, which combines the relevant cases of DELEGATECALL and CREATE.

I have prepared this presentation for ACDE: SETCODE Designs - Google Slides
It will be interesting to see if ACDE prefers the CODE_ADDRESS design.

With the neutering/removal of SELFDESTRUCT, and the general move away from mutable code, do you feel that this proposal is still viable?

What is the rationale to replace code of a smartcontract ? Isnt a proxy update approach better where you clearly see that the contract bytecode has changed.

Mutable code is broken by SELFDESTRUCT removal, and this is the reason this EIP was published. SELFDESTRUCT’s removal was considered a prerequisite for Verkle (because it clears storage), and this is the reason it happened. The main issues with SELFDESTRUCT as a method for updating code are presented in the EIP. There is not a “general move away from mutable code”. Mutable code may be restored in the future, and this EIP seeks to be one of the ways it can happen. Another way account code could be mutable in the future is special transactions that set the code of an EOA.

Mutable code and mutable sequential data.

Proxies cannot trade on DEXes without considerable overhead, and this means that any account abstraction method using them cannot compete with MEV bots. This hinders adoption of account abstraction for trading, currently the dominant use case for Ethereum.

Under the current SETCODE specification it is easy to identify mutable code (easier than identifying proxies), and it would be as easy for a block explorer to show previous code as it is for them to show proxy implementation changes. As for your specific complaint, Etherscan already identifies when code has changed but does not show when proxies have changed.