What is a Smart Contract?

A Smart Contract is a program composed of 3 things:

  • an entrypoint
  • a storage
  • a code

The entrypoints represents the type of the transaction that can be sent to the smart contract.

When a transaction is sent to the smart contract, the code of the smart contract will be executed and a new storage will be returned.

Because the code is executed on each node of the network, it ensures that the transaction takes place in a fully distributed, and trust-less environment.

What are we going to write?

We're going to write a simple smart contract. In a nutshell, it will have one entrypoint that accepts ꜩ (tez/XTZ), and distribute this amount to two other addresses. The Smart Contract will ensure that the two parties received the same amount of tez.

Let's code.

In Tezos there are many languages to create a Smart Contract. You can use Michelson which is the lowest level to write Smart Contract, it's like the assembler of Tezos. If you like Python you can use SmartPy. And if you're crazy about Ocaml/JavaScript I recommend LigoLang.

An empty contract.

First, let's create a file: contract.ligo

$ touch contract.jsligo
bash

Now we are ready to create an empty contract.

Like any Smart Contract, we have to define the type of the storage, the type of the entrypoint, and the code. Because our Smart Contract is very simple, the storage and the entrypoint will be unit.

type storage = unit; // The type of the storage of the smart contract type result = [list<operation>, storage]; // What returns a call to the smart contract type entrypoint = unit; // The type of the entrypoint @entry const main = (_: entrypoint, storage: storage): result => { // The function called when the smart contract is triggered return [list([]), storage] };
js

As you noticed the main function returns a pair, the new storage and a list of operations. The list of operations represents the different operations that your Smart Contract can send to other smart contracts/address.

Let's compile the smart contract to make sure it's working.

$ ligo compile contract contract.jsligo
bash

The command will output the michelson instructions that will be executed on chain.

{ parameter unit ; storage unit ; code { CDR ; NIL operation ; PAIR } }
txt

As you noticed there are the parameters, the storage, and the code of the smart contract.

The division of the amount.

Let's get the amount of tez sent to this Smart Contract and divide it by 2.

Smart Contracts has to be determinist, so we can't maniulate floats. That is said, if you want to divide something you always have to manage the remaning part of the euclidian division.

type storage = unit; // The type of the storage of the smart contract type entrypoint = unit; // The type of the entrypoint @entry const main = (_: unit, storage: storage): [list<operation>, storage] => { // The function called when the smart contract is triggered let amount = Tezos.get_amount(); // Returns the amount of tez associated to the transaction. let _amount_to_send: tez = amount / (2 as nat); // split the amount of tez by 2 let _remaining: tez = amount % (2 as nat); // Get the remaining part of the division of tez return [list([]), storage] };
javascript

Don't forget to compile

$ ligo compile contract contract.jsligo
bash

You can compile the code, and notice that the generated michelson is a bit bigger than previously.

The transfer amount to the beneficiaries.

Last step is to send the divided amount to the different beneficiaries.

Because the Smart Contract will create some operations, we will have to returns them.

type storage = unit; // The type of the storage of the smart contract type result = [list<operation>, storage]; // What returns a call to the smart contract @entry const main = (_: unit, storage: storage): result => { // The function called when the smart contract is triggered let amount = Tezos.get_amount(); // Returns the amount of tez associated to the transaction. let amount_to_send: tez = amount / (2 as nat); // split the amount of tez by 2 let remaining: tez = amount % (2 as nat); // Get the remaining amount of tez // Parsing the addresses let address_1 = Tezos.get_contract("tz1cBUPLRLzM77p5iQKTUxfDUp3vwPp9BKfQ" as address); let address_2 = Tezos.get_contract("tz1cBUPLRLzM77p5iQKTUxfDUp3vwPp9BKfQ" as address); let sender = Tezos.get_contract(Tezos.get_sender()); // Sends the respective amounts let op1 = Tezos.transaction(unit, amount_to_send, address_1); let op2 = Tezos.transaction(unit, amount_to_send, address_2); let op3 = Tezos.transaction(unit, remaining, sender); return [list([op1, op2, op3]), storage] };
javascript

Never forget to compile your code.

$ ligo compile contract contract.jsligo
bash

Conclusion

That's it, you learned how to write a simple Smart Contract. You also discovered ligo, the best Smart

Contract language for Tezos. The language is still evolving, and it's making really good progress.

You can follow the language on Linkedin, Twitter and Github/Gitlab.