1

Gas cost is an important topic in smart contract development. We want to maintain the costs as low as possible to allow for more operations in a block. There is a handy gas consumption reference, but it is already over a year old (there were lots of gas optimizations in Delphinet so the example calculation is probably out of date) and the rules are quite complicated such that it might be hard to keep all of them in mind.

Questions for experienced teams and individuals that write Michelson or designing programming languages that compile to Michelson:

  1. What are you doing to reduce gas costs?

  2. Are there certain instructions you avoid? For example I have heard that DIP is expensive operation, that leads me to believe it would be better to do a combination of DUP, SWAP and DIG.

  3. What techniques are you using to analyze gas costs and determine if your optimization is truly better? Do to the stack nature of Michelson it can be expensive (time wise) to reorganize code.

  4. When you have multiple pieces of data you need to alter (for example you want to do something like x + y * x - z then send it to another contract), do you start with an ideal stack order in mind or do you make something work then try to reorganize it later.

  5. Finally, any patterns you have discovered would be helpful.

1
  • 1
    Just a quick comment: the handy gas consumption reference you refer to will be ntegrated into the tezos developer documentation: gitlab.com/tezos/tezos/-/merge_requests/2038 this version still hasn't been updated for delphi though.
    – arvidj
    Jan 20 at 11:00
2

What are you doing to reduce gas costs?

The first thing to do is to do algorithmic optimisation, without worrying about Michelson's own constraints.

Then, to make additional savings, lower level optimisations can be done :

• organise the stack so as to reduce the number of stack operations,

• In a complex contract where the optimisation of one entry point will often be to the detriment of the others, the gas cost of the entry points that will be used most must be minimised.

• The organisation of the entry points in the parameter must be constructed in such a way that the most used entry points are more easily accessible: e.g. (or (or a b) (or c (or d e)) makes sense if a b and c are used at approximately equal frequency, if this is not the case and a is used more often, or a (or b c) (or d e)) will be more relevant.

Are there certain instructions you avoid? For example I have heard that DIP is expensive operation, that leads me to believe it would be better to do a combination of DUP, SWAP and DIG.

I have not heard that DIP is particularly expensive, however it is rarely effective to replace a single instruction with a series of instructions.

It is unlikely that such a sequence would be more gas efficient than using DIP, as this would imply a problem in the gas model and in this case would be amended in the future.

for example this sequence :{DUG 2; ADD; SWAP}; is more expensive than this one : DIP {ADD}.

you can test with the instruction tezos-client run script <contract_name>.tz on storage <storage> and input <parameter> --trace-stack.

Keep in mind that micro-optimisations must be avoided because the gas cost of instructions is likely to change with amendments, especially if those instructions are too expensive.

What techniques are you using to analyze gas costs and determine if your optimization is truly better?

When the client executes, the cost of gas execution is indicated, so to see if one set of instructions is better than another, simply make a minimum contract that successively contains both and compare the gas costs.

When you have multiple pieces of data you need to alter (for example you want to do something like x + y * x - z then send it to another contract), do you start with an ideal stack order in mind or do you make something work then try to reorganize it later.

It is certainly preferable to plan in advance how access to the elements will be done, however, it may happen that optimizations are found during the coding.

3
  • 1
    Minor note: the size of DUG 2; ADD; SWAP is 8 bytes, while the size of DIP { ADD } is 9 bytes. I don't think run script will reflect all of the costs associated with code loading/typechecking. I am not sure how the total net gas looks in this example (one byte is not much.) But generally we might care somewhat independently about both code size and total gas, because code size leads to burn and counts against the origination op size limit.
    – Tom
    Jan 20 at 17:57
  • 1
    (However, the question does specifically ask about gas!)
    – Tom
    Jan 20 at 18:18
  • I misspoke about DIP then, it was the byte size not the gas cost.
    – MCH
    Jan 21 at 8:45
3

You may find this article useful: https://medium.com/tqtezos/how-to-minimize-transaction-costs-of-tezos-smart-contracts-9962347faf64

1
  • Thank you, this is a great resource.
    – MCH
    Jan 20 at 13:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.