Skip to content
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

Blockchain rent: exponential rent-to-own edition #87

vbuterin opened this issue Apr 3, 2016 · 13 comments

Blockchain rent: exponential rent-to-own edition #87

vbuterin opened this issue Apr 3, 2016 · 13 comments


Copy link

@vbuterin vbuterin commented Apr 3, 2016

A previous EIP discussed the possibility of introducing a notion of "blockchain rent": paying not just a one-time fee for adding storage and getting a one-time refund for removing it, but actually paying per unit time. This was met with the primary criticism that users liked the aspect of Ethereum that contracts sit on the chain forever, and once a contract is placed there is no risk of the contract suddenly disappearing due to no longer being able to afford rent.

This EIP describes a mechanism where contracts can purchase storage in a "rent-to-own" model, where a contract may purchase storage and pay a small fee if they clear the storage in a limited amount of time, with the fee being roughly proportional to the amount of time that the storage is used, but if a contract holds onto a storage key for a long time the storage fee reduces exponentially. Unlike traditional such agreements, however, the "lease" is collateralized, and so there is no possibility of storage being "repoed".


To see how this works, consider a model where there is one storage key, and two parameters: F, the fee for using storage, and I, the inverse per-block interest rate. A contract can write to a previously blank storage key by paying F gas (or ether; there are two versions of this scheme where one uses gas as the "currency" and the other uses ether), and records the current block number B_0 into a special storage slot. Changing a non-blank storage key would take ~5,000 gas, just as now, although one may also consider a provision where if the key in question has already been changed during that block the cost goes down to 500 gas; this makes "cheque" mechanisms much cheaper. Emptying a storage key would refund F * 1/e ** ((B - B_0) / I), where B is the block number at the time storage is cleared. Hence, filling a previously blank storage key would always require up-front payment equal to the cost of "owning" that key outright, but the excess payment is refunded when the storage is cleared.

A chart of what this cost structure looks like in practice can be found here:

For a contract storing multiple keys, the above method could be applied on a per-slot basis; however, this would be too inefficient. Hence, we provide a simpler alternative. Suppose that each contract keeps track of two values, D ("deposit"), T ("last timestamp") and S ("slot count"). Filling an unused storage key costs F, sets D += F, S += 1 and T = block.timestamp. Clearing a storage key sets D *= 1/e ** ((block.timestamp - T) / I) * (S-1) / S, and refunds D / S (after reducing D); it then also setsS -= 1 and T = block.timestamp. Effectively, rather than tracking time stored on a per-slot basis, this scheme tracks it for the entire contract, and uses a kind of average cost basis accounting to perform refunds.

For example, consider a case where one slot is filled at time 0, one slot at time I * 0.693 (the constant selected since 1/e ** 0.693 = 0.5), then one slot is cleared at time I * 0.693 * 2 and one at time I * 0.693 * 4. Suppose F = 1 for simplicity. After the first slot is filled, we have D = 1, T = 0, S = 1. After the second slot is filled, we have D = 1.5, T = I * 0.693, S = 2. After the first slot is cleared, we have D = 0.375, T = I * 0.693 * 2, S = 1, and a refund of 0.375 is paid. After the second slot is cleared, we have D = 0, T = I * 0.693 * 4, S = 0, and a refund of 0.09375 is paid. An equivalent formulation of this would be accounting for the deposit of each slot separately, except when a slot is deleted it instead refunds an equal portion of the deposits for all slots: after the first slot is cleared, we refund 50% of the deposit for both the first and the second slot, and after the second slot is cleared we refund the remainder. If there are insertions after deletions, then deletion is proportional: if one deposit is already 60% refunded (ie. 40% remaining) while another is 20% refunded (ie. 80% remaining), then if one out of ten extant slots is cleared, the first slot receives an additional 4% refund out of its current remaining balance, and the second receives an additional 8% refund out of its current remaining balance. This kind of average cost basis accounting is likely the best that can be achieved while keeping low overhead requirements: a FIFO or LIFO scheme would require tracking additional data for each storage key.

Ether vs Gas

F can be charged, and refunded, in either ether or gas. The arguments for both sides are as follows:

  • If F is in gas, then it is easier to set a fixed price, and not have to deal with market mechanics for determining its cost: the market mechanic is already baked into the gas limit.
  • If F is in ether, then it becomes easier to economically decouple the cost of storage and the cost of computation, as the physical costs of these two resources may vary disproportionately over time, and price-fixing between them as gas-based schemes are bound to do will necessarily introduce inefficiencies/Pareto suboptimalities.
  • If F is in ether, this creates a stable source of demand for ETH, perhaps reducing volatility.
  • If F is in gas, then there may arise opportunities for inter-temporal gas arbitrage (ie. buying storage when gas is cheap and releasing when gas is expensive); this expands the de-facto gas limit to unintended levels during peak usage time. On the other hand, this may arguably be good, as there is no hard limit on what transactional load a blockchain can technologically handle; rather, there are centralization risks and security concerns that increase steadily with increasing throughput, and so at peak time when the benefits of increasing throughput are greater we may actually want a scheme that flexibly picks a higher point on the throughput/decentralization tradeoff curve.
  • If F is in gas, then any attempt to call a "cleanup mechanism" will need to be paired with other transactions that consume the gas that gets refunded; this makes it more difficult to benefit from refunds in practice, and so particularly reduces the incentive to clean out entire contracts via the self-destruct opcode.


Many uses of contracts in Ethereum actually do not need to use storage for a long time; in the extreme case, we have use cases like cheques where a storage key is filled, read, and can then be deleted all within a single block. These uses should not have to pay as much as those who fill storage up forever; blockchain rent schemes accomplish this. However, the exponential rent-to-own scheme does this in such a way that it allows those who do want to own storage forever to do so.

Copy link

@rfikki rfikki commented Apr 3, 2016

So, in laymen's terms what would the relationship in cost actually be of temporary rental vs. permanent storage? What is the proposed basis for coming up with the actual value proposition? How does one know the calculation makes economic sense over the long term? Is this being instituted as an alternative to the "suicide" option?

Copy link
Contributor Author

@vbuterin vbuterin commented Apr 3, 2016

So, in laymen's terms what would the relationship in cost actually be of temporary rental vs. permanent storage?

Depends on I. For example, suppose I is set to 2 years. Then, renting for 1 day would cost ~462 times less than filling and never emptying, and renting for 1 minute would cost ~665395 times less; however, these figures aren't quite adequate because each individual change to storage also still has its own gas cost that is independent of the cost of renting storage itself.

Also, for the true layman, here's a chart :)

What is the proposed basis for coming up with the actual value proposition?

You mean what is the basis for determining F and I? IMO I should just be fixed at some value decided by developers; ideally, F would be market-based in some way. One idea that I had was targeting a linearly growing state size, eg. 1 million storage keys + 100,000 per year, and increasing F hyperbolically as we approach that, ie. F = x if storage is empty, 2x if storage is at 50% of the maximum, 3x if it's 67%, 10x if it's 90%, etc.

Is this being instituted as an alternative to the "suicide" option?

This is being proposed as a replacement for the current refund mechanism (for both sstore clears and suicide).

Copy link

@Smithgift Smithgift commented Apr 4, 2016

The advantage (and I think it's a very big one) of this proposal is its elegance and (if F is paid in gas) backwards-compatibility. For the latter, every old contract will continue to work, and at worst will become uneconomical, which is no different than synchronous calls with binary sharding.

If we could wave a magic wand and implement an ether-based scheme originally, then we have an easily-grokked use of ether. You "harden" ether into a contract, and when you're done with it you "melt" it back into ether. But getting old contracts to work in a world where store operations no longer use gas is nontrivial. Brute force method: write a cheque to the contract to pay for any store operations, cancel it after the call, and figure out some way to ensure contracts aren't tricked into paying with their own ETH. (But then what about subcalls? Does the original account write cheques to every future contract, or do we rewrite all old code to force it to write subcheques? (new code, can, obviously, specify))

The disadvantage is that old contracts without self-destruct are permanent. Blockchain spam may be expensive, but it can never be cleaned up. I believe that if this is implemented, there will be a sense that data is permanent, and therefore there will never afterwards be a successful movement to implement protocol-level state pruning, for better or worse.

Copy link

@Smithgift Smithgift commented Apr 5, 2016

Assuming (a) an ether-based scheme, and (b), the market-based F scheme as proposed above, I foresee a potential attack vector: A deep-pocketed attacker spams the state with large numbers of useless keys, driving up storage costs for everyone. In a gas-based scheme, all the attacker would do is expand the gas limit.

With an F scheme that adapts to changes in rates of usage (like the default miner gas formula, or heck, if the miners are allowed to vote on F in their block) this may be mitigated.

Copy link
Contributor Author

@vbuterin vbuterin commented Apr 6, 2016

Now that I think about it more, at least in a non-scalable context a fixed ETH-denominated fee, or at least a fixed fee that declines according to an inverse linear schedule, could potentially work well. The simple reason is that you could agree on some maximum state size (eg. 1 TB) ahead of time, and work backwards to compute the fee in such a way that the total quantity of ether maps to that amount (eg. in this case the price of "owning" 1 byte would be 0.1 finney, so 10 kb = 1 eth and 1 TB = 10^8 eth, which is roughly the total supply). This way, an attacker would not be able to drive up fees for anyone; it would also give an interesting value proposition to ether as you could call it "virtual land on the world computer's hard drive".

Copy link

@psionic81 psionic81 commented Apr 7, 2016

y'all should really consider looking into the graph sequencing & isomorphism checks more.

breaking down a circuit diagram into components:

then measure and attribute by relative "novelty":

That would both optimize and ensure that the contracts' subcomponents were never more than a single dictionary call in the forever-long-run and getting exponentially close to this in the short to medium term. Plus any subcomponent that does stuff in the same way would be the exact same dictionary index, since it's based on graphs instead of rearrangeable evm code. The concept of "function primitives" comes into play (like a bridge rectifier in circuit land.)

Having a system that loses the ability to be audited on the long term because parts of it need to "melt" to ensure anti-spam simply means that attackers can destroy the system's coherence whenever they feel like it. Thus these DDOS tradeoffs mean censorship is easily possible.

Considerately, the data and circuit pathways are separated in the flow model I propose we implement here. I have a fundamental disagreement with losing the logic elements, ever. Maybe something snarky can be done with the data itself.

I'll write up a full thesis on what would happen here in the next few weeks after I discuss the estimation functions with my crew. I understand that many are not considering this methodology, and I don't expect them to at this point.. the primary research papers were only mass broadcast in the last few months of 2015.

Copy link

@Smithgift Smithgift commented May 11, 2016

After thought, I think this is the best option so far. It's easily backwards compatible, for one. Further, I realized there are many dapps, particularly registries, where users mainly read from the chain, but do not often write. In a system where a contract could involuntarily be deleted, someone would have to pay for the free use of others.

The big question in my mind is fixed ETH fee vs. gas. If it wasn't for the additional technical issues related to retrofitting a fixed ETH fee, I'd lean towards it more.

Copy link

@tawaren tawaren commented Mar 15, 2017

I wrote a comment on #35 before I read this proposal. This one has none of the drawbacks that #35 had and I thus agree with @Smithgift that this is the best option so far if there has to be changed anything at all.
Something that was unclear to me is if the cost would be payed in ETH, who does pay it.

I assume it would be the sender of the transaction and then I assume the refound would go to the sender of the current transaction too, which would incentivice to call state cleaning methods on contracts. The Drawback may be that this is in conflict with ongoing abstractions, that would allow a dynamic payment system where contracts can pay for gas instead of transaction senders, as well as introducing the possibility of attacks where a contract steels money from the transaction sender by allocating storage and then freeing the storage himself to get the ETH, so this variant would need something like a rent_limit (similar to max_gas)

If on the other hand it would be payed from the contracts balance then this incentive would not be their and it would become complicated to track balances and manage ETH, because any SSTORE could change that balance in a non-local predictable way (with non-local I mean we need to know F,S,T and can't just infer it from only knowing the current code), this would make static analysis of the ETH balance nearly impossible beside just assuming that it changes on each SSTORE. Further it would enforce each contract to manage ETH in some way, a contract that does not plan to hold any ETH at all would be impossible and not backwards compatible at all.

So in my opinion the only options would be gas or ETH payed by the transaction sender with a rent_limit because contract paying would not be backwards compatible and would force each contract to hold ETH and makes contract that do manage ETH a lot more complicated as it already is, what would introduce new sources for bugs and exploits.

Copy link

@Smithgift Smithgift commented Mar 15, 2017

Last I heard, the latest rent plan was simply for storing a new key to be very expensive (in ordinary gas), thus incentivizing contracts to store more temporary data in "landlord" contracts, which charge rent.

Copy link

@amazingandyyy amazingandyyy commented Jun 17, 2017

This is really interesting. Follow up.

Copy link

@jamesray1 jamesray1 commented Nov 10, 2017

Referenced here:

With a stateless client concept an advantage is: "All of the thorny questions about state storage economics that lead to the need for designs like rent (eg. #35 and even the current complex SSTORE cost/refund scheme disappear, and blockchain economics can focus purely on pricing bandwidth and computation, a much simpler problem)".

Copy link

@gitcnd gitcnd commented Feb 26, 2018

At today's storage prices, you can hold 153,846,153 average-sized transactions for $1 - or in other words, each transaction costs $0.0000000065 - and this cost is falling Extremely rapidly.
Proposing to pay rent on something that's worth $0.0000000065 which you already paid more than a million times it's worth to store in the first place is not sensible.

Copy link

@MicahZoltu MicahZoltu commented Mar 4, 2018

20,000 gas per 256-bits = 625 gas per byte = 640,000 gas per KB = 655,360,000 per MB
1 megabyte * 36,000 nodes (replication factor) = 655,360,000 gas per 36,000 MB of disk space consumed = 18,204 gas per MB of disk space consumed
1 nanoeth per gas = 0.000018204 ETH per MB
850 USD per ETH = 0.0154734 USD per MB = 16 USD per GB

Cost of storage (AWS S3, bulk): 0.021 USD per GB per month

16 USD/GB gets you ~63 years of storage before you are a net drain on the system, if you accept the numbers above as being reasonable. While this is a bit of buffer, it certainly isn't paid a million times. It also assumes replication factor remains at around 36,000 RF and does not grow, and gas prices do not decrease.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet