5.3 KiB
id | title |
---|---|
what-and-why | What & Why |
Before we get into what LIGO is and why LIGO needs to exist, let's take a look at what options the Tezos blockchain offers us out of the box. If you want to implement smart contracts natively on Tezos, you have to learn Michelson.
💡 The (Michelson) language is stack-based, with high level data types and primitives and strict static type checking.
Here's an example of Michelson code:
counter.tz
{ parameter (or (or (nat %add) (nat %sub)) (unit %default)) ;
storage int ;
code { AMOUNT ; PUSH mutez 0 ; ASSERT_CMPEQ ; UNPAIR ;
IF_LEFT
{ IF_LEFT { ADD } { SWAP ; SUB } }
{ DROP ; DROP ; PUSH int 0 } ;
NIL operation ; PAIR } }
The contract above maintains an int
in its storage. It has two entrypoints (functions) add
and sub
to modify it, and the default entrypoint of type unit will reset it to 0.
The contract itself contains three main parts:
parameter
- Argument provided by a transaction invoking the contractstorage
- Type definition for the contract's data storage.code
- Actual Michelson code that has the provided parameter & the current storage value in its initial stack. It outputs a pair of operations and a new storage value as its resulting stack.
Michelson code consists of instructions like IF_LEFT
, PUSH ...
, UNPAIR
that are bundled togeter in what is called a sequence. Stack represents an intermediate state of the program, while storage represents a persistent state. Instructions are used to modify the run-time stack in order to yield a desired stack value when the program terminates.
💡 A Michelson program running on the Tezos blockchain is meant to output a pair of values including a
list of operations
to emit and a newstorage
value to persist
Differences between a stack and traditional variable management
Stack management might be a little bit challanging, especially if you're coming from a C-like language. Let's implement a similar program in Javascript:
counter.js
var storage = 0;
function add(a) {
storage += a
}
function sub(a) {
storage -= a
}
// We're calling this function reset instead of default
// because `default` is a javascript keyword
function reset() {
storage = 0;
}
In our javascript program the initial storage
value is 0
and it can be modified by running the functions add(a)
, sub(a)
and reset()
.
Unfortunately (???), we can't run Javascript on the Tezos blockchain at the moment. But we can choose LIGO, which will abstract the stack management and allow us to create readable, type-safe, and efficient smart contracts.
💡 You can try running the javascript program here
C-like smart contracts instead of Michelson
Let's take a look at a similar LIGO program. Don't worry if it's a little confusing at first; we'll explain all the syntax in the upcoming sections of the documentation.
type action is
| Increment of int
| Decrement of int
| Reset of unit
function main (const p : action ; const s : int) : (list(operation) * int) is
block { skip } with ((nil : list(operation)),
case p of
| Increment(n) -> s + n
| Decrement(n) -> s - n
| Reset(n) -> 0
end)
type action =
| Increment of int
| Decrement of int
| Reset of unit
let main (p, s: action * int) : operation list * int =
let result =
match p with
| Increment n -> s + n
| Decrement n -> s - n
| Reset n -> 0
in
(([]: operation list), result)
type action =
| Increment(int)
| Decrement(int)
| Reset(unit);
let main = ((p,s): (action, int)) : (list(operation), int) => {
let result =
switch (p) {
| Increment(n) => s + n
| Decrement(n) => s - n
| Reset n => 0
};
(([]: list(operation)), result);
};
💡 You can find the Michelson compilation output of the contract above in
ligo-counter.tz
The LIGO contract behaves exactly* like the Michelson contract we've saw first, and it accepts the following LIGO expressions/values: Increment(n)
, Decrement(n)
and Reset(n)
. Those serve as entrypoint
identification, same as %add
%sub
or %default
in the Michelson contract.
*not exactly, the Michelson contract also checks if the AMOUNT
sent is 0
Runnable code snippets & exercises
Some of the sections in this documentation will include runnable code snippets and exercises. Sources for those are available at the LIGO Gitlab repository.
Snippets
For example code snippets for the Types subsection of this doc, can be found here:
gitlab-pages/docs/language-basics/src/types/**
Exercises
Solutions to exercises can be found e.g. here: gitlab-pages/docs/language-basics/exercises/types/**/solutions/**
Running snippets / excercise solutions
In certain cases it makes sense to be able to run/evaluate the given snippet or a solution, usually there'll be an example command which you can use, such as:
ligo evaluate-value -s pascaligo gitlab-pages/docs/language-basics/src/variables-and-constants/const.ligo age
# Outputs: 25