This is (Part 1): An Introduction to Michelson: the Scripting Language of Tezos
Michelson must be one of the most exciting programming languages for smart contracts at the moment. It’s a stack-based, strictly typed language in which smart contracts are written to ensure the safety of the Tezos blockchain. Michelson is comparable to the bytecode of the Ethereum smart contracts but it’s more readable, safer, and more robust. All the high-level languages you can use to write smart contracts for Tezos — like SmartPy, Ligo, or Lorentz — eventually compile down to Michelson.
In this first article, we will dip our toes into Michelson language, understand what “stack-based” means and write some very simple smart contracts. This article is mainly written for beginners in programming and/or Tezos development, but intermediate programmers who want to know more about Michelson will also find useful information here. We are going to use the Jupyter kernel developed by Baking Bad to write Michelson code in the Jupyter notebook. You will find a link in each section if you want to see the code at work.
Let’s write some code!
The stack
To understand how Michelson works, one of the main concepts to understand properly is the stack. Every Michelson contract is a list of instructions that follow each other. These instructions are in a precise order and are executed in the order they’re written in.
Every instruction will manipulate the stack in some way. Imagine it as a pile of data. The instructions you write will cause an effect on the data present in the pile. You can, for example, add together two pieces of data on top of the pile, remove the one on the top, put another piece of data on top, transfer some tokens, etc. The stack works on a last in, first out basis: if you want to access a piece of data that is not at the top of the stack, you must first deal with the ones above it.
There are three main concepts you must remember when coding in Michelson:
- New data goes on top of the stack.
- The data in the stack only become accessible when they are at the top of the stack (or in the second position for some operations, as described below).
- The order in which the data are processed goes from the top of the stack to the bottom.
Let’s look at an example.
The PUSH Operation
If you want to add a piece of data on top of the stack, you will call the PUSH operation. This is how it works:
Note that there may already be data in the stack, in which case the new value will be put on top of them. This is how you push new data in Michelson:
PUSH value-type valueFor example, if you want to push an integer, you will write 
PUSH int 2PUSH string "Tezos"The Michelson Smart Contract Structure
A smart contract in Michelson displays a simple structure made of three components:
- The type of the expected parameter.
- The type of the storage.
- The Michelson code.
This translates to the following code:
parameter parameter-type ;
storage storage-type ;
code {
  ...
}In addition to this structure, there are two rules you must keep in mind when writing a smart contract in Michelson:
- A pair containing the parameter and the storage 
 is always automatically pushed to the stack when the code is executed. Remember — if there’s no parameter,(pair parameter storage)
 is used instead.Unit
- The code must always return a pair containing a list of operations and the (updated) storage 
 . The execution will stop when this kind of pair is the last thing remaining in the stack.(pair list(operation) storage)
A Simple Michelson Smart Contract
Now that we know about PUSH and the structure of a smart contract in Michelson, let’s write one!
For this contract, we are going to write a “Hello world” contract and save a string into the storage:
Here’s what happens when this code is executed:
 indicates that the passed parameter is of type- parameter unit
 (basically, no parameter).- unit
 indicates that the contract has storage of type- storage string
 .- string
 is an operation code that removes whatever is at the top of the stack. Remember, we said earlier that a pair with the parameter and the storage is automatically included on top of the stack at the beginning, we are not going to use it, we can just drop it.- DROP
 brings a value on top of the stack, here the string “Hello world”.- PUSH
 is an opcode that adds an empty list of the specified type (- NIL
 here) on top of the stack.- operation
 takes the two elements on top of the stack, creates a new pair containing these two elements, and pushes back the pair on the stack.- PAIR
Note: Every instruction ends with a semi-colon (it is optional for the last instruction though).
Adding Integers and Saving the Result
Let’s introduce a new operation: 
ADDHere’s a simple contract that demonstrates how it works:
Let’s go through each operation to understand what is happening inside the stack:
parameter unitstorage intDROPPUSH int 2 ; PUSH int 3 ;int 2int 3ADDPAIRADDNILPAIRConclusion
The complexity of the Michelson language is often overestimated. That’s probably due to the fact that there are no beginner-friendly tutorials out there and the rare documentation available online is extremely technical and difficult to read for neophytes. This’s why I decided to go through the process of learning Michelson myself, using the difficult documentation to create a series of tutorials that I hope are more accessible.
Understanding Michelson is key to understanding and appreciating the uniqueness of the Tezos blockchain and what makes it more secure and more useful.
In the next part, we will continue diving into Michelson. We’ll write some simple smart contracts and explore the amazing Jupyter notebooks created by the Baking Bad team that will allow us to write Michelson code and understand exactly what’s going on.
Stay tuned!
