Developing Efficient Contracts
Written by Dan Larimer
One of the major challenges facing users of the EOS blockchain is the scarcity of CPU resources. There are two approaches to resolving this scarcity: increase CPU capacity or reduce CPU demand through higher efficiency. Block One is working to increase capacity, but it is up to application developers to write more efficient contracts to reduce demand.
I recently reviewed a single transaction with a single action which spawned 28 child actions. These child actions included 10 transfers (and related notifications to sender/receiver). 3 issue actions, and communication between 4 inter-related contracts.
The design of this application uses a lot of copy-n-paste code for their token contract, combined with a lot of atomic micro-payments involving EOS and their own DICE token. This modular design has some security benefits (minimizing the amount of time tokens are under management of the smart contract), but it comes at the price of heavy CPU usage. Each action must set up and tear down its own execution context, validate its own permissions, and perform other redundant computations. All told this operation was billed 5.37 ms of CPU time (an average of 0.2 ms per inline action).
The same effect could be achieved with the following changes:
merge the independent contracts (betdicetoken and betdicegroup and betdicelucky) into a single contract.
Once merged all of the inter-contract communication can be eliminated. DICE tokens can be issued and deposited into respective account holder’s balances without creating any inline actions.
Allow users to maintain a deposit balance with the betdicegroup. This way users can deposit once, bet many times, withdraw once. This will eliminate the need to communicate with the eosio.token contract multiple times. User account balances can be updated quickly and efficiently internal to the betdice contract without having to notify sender / receiver for every micro-payment.
With a few small optimizations at the application level, I suspect the CPU required to play this dice game could be reduced by 80% or more. Users could play 5x as much before running out of CPU time.
In a not-to-distant upgrade to EOSIO we will enable the application developer to pay for the CPU on a per-transaction basis. This means that users will not require any CPU resources to play the game and the developer can monetize the CPU usage by other means. Under this world, efficient contract development will reduce the capital costs of the application developer by 80% or more. Today’s apps push these costs on to the user which must either buy stake or borrow it.
It is time for application developers to start carefully considering the efficiency of their designs or they will be outcompeted by more efficient and cost effective alternatives.
Intel, Apple, and Microsoft can only improve application performance so much though improving their hardware and operating systems. The largest performance gains are in the hands of application developers. The same applies to blockchain applications.