ReasonLIGO | Building Smart Contracts & Dapps On Tezos
Tezos smart contracts are compiled from a custom low level language called Michelson. For web developers however learning a new low level programming language is a barrier to entry… Enter LIGO and specifically ReasonLigo.
ReasonLIGO is the most accessible way to develop smart contracts for web developers. ReasonLIGO is based on ReasonML which is based on Typescript which is based on Javascript. It’s a bit convoluted but basically if you can read Javascript you’ll probably understand ReasonLIGO and be able to create smart contracts. Let’s take a look at a simple ReasonLIGO smart contract.
type storage = int;
/* variant defining pseudo multi-entrypoint actions */
type action =
| Increment(int)
| Decrement(int);
let add = ((a,b): (int, int)): int => a + b;
let sub = ((a,b): (int, int)): int => a - b;
/* real entrypoint that re-routes the flow based on the action provided */
let main = ((p,storage): (action, storage)) => {
let storage =
switch (p) {
| Increment(n) => add((storage, n))
| Decrement(n) => sub((storage, n))
};
([]: list(operation), storage);
};
So this contract is storing a number and providing two functions to increase the number or decrease it.
If you are coming from a Javascript background the main difference is that this is strongly typed. That means that when you define a variable you have to describe the type such as string/integar/object etc.
You’ll notice the big arrow function main is similar in construction to a modern ES6 Javascript function and this will be the main entry point when invoking or using the contract after it has been deployed.
Deploying A ReasonLIGO Contract
Let’s try deploying this contract to the babylon testnet using the LIGO playground IDE.
Open up this link and select ReasonLIGO from the list of options. This is a development playground where you can test, compile, deploy and evaluate smart contracts.
Select Deploy > Run and your smart contract will be deployed to the blockchain.
Next step is getting this working using your own credentials inside a dapp.
First job is to get some credentials and testnet tokens.
In this example we use an external library called ConseilJS to interact with a public Tezos node. We use this to initiate our test account using the credentials from the faucet and then deploy a very simple smart contract.
Let’s compile the contract using the IDE. Select Compile and then tick the “Output Michelson as JSON” box, then click Run. Copy and paste the result into the script above between the backticks at “const contract = “;”
Now lets run the script:
npm install conseiljs
node conseilTest.js
In the output you should get an operation hash which can be entered on the block explorer here: https://better-call.dev/
Remember to change the network from mainnet to babylon testnet.
You’ve now successfully created a smart contract in ReasonLIGO, compiled it to a Michelson JSON file and then deployed it in a Javascript application.
Enter the contract address from the block explorer in the first line. This increments the stored number by 5. We need the tezosNode and keystore (generated from initaccount()) data a well from the previous code.
Each time we call the above code we are interacting with our smart contract. Any functions we have as part of the “main” entry point in ReasonLIGO can be called in this way.
ReasonLIGO A Beginners Guide
Here are some code snippets which should help with getting started developing smart contracts with ReasonLIGO
// constants
let age : int = 25;
// variables
let add = ((a, b): (int, int)): int => {
let c : int = a + b;
c;
};
// arithmetic
let plus_op = (n: int): int => n + 42;
let minus_op = (n: int): int => n - 42;
let times_op = (n: int): int => n * 42;
let div_op = (n: int): int => n / 2;
let neg_op = (n: int): int => - n;
let foo = (n: int): int => n + 10;
// functions
let my_function = (i: int): int => {
let my_number: int => int = (i: int) => 5 + i;
my_number;
};
// blockless functions
function add (const a: int; const b : int) : int is a + b
// anonymous functions
let increment = (b : int) : int => ((a : int) : int => a + 1) (b);
let a : int = increment (1); // a == 2
// boolean operators
let or_true = (b: bool): bool => b || true;
let or_false = (b: bool): bool => b || false;
let and_true = (b: bool): bool => b && true;
let and_false = (b: bool): bool => b && false;
let not_bool = (b: bool): bool => !b;
let a : int = 5;
let b : int = 4;
let c : bool = (a == b);
let d : bool = (a > b);
let e : bool = (a < b);
let f : bool = (a <= b);
let g : bool = (a >= b);
let h : bool = (a != b);
// conditions
let main = (i: int) =>
if (i == 2) {
42;
} else {
0;
};
// loops
let loopy_for_ligo = (i: int): (bool, int) =>
if (i < 100) {
continue(i + 1);
} else {
stop(i);
};
// storage
type storage = {
customers: map(address, nat),
total: tez,
owner: address
}
// addresses
let my_account : address =
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address);
let main = (p : key_hash) : address => {
let c : contract(unit) = Current.implicit_account(p) ;
Current.address(c) ;
};
// strings
let size_op = (s: string): nat => String.size(s);
let slice_op = (s: string): string => String.slice(1n, 2n, s);
let concat_syntax = (s: string) => s ++ "test_literal";
//booleans (true or false)
let a : bool = true;
let b : bool = false;
// amount
let check_ = (p: unit) : int =>
if (Current.amount == 100tz) {
42;
}
// records
type user = {
id : nat,
is_admin : bool,
name : string
};
// maps
type move = (int, int);
type register = map (address, move);
// check signature
let check_signature = (param: (key, signature, bytes)) : bool => {
let pk, signed, msg = param;
Crypto.check(pk, signed, msg);
};
// error reporting
failwith("This contract always fails");
// includes
#include "included.religo"
// time
let today : timestamp = Tezos.now;
let one_day : int = 86400;
let in_24_hrs : timestamp = today + one_day;
let some_date : timestamp = ("2000-01-01t10:10:10Z" : timestamp);
let one_day_later : timestamp = some_date + one_day;
let not_tomorrow : bool = (Tezos.now == in_24_hrs);
Conclusion
ReasonLIGO is a coding language which can be used to develop Tezos blockchain applications. It’s Javascript-esque format make it a good choice for developers coming from a web dev background.
The Blockchain Sector newsletter goes out a few times a month when there is breaking news or interesting developments to discuss. All the content I produce is free, if you’d like to help please share this content on social media.
Thank you.
Disclaimer: Not a financial advisor, not financial advice. The content I create is to document my journey and for educational and entertainment purposes only. It is not under any circumstances investment advice. I am not an investment or trading professional and am learning myself while still making plenty of mistakes along the way. Any code published is experimental and not production ready to be used for financial transactions. Do your own research and do not play with funds you do not want to lose.