Decentralized App development on Tezos for beginners part 2

Meet the Tezos smart contract language — Michelson

catsigma
4 min readFeb 26, 2018

Updated @ 2018.02.26 (outdated, waiting for the formal release of zeronet)

Series parts

  1. Set up your own Tezos node and learn the basics concepts.
  2. Meet the Tezos smart contract language — Michelson.
  3. Use Liquidity to easily write Michelson contracts.
  4. Let’s deploy our first Michelson contract on Tezos.
  5. Build a website to interact with our Tezos contract.

— — — — — — — — — — — — — — — — — — — — — — — — — — — — —

Michelson is a strict static typing and stack-based language. It looks like this

parameter string;
return string;
storage unit;
code {... some instructions here ...};
  1. parameter defines the input-type of the contract. The type information will try to do the check to make sure the input is type correct when the contract is called.
  2. return defines the return-type of the contract. The type information is only used for type checking when the contract is called by another contract though code block instruction. The first calling from outside won’t get the result because of the asynchronous.
  3. storage defines the type of what kind of data can be stored on the Blockchain. Whatever data you want to store must fit in this type.
  4. The types of Michelson are composable, so complex data can be annotated by one large type.
  5. The instructions in code block are something like CAR; CDR; DUP; PAIR;. You can just consider it as a human readable version of Michelson bytecode. Here is what the official document says —

A Michelson program is a series of instructions that are run in sequence: each instruction receives as input the stack resulting of the previous instruction, and rewrites it for the next one. The stack contains both immediate values and heap allocated structures. All values are immutable and garbage collected.

I guess you might be a little bit confused right now. It’s totally different from some normal programming languages. In fact, it’s almost a kind of virtual machine’s operation code. Although you can write Michelson by hand, it’s not necessary to do this. One option is to use a high-level programming language called Liquidity which compiles to Michelson. Another alternative language is fi.

In next part, we’ll learn to write a Liquidity contract. But before we reach that, you still have to know

What must you know about Michelson?

1) An Account is a contract with no code and unit unit type.

parameter unit;
return unit;
storage unit;
code {};

So if you deployed a contract like this with parameter spendable=true, it works exactly like a normal account.

2) The special transfer instruction.

The first thing about the transfer is that you cannot access parameter after using the transfer instruction. This feature is made for preventing vulnerabilities when there is a loop calling within contracts. One method to overcome this is to save your previous states including parameters to the storage before running the transfer instruction. But the better practical way is to use transfer only once per contract and place it at the end of the codes.

— — — — — — — — — — — — — — — — — — — — — — — — — — — — —

One vulnerable example: We have a contract X with some XTZ in it. The functionality of X is to send 1 XTZ to every account who asks for it. X will memorize if one account has been sent or not in its storage. If the code of X updates the storage after the transfer instruction, then there is a vulnerability here. Let’s create a contract Q:

parameter unit;
return unit;
storage unit;
code { call X };

Here we have created a loop calling. The parameter-type and return-type of Q are both unit . So it can work exactly like an Account. X will treat Q like an account and send Q the 1 XTZ and then Q will call X again to ask for 1 more XTZ before X mark Q on his ledger.

— — — — — — — — — — — — — — — — — — — — — — — — — — — — —

The second thing about the transfer is that you cannot use it in a closure. And do not use it in a loop or an iteration as an anti-pattern.

3) The 16K size limitation.

This size of bytecode of the contract should be below 16KB, otherwise, it can’t be deployed.

4) How is the type information used?

Michelson is a static typing language and more than that, it can do type checking during the run-time. For this reason, unlike normal static typing language which will eliminate the type info after the compiling, Michelson will keep the type info in its bytecode. This feature gives Tezos the ability to do type checking when people calling contracts(doing transfers). If the type of calling parameters is not the same as the type predefined in the contract, a type mismatch error will be thrown.

Here is end of this part. We won’t mention the details of Michelson instructions in this part because we’ll learn a high-level language Liquidity which is far more easy to write and read.

Donation BTC: 1L7oCqy7GHx7EiQc9SPFputCWftfaoT3kB

View the next part…Use Liquidity to easily write Michelson contracts.

--

--