I'm quite new to ethereum but after reading the white and yellow papers I must say I'm very excited about it! I, however, have a worry about the fee schedule. My background is in economics and I tend to focus on how such a schedule incentivizes people rather than the more computer science oriented parts. From that perspective I see three potential problems with the current schedule. Being new to this, I hope I've not misunderstood anything or missed if this already is a ongoing discussion.
- Data storage. Storing data in the ethereum blockchain is extremely cheap and there is no incentive to remove data that is not needed. This is potentially a huge problem as, unlike most other blockchain implementations, any data can be stored in it and therefore runs the risk of being exploited.
As a, maybe not completely fair but still illustrative, example: Storing one 32-byte word in Amazon's AWS for one month costs more than 800 000 times the cost of a single ordinary computational operation (see below for calculation). In ethereum the cost of storing a 32-byte word indefinitely is only 200 times the cost a computational operation. This is of course only the relative price, the absolute price is likely to still be lower at Amazon. This, however, incentivizes developers in ethereum to develop applications with a space–time tradeoff that does not reflect the true costs.
An example of this would be any Dapp with a bit of complexity (and it does not need to be much) which then would benefit from caching all incoming calls. E.g., a Dapp that require 4 000 fuel to complete, could for an extra 200 one-time fuel cost reduce all subsequent calls to a mere 20 (a single SLOAD operation). Imagine if most Dapp start caching every call and what that would do to the size of the blockchain.
This is made much worse by the fact that there's no incentive to remove information once it's stored. The yellow paper states that the fee for clearing memory is waived (or rather payed upfront). The effect of this is that it is slightly cheaper to overwrite storage rather use new space. But it provides no incentive to clear unused space -- actually it does the opposite. By clearing storage one would need to pay 200 fuel to reclaim it in the future. By not clearing it one would only pay 100. And in any case, why throw away free information that one might need in the future (even if the probability that one need it is very small)?
Since there is no incentive to clear memory each Dapp is likely to weakly increase it's storage use over time, leading to an explosion of the blockchain size. This is especially true for data feed Dapps that are likely to have a varied storage need. For example, an app providing all major Bitcoin transactions the past day will sometimes need to store millions of transactions and sometimes only a few thousands. Since the app developer knows that storage needs varies and than clearing memory will lead to future costs (but that it's free to keep the information), the storage of the app will be the maximum of the storage need at any time in its history.
Suggestion: The classical suggestion from an economist in these cases is that the price should reflect the cost. In this case the storage cost is not one-off as the the price (the 100-200 fuel for a SSTORE operation) but rather a continuous storage cost. Instead a more appropriate schedule would be to reduce the cost of putting information into storage to at, or near, the price of a normal operation and impose a continuous cost. For example all accounts could be forced to pay a couple of wei per stored word per generated block. When an account cannot pay for its storage it is removed. (This could be extended so accounts need to pay also for its stored code as well, which would help to keep the block state clean).
- Stack versus memory. If I understood this correctly, the computational stack is unlimited and free which memory is not. This will push developers to be overly stack focused and lead to inefficient Dapps. Why use memory when one can store all the information one want for free in the stack? Of course this problem is mitigated by that many tasks would require more other operations when solely using the stack compared to also using memory and by that one still has to pay for an ordinary operation to push to the stack, but the problem is by no means solved.
Suggestion: Again, making the price reflect the cost is usually a good way forward. The stack and (virtual) memory require approximately the same amount of (machine) memory and thus should face the same price. A question is however whether this should be as now where one pays to use memory. The stack (unlikely memory) is likely to fluctuate greatly making it very costly to increase the price of pushing to the stack. An alternative would be to keeping track of the maximum combined memory (i.e. virtual memory + stack) used at any time during its execution and base the fee on that. The app would then instead be terminated if the maximum memory counter exceeds the remaining fuel.
- Calling costs and modularity. One of the great possibilities of ethereum is its modularity. Someone can implement the equivalent to a software library with all kinds of functions and data feeds that other Dapp can call. However, if the transactions costs (i.e. calling costs) are too high, people will not do this and this will reduce the modularity of the network. This is especially true since everything on ethereum has its machine code in the open. Thus, even if a Dapp takes a fair price, too high calling costs will lead to developers that copy-paste functionalities directly into their Dapps leading to very large Dapp code bases.
Suggestion: I've not really researched this but to me the calling costs seem a bit high (20 fuel for a call and 5 fuel per byte information transferred). Reducing this as close as possible to the 1 fuel for an ordinary operation would be ideal and I don't really see the need for a fee for information transfers (over-and-about the ordinary memory costs). However, a call necessarily imposes quite a bit of overhead (fuel calculations, program initiation, etc). One way around all of this would be to introduce different kinds of calls. For example, one could have one call that is well-separated as now and have the same cost as now. And then a cheap direct call with much less overhead, e.g., sharing fuel, memory etc.
(The Amazon AWS calculation: one GB of data costs $0.1 per month, which is $(32 * 0.1 / 1024^3) per 32-byte word per month. A T2 micro instance costs $0.013 for an hour which gives 6 minutes of 100% utilization of a "High Frequency Intel Xeon Processor operating at 2.5GHz". Assuming 4 operations per clock-cycle this yields $(0.013 / 6 * 60 * 4 * 2.5 * 10^9) per operation. The ratio is then (32 * 0.1 / 1024^3) / (0.013 / 6 * 60 * 4 * 2.5 * 10^9) = 825 295.1.)