# Contracts that reference unobserved contracts

**URL:** <https://forum.canton.network/t/contracts-that-reference-unobserved-contracts/758>\
**Category:** App Development\
**Tags:** daml\
**Created:** [June 30, 2020, 2:11pm UTC](https://forum.canton.network/t/contracts-that-reference-unobserved-contracts/758 "2020-06-30T14:11:11Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![alex\_m](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/alex_m/32/550_2.png) [@alex\_m](https://forum.canton.network/u/alex_m)\
**Post date:** [June 30, 2020, 2:11pm UTC](https://forum.canton.network/t/contracts-that-reference-unobserved-contracts/758/1 "2020-06-30T14:11:11Z")

</div>

**Mod note: As of SDK 1.5.0 Scenarios have been superseded by the more powerful [Daml Script](https://docs.daml.com/daml-script/index.html). We now recommend using that for all purposes. [For more information, and to learn how to use Script please check out @Andreas’ post on our blog](https://daml.com/blog/engineering/daml-script-scenarios-2-0/).**

There may be a few of these questions coming from me over the next few weeks as I figure out the architecture of my app and whether or not DAML is right for my project.

Let’s say you have a contract:

```
template Product
  with
    producer : Party
    productType : ProductType
    label : Text
  where
    signatory producer

```

and another:

```
template ProductType
  with
    admin : Party
    description : Text
  where
    signatory admin

```

`ProductType` contracts are created by site admins and are basically categories for different types of products. `Product` contracts are created by producers. Is it possible for a producer to create a `Product` given that they are not observers on `ProductType` contract? I tried this test code:

```
productScenario = scenario do
  admin <- getParty "Admin"
  producer <- getParty "Producer"

  productTypeCid <- submit admin do
    create ProductType with
      description = "product"
      admin

  productCid <- submit producer do
    productType <- fetch productTypeCid
    create Product with
      producer
      productType
      label = "label

  return productCid

```

…it fails because the producer cannot fetch a `ProductType` contract as he/she is not an observer on it. Maybe there is a hacky way to do this in the UI code, by:

- making `ProductType` observable to a `public` party (as discussed here [Should everything be on the ledger? - #2 by anthony](https://discuss.daml.com/t/should-everything-be-on-the-ledger/751/2))
- fetching `ProductType` with the public token
- creating the `Product` with the producer token

Or maybe I should just have a `ContractId ProductType` on the `Product`?

Would either work? Do you foresee any problems?

Thanks!

---

<div class="post-metadata">

**Author:** ![Luciano](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/luciano/32/319_2.png) [@Luciano](https://forum.canton.network/u/Luciano)\
**Post date:** [June 30, 2020, 3:09pm UTC](https://forum.canton.network/t/contracts-that-reference-unobserved-contracts/758/2 "2020-06-30T15:09:05Z")

</div>

Hi Alex, no worries, this is the place to ask questions! Beware you may get different answers here.

I would not go down the route of making the `ProductType` public. I think there is a simpler solution here. You could add a choice `CreateProduct: Product` on `ProductType`, and specifically use the [choice first syntax](https://docs.daml.com/daml/reference/choices.html#id12) to pass the producer as an argument to the choice - this way you don’t need to maintain an explicit list of observers.

However, you should ask yourself: _is every producer allowed to create every type of product_? If that is not the case, it would be better to maintain a list of parties on the `ProductType` template that are allowed to create that type of product. In this case, use the [controller first choice syntax](https://docs.daml.com/daml/reference/choices.html#id13) for your `CreateProduct` choice.

Btw the pattern that we’re using here is the ‘master agreement’ pattern. It has an analogue in real life. For instance, in finance/brokerage, a broker will have a ‘master agreement’ with a client. It will say in broad terms that they can agree to enter into an agreement to buy/sell securities with discretion; meaning, they don’t need to physically sign a contract every single time a new transaction takes place, but rather use the master contract to delegate this right. The same happens when you add observers to your `ProductType` contract - that is the act of the ‘admins’ (as you call them) delegating the producers the right to create new `Products` in future, without having to agree every single time.

Let me know if that answers your question.

---

<div class="post-metadata">

**Author:** ![alex\_m](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/alex_m/32/550_2.png) [@alex\_m](https://forum.canton.network/u/alex_m)\
**Post date:** [June 30, 2020, 4:48pm UTC](https://forum.canton.network/t/contracts-that-reference-unobserved-contracts/758/3 "2020-06-30T16:48:41Z")

</div>

Thank you @Luciano.

Ah, that looks nifty! Glad I asked on the forum!

So could do something like:

```
template ProductType
  with
    admin : Party
    description : Text
  where
    signatory admin
    choice CreateProduct : ContractId Product
      with
        producer : Party
        label : Text
      controller producer
        do
          create Product with
            producer
            productType = this -- ????
            label

```

(I haven’t tried this in the IDE, but something like that)  
Is `productType = this` correct?

EDIT: This design pattern still fails in a test scenario for the same reason. Even with the choice as ‘choice first’, the producer is not an observer of `ProductType` and hence cannot make the `CreateProduct` choice!

---

<div class="post-metadata">

**Author:** ![alex\_m](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/alex_m/32/550_2.png) [@alex\_m](https://forum.canton.network/u/alex_m)\
**Post date:** [June 30, 2020, 5:28pm UTC](https://forum.canton.network/t/contracts-that-reference-unobserved-contracts/758/4 "2020-06-30T17:28:30Z")

</div>

That page on choice first says:  
" If you do this, you **must** make sure that you add that party as an `observer` , otherwise they won’t be able to see the contract (and therefore won’t be able to exercise the choice)."

So I would have to make `producer` observer on the `ProductType` contract? That seems like it doesn’t solve the problem because there could be many producers that want to make a product of `ProductType`.

---

<div class="post-metadata">

**Author:** ![alex\_m](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/alex_m/32/550_2.png) [@alex\_m](https://forum.canton.network/u/alex_m)\
**Post date:** [June 30, 2020, 8:43pm UTC](https://forum.canton.network/t/contracts-that-reference-unobserved-contracts/758/5 "2020-06-30T20:43:02Z")

</div>

Here is a complete scenario that fails with ‘choice first’. Any advice?

```
template Product
  with
    producer : Party
    productType : ProductType
    label : Text
  where
    signatory producer

template ProductType
  with
    admin : Party
    description : Text
  where
    signatory admin
    choice CreateProduct : ContractId Product
      with
        producer : Party
        label : Text
      controller producer
        do
          create Product with
            producer
            productType = this -- ????
            label

test = scenario do
  admin <- getParty "platform admin"
  producer <- getParty "starbucks"

  productTypeCid <- submit admin do
    create ProductType with
      admin
      description = "coffee"

  productCid <- submit producer do
    exercise productTypeCid CreateProduct with
      producer
      label = "starbucks coffee"

  return productCid
```

---

<div class="post-metadata">

**Author:** ![Luciano](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/luciano/32/319_2.png) [@Luciano](https://forum.canton.network/u/Luciano)\
**Post date:** [July 1, 2020, 9:51am UTC](https://forum.canton.network/t/contracts-that-reference-unobserved-contracts/758/6 "2020-07-01T09:51:20Z")

</div>

That’s very close. I realize now I made an error of judgement above - you won’t be able to simply to create new products without first ‘registering’ the producer.

I added a choice `AddProducer` to do this.

I also added a `productId`, which is used to distinguish different product types. This also serves to decouple the `ProductType` form `Product`. I would eventually set this as a [key](https://docs.daml.com/daml/reference/contract-keys.html) to allow producers to look up products easily.

Finally, for clarity, I renamed `producerType` to `producerMasterAgreement`.

```haskell
daml 1.2

module Main where

import DA.Next.Set

type ProductId = Text
-- | ^ Should use a newtype instead (if dynamic) or a data (sum) type 
-- | if there are an exhaustive/known number of products.

template Product
  with
    producer : Party
    productId : ProductId
    label : Text
  where
    signatory producer

template ProductMasterAgreement -- formerly ProductType
  with
    admin : Party
    id: ProductId 
    description : Text
    producers : Set Party
  where
    signatory admin

    observer producers

    choice AddProducer: ContractId ProductMasterAgreement
      with producer: Party
      controller admin
      do create this with producers = insert producer producers

    nonconsuming choice CreateProduct : ContractId Product
      with
        producer : Party
        label : Text
      controller producer
        do
          create Product with
            producer
            productId = id
            label

test = scenario do
  admin <- getParty "platform admin"
  producer <- getParty "starbucks"

  productMasterAgreementCid <- submit admin do
    create ProductMasterAgreement with
      admin
      id = "00001"
      description = "coffee"
      producers = empty
  productMasterAgreementCid <- submit admin do
    exercise productMasterAgreementCid (AddProducer producer)

  productCid <- submit producer do
    exercise productMasterAgreementCid CreateProduct with
      producer
      label = "starbucks coffee"

  return productCid

```

---

<div class="post-metadata">

**Author:** ![alex\_m](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/alex_m/32/550_2.png) [@alex\_m](https://forum.canton.network/u/alex_m)\
**Post date:** [July 1, 2020, 11:30am UTC](https://forum.canton.network/t/contracts-that-reference-unobserved-contracts/758/7 "2020-07-01T11:30:48Z")

</div>

Thank you for your help @Luciano. Unfortunately the need to register producers each time may mean the app isn’t scalable. The app is being made as if it would ultimately used for a fairly large-scale trading platform. I’ll have to think about this for a while!

EDIT: Maybe this would be a good point to ask (and maybe the answer is unclear, or platform dependant): At what point would an app with many ‘producers’ incur considerable overhead for the ledger (in terms of size, transaction time e.g.)? (If you had to regenerate the contract for every producer that wanted to make a product of a given type)

---

<div class="post-metadata">

**Author:** ![Luciano](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/luciano/32/319_2.png) [@Luciano](https://forum.canton.network/u/Luciano)\
**Post date:** [July 1, 2020, 12:44pm UTC](https://forum.canton.network/t/contracts-that-reference-unobserved-contracts/758/8 "2020-07-01T12:44:58Z")

</div>

I’m not sure I completely understand your concern here. There may be some confusion:

> the need to register producers each time may mean the app isn’t scalable.

> If you had to regenerate the contract for every producer that wanted to make a product of a given type

Just so that we’re on the same page here: you don’t need to register a producer every time you create a new product - this only needs to be done once per producer, per product type. If you key your template by `productId`, it means you can have multiple `ProductType` contracts with different `productId`s.

Also note the `nonconsuming` keyword I use in my code example - this prevents the contract from being archived when you are creating new products.

The only potential problem I can think of here is if you really have a constantly changing number of producers - this could induce some contention on your `ProductType` contract. The way around this would be to refactor to have a single `ProductType` per producer, per product.

Also, keep in mind, as per your point:

> maybe the answer is … platform dependant

DLTs tend to have a much higher throughput than public blockchains - we’re talking about thousands of transactions per second, rather than a single block every couple of seconds.

MIght I make a suggestion? Have a look at [https://github.com/RobinKrom/dbay](https://github.com/RobinKrom/dbay). This is an ebay-like application by @drsk , running on DAML. That could give you some ideas about how to go about implementing an e-commerce platform.

---

<div class="post-metadata">

**Author:** ![alex\_m](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/alex_m/32/550_2.png) [@alex\_m](https://forum.canton.network/u/alex_m)\
**Post date:** [July 1, 2020, 12:47pm UTC](https://forum.canton.network/t/contracts-that-reference-unobserved-contracts/758/9 "2020-07-01T12:47:34Z")

</div>

Cheers @Luciano. Thank you for the clarification. I’ll check out the app. I was worried that a ledger that held a new contract for every new person added, as well as all the archived ones, would mean that memory would inflate. That being said, I am still super green when it comes to blockchain! This is my first foray into the topic!

I have to say I am incredibly impressed with the help I have received on the forum. Please pass my regards!
