This feature is under active development and not officially supported in production environments.
In Daml, an interface defines an abstract type which specifies the behavior that a template must implement. This allows decoupling such behavior from its implementation, so other developers can write applications in terms of the interface instead of the concrete template.
An interface declaration is somewhat similar to a template declaration.
interface MyInterface where
- This is the name of the interface.
- It’s preceded by the keyword
interfaceand followed by the keyword
- It must begin with a capital letter, like any other type name.
method1 : Party method2 : Int method3 : Bool -> Int -> Int -> Int
An interface may define any number of methods.
Methods are in scope as functions at the top level, in the ensure clause, and in interface choices. These functions always take an unstated first argument corresponding to a contract that implements the interface:
func1 : Implements t MyInterface => t -> Party func1 = method1 func2 : Implements t MyInterface => t -> Int func2 = method2 func3 : Implements t MyInterface => t -> Bool -> Int -> Int -> Int func3 = method3
Methods are also in scope in interface choices (see Interface Choices below).
ensure myGuard (method1 this)
- A precondition is introduced with the keyword
ensureand must be a boolean expression.
- It is possible to define interfaces without an
ensureclause, but writing more than one is a compilation error.
thisis in scope in the method with the type of the interface.
self, however, is not.
- The interface methods can be used as part of the expression (e.g.
- It is evaluated and checked right after the implementing template’s precondition upon contract creation
choice MyChoice : (ContractId MyInterface, Int) with argument1 : Bool argument2 : Int controller method1 this do let n0 = method2 this let n1 = method3 this argument1 argument2 n0 pure (self, n1) nonconsuming choice MyNonConsumingChoice : Int controller method1 this do pure $ method2 this
- Interface choices work in a very similar way to template choices. Any contract of an implementing interface will grant the choice to the controlling party.
- Interface methods can be used to define the controller of a choice
method1) as well as the actions that run when the choice is exercised (e.g.
- As for template choices, the
choicekeyword can be optionally prefixed with the
nonconsumingkeyword to specify that the contract will not be consumed when the choice is exercised. If not specified, the choice will be
consuming. Note that the
postconsumingqualifiers are not supported on interface choices.
- See Reference: Choices for full reference information, but note that controller-first syntax is not supported for interface choices.
- It is possible (though not necessarily useful) to define an interface without
methods, precondition or choices. In such a case, the
wherekeyword can be dropped.
interface OurInterface requires MyInterface, YourInterface where
An interface can depend on other interfaces. These are specified with the
requireskeyword after the interface name but before the
wherekeyword, separated by commas.
For a template’s implementation of an interface to be valid, all its required interfaces must also be implemented by the template.
If the interface doesn’t have any methods, precondition or choices, the
wherekeyword after the last required interface can be dropped:
interface TheirInterface requires MyInterface, YourInterface
For context, a simple template definition:
template MyTemplate with field1 : Party field2 : Int where signatory field1
implements MyInterface where method1 = field1 method2 = field2 method3 False _ _ = 0 method3 True x y | x > 0 = x + y | otherwise = y
- To make a template implement an interface, an
implementsclause is added to the body of the template.
- The clause must start with the keyword
implements, followed by the name of the interface, followed by the keyword
where, which introduces a block where all the methods of the interface must be implemented.
- Methods can be defined using the same syntax as for top level functions,
including pattern matches and guards (e.g.
Empty Implements Clause¶
- If the interface being implemented has no methods, the
wherekeyword can be dropped.
||The value of the resulting
||Converts a template value into an interface value. Can also be used to convert an interface value to one of its required interfaces.|
||Attempts to convert an interface value back into a template value.
The result is
||Convert a template contract id into an interface contract id. Can also be used to convert an interface contract id into a contract id of one of its required interfaces.|
||Converts an interface contract id into a template contract id.
Can also be used to convert an interface contract id into a contract id
of a one of its requiring interfaces.
This function does not verify that the given contract id actually points
to a contract of the resulting type; if that is not the case, a
||Attempts to fetch and convert an interface contract id into a template,
returning both the converted contract and its contract id if the
conversion is successful, or