# Choices, delegation, and divugence: how to delegate visibility on contracts?

**URL:** <https://forum.canton.network/t/choices-delegation-and-divugence-how-to-delegate-visibility-on-contracts/5689>\
**Category:** App Development\
**Tags:** divulgence, choice-observers, choices\
**Created:** [November 23, 2022, 2:50am UTC](https://forum.canton.network/t/choices-delegation-and-divugence-how-to-delegate-visibility-on-contracts/5689 "2022-11-23T02:50:58Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![ryan](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/ryan/32/4753_2.png) [@ryan](https://forum.canton.network/u/ryan)\
**Post date:** [November 23, 2022, 2:50am UTC](https://forum.canton.network/t/choices-delegation-and-divugence-how-to-delegate-visibility-on-contracts/5689/1 "2022-11-23T02:50:58Z")

</div>

I’m running into an issue in a situation similar to the one described [here](https://discuss.daml.com/t/deprecation-of-using-divulged-contracts/2974/2) by @cocreature .

Specifically, I know that choices can be used to delegate authority when creating new contracts, but it looks like they can’t delegate ability to fetch (or exercise a choice on) contracts that are otherwise invisible to the submitter?

More concretely, to add to the example linked above

```haskell
template PasswordManager
  with
    root : Party
    password: Text
  where
    signatory root
    key root: Party
    maintainer key
  
template Checker
  with
    root : Party
    obs : Party
  where
    signatory root
    observer obs
    nonconsuming choice CheckPassword : bool
      with
        guess: Text
      controller obs
      do 
         password <- fetchByKey @PasswordManager root
         return guess == password

```

Basically, I don’t want the `PasswordManager` contract visible to `obs` since that would reveal the actual text of the password. But I do want `obs` to be able to run `CheckPassword`.

This is obviously a contrived example, but it illustrates what I’m trying to accomplish by keeping contract data private but delegating computation on it in predefined ways. It fails though with `CONTRACT_KEY_NOT_FOUND`

Any ideas about how to go about delegating reading contracts in this way?

---

<div class="post-metadata">

**Author:** ![bernhard](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/bernhard/32/356_2.png) [@bernhard](https://forum.canton.network/u/bernhard)\
**Post date:** [November 23, 2022, 10:57am UTC](https://forum.canton.network/t/choices-delegation-and-divugence-how-to-delegate-visibility-on-contracts/5689/2 "2022-11-23T10:57:07Z")

</div>

Hi @ryan , [Daml’s execution model](https://docs.daml.com/daml/intro/7_Composing.html#daml-s-execution-model) is such that the submitting party of a transaction sees all contracts that have an action on them .

That means specifically that `obs` cannot submit a transaction that does a password check via equality in a transaction that they submit. That gives you two options:

1. Do the check in two transactions, where it’s root that does the comparison `guess == password`
2. Check against a hash of the password. Ie on `PasswordManager` store `passwordSha256` and make the comparison `sha256 guess = passwordManager.passwordSha256`

Note though that in either case, anyone that witnesses one of the events where the password is handled in plain-text, will see the password and can extract it.

---

<div class="post-metadata">

**Author:** ![ryan](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/ryan/32/4753_2.png) [@ryan](https://forum.canton.network/u/ryan)\
**Post date:** [November 23, 2022, 6:47pm UTC](https://forum.canton.network/t/choices-delegation-and-divugence-how-to-delegate-visibility-on-contracts/5689/3 "2022-11-23T18:47:54Z")

</div>

I see – thanks for explaining.

Just to check I understand [“principle 1” and “principle 2” there](https://docs.daml.com/daml/intro/7_Composing.html?_gl=1*ipikxr*_ga*MTk5NTc4NDM4MS4xNjYwOTUyOTM4*_ga_GVK9ZHZSMR*MTY2OTIyNDI3Ny44Mi4xLjE2NjkyMjQyODQuMC4wLjA.&_ga=2.255048461.409360370.1669077299-1995784381.1660952938#privacy). In another example:

```haskell
template Account
  with
    root : Party
    client : Party
  where
    signatory root
    observer client
  
template AccountArchiver
  with
    root : Party
  where
    signatory root
    nonconsuming choice ArchiveMany: ()
      with
        accounts: [ContractId Account]

      controller obs
      do
        forA accounts archive
        return ()

```

So what I’m wondering here is what exactly is meant by **consequences** in “Every party that sees an action sees its (transitive) consequences”. Here the actions in questions are the `archive`s on each of the `Account`s in `ArchiveMany`.

Say we call `ArchiveMany` in a transaction with contracts `[cidA, cidB]` as arguments. Will the `client` for the `Account` referenced by `cidA` be able to see the archive action/the `Account` for `cidB` (i.e., since both `archive`s happen in the same transaction will each `Account` now be divulged to all of the different `client`s)?

---

<div class="post-metadata">

**Author:** ![bernhard](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/bernhard/32/356_2.png) [@bernhard](https://forum.canton.network/u/bernhard)\
**Post date:** [November 23, 2022, 7:20pm UTC](https://forum.canton.network/t/choices-delegation-and-divugence-how-to-delegate-visibility-on-contracts/5689/4 "2022-11-23T19:20:03Z")

</div>

You get a transaction tree

```haskell
#1 Exercise ArchiveMany [cidA, cidB]
  | - #2 Exercise Archive cidA
  | - #3 Exercise Archive cidB

```

The stakeholders of #1 are `root` as the signatory of Account and controller of `ArchiveMany`. They see both of the archived contracts.

The `client` on `cidA` is only a stakeholder of #2 as that’s a consuming choice. They will see that and only that.

The term _consequence_ is formally defined [here](https://docs.daml.com/concepts/ledger-model/ledger-structure.html#actions-and-transactions).

A more practical way to learn these things interactively is via the IDE script integration. Once you make your code compile, you can get detailed disclosure information:

```haskell
module Disclosure where

import Daml.Script

template Account
  with
    root : Party
    obs : Party
    client : Party
  where
    signatory root
    observer client, obs
  
template AccountArchiver
  with
    root : Party
    obs : Party
  where
    signatory root
    observer obs

    nonconsuming choice ArchiveMany: ()
      with
        accounts: [ContractId Account]
      controller obs
      do
        forA accounts archive
        return ()

test_disclosure : Script ()
test_disclosure = script do
  [root, obs, alice, bob] <- mapA allocateParty ["root", "obs", "alice", "bob"]
  cidA <- submit root do createCmd Account with client = alice; ..
  cidB <- submit root do createCmd Account with client = bob; ..
  archiver <- submit root do createCmd AccountArchiver with ..
  submit obs do exerciseCmd archiver ArchiveMany with accounts = [cidA, cidB]
  return ()

```

 ![image](https://canada1.discourse-cdn.com/flex028/uploads/daml/original/2X/a/a5ee29d332b3c83bb792e389cedc9012de7cb08a.png)

You can see here that alice and bob do not see each others’ accounts.

---

<div class="post-metadata">

**Author:** ![bernhard](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/bernhard/32/356_2.png) [@bernhard](https://forum.canton.network/u/bernhard)\
**Post date:** [November 23, 2022, 7:37pm UTC](https://forum.canton.network/t/choices-delegation-and-divugence-how-to-delegate-visibility-on-contracts/5689/5 "2022-11-23T19:37:01Z")

</div>

“O” and “S” stand for “Observer” and “Signatory” in that table. You have to tick “Show detailed” to see that.

To see a more complex interaction, I’ve split out the roles here somewhat:

```haskell
module Disclosure where

import Daml.Script

template Account
  with
    creator : Party
    archiver : Party
    client : Party
  where
    signatory creator
    observer client, archiver

    choice DelegatedArchive : ()
      controller archiver
      do return ()
  
template AccountCreator
  with
    creatorRoot : Party
    creatorController : Party
  where
    signatory creatorRoot
    observer creatorController

    nonconsuming choice CreateMany: [ContractId Account]
      with
        parties: [Party]
        archiver: Party
      controller creatorController
      do
        forA parties (\client -> create Account with creator = creatorRoot; ..)

template AccountArchiver
  with
    archiverRoot : Party
    archiverController : Party
  where
    signatory archiverRoot
    observer archiverController

    nonconsuming choice ArchiveMany: ()
      with
        accounts: [ContractId Account]
      controller archiverController
      do
        forA accounts (\cid -> exercise cid DelegatedArchive)
        return ()

test_disclosure : Script ()
test_disclosure = script do
  [creatorRoot, creatorController, archiverRoot, archiverController, alice, bob] <- 
    mapA allocateParty ["creatorRoot", "creatorController", "archiverRoot", "archiverController", "alice", "bob"]
  creator <- submit creatorRoot do createCmd AccountCreator with ..
  archiver <- submit archiverRoot do createCmd AccountArchiver with ..
  accounts <- submit creatorController do 
    exerciseCmd creator CreateMany with 
        parties = [alice, bob]
        archiver = archiverController
  submit archiverController do exerciseCmd archiver ArchiveMany with accounts
  return ()

```

What you now see is this:

 ![image](https://canada1.discourse-cdn.com/flex028/uploads/daml/original/2X/a/a4ad0f5c40fad0b4a9a2576f07c0f46597cfcb54.png)

`creatorController` has witnessed (W) the creation of the contract. They are an informee of the exercise of `CreateMany` since they are the controller. The creates are a consequence of `CreateMany`. `archiverRoot` has had the accounts divulged (D) to them since they are a signatory on the `AccountArchiver` and the exercises of `DelegatedArchive` are a consequence of that.

You can see a lot of that info in the transaction view in the IDE as well:

```haskell
 TX 3 1970-01-01T00:00:00Z (Disclosure:60:3)
  #3:0
  │ disclosed to (since): 'archiverController' (3), 'archiverRoot' (3)
  └─> 'archiverController' exercises ArchiveMany on #1:0 (Disclosure:AccountArchiver)
                           with
                             accounts = [#2:1, #2:2]
      children:
      #3:1
      │ disclosed to (since): 'archiverController' (3), 'archiverRoot' (3), 'alice' (3),
                                'creatorRoot' (3)
      └─> 'archiverController' exercises DelegatedArchive on #2:1 (Disclosure:Account)
      
      #3:2
      │ disclosed to (since): 'archiverController' (3), 'archiverRoot' (3), 'bob' (3),
                                'creatorRoot' (3)
      └─> 'archiverController' exercises DelegatedArchive on #2:2 (Disclosure:Account)

```

You can see on #3:1 that that event is disclosed to `archiverRoot`. The reason is that it’s a consequence of #3:1, which is disclosed to `archiverRoot`.
