Operations
The final stack after a contract execution is a pair containing a new storage and a list of operations. An operation is either a transfer, an account creation (a.k.a. origination), a delegation or the emission of an event.
There are no literal values of type operation. Instead, such values
are created using the following functions from the standard library:
Mavryk.create_contract
(origination), Mavryk.transaction
(transfer),
Mavryk.set_delegate
(delegation), and Mavryk.emit
(emission of
event).
Origination
The call Mavryk.create_contract(e,d,a,s)
returns a contract creation
operation (origination) for the entrypoint e
(as a function) with
optional delegate d
, initial amount a
and initial storage s
,
together with the address of the created contract. Note that the
created contract cannot be called immediately afterwards (that is,
Mavryk.get_contract_opt
on that address would return None()
), as the
origination must be performed successfully first, for example by
calling a proxy contract or itself.
Transaction
The call Mavryk.transaction(param, amount, contract_addr)
evaluates
in an operation that will send the amount amount
in mumav to the
contract at the valid address contract_addr
, with parameter
param
. If the contract is an implicit account, the parameter must be
unit
.
The following example shows a transaction sent from one contract to
another. The former is derived from a namespace B
with an entrypoint
increment
; the latter is derived from a namespace A
with an
entrypoint add
. The entrypoint increment
calls add
with 1
. We
assume that the contract associated with namespace A
is deployed
under the address "KT1TxqZ8QtKvLu3V3JH7Gx58n7Co8pgtpQU5"
.
Contract (derived from) B
needs to provide the parameter of the
called contract. The convention is to transform the entrypoint being
called to a variant. Here, add
in A
becomes Add
. The variant
Add
carries the value of the parameter of the entrypoint, here 1
because we show how to increment the storage (storage + delta
in
A
). The type of the parameter of the contract A
is obtained by A
parameter_of
, and it is the type of Add(1)
.
It is possible for a contract to have multiple entrypoints, which is
implicitly translated in LIGO to a parameter
with a variant type as
shown below. The following contract:
is translated internally to a contract similar to this one:
This contract can be called by another contract, like this one:
Notice how we directly use the %sub
entrypoint without mentioning
the %add
entrypoint. This is done with the help of
annotations. Those annotations correspond to the name of the function
defining the entrypoints, prefixed by a %
, so sub
becomes
%sub
. Also, as shown above, each entrypoint corresponds to an
implicit variant type whose name is the entrypoint function whose
first character is capitalised, so sub
becomes Sub
, as far as
parameters are concerned.
Delegation
The call Mavryk.set_delegate(d)
evaluates in an operation that sets
the delegate of the current smart contract to be d
, where d
is an
optional key hash. If None()
, the delegation is withdrawn. If the
contract has no delegation, then no change occurs. If d
is
Some(kh)
, where kh
is the key hash of a registered delegate that
is not the current delegate of the contract, then this operation sets
the delegate of the contract to this registered delegate. A failure
occurs if kh
is the current delegate of the contract or if kh
is
not a registered delegate. However, the instruction in itself does not
fail; it produces an operation that will fail when applied.
Event emission
The call Mavryk.emit(event_tag, event_type)
evaluates in an operation
that will write an event into the transaction receipt after the
successful execution of this contract. The event is annotated by the
string event_tag
if it is not empty. The argument event_type
is
used only to specify the type of data attachment.