Reference
An archetype contract is composed of declarations, actions (aka entry points) and optionally specification for formal verification.

Declarations

  • constant and variables declare global variables. A constant value cannot be modified in the contract's actions.
1
constant rate : rational = 0.2
Copied!
1
variable price : tez = 10tz
Copied!
  • states declares contract's possible states. It is then possible to use transitions to change the contract states (see below)
1
states =
2
| Created initial
3
| Confirmed
4
| Canceled
5
| Success
6
| Fail
Copied!
initial is used to declare the initial state value of the contract.
  • action declares an entry point of the contract. An action has the following sections:
    • specification (optional) to provide the post conditions the action is supposed to have
    • accept transfer (optional) to specify that transfer of tez is accepted
    • called by (optional) to declare which role may call this action
    • require (optional) to list the necessary conditions for the action to be executed
    • failif (optional)to list the conditions which prevent from execution
    • effect is the code to execute by the action
1
action an_action_1 (arg1 : string, arg2 : int) {
2
specification {
3
// see 'specification' section below
4
}
5
called by a_role
6
require {
7
r1 : arg2 > 0
8
}
9
failif {
10
f1 : arg2 > 10
11
}
12
effect {
13
// ...
14
}
15
}
Copied!
  • transition declares an entry point of the contract that changes the state of the contract. A transition has the same sections as an action (except effect, see above) plus:
    • from to specify the states the transition starts from
    • to to specify the states after the transition
    • when (optional) to specify the transition condition
    • with effect to specify the effect of the transition
1
states
2
| Created initial
3
| Confirmed
4
| Canceled
5
| Success
6
| Fail
7
8
transition confirm {
9
from Created
10
to Confirmed
11
when { transferred > 10 tz }
12
with effect {
13
transfer 1tz to @tz1RNB9PXsnp7KMkiMrWNMRzPjuefSWojBAm
14
}
15
}
Copied!
It is possible to specify several to ... when .... with effect ... sections in a transition. It is possible to specify a list of original states for the transition to start from:
1
transition fail {
2
from Created or Confirmed
3
to Fail
4
when { ... }
5
}
Copied!

Builtin types

  • bool : boolean values
  • int : integer values
  • rational : floating value that can be expressed as the quotient or fraction of two integers
  • address : account address
  • role : an address that can be used in action's called by section
  • date : date values
  • duration : duration values (in second, minute, hour, day, week)
  • string : string of characters
  • tez : Tezos currency
  • bytes : bytes sequence

Composite types

  • * declares a tuple made of other types.
1
constant pair : int * string = (1, "astr")
Copied!
  • option declares an option of type.
1
constant value : int option = none
Copied!
  • list declares a list of any type (builtin or composed)
1
variable vals : string list = []
Copied!
  • asset declares a collection of asset and the data an asset is composed of. For example the following declares a collection of real estates described by an address, a location and an owner:
1
asset real_estate identified by addr {
2
addr : string;
3
xlocation : string;
4
ylocation : string;
5
owner : address;
6
}
Copied!
  • enum declares an enumeration value. It is read with a match ... with command (see below).
1
enum color =
2
| White
3
| Red
4
| Green
5
| Blue
Copied!
It is then possible to declare a variable of type color:
1
variable c : color = Green
Copied!
  • contract declares the signature of another existing contract to call in actions.
1
contract called_contract_sig {
2
action set_value (n : int)
3
action add_value (a : int, b : int)
4
}
Copied!
It is then possible to declare a contract value of type called_contract_sig and set its address:
1
constant c : called_contract_sig = @KT1RNB9PXsnp7KMkiMrWNMRzPjuefSWojBAm
Copied!
  • collection declares an asset field as a collection of another asset.
1
asset an_asset identified by id {
2
id : string;
3
a_val : int;
4
asset_col : another_asset collection
5
}
Copied!
  • partition declares an asset field as a collection of another asset. The difference with collection is that a partition ensures at compilation that every partitioned asset (i.e. element of the partition) belongs to one and only partitioning asset.
1
asset partitioning_asset identified by id {
2
id : string;
3
asset_part : partitioned_asset partition;
4
}
Copied!
As a consequence of the partition, a partitioned asset cannot be straightforwardly added or removed to its global collection with add and remove (see operation below). This has to be done via a partition field:
1
my_partitioning_asset.asset_part.add(a_new_partitioned_asset)
Copied!

Effect

An action's effect is composed of instructions separated by a semi-colon.

Declaration

  • var declares a local variable with its value. While possible, it is not necessary to declare the type a local variable. Local variables' identifier must be unique (no name capture in Archetype).
1
var i = 0;
Copied!

Assignment

  • := enables to assign a new value to a global or local variable.
1
i := 1;
Copied!
  • += , -= , *= and /= enable to respectively increment and decrement an integer variable (local or global).
1
i *= 2; // i := i * 2
2
d += 3w; // d := i + 3w, date d is now previous d plus 3 weeks
Copied!

Effects on asset collection

  • add enables to add an asset to an asset collection. It fails if the asset key is already present in the collection.
1
an_asset.add({ id = "RJRUEQDECSTG", asset_col = [] }); // see 'collection' example
Copied!
  • update enables to update an existing asset; it takes as arguments the id of the asset to update and the list of effects on the asset. It fails if the id is not present in the asset collection.
1
an_asset.update("RJRUEQDECSTG", { a_value += 3 });
Copied!
  • addupdate is similar to update except that it adds the asset if its identifier is not present in the collection.
1
an_asset.addupdate("RJRUEQDECSTG", { a_value += 3 });
Copied!
  • remove removes a an asset from its collection.
1
an_asset.remove("RJRUEQDECSTG");
Copied!
  • removeif enables removing assets under a condition.
1
an_asset.removeif(a_val > 10); // "a_val" is an asset field
Copied!
  • clear clears an asset collection.
1
an_asset.clear();
Copied!

Control

  • ; sequence
1
res := 1;
2
res := 2;
3
res := 3;
Copied!
  • if then and if then else are the conditional branchings instructions.
1
if i > 0 then (
2
// (* effect when i > 0 *)
3
) else (
4
// (* effect when i <= 0 *)
5
);
Copied!
  • match ... with ... end FIXME
1
archetype effect_control_matchwith
2
3
enum t =
4
| C1
5
| C2
6
| C3
7
| C4
8
| C5
9
10
variable res : int = 0
11
12
action exec () {
13
specification {
14
s0: res = 1;
15
}
16
effect {
17
var x : t = C3;
18
match x with
19
| C1 | C2 -> res := 0
20
| C3 -> res := 1
21
| _ -> res := 2
22
end
23
}
24
}
Copied!
  • for in do done iterates over a collection.
1
var res = 0;
2
for a in an_asset do
3
res += a.a_val;
4
done;
Copied!
  • iter to do done iterates over a sequence of integer values (starting from 1).
1
var res = 0
2
iter i to 3 do // iterates from 1 to 3 included
3
res += i;
4
done; // res is 6
Copied!
  • transfer transfers an amount of tez to an address or a contract.
1
transfer 2tz to @tz1RNB9PXsnp7KMkiMrWNMRzPjuefSWojBAm;
Copied!
With the contract keyword presented above, it is possible to transfer to a contract and call an entry point. In the example below, the entry point set_value of contract c is called and 2tz is transferred.
1
contract contract_called_sig {
2
action set_value (n : int)
3
action add_value (a : int, b : int)
4
}
5
6
constant c : called_contract_sig = @KT1RNB9PXsnp7KMkiMrWNMRzPjuefSWojBAm
7
8
action update_value(n : int) {
9
effect {
10
transfer 2tz to c call set_value(n);
11
}
12
}
Copied!
  • fail aborts the execution. It prevents from deploying the contract on the blockchain. As a consequence the storage is left unchanged when executed.
1
fail("a message");
Copied!
  • require and failif fail if the argument condition is respectively false and true. require(t) is sugar for if t then fail("").
1
require(val > 0);
2
failif(val <= 0);
Copied!

Expressions

Literals

  • boolean
1
constant x : bool = true
2
constant y : bool = false
Copied!
  • integer
1
constant i : int = 1
2
constant j : int = -42
Copied!
  • rational
1
constant f : rational = 1.1
2
constant g : rational = -1.1
3
constant r : rational = 2 div 6
4
constant t : rational = -2 div 6
Copied!
  • string
1
constant s : string = "hello world"
Copied!
  • tez
1
constant ctz : tez = 1tz
2
constant cmtz : tez = 1mtz
3
constant cutz : tez = 1utz
Copied!
  • address / role
1
constant a : address = @tz1Lc2qBKEWCBeDU8npG6zCeCqpmaegRi6Jg
Copied!
  • duration
1
// duration of 3 weeks 8 days 4 hours 34 minutes 18 seconds
2
constant d : duration = 3w8d4h34m18s
Copied!
  • date
1
constant date0 : date = 2019-01-01
2
constant date1 : date = 2019-01-01T01:02:03
3
constant date2 : date = 2019-01-01T01:02:03Z
4
constant date3 : date = 2019-01-01T00:00:00+01:00
5
constant date4 : date = 2019-01-01T00:00:00-05:30
Copied!
  • list
1
constant mylist : int list = [1; 2; 3]
Copied!
  • option
1
constant op1 : int option = none
2
constant op2 : int option = some(0)
Copied!
  • bytes
1
constant bl : bytes = 0x12f12354356a
Copied!

Operators

Logical

  • and operator of logical conjunction
1
var bool_bool_and : bool = (true and false);
Copied!
  • or operator of logical disjunction
1
var bool_bool_or : bool = (true or false);
Copied!
  • not operator of logical negation
1
var bool_bool_not : bool = not true;
Copied!

Operator

  • = FIXME
1
var int_int_eq : bool = 1 = 2;
2
var rat_int_eq : bool = (1 div 2) = 2;
3
var int_rat_eq : bool = 1 = (2 div 3);
4
var rat_rat_eq : bool = (1 div 3) = (2 div 3);
5
var tez_tez_eq : bool = 1tz = 2tz;
6
var dur_dur_eq : bool = 1h = 2h;
7
var date_date_eq : bool = 2020-01-01 = 2020-12-31;
8
var bool_bool_eq : bool = true = false;
9
var addr_addr_eq : bool = @tz1Lc2qBKEWCBeDU8npG6zCeCqpmaegRi6Jg = @tz1bfVgcJC4ukaQSHUe1EbrUd5SekXeP9CWk;
10
var str_str_eq : bool = "a" = "b";
Copied!
  • <> FIXME
1
var int_int_ne : bool = 1 <> 2;
2
var rat_int_ne : bool = (1 div 2) <> 2;
3
var int_rat_ne : bool = 1 <> (2 div 3);
4
var rat_rat_ne : bool = (1 div 2) <> (2 div 3);
5
var tez_tez_ne : bool = 1tz <> 2tz;
6
var dur_dur_ne : bool = 1h <> 2h;
7
var date_date_ne : bool = 2020-01-01 <> 2020-12-31;
8
var bool_bool_ne : bool = true <> false;
9
var addr_addr_ne : bool = @tz1Lc2qBKEWCBeDU8npG6zCeCqpmaegRi6Jg <> @tz1bfVgcJC4ukaQSHUe1EbrUd5SekXeP9CWk;
10
var str_str_ne : bool = "a" <> "b";
Copied!
  • < FIXME
1
var int_int_lt : bool = 1 < 2;
2
var rat_int_lt : bool = (1 div 2) < 2;
3
var int_rat_lt : bool = 1 < (2 div 3);
4
var rat_rat_lt : bool = (1 div 2) < (2 div 3);
5
var tez_tez_lt : bool = 1tz < 2tz;
6
var dur_dur_lt : bool = 1h < 2h;
7
var date_date_lt : bool = 2020-01-01 < 2020-12-31;
Copied!
  • <= FIXME
1
var int_int_le : bool = 1 <= 2;
2
var rat_int_le : bool = (1 div 2) <= 2;
3
var int_rat_le : bool = 1 <= (2 div 3);
4
var rat_rat_le : bool = (1 div 2) <= (2 div 3);
5
var tez_tez_le : bool = 1tz <= 2tz;
6
var dur_dur_le : bool = 1h <= 2h;
7
var date_date_le : bool = 2020-01-01 <= 2020-12-31;
Copied!
  • > FIXME
1
var int_int_gt : bool = 1 > 2;
2
var rat_int_gt : bool = (1 div 2) > 2;
3
var int_rat_gt : bool = 1 > (2 div 3);
4
var rat_rat_gt : bool = (1 div 2) > (2 div 3);
5
var tez_tez_gt : bool = 1tz > 2tz;
6
var dur_dur_gt : bool = 1h > 2h;
7
var date_date_gt : bool = 2020-01-01 > 2020-12-31;
Copied!
  • >= FIXME
1
var int_int_ge : bool = 1 >= 2;
2
var rat_int_ge : bool = (1 div 2) >= 2;
3
var int_rat_ge : bool = 1 >= (2 div 3);
4
var rat_rat_ge : bool = (1 div 2) >= (2 div 3);
5
var tez_tez_ge : bool = 1tz >= 2tz;
6
var dur_dir_ge : bool = 1h >= 2h;
7
var date_date_ge : bool = 2020-01-01 >= 2020-12-31;
Copied!

Arithmetic

  • + FIXME
1
var int_int_plus : int = 1 + 2;
2
var rat_rat_plus : rational = 1.1 + 1.2;
3
var int_rat_plus : rational = 1 + 1.2;
4
var rat_int_plus : rational = 1.1 + 2;
5
var dur_dur_plus : duration = 1h + 2s;
6
var date_dur_plus : date = 2020-01-01 + 1d;
7
var dur_date_plus : date = 1d + 2020-01-01;
8
var str_str_plus : string = "str1" + "str2"; (* concat *)
9
var tez_tez_plus : tez = 2tz + 1tz;
Copied!
  • - FIXME
1
var int_int_minus : int = 1 - 2;
2
var rat_rat_minus : rational = 1.1 - 1.2;
3
var int_rat_minus : rational = 1 - 1.2;
4
var rat_int_minus : rational = 1.1 - 2;
5
var date_date_minus : duration = 2020-01-01 - 2019-12-31; (* absolute value *)
6
var dur_dur_minus : duration = 1h - 2s; (* absolute value *)
7
var date_dur_minus : date = 2020-01-01 - 1d;
8
var tez_tez_minus : tez = 2tz - 1tz;
Copied!
  • * FIXME
1
var int_int_mult : int = 1 * 2;
2
var rat_rat_mult : rational = 1.1 * 1.2;
3
var int_rat_mult : rational = 1 * 1.2;
4
var rat_int_mult : rational = 1.1 * 2;
5
var int_dur_mult : duration = 2 * 1h;
6
var int_tez_mult : tez = 1 * 1tz;
7
var rat_tez_mult : tez = 1.1 * 1tz;
Copied!
  • / FIXME
1
var int_int_div : int = 1 / 2;
2
var rat_rat_div : rational = 1.1 / 1.2;
3
var int_rat_div : rational = 1 / 1.2;
4
var rat_int_div : rational = 1.1 / 2;
5
var dur_int_div : duration = 1h / 2;
Copied!
  • % FIXME
1
var int_int_modulo : int = 1 % 2;
Copied!

Constant

  • caller FIXME
1
var v : address = caller; (* SENDER *)
Copied!
  • source FIXME
1
var v : address = source; (* SOURCE *)
Copied!
  • balance FIXME
1
var v : tez = balance; (* BALANCE *)
Copied!
  • transferred FIXME
1
var v : tez = transferred; (* AMOUNT *)
Copied!
  • now FIXME
1
var v : date = now; (* NOW *)
Copied!
  • state FIXME
1
archetype sample_state
2
3
states =
4
| First
5
| Second
6
| Third
7
8
9
transition mytr () {
10
from First
11
to Second
12
with effect {
13
require (state = First)
14
}
15
}
Copied!

Builtin functions

  • min FIXME
1
var int_int_min : int = min(1, 2);
2
var rat_int_min : rat = min(1 div 2, 1);
3
var int_rat_min : rat = min(2, 1 div 3);
4
var rat_rat_min : rat = min(1 div 2, 1 div 3);
5
var date_date_min : date = min(2020-01-01, 2020-12-31);
6
var dur_dur_min : dur = min(1h, 1s);
7
var tez_tez_min : tez = min(1tz, 2tz);
Copied!
  • max FIXME
1
var int_int_max : int = max(1, 2);
2
var rat_int_max : rat = max(1 div 2, 1);
3
var int_rat_max : rat = max(2, 1 div 3);
4
var rat_rat_max : rat = max(1 div 2, 1 div 3);
5
var date_date_max : date = max(2020-01-01, 2020-12-31);
6
var dur_dur_max : dur = max(1h, 1s);
7
var tez_tez_max : tez = max(1tz, 2tz);
Copied!
  • abs FIXME
1
var int_abs : int = abs(-1);
2
var rat_abs : rat = abs(-1 div 2);
Copied!

List

  • contains FIXME
1
archetype expr_list_contains
2
3
variable res : bool = false
4
5
action exec () {
6
specification {
7
s0: res = true;
8
}
9
effect {
10
var l : string list = ["1"; "2"; "3"];
11
res := contains(l, "2")
12
}
13
}
Copied!
  • count FIXME
1
archetype expr_list_count
2
3
variable res : int = 0
4
5
action exec () {
6
specification {
7
s0: res = 3;
8
}
9
effect {
10
var l : string list = ["1"; "2"; "3"];
11
res := count(l)
12
}
13
}
Copied!
  • nth FIXME
1
archetype expr_list_nth
2
3
variable res : string = ""
4
5
action exec () {
6
specification {
7
s0: res = "2";
8
}
9
effect {
10
var l : string list = ["1"; "2"; "3"];
11
res := nth(l, 1)
12
}
13
}
Copied!
  • prepend adds an element to a list at the first position.
1
archetype expr_list_prepend
2
3
variable res : string list = []
4
5
action exec () {
6
specification {
7
s0: res = ["0"; "1"; "2"; "3"];
8
}
9
effect {
10
var l : string list = ["1"; "2"; "3"];
11
res := prepend(l, "0");
12
}
13
}
Copied!

Asset Collection

  • contains FIXME
1
archetype expr_method_asset_contains
2
3
asset my_asset identified by id {
4
id : string;
5
value : int;
6
} initialized by {
7
{"id0"; 0};
8
{"id1"; 1};
9
{"id2"; 2}
10
}
11
12
variable res : bool = false
13
14
action exec () {
15
specification {
16
s0: res = true;
17
}
18
effect {
19
res := my_asset.contains("id0")
20
}
21
}
Copied!
  • count FIXME
1
archetype expr_method_asset_count
2
3
asset my_asset identified by id {
4
id : string;
5
value : int;
6
} initialized by {
7
{"id0"; 0};
8
{"id1"; 1};
9
{"id2"; 2}
10
}
11
12
variable res : int = 0
13
14
action exec () {
15
specification {
16
s0: res = 3;
17
}
18
effect {
19
res := my_asset.count()
20
}
21
}
Copied!
  • get FIXME
1
archetype expr_method_asset_get
2
3
asset my_asset identified by id {
4
id : string;
5
value : int;
6
} initialized by {
7
{"id0"; 0};
8
{"id1"; 1};
9
{"id2"; 2}
10
}
11
12
variable res : int = 0
13
14
action exec () {
15
specification {
16
s0: res = 1;
17
}
18
effect {
19
var a = my_asset.get("id1");
20
res := a.value
21
}
22
}
Copied!
  • nth FIXME
1
archetype expr_method_asset_nth
2
3
asset my_asset identified by id {
4
id : string;
5
value : int;
6
} initialized by {
7
{"id0"; 0};
8
{"id1"; 1};
9
{"id2"; 2}
10
}
11
12
variable res : int = 0
13
14
action exec () {
15
specification {
16
s0: res = 1;
17
}
18
effect {
19
var a = my_asset.nth(1);
20
res := a.value
21
}
22
}
Copied!
  • head FIXME
1
archetype expr_method_asset_head
2
3
asset my_asset identified by id {
4
id : string;
5
value : int;
6
} initialized by {
7
{"id0"; 4};
8
{"id1"; 3};
9
{"id2"; 2}
10
}
11
12
variable res : int = 0
13
14
action exec () {
15
specification {
16
s0: res = 3;
17
}
18
effect {
19
var l = my_asset.head(2);
20
var a = l.nth(1);
21
res := a.value
22
}
23
}
Copied!
  • tail FIXME
1
archetype expr_method_asset_tail
2
3
asset my_asset identified by id {
4
id : string;
5
value : int;
6
} initialized by {
7
{"id0"; 0};
8
{"id1"; 1};
9
{"id2"; 2}
10
}
11
12