Reference: Interfaces¶
Warning
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.
Interface declaration¶
An interface declaration is somewhat similar to a template declaration.
Interface name¶
interface MyInterface where
- This is the name of the interface.
- It’s preceded by the keyword
interface
and followed by the keywordwhere
. - It must begin with a capital letter, like any other type name.
Interface methods¶
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).
Interface precondition¶
ensure myGuard (method1 this)
- A precondition is introduced with the keyword
ensure
and must be a boolean expression. - It is possible to define interfaces without an
ensure
clause, but writing more than one is a compilation error. this
is 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.
method1
). - It is evaluated and checked right after the implementing template’s precondition upon contract creation
Interface choices¶
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
(e.g.
method1
) as well as the actions that run when the choice is exercised (e.g.method2
andmethod3
). - As for template choices, the
choice
keyword can be optionally prefixed with thenonconsuming
keyword to specify that the contract will not be consumed when the choice is exercised. If not specified, the choice will beconsuming
. Note that thepreconsuming
andpostconsuming
qualifiers 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.
Empty interfaces¶
interface YourInterface
- It is possible (though not necessarily useful) to define an interface without
methods, precondition or choices. In such a case, the
where
keyword can be dropped.
Required interfaces¶
interface OurInterface requires MyInterface, YourInterface where
An interface can depend on other interfaces. These are specified with the
requires
keyword after the interface name but before thewhere
keyword, 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
where
keyword after the last required interface can be dropped:interface TheirInterface requires MyInterface, YourInterface
Interface implementation¶
For context, a simple template definition:
template MyTemplate
with
field1 : Party
field2 : Int
where
signatory field1
Implements clause¶
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
implements
clause 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 keywordwhere
, 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.
method3
).
Empty implements clause¶
implements YourInterface
- If the interface being implemented has no methods, the
where
keyword can be dropped.
Interface functions¶
Function | Type | Instantiated type | Notes |
---|---|---|---|
interfaceTypeRep |
HasInterfaceTypeRep i => i -> TemplateTypeRep |
MyInterface -> TemplateTypeRep |
The value of the resulting TemplateTypeRep indicates what template
was used to construct the interface value. |
toInterface |
forall i t. HasToInterface t i => t -> i |
MyTemplate -> MyInterface |
Converts a template value into an interface value. Can also be used to convert an interface value to one of its required interfaces. |
fromInterface |
HasFromInterface t i => i -> Optional t |
MyInterface -> Optional MyTemplate |
Attempts to convert an interface value back into a template value.
The result is None if the expected template type doesn’t match the
underlying template type used to construct the contract. Can also be
used to convert a value of an interface type to one of its
requiring interfaces. |
toInterfaceContractId |
forall i t. HasToInterface t i => ContractId t -> ContractId i |
ContractId MyTemplate -> ContractId MyInterface |
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. |
fromInterfaceContractId |
forall t i. (HasFromInterface t i, HasFetch i) => ContractId i -> Update (Optional (ContractId t)) |
ContractId MyInterface -> Update (Optional (ContractId MyTemplate)) |
Attempts to convert an interface contract id into a template contract id. In order to verify that the underlying contract has the expected template type, this needs to perform a fetch. Can also be used to convert a contract id of an interface type to a contract id of one of its requiring interfaces. |