Hackernoon logoUsing the Michelson Programming Language to Write Smart Contracts on Tezos [A How-To Guide] - Part 2 by@claudebarde

Using the Michelson Programming Language to Write Smart Contracts on Tezos [A How-To Guide] - Part 2

Author profile picture

@claudebardeClaude Barde

Tezos smart contract developer in the making 🌮

We’re going to write a new smart contract in Michelson using a string passed in the parameter by the user that we'll concatenate to the string already present in the storage before saving the new string into the storage.
(Part 1 is available here.)
After introducing the basics of Michelson in the previous article, we’re going to continue our exploration of this programming language.
In this new installment, we’re introducing an amazing tool that’ll help us write, debug, and examine our Michelson code: the Jupyter notebook with the Michelson kernel developed by the Baking Bad team.
We’re going to write a new smart contract in Michelson using a string passed in the parameter by the user that we'll concatenate to the string already present in the storage before saving the new string into the storage.
It’s highly recommended to read Part 1 first, as it introduces concepts about smart contracts in Michelson we’re going to use here.
But first, let’s have a look at what’s probably the best tool around to code: Michelson!

Baking Bad’s Jupyter Notebook

Baking Bad developed an online Michelson compiler that goes beyond compiling your Michelson code.
It offers syntax highlighting, debugging, and a step-by-step visualization of the stack. You can open the notebook we’re going to use for this lesson using this link (bear in mind the kernel needs a minute or two to load) before selecting the 
MichelsonTutorial-Demo3.ipynb
 file.
The file is divided into two parts:

The inline code

In the first part, the whole smart contract is dropped into a single cell. You can compile and run it by writing
RUN
%default
parameter storage
 in the following cell.
After running the smart contract, there’s a detailed description of each step and what each instruction did to modify the stack (in 
In [10]
 on the picture). At the end of the runtime (in 
Out [10]
 on the picture), you’re left with your new storage.

The step-by-step code

Where this compiler shines is you can enter the instructions to modify the stack one by one and examine their effect after each step.
As in every Michelson smart contract, you start by specifying the parameter and the storage. Then, you type 
BEGIN
parameter storage
 to start the execution.
After this configuration step, you can enter the instructions one by one and run them by hitting 
CMD/CTRL + SHIFT
 to see how they modify the stack. In the 
Out [...]
 cell, you’re presented with the current value at the top of the stack.
Note: you can see a 
DUMP
 instruction in the step-by-step code. This is not Michelson — this is just an instruction used in the Jupyter notebooks to print the current state of the stack.
When you want to end the execution of the smart contract, you enter 
COMMIT
, and it’ll return the new storage, provided there’s no error in your code. If there’s one at any step of the execution, you’ll see a message and be able to fix it right away without having to review your code line by line.

Handling Parameters in a Michelson Smart Contract

In the last lesson, we introduced a few instructions that manipulated data either already in the stack or that we pushed ourselves. But what about handling users’ input? This is actually pretty easy!
We’re going to work with the contract present in the Jupyter notebook introduced above. You’re welcome to follow along in the notebook and run the instructions one by one to get a better understanding of how the stack looks like after each instruction. Here’s the full smart contract:
If you remember, a pair containing the parameter and the storage is automatically pushed at the top of the stack when the contract is called. We can then get the left part of the pair (the parameter) and use it. Here’s how it works.
First, let’s initialize our stack:
In this step, we get a fresh stack with a pair containing a parameter of type 
string
 (
world
) and the storage of type 
string
, too (
Hello
). Our final goal is to concatenate these two strings and return them.
In the next step, we duplicate the top element of the stack because we need the parameter and the storage in two separate elements of the stack to be able to put them together in one single string.
Michelson doesn’t have variables and is immutable by nature. New elements of the stack can be created with different methods — for example, by pushing them (with the 
PUSH
 instruction) or by duplicating them (with the 
DUP
 instruction). Remember at every step of the execution, you’re dealing with the top element of the stack. It’s the only one you can work with.
Let’s start with the first element of the stack, and let’s get the parameter out of the pair. We use the 
CAR
 instruction, whose purpose is to break an element of type 
pair
 and to return the left side of the pair (in this case, the parameter passed to the smart contract). After running 
CAR
, we’re left with the string 
world
 on top of the stack.
Now you may be wondering: How can I work with the second element of the stack if Michelson only deals with the first one? It’s very easy! Bring the second element to the top with the 
SWAP
 instruction, and keep the other one for later.
When using the 
SWAP
 instruction, you tell Michelson: “I don’t need the first element for now, but I’d like to work on the second one.” Michelson will bring down the first element to the second position and the second element up to the first position.
Now that the second pair we duplicated at the beginning is at the top, we can use a reverse 
CAR
 to get the right part of the pair with the 
CDR
 instruction.
The 
CDR
 instruction works like the 
CAR
 instruction, but you’ll keep the right side of the pair you’re manipulating (a pair always contains only two elements, so 
CDR
 and 
CAR
 are the only possible operations). After that, you can see our stack is made of two elements: in the first position, the string 
Hello
 and in the second position, the string 
world
.
Now let’s put them together!
In computer programming, the operation of putting two strings together is called concatenation. It’s only logical that the instruction to put two strings together in Michelson is called 
CONCAT
. The operation takes the two strings currently at the top of the stack and returns a single string. For the operation to be successful, two conditions must be true:
  1. You do have two elements on top of the stack (it’ll generate an error if there’s only one element left). If more elements are present, it’ll only deal with the two elements at the top.
  2. The two elements on top of the stack are strings (Michelson is strictly typed — it knows what kind of values it has in its stack, so don’t even try to fool it)
Now if you remember what we talked about in Part 1, you know what’s going to happen. We must create a pair with a list and the new storage to end the execution of the smart contract (it’s like saying goodbye in Michelson).
First, let’s push an empty list on the top of the stack:
Once the empty list is there, we can create a pair with the empty list and the string:
Once again, be very wary of the order of your elements and their type: Michelson will take the first element to put it on the left side of the pair and the second element to put it on the right side of the pair. Returning a pair of type (Pair string list (operation)) will generate an error.
Now our stack is clean and contains a pair with a list of operations and a string, the execution of the smart contract comes to an end.
You can see the full execution and the transformations of the stack in the video below:

Conclusion

In this new part of the Michelson tutorial for beginners, we had a look at a Jupyter notebook with a Michelson kernel that we’ll use heavily in the following parts of this tutorial to write, debug, and execute code.
New operation codes in Michelson were introduced: 
CAR
, which extracts the left part of a pair; 
DUP
, which duplicates the top element of the stack; 
CDR
, which extracts the right part of a pair; 
SWAP
, which swaps the positions of the two elements on the top of the stack; and 
CONCAT
, which takes two strings and returns a single string made of the two previous strings put together.
Animations that represent the operations in the stack were also added to help you better visualize and follow what happens at every step. This will become even more useful when the operations in the stack become more complicated and intricate.
Stay tuned!
(Previously published behind a paywall here: https://medium.com/better-programming/an-introduction-to-michelson-the-scripting-language-of-tezos-part-2-4cc972c8237c )

Tags

The Noonification banner

Subscribe to get your daily round-up of top tech stories!