I have an interface defined as below:
data VAsset = VAsset with
issuer : Party
owner : Party
interface IAsset where
setOwner: Party -> IAsset
setObs: [Party] -> IAsset
setQuantity : Decimal -> IAsset
I am trying to use it in a template as given below:
template TransferProposal --this gives error
signatory (signatory asset)
choice AcceptProposal: ContractId IAsset
create (fromInterface @VAsset asset) with
owner = newOwner
- I get an error:
No instance for (Show IAsset)
arising from the second field of ‘TransferProposal’ (type ‘IAsset’)
use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
• When deriving the instance for (Show TransferProposal)typecheck
I tried making VAsset deriving (Eq, Show) but that doesn’t help.
- Is the create… statement written above the right way to create an asset without knowing which asset type it is? Only owner is changed.
An interface can only be used to abstract over the representation of whole contracts on the ledger, providing (one way!) access to each one’s view, and of course abstract choice signatures. It cannot be used to abstract over arbitrary data structures, which is what the
asset variable as used here must be.
This is because there is no way to make an interface serializable according to the specific definition linked here. The
(Eq, Show) test is usually just a quick sanity check as a shortcut to this, but even if you try to hack around the system, you won’t be allowed to do it:
error type checking template Main.TransferProposal :
expected serializable type:
* reason: template argument
* found: Main:TransferProposal
unserializable data type Main:TransferProposal [Daml-LF typechecker]
You cannot create a contract without knowing what template type it has. Once it has been created, you can interact with its choices, its view, and optionally convert to a template (note that
@VAsset cannot possibly be a
fromInterface argument because it is not a template), but it must be created concretely.
To abstract over
create template, that selection should be abstracted behind an interface choice; if you have a
ContractId of that interface, you can then invoke all sorts of choices whose actual concrete resulting templates depend on the implementer of the interface.
The error goes away if I change the asset type to ContractId IAsset
asset: ContractId IAsset