Contract Keys Question when signatory is not the same as the observer asking for contract

Hi,

I have a template with a contract Key. The contract is created by one user and a list of other users are observers.

I’d like to retrieve this contract using a contract key since each of the parties may have many other contracts disclosed to them which don’t really need to be retrieved and parsed.

However, since contract keys need to have a signatory in them, how will the observers below retrieve the contract? At the time of fetching this contract, they won’t know who created it.

e.g.

template Client
  with 
    uniqueKey: Text
    clientName: Text 
    clientCountry: Text 
    proposer: Party 
    observers : [Party]
  where 
    signatory proposer 
    observer observers

    key (proposer, uniqueKey) : (Party, Text)
    maintainer key._1
1 Like

If they don’t know who proposed it, how do they know the uniqueKey?

1 Like

Because they are on it, and the unique key is public and doesn’t change.

e.g. I want to fetch the client with key CLIENTX (which I got from another contract). How do I fetch this contract?

1 Like

You have some way to get your hands on uniqueKey. Can you use the same channel to also make proposer available?

I want to fetch the client with key CLIENTX (which I got from another contract)

Couldn’t you also get the proposer from there?

1 Like

ok. so I misunderstood keys. An observer passing the (proposer party id, unique key) can fetch the contract? In that case, yes I can have the metadata include the proposer party also. A little complex but can be done.

Thanks!

1 Like

Yes, observers can always fetchByKey. Using authority from the maintainers, they can also lookupByKey.

2 Likes

Let me see if I understand your requirements here. You have a predefined token, and a bunch of parties who are expecting a contract with that token as the key. In your ideal world, the key for the contract would be just that token, and everyone interested (among the authorized parties) could retrieve the contract using that token, with no regard for who created said contract.

But DAML gets in your way because it requires the key to contain a Party, and using the creator of the contract as the party here makes the contract impossible to find.

We can’t get around the fact that a key needs a maintainer — @bernhard can explain the reasons better than I, but it essentially boils down to the fact that we’re in a distributed system so we need to have someone we can ask for the contract with that key.

One option here would be to have a “central” authority, i.e. a party whose job is to publish the tokens and sign the contracts; perhaps something like:

module Main where

import Daml.Script

template Registry
  with
    clients: [Party]
    operator: Party
  where
    signatory operator
    observer clients
    nonconsuming choice CreateTopic : ()
      with
        proposer: Party
        token: Text
      controller proposer
     do
       assert $ proposer `elem` clients
       create Topic with token, proposer, observers = clients, operator
       return ()


template Topic
  with 
    token: Text
    proposer: Party 
    observers : [Party]
    operator: Party
  where 
    signatory operator
    observer observers

    key (operator, token) : (Party, Text)
    maintainer key._1

    nonconsuming choice Demo : ()
      with
        p: Party
      controller p
      do return ()

test = script do
  alice <- allocatePartyWithHint "Alice" (PartyIdHint "Alice")
  bob <- allocatePartyWithHint "Bob" (PartyIdHint "Bob")
  charlie <- allocatePartyWithHint "Charlie" (PartyIdHint "Charlie")

  reg <- submit alice do
    createCmd Registry with clients = [alice, bob, charlie], operator = alice
  submit bob do
    exerciseCmd reg $ CreateTopic with proposer = bob, token = "blabla"

  submit charlie do
    exerciseByKeyCmd @Topic (alice, "blabla") Demo with p = charlie

  return ()

So the maintainer is always the same and you don’t need to pass it around.

1 Like

Thanks for this alternate approach @Gary_Verhaegen

1 Like

Note that in a not-so-distant future you may be able to sidestep the Registry template and just create the Topic directly with a multi-party connection, assuming “operator” here is a public party of some kind. I’m not entirely sure about the tradeoffs involved; for example, I don’t know how you’d then get the list of observers, but thought I’d mention it nonetheless.

1 Like