Tezos smart contracts are natively written in Michelson – a purely functional, statically typed programming language.
Note: See our cryptocurrency programming languages article, specifically the Haskell section, for reasons why purely functional statically typed languages are highly desirable for crypto development.
Since Michelson isn’t very user-friendly, Tezos allows you to write smart contracts in various different languages which can be compiled (transpiled, to be accurate) to Michelson. Ligo, ReasonML, Smartpy and Archetype are common choices here. See our links at the end of this article for different alternatives to Michelson.
Here’s a set of links to a complete Michelson tutorial where you can go from zero to Tezos smart contract development in no time:
Example Smart Contract
Here’s a simplistic auction smart contract developed in Liquidity, taken from Apriorit Tezos smart contract tutorial:
[%%version 0.4]
type storage = {
auction_end : timestamp;
highest_bid : tez;
bidder : key_hash;
}
let%entry main
(parameter : key_hash)
(storage : storage) =
(* Check if auction has ended *)
if Current.time () > storage.auction_end then Current.failwith ("The auction has ended");
let new_bid = Current.amount () in
let new_bidder = parameter in
(* Check if new bid is higher that the last *)
if new_bid <= storage.highest_bid then Current.failwith ("The bid is too low");
let previous_bidder = storage.bidder in
let previous_bid = storage.highest_bid in
(* Set new highest bid in storage *)
let storage = storage.highest_bid <- new_bid in
let storage = storage.bidder <- new_bidder in
(* refund previous bid to previous bidder *)
let refund_to = Account.default previous_bidder in
let op = Contract.call refund_to previous_bid () in
([op], storage)
Here’s an example Tezos token / digital asset developed in Ligo, taken from Protofire Github
// variant defining pseudo multi-entrypoint actions
type entry_action is
| Deposit
| Withdraw
type finance_storage is record
liquidity: tez;
end
const noOperations: list(operation) = nil;
function depositImp(var finance_storage: finance_storage): (list(operation) * finance_storage) is
block {
if amount = 0mutez
then skip //fail("No tez transferred!");
else block {
finance_storage.liquidity := finance_storage.liquidity + amount;
}
} with(noOperations, finance_storage)
function withdrawImp(var finance_storage: finance_storage): (list(operation) * finance_storage) is
block {
const withdrawAmount: tez = 1000000mutez;
var operations: list(operation) := nil;
if withdrawAmount > finance_storage.liquidity
then skip //fail("No funds to withdraw!")
else block {
const receiver: contract(unit) = get_contract(sender);
const payoutOperation: operation = transaction(unit, withdrawAmount, receiver);
operations:= list
payoutOperation
end;
finance_storage.liquidity := finance_storage.liquidity - withdrawAmount;
}
} with(operations, finance_storage)
function main(const action: entry_action; var finance_storage: finance_storage): (list(operation) * finance_storage) is
block {
skip
} with case action of
| Deposit(param) -> depositImp(finance_storage)
| Withdraw(param) -> withdrawImp(finance_storage)
end;
Tezos smart contracts are written in Michelson
It’s a very low level language, but which has several desirable characteristics for cryptocurrency development.
Various more friendly languages, like Ligo and Liquidity, compile down to Michelson so you can write the contracts in a more readable language and then compile them to the lower level code required by Tezos.
Michelson Programming language
Choosing a Language for Smart Contracts on Tezos
French Cybercrime Division Uses Smart Contracts on Tezos Blockchain
Liquidity Smart Contracts Language
Michelson Topic at Tezos Stack Exchange
Tezos smart contracts with ReasonML, Docker and a sandboxed node