-
Notifications
You must be signed in to change notification settings - Fork 5.9k
Description
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".
Mechanism
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: http://vitalik.ca/files/costchart.jpg
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.
Benefits
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.
