Feedback: Let's write a Daml template from scratch Video

Hi All.

In the code for Daml 101/Video 9 , saw 4 issues:

  1. The Test Scripts will not run at all
  2. There is a consistent error in the Test Script code that endures
  3. The actual app will build, but does not produce a valid Contract
  4. On daml start, it takes some time to build, and there is a warning about the entropy pool seems empty.

System specs:

  • Ubuntu 18.04 LTS
  • Daml ver 1.16.0
  • VS Code ver 1.60.2
App/daml/Main.daml
module Main where

import Daml.Script

type ItemCustodyId = ContractId ItemCustody

-- tracks chain of custody of my property
template ItemCustody
  with
    owner : Party
    custodian : Party
    {-- neighbor : Party --}
    itemName : Text
    {-- meterCount : Int -- shutter clicks --}
  where
    signatory owner
    signatory neighbor

    controller owner can
      ReleaseItemTo : ItemCustodyId
        with
          friend : Party
          {-- currentMeterCount : Int --}
        do
          create this with  
            custodian = friend
            {-- meterCount = currentMeterCount --}

    controller custodian can
      ReturnItemTo : ItemCustodyId
        with
          rightfulOwner : Party
          {-- currentMeterCount : Int --}
        do
          create this with
            owner = rightfulOwner
            {-- meterCount = currentMeterCount --}

-- Test
setup : Script ItemCustodyId
setup = script do
  jerry <- allocateParty "Jerry"
  elaine <- allocateParty "Elaine"

  brandNewCamera <- submit jerry do
    createCmd ItemCustody with
    owner = jerry <-- The `=` is error highlighted
    custodian = jerry
    itemName = "Really expensive Camera"

  elaineHasCamera <- submit jerry do
    exerciseCmd brandNewCamera ReleaseItemTo with friend = elaine, currentMeterCount = 360

  submit elaine do
    exerciseCmd elaineHasCamera ReturnItemTo with rightfulOwner = jerry, currentMeterCount = 1000
App/daml.yaml
sdk-version: 1.16.0
name: MyBorrowApp
source: daml
init-script: Main:setup
parties:
  - Jerry
  - Elaine
  #- Kramer
version: 0.0.1
dependencies:
  - daml-prim
  - daml-stdlib
  - daml-script
sandbox-options:
  - --wall-clock-time

I have Ctrl-A/Del this a few times now, no joy.

Update: I can get valid Contracts now but I have to comment out all references to the Daml.Script module & the test scripts in Main.daml and the init-script from daml.yaml.

To me it seems that Daml.Script on Daml-on-Ubuntu is being odd.

Hi @quidagis,

The issue seems to be the indentation of the with argument:

  brandNewCamera <- submit jerry do
    createCmd ItemCustody with
    owner = jerry <-- The `=` is error highlighted
    custodian = jerry
    itemName = "Really expensive Camera"

should be:

  brandNewCamera <- submit jerry do
    createCmd ItemCustody with
      owner = jerry <-- The `=` is error highlighted
      custodian = jerry
      itemName = "Really expensive Camera"

There is only one space in the video (which is valid: Daml cares that it is indented, it does not care by how much), which can seem a bit confusing given how VSCode displays that with the vertical line.

1 Like

Your code doesn’t quite match the one from the video:

  1. neighbor is an observer in the video not a signatory.
  2. The script needs to be adjusted to set the meter count and the neighbor

In the end, you end up with the following which works correctly and matches what is shown in the video I believe.

module Main where

import Daml.Script

type ItemCustodyId = ContractId ItemCustody

-- tracks chain of custody of my property
template ItemCustody
  with
    owner : Party
    custodian : Party
    neighbor : Party
    itemName : Text
    meterCount : Int -- shutter clicks
  where
    signatory owner
    observer neighbor

    controller owner can
      ReleaseItemTo : ItemCustodyId
        with
          friend : Party
          currentMeterCount : Int
        do
          create this with  
            custodian = friend
            meterCount = currentMeterCount

    controller custodian can
      ReturnItemTo : ItemCustodyId
        with
          rightfulOwner : Party
          currentMeterCount : Int
        do
          create this with
            owner = rightfulOwner
            meterCount = currentMeterCount

-- Test
setup : Script ItemCustodyId
setup = script do
  jerry <- allocateParty "Jerry"
  elaine <- allocateParty "Elaine"
  kramer <- allocateParty "Kramer"

  brandNewCamera <- submit jerry do
    createCmd ItemCustody with
      owner = jerry
      custodian = jerry
      neighbor = kramer
      itemName = "Really expensive Camera"
      meterCount = 347

  elaineHasCamera <- submit jerry do
    exerciseCmd brandNewCamera ReleaseItemTo with friend = elaine, currentMeterCount = 360

  submit elaine do
    exerciseCmd elaineHasCamera ReturnItemTo with rightfulOwner = jerry, currentMeterCount = 1000
1 Like

Thanks. As you state, it now works.

Just a minor point, in the Video @SteveSeow changes the term in the controller custodian from Owner to Custodian as Jerry is always the Owner of the Camera, he is just lending it out, so the person who borrows it, becomes the Custodian.

Programmatically either work, but ITRW, Custodian would be apropos I believe.

Thanks again @cocreature … as usual, awesome :+1:t2:

P.S. I need to go and modify my comment on the Youtube video :ballot_box_with_check:

Making some further modifications, and included an Issue & Accept layout from @SteveSeow next Youtube video. The contract will not execute, as there seems to be a signatory issue.

Edits as per your queries below :point_down:t2:

mylittleshop/daml/navigator.log (Barnados NZ Login):
08:56:41.844 [da-ui-backend-akka.actor.default-dispatcher-11] INFO
c.d.n.s.platform.PlatformSubscriber - Command '7519120809d46dfc' completed \
with status 'CommandStatusError(INVALID_ARGUMENT,Invalid argument: Command \
interpretation error in LF-DAMLe: Interpretation error: Error: node NodeId(0) \
(b57c95e0a40d8e27d5691dd113e749024d4b2ad38da177752ba7dc73f22d91ee:\
Main:DonateProposal) requires authorizers Barnados NZ,Johns Grocery, but only \
Barnados NZ were given.
From mylittleshop/daml/navigator.log (Johns Grocery Login):
08:57:27.102 [da-ui-backend-akka.actor.default-dispatcher-10] INFO \
c.d.n.s.platform.PlatformSubscriber - Command '2a95fb396404e34c' completed \
with status 'CommandStatusError(INVALID_ARGUMENT,Invalid argument: Command \
interpretation error in LF-DAMLe: Interpretation error: Error: node NodeId(0) \
(b57c95e0a40d8e27d5691dd113e749024d4b2ad38da177752ba7dc73f22d91ee: \
Main:DonateProposal) requires authorizers Barnados NZ,Johns Grocery, but only \
Johns Grocery were given
Complete => mylittleshop/dam/Main.daml
-- Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
-- SPDX-License-Identifier: Apache-2.0

-- more header content about who did what why etc
-- version author tested
-- ask for guidance from the Daml Forum 8-/

module Main where

{-- import Daml.Script  --} -- removed until it all works 8-)

type ItemSellId = ContractId ItemSell -- Sell stuff (DONE)
{-- type ItemRefund = ContractId ItemRefund --} -- Refund stuff
{-- type ItemReturnId = ContractId ItemReturn --} -- Return stuff
{-- type ItemDestroyedId = ContractId ItemDestroy --} -- Destroy stuff
{-- find out where is the *best* location for Type statements --}

{-- This Smart Contract tracks the chain of custody for
 my small, online shop based on the Issue & Accept example by Steve S.
 Currently there are no costings associated with this model,
 and it assumes full JIT compliance --}

template ItemSell
  with
    vendor : Party
    customer : Party
    merchantBank : Party
    item1Name : Text -- type of Fruit
    item1Count : Int -- how many pieces of Fruit
    item2Name : Text -- type of Fruit
    item2Count : Int -- how many pieces of Fruit
    item3Name : Text -- type of Fruit
    item3Count : Int -- how many pieces of Fruit
    
    {-- find out if you can reference a preloaded KV store as
     some sort of in-app Db. Can you access it like an Array?
     Or some sort of List processing? --}
  
  where
    signatory vendor -- Johns Grocery
    observer merchantBank -- ASB

    controller vendor can
      TransportItemTo : ItemSellId
        with
          company : Party
          currentItem1Count : Int
          currentItem2Count : Int
          currentItem3Count : Int
        do
          create this with  
            customer = company
            item1Count = currentItem1Count
            item2Count = currentItem2Count
            item3Count = currentItem3Count

    controller vendor can
      DonateItemTo: ItemSellId
        with
          charity : Party
          currentItem1Count : Int
          currentItem2Count : Int
          currentItem3Count : Int
        do
          create this with
            customer = charity
            item1Count = currentItem1Count
            item2Count = currentItem2Count
            item3Count = currentItem3Count

{--        
    controller vendor can -- legitimate destruction of Stock
      DestroyItemTo: ItemSellId
        with
          vendor : Party
          currentItem1Count : Int
          currentItem2Count : Int
          currentItem3Count : Int
        do
          create this with
            vendor = vendor
            item1Count = currentItem1Count --}
            
    controller customer can -- legitimate return of surplus Stock at discount
      ReturnItemTo : ItemSellId
        with
          rightfulOwner : Party
          currentItem1Count : Int
          {--reasonItem1 : Text --}
          {-- currentItem2Count : Int --}
          {-- reasonItem2 : Text --}
          {-- currentItem3Count : Int --}
          {-- reasonItem3 : Text --}
        do
          create this with
            vendor = rightfulOwner
            item1Count = currentItem1Count

type DonateProposalId = ContractId DonateProposal -- Propose to get donations
type DonateContractId = ContractId DonateContract -- Contract for donations

template DonateProposal -- Request Donation of surplus Stock from a vendor 
  with
    vendor : Party -- My Little Shop
    charity : Party -- Graciously receives donations
    itemName : Text -- what do they need
    itemNote : Text -- how much do they need (Units, Kgs, Metric Tonnes etc)
  where
    signatory vendor, charity
    
    -- what the Charity can do
    controller charity can
    -- Propose
      Propose : DonateProposalId
        do
          create this
    -- Revise
      Revise : DonateProposalId
        with
          revision : Text
          foodneedText : Text
        do
          create this with
            itemName = revision
            itemNote = foodneedText

    -- what the Vendor can do
    controller vendor can
    -- reject
      Reject : DonateProposalId
        with
          foodneed : Text
        do
          create this with
            itemNote = foodneed

    -- accept
      Accept : DonateContractId
        do
          create DonateContract with
            vendorInContract = vendor
            charityInContract = charity
            item1Name = itemName

-- DonateContract
template DonateContract
  with
    vendorInContract : Party
    charityInContract : Party
    item1Name : Text
  where
    signatory vendorInContract, charityInContract

-- EOF

Update: I did nothing more to execute than than daml start in mylittleshop/ So when I was logged in as a Charity, the Charity signatory worked, and when I was logged in as the vendor, the Vendor signatory work.

Am going back through the app now, in case I have some redundant conflict(s).

Can you share the steps you’re running through to get that error maybe in the form of a Daml Script? From the navigator log it’s not clear what exactly you’re running.

1 Like

The sequence of who proposes is up to your scenario. In that video, I have the child propose a paid chore he would like to do, and then the parent can choose to accept/reject it.

I can imagine charities soliciting for donations/services/etc. from vendor, and also vendors approaching charities to provide their services so they can write off their taxes :slight_smile: Assuming that is what you are building.

Per @cocreature, share the steps ad we can take a closer look.

1 Like