Skip to main content
Version: Next

Mavryk Domain-Specific Operations

LIGO is a programming language for writing Mavryk smart contracts. It would be a little odd if it did not have any Mavryk specific functions. This page will tell you about them.

Pack and Unpack

As Michelson provides the PACK and UNPACK instructions for data serialisation, so does LIGO with Bytes.pack and Bytes.unpack. The former serialises Michelson data structures into a binary format, and the latter reverses that transformation. Unpacking may fail, so the return type of Byte.unpack is an option that needs to be annotated.

⚠️ PACK and UNPACK are Michelson instructions that are intended to be used by people that really know what they are doing. There are several risks and failure cases, such as unpacking a lambda from an untrusted source or casting the result to the wrong type. Do not use the corresponding LIGO functions without doing your homework first.

const id_string = (p) => {
let packed = Bytes.pack(p);
return Bytes.unpack(packed);
};

Hashing Keys

It is often desirable to hash a public key. In Michelson, certain data structures such as maps will not allow the use of the key type. Even if this were not the case, hashes are much smaller than keys, and storage on blockchains comes at a cost premium. You can hash keys with a predefined functions returning a value of type key_hash.

const check_hash_key = (kh1: key_hash, k2: key) => {
let kh2 = Crypto.hash_key(k2);
return [kh1 == kh2, kh2];
};

Checking Signatures

Sometimes a contract will want to check that a message has been signed by a particular key. For example, a point-of-sale system might want a customer to sign a transaction so it can be processed asynchronously. You can do this in LIGO using the key and signature types.

⚠️ There is no way to generate a signed message in LIGO. This is because that would require storing a private key on chain, at which point it is not... private anymore.

const check_signature =
(pk: key, signed: signature, msg: bytes) =>
Crypto.check(pk, signed, msg);

Contract's Own Address

Often you want to get the address of the contract being executed. You can do it with Mavryk.get_self_address.

⚠️ Due to limitations in Michelson, Mavryk.get_self_address in a contract is only allowed at the top-level. Using it in an embedded function will cause an error.

const current_addr = Mavryk.get_self_address();

Origination of a contract

Mavryk.create_contract allows you to originate a contract given its code, delegate (if any), initial balance and initial storage. The return value is a pair of type (operation * address).

⚠️ Due to limitations in Michelson, Mavryk.create_contract first argument must be inlined and must not contain references to free variables

const origination = Mavryk.create_contract(
(p: nat, s: string) => [[], s],
None(),
3mav,
"initial_storage"
);