This started out as a reply to a message in another thread, but boiled off into a rant.
That has essentially been answered.
However, I’d like to add that the currently dominant contract architecture, coupled with wallet design tropes, prevents the
SSTORE-refund incentive from being usable.
For people to want to clean up after themselves, the cleaning-up has to happen within the same transaction as some other “useful” work. But there is no way to “chain” the two.
GasToken currently suggests using it from within other contracts, but this puts users at the mercy of contract developers. Also, from observing the ecosystem for years, most (sane) developers are reluctant to put code into their contracts that is not strictly related to its business logic.
If we want to incentivise certain kinds of behaviour, we must incentivise the users, not the contract coders - as, ultimately, it is the users that are the initiators of transactions that result in storage increase; and coders all too often have the option of shifting costs onto users anyway, so tend to be less frugal.
I’ve been working recently on an alternative program execution paradigm, which I call transient programs (in comparison to resident programs, commonly known as “contracts”).
For a short (and wholly-incorrect) explanation of what it is, to people who are familiar with Solidity only: “it’s like stuffing everything into the constructor”.
Transient programs execute at the bottom of the call stack, and are calling nobody (leaving the
to field empty).
Using transient programs could remove the need for explicit GasToken support in end-contracts (as is currently suggested by GasToken crew), special “clean-up proxy contracts” (proxy this proxy that ugh the word is as sickening by now as your lack of imagination get a dictionary),
batchStuff() functions that bloat contracts; and the general notion that for code to run, an authority has to deploy it first.
It could allow for vastly more to be “garbage-collected”; what comes to mind immediately is outdated ERC-20 allowances and
spam naïve air-drop ERC-20 balances, both of which are relatively easy to track by wallet software.
I’ve called this execution paradigm “ancient” in the title, because that’s how
contracts resident programs have been created since forever: a certain kind of a transient program claims a tiny bit of address space, where it pushes its payload.
However, development of transients seems to have stopped immediately afterwards; and residents are now completely entrenched.
I can’t start imagining how to convince wallet makers that this feature is one that they’d want to develop and support. Most wallets (all?..) don’t even have a way to deploy user-provided residents (they don’t allow leaving the
to field empty).
Perhaps the above is too tongue-in-cheek; and this is a use pattern that no one thought of (not counting me sitting on my hands…). Indeed, some EVM design choices tend to suggest so.
If you followed either of the LLL links above, you’d have read that:
In a transient program, both code and data must be passed in the same transaction field. Although called “transaction data” when viewed externally, it will be available as code in its entirety during execution.
In the linked repository, it seems awkward that the resident variant accesses its data via
CALLDATALOAD, whereas the transient has to resort to
The fact that leaving the
to field empty results in increased gas use - by way of a
nonced account address assignment, instead of just using the EOA’s address and deferring the
nonce-ing until an actual
CREATE is requested, - suggests that “contract deployment” at this point is expected. (For this reason, the linked transient multi-send program only starts saving gas when having at least 5 recipients.)
I was thinking of having this ready around Devcon; for many reasons, a month later, it’s in a state as sorry as ever - so here you go, a rant for a