Fetch a contract as a non-stakeholder

Hi!

I’m trying to write a choice that allows its controller to fetch a contract as a non-stakeholder. I assume it’s possible because of the following documentation, but I can’t get the code to work.

The documentation here says: “if the fetch appears in an update block of a choice ch on a contract c1, and the fetched contract ID resolves to a contract c2, then the actors are defined as the intersection of (1) the signatories of c1 union the controllers of ch with (2) the stakeholders of c2.”

The corner case I’m trying to achieve is that the resulting intersection only contains the signatory of c1. Here is the template and test script I came up with:

template Iou
  with
    bank: Party
    owner: Party
  where
    signatory bank
    observer owner

template IouSharing
  with
    owner: Party
    painter: Party
  where
    signatory owner
    observer painter
  
    nonconsuming choice RequestIou: Iou
      with
        iouID: ContractId Iou
      controller painter
        do fetch iouID
iou <- submit bank do
    createCmd Iou with
      bank = bank
      owner = alice

  iouSharing <- submit alice do
    createCmd IouSharing with owner = alice; painter

  submit painter do
    exerciseCmd iouSharing RequestIou with iouID = iou

(this is a tweaked version of this example. Instead of showIou to the painter, I’m letting the painter to proactively request the iou.)

I expect the last line of the script to work because the intersection for determining the fetch actors is nonempty (the intersection is “Alice” who is the signatory of iouSharing and stakeholder of iou). However, the code results in the following runtime error:

Attempt to fetch or exercise a contract not visible to the reading parties.
  Contract:  #0:0 (Main:Iou)
  actAs: 'Painter'
  readAs:
  Disclosed to: 'Alice', 'Bank'

Could anyone explain what I’m missing or is this a bug in DAML? Thanks a lot!

The problem in your example is that the painter has no visibility of the original IOU and so cannot fetch it as the error implies.

It would need to be the owner (alice) who fetches the IOU contract. In this case the IOU would then be divulged to the Painter as per the example in the docs.

Thank you @b_heather ! I’ve got a followup question.

Now my question is the documentation above says “the actors are defined as the intersection of (1) the signatories of c1 union the controllers of ch with …”. According to your answer, ‘Alice’ must be the controller of the RequestIou choice, then shouldn’t the documentation be corrected to “the actors are defined as the intersection of (1) the controllers of ch with …”?

Another way to put that question is: what’s the scenario where the fetch actor is signatory of c1 but NOT the controller of ch? Because according to the current documentation, there should exist such a scenario. I’m trying to implement that scenario with the template and script above. If that implementation doesn’t work, I feel the documentation is saying something that DAML doesn’t support.

In summary, I understand the rationale of reporting that runtime error, but that rationale seems to break what the documentation is promising.

Thanks for your help!

I believe the misunderstanding is in the fact that it is always the controller of the choice that is actually calling the fetch. Therefore the fetched contract must be visible to the controller prior to fetching.

Let’s change your example slightly to better understand the documentation:

template RequestIou
  with
    owner: Party
    painter: Party
  where
    signatory painter
    observer owner
  
    nonconsuming choice ShareIou: Iou
      with
        iouID: ContractId Iou
      controller owner
        do fetch iouID
iou <- submit bank do
    createCmd Iou with
      bank = bank
      owner = alice

  iouSharing <- submit painter do
    createCmd RequestIou with owner = alice; painter

  submit alice do
    exerciseCmd iouSharing ShareIou with iouID = iou

if the fetch appears in an update block of a choice ch on a contract (RequestIou), and the fetched contract ID resolves to a contract (Iou), then the actors are defined as the intersection of (1) the signatories of c1 (painter) union the controllers of ch (alice) with (2) the stakeholders of c2 (bank,alice).

the signatories of c1 (painter) union the controllers of ch (alice)

Hi @b_heather , if “it is always the controller of the choice that is actually calling the fetch”, then there is no point mentioning that union operation. so I think the documentation should be updated. I can create a pull request in the docs github repo. Let me know if you have a different opinion:)

Thank you!

Hi @b_heather , PR has been created here.

Hi @b_heather , I figured out the problem now. The union is useful when the controller is the divulgee of c2. In my original example, I need to divulge the Iou to the painter before the painter can exercise RequestIou successfully.

I’ll close the PR now. Thanks!