Interfaces - How to get the signatures of an underlying template from an Interface?

Hi,

Given an scenario where we have a choice Service which has a Holding.I as input. Is there a way to get the signatures (signing parties) of the underlying holding Template (whichever is - Fungible.T, Transferable.T, etc) without coercing to an implementation (we don’t want to create a implementation dependency in the Service - only Interfaces).

This question comes up from a concern about if we should trust the underlying implementation of an Interface.

Thanks!
Jose

Hi @jvelasco.intellecteu,

You can achieve what you describe by using the interfaceTypeRep function. It takes an interface as an input and returns a “signature” of the template used to construct the interface value.

You can then make checks such as

assertMsg "error, not a fungible" $ interfaceTypeRep i == (templateTypeRep @Fungible.T)

Unfortunately templateTypeRep does not implement a show instance, hence it cannot be stored inside a contract and you will need to reference the corresponding implementation.

Also, note that using a check such as the one above makes it harder to perform upgrades: a new version of a fungible holding would not verify the equality above, hence you would need to upgrade the contract performing the sanity check. This is why in Daml Finance we keep the usage of typereps to a minimum.

I hope this helps!
Matteo

1 Like

Ok, so there’s no way to get the parties signing the underlying template without depending on the implementation.

Do you think that would be a feasible new feature?

Thanks
Jose

You should already be able to use the signatory function to get the signatories of the underlying template.

Now that I re-read your original question, I believe this is the answer you were looking for :slight_smile: ( I misread signatures to mean something else)

2 Likes

I’ve tried this, however the compiler complains that:

No instance for (HasSignatory TemplateTypeRep)
arising from a use of ‘signatory’

nonconsuming choice MyChoice : ()
  with
    holdingCid : ContractId Holding.I
    provider : Party
  controller customer
  do
    holding <- fetch holdingCid
    let holdingSigningParties = signatory (interfaceTypeRep holding)  -- Boom!
    assertMsg "invalid holding" $ Set.member provider (Set.fromList holdingSigningParties)

Am I missing something?

Thanks!
Jose

should be what you are looking for

1 Like

Omg! :grinning:
Life is easier than it looks like …

Thanks @Matteo_Limberto !

1 Like

To add a general point: the trust issue on implementations of interfaces is usually delegated to “package vetting”. Each participant needs to approve every package, and it is assumed that the code is vetted before doing so. We usually cannot make sufficient assertions in code to allow arbitrary implementation packages to be used. Even if we check the signatories we cannot be sure they have vetted the implementation they use, so it could contain malicious/erroneous code. But the fact that each participant has control over which packages it accepts controls that risk at a different level.

3 Likes