A simple and principled way to compute rent fees

OK, that’s fair enough, I neglected to think of that.

That’s orthogonal, the complexity is inherent in demurrage itself. Things like wrapped eth become impossible; at best it reduces to ‘eth during creation’. Everything that uses eth as a currency - all decentralized exchanges, bet contracts, even cryptokitties - would have to change their logic for a decaying currency. Decaying collateral would mean that liquidation of a dai stablecoin contract becomes a certainty.
Indefinite payment channels are dead. A valid signed transfer of 1 eth today can stop being valid tomorrow.

Tokens would have none of these problems, so ether would become the worst unit of account, unit of exchange and store of value on the platform. A utility token used exclusively for fees.
Ironically, much lower price resulting from this would almost certainly result in more state stored than the simple locking model.

Psychologically it destroys the immutability and store of value meme. It’s fine to argue technical points about rents, but all a typical crypto holder is going to see is that he has less eth that he should and interpret that as theft.

The question is not about whether to internalize costs, but how.
Locking eth already internalizes cost, the only difference is that state isn’t automatically deleted:

unless hardfork/gas limit like/ increases are going to be substantially smaller than increases in the total supply, the explicit payment model makes no sense, as it adds complexity for no gain.
IF they are going to be, then all that additional complexity is there only to prevent a few percentage points of growth at most.

3 Likes

Not true. Storing tokens would also require paying rent, just like storing both tokens and ETH already requires transaction fees.

Everything that uses eth as a currency - all decentralized exchanges, bet contracts, even cryptokitties - would have to change their logic for a decaying currency. Decaying collateral would mean that liquidation of a dai stablecoin contract becomes a certainty.

If we want to, we could store TTL separately from ETH balances, and then users would always have the ability to just pay the minimum 1-week upkeep every time, and reawaken their contracts every time they need to; this would be equivalent to what they would have to do if we were in a stateless client model, they would just experience the upkeep as just another kind of gas fee they only have to pay when they use the system. It would be more expensive for them to do things this way, but still likely substantially cheaper than the current status quo without sharding.

2 Likes

If we want to, we could store TTL separately from ETH balances

That’s way better, as long as the basic account itself is free (balance + nonce) to prevent all problems from demurrage. The balance could theoretically function as a read-only store, but setting the minimum positive balance to eg. 100 gwei should prevent any actual abuse.

I agree that would work. Without demurrage and with the inevitable rent-paying markets that take people’s eth for staking and pay for chosen storage, this becomes economically equivalent to the direct eth locking model, although more complex and requiring maintenance. The maintenance aspect satisfies the behavioral incentive function you want.

1 Like

In the future, the storage capacity of devices will increase, and we will want to decrease the price. The initial version should include a governance mechanism to allow this. Tying it to the governance mechanism used to determine max block size seems reasonable, so that when better governance mechanisms are researched, they can both change at the same time. The current mechanism also throttles the rate at which this sort of constant can change, which will be nice for people to be able to create their contract and forget about the rent for a long time.

1 Like

In the future, the storage capacity of devices will increase, and we will want to decrease the price. The initial version should include a governance mechanism to allow this

Agree. I would also say that we should have the ability to decrease, but not increase the storage price. This way we get the kind of flexibility that will end up mattering more in practice, and also give the direction of price predictability that matters more in practice.

1 Like

In this computation is the rent burnt or paid to validators?

If it is paid to validators, it seems to me that the “long-run cap” actually increases by about 0.5% every year

Would address balances decay over time or would it be an initiated process?

If it’s a decaying model, you could just leave a balance of 1 ETH and have storage security for 41 years. I think that’s pretty low risk if you have millions in this address (>1 ETH).

It is burnt. Ultimately there’s no reason to make short-run validator income dependent on short-run fluctuations in state storage. In the long run, there are proposals to have a long-run cap (eg. 120 million) and then scale all rewards by a factor of (120 million - current total supply), which would mean that in the long run all burnt ETH is paid to validators, but that’s a different mechanic and doesn’t affect short-run incentives in the same way.

I think rent fees are an awful idea, to be honest.
It completely breaks the original promise made by the ethereum project: Build unstoppable applications.
You can’t call an application unstoppable if it gets shut down for not paying “rent”.

If you want to clean the state from contracts that are no longer used, you should instead incentivize self-destruction of contracts by refunding a partial amount of the gas used by that same contract for storing its data.

1 Like

Do you mean like the existing refunds for sstore and selfdestruct? https://gastoken.io/#how

Yes, but if people don’t use it, maybe it’s because a refund of half the gas used is not enough? Or maybe the cost of storage is too low in the first place? Both?
I don’t know, but destroying the original purpose of the project is clearly not a good solution to the problem.

Not sure how this breaks the original promise of the project. To straw man a little, what if you can prepay for 100 years? What if you have a DAO that pays its own rent? Close enough to unstoppable?

Anyway I think we should separate philosophical “is rent a good idea” discussions from “how to do rent if it is a good idea” discussions. This should probably stay the latter.

2 Likes

Does this mechanism address your concern: Improving the UX of rent with a sleeping+waking mechanism? A contract that misses a rent payment doesn’t get shut down; anyone can still use it. It’s just that when you use it, you have to pay a little extra and provide a little extra data to remind everybody what was in it.

I think it’s helpful to come at this from the opposite direction. Imagine Ethereum had started out with fully stateless validation. Every transaction has to prove the current state of every contract it touches (with Merkle proofs from previous state headers).

This would be very efficient for validators—no need to track almost any state except the block headers! And IMO it would still fulfill the promise of unstoppable applications. But it would be pretty inefficient for contracts that are accessed very frequently, and leads to complicated race conditions when the proof that comes with a transaction is from an outdated Merkle root.

So we could ameliorate those problems by requiring that validators cache the state of each contract for some amount of time after such a proof is provided. And for convenience, if a contract wants to avoid being dropped from the cache, it can burn some ETH to bump its TTL. If you don’t pay rent, your contract gets dropped from the cache, but it’s still part of the Ethereum state, and can still be accessed by anyone just by providing the necessary proofs.

2 Likes

I might be wrong, but wouldn’t this break backward compatibility with a bunch of frontends/interactions between existing contract, that require the use of pure/view functions to work?

What happens if A is removed from the state?

contract A {
  function a() public pure returns (uint){
    return 1;
  }
}
contract B {
  A a;
  function b() public view returns (uint) {
    return a.a()+1;
  }
}
1 Like

You’re always free to keep more state than is strictly required for block validation. Infura could maintain every contract’s state (and even provide your client with a proof of that state, so you don’t have to trust them). And your local Mist could maintain the state of contracts you’ve viewed, or that it knows you are interested in.

But yes, interfaces will probably have to consider the possibility of failure. It’s definitely a tradeoff (link rot is a real problem on the web) but maybe one worth making to prevent the validator state from growing without bound.

2 Likes

As long as SELFDESTRUCT is a thing you will always need to reason about the probability of or lack of probability of failure. Having more explicit reasoning about the liveness of dependencies isn’t a huge burden, IMO.

In your example, B would throw until someone paid to resurrect A (the trickier example is if someone used the unchecked .call() construct, then they could potentially get an unexpected “return 0”, but such unchecked sends are not recommended anyway).

The alternatives are unsustainable state size growth, or stateless-clients-only, which have the same dev UX limitations surrounding state storage.

2 Likes

Yes - I think a rent mechanism for state is the right thing to do. Will state rent be burned so will this be a deflationary factor? Also, I guess ether balances will have a special role and not require rent, correct?

The answer is that calling B.b() will also fail (calls to empty code would throw by default in this proposal), and if you want to call it then you would have to wake A.

I Love the way that you think in terms of ensuring accessible technologies for all. If we can maintain this stance across all emerging tech, the ethical barriers we’re facing will be dissolved. Great thread. I’m learning a lot. Thank You to all contributors.

1 Like