Interoperability
LIGO can work together with other smart contract languages on Tezos, such as calling them and receiving calls from them. However, data structures from different high-level languages might have different representations in Michelson and not how LIGO structures them by default. When a LIGO contract calls contracts that were written in other high-level languages, it must pass parameters that are compatible with the data structures in the other contracts.
Michelson types and annotations
Michelson types consist of or
types and pair
types, combined with field annotations.
Field annotations add constraints on a Michelson type.
To be compatible, two types must meet these criteria:
- They must have the same types in the same structure
- Their annotations must be compatible, which means that one of the following is true:
- Both types have no annotations
- Both types have annotations that are identical
- One type has annotations and the other type has no annotations
For example, this Michelson type is a pair that contains an integer and a string, both with annotations:
That type is compatible with this type because it is identical:
It is also compatible with this type because it has the same types minus the annotations:
However, it is not compatible with the following type because the primitive types have a different structure, even though the annotations are on the same types:
It is also not compatible with the following type even though the following type uses the same primitive types in the same structure. The annotations don't match and therefore the types don't match.
It is also not compatible with the following type because this type has some annotations but not all of the annotations in the other type:
In this way, to call another contract, you may need to change the output Michelson format of your types to match the type that the other contract expects.
When possible, use annotations when you define or call entrypoints. Annotations help make it clear which entrypoint you are referring to.
Setting the Michelson layout of LIGO data structures
LIGO can format types in Michelson in two basic layouts: combs and trees. For more information about combs and trees, see Pairs on docs.tezos.com.
Right comb layout
Since version 1.0, the default Michelson data representation of LIGO data structures is a right comb that matches the order of the LIGO declarations.
You can use the decorator @layout("comb")
to make this choice explicit, as in this example of a variant type:
The resulting Michelson code looks like this:
The decorator @layout("comb")
can also be used on record types:
Unlike the variant type, the compiled Michelson code of a record type in a right comb is a nested pair. The previous example looks like this in Michelson:
Left-balanced tree layout
Prior to version 1.0, LIGO formatted data types into alphabetically ordered left-balanced trees by default.
You can get the equivalent in version 1.0 and later with the decorator @layout("tree")
, as in this example:
The resulting Michelson code looks like this:
Note that the variant cases are ordered alphabetically.
Setting Michelson annotations
To specify the annotation for a LIGO declaration, use the @annot
decorator.
For example, this variant type has custom annotations on each case:
The resulting Michelson looks like this:
The decorator @annot("<name>")
can also be used on record field
annotations:
If the @layout
and @annot
decorators are not adequate for your use case, you can format Michelson types manually as described in the next section.
Manually formatting Michelson types
To interoperate with existing Michelson code or to be compatible with
certain development tooling, LIGO has two special interoperation
types: michelson_or
and michelson_pair
. These types provide the
flexibility to model the exact Michelson output, including field
annotations.
The LIGO michelson_or
type creates a Michelson or
type from two LIGO types and their annotations.
Similarly, the LIGO michelson_pair
type creates a Michelson pair
type.
In either case, you must provide annotations for both types, but if you provide an empty string, LIGO omits the annotation in the Michelson code.
Take for example the following Michelson type that we want to interoperate with:
To reproduce this type we can use the following LIGO code:
Alternatively, if annotations are not important you can also use plain tuples for pairs instead. Plain tuples do not have any annotations.
To use variables of type michelson_or
you have to use M_left
and
M_right
. M_left
picks the left or
case while M_right
picks
the right or
case. For michelson_pair
you need to use tuples.
Manual data structure conversion
If you want to get your hands dirty, it is also possible to do manual data structure conversion. The following code provides some examples:
Entrypoints and annotations
When a contract has multiple entrypoints, LIGO implicitly creates a parameter for it with a variant type.
For example, the following contract has entrypoints named left
and right
:
Internally, LIGO structures the contract with a parameter type:
This contract can be called by another contract, like this one:
The calling contract uses the entrypoint with the %left
annotation without mentioning the %right
entrypoint.
LIGO uses the annotation to determine which side of the pair to put the int
type into.
This currently only works for or
's and variant types in LIGO.
Amendment
With amendment 007 to Tezos this is changed though, and also pair
s
can be ordered differently.