Testing fetchByKey

Hello everyone, happy new year! I am working on contracts to sell assets. I am trying to test the code but it’s unclear to me how to recall the data included in “Asset” and to get the test of SellAsset done. I know it’s banal for you all, but there are a few concepts that I am struggling to understand by reading the documentation. Could someone with some free time and patience explain this to me? I have copied my code below.

module SellAsset where

import Asset 

type SellAssetId = ContractId SellAsset

template SellAsset
    with
        asset : Asset
        newOwnerSolicitor:Party
        newOwner:Party
        notes: Text
       
    where 
        signatory asset.ownerSolicitor
        observer asset.owner, newOwner, asset.auctionHouse

        choice AssetDocOffer_GetAsset : Asset
          controller asset.ownerSolicitor
          do
            (_, asset') <- fetchByKey @Asset (key asset)
            return asset

And this is the test:

module Main_I where
import Asset 
import SellAsset

import Daml.Script

sell_asset_test : Script SellAssetId
sell_asset_test = script do

    cms <- allocatePartyWithHint "CMS" (PartyIdHint "CMS")   
    claudia <- allocatePartyWithHint "Claudia" (PartyIdHint "Claudia")  
    christie<- allocatePartyWithHint "Christie" (PartyIdHint "Christie") 
    claudia_Budha <- allocatePartyWithHint "Claudia_Budha" (PartyIdHint "Claudia_Budha") 
    mishconDeReya <- allocatePartyWithHint "MishconDeReya" (PartyIdHint "MishconDeReya")   
    silvia <- allocatePartyWithHint "Silvia" (PartyIdHint "Silvia")  
    time <- getTime

    submit cms do 
        createCmd SellAsset with
            
            asset = asset.Asset
            newOwnerSolicitor = mishconDeReya
            newOwner = silvia
            notes = "Questa villa e' stata venduta"

Thank you ever so much if someone has a bit of time to help! :smile: :smile: :smile:

Welcome back, @claudia_giannoni!

Does your Asset template include a Contract Key in its definition? Knowing that and how it is defined will help us answer your question. If not, try adding a key to the Asset template as described here and let us know how it goes.

Also, keep in mind that keys are not required to fetch contracts. You can reference contracts either by key or ContractId, as explained in that referenced page. The approach you use depends on your workflow.


By the way, thanks for pasting your code into code blocks with the three backticks. You may notice it did not get formatted exactly right. If you place the three backticks on a line all by themselves I think you will get better formatting. (You could even edit your original post to clean it up.)

Hi Wallace, thank you for replying to me again! Yes, I have a contract key in my Asset template.
Here is the code:

module Asset where

type AssetId = ContractId Asset

template Asset 
  with

    ownerSolicitor : Party
    owner : Party
    auctionHouse :Party --also makes sure that all parties are legit
    address :Text
    idCode: Text --To check how to create an asset ID. To be generated offline 
    a_description : Text 
    a_documents : [Text]
    a_docLink : Text --to be reviwed to create a link to the documents       
    v_description : Text 
    v_documents : [Text]
    v_docLink : Text --to be reviwed to create a link to the documents 
    date: Time

  where
    signatory ownerSolicitor
    observer owner,auctionHouse  

    key (ownerSolicitor, idCode) : (Party, Text)
    maintainer key._1
        
    choice UpdateAsset 
      : ContractId Asset 
      with 

            new_owner : Party
            new_address :Text
            new_idCode: Text 
            new_a_description : Text 
            new_a_documents : [Text]
            new_a_docLink : Text       
            new_v_description : Text 
            new_v_documents : [Text]
            new_v_docLink : Text 
            new_date:Time

      controller ownerSolicitor 
        do 
            create this with
 
              owner = new_owner
              address = new_address
              idCode = new_idCode
              a_description = new_a_description 
              a_documents = a_documents ++ new_a_documents
              a_docLink = new_a_docLink      
              v_description = new_v_description
              v_documents = v_documents ++ new_v_documents
              v_docLink = new_v_docLink
              date = new_date

Sorry for getting wrong the ```.

First, let’s address what it would take to get your code to compile. Secondly, we can address the overall design.


Your code does not compile as-is. The problem is in the test. Specifically the following does not work:

    submit cms do 
        createCmd SellAsset with
            
            asset = asset.Asset
            newOwnerSolicitor = mishconDeReya
            newOwner = silvia
            notes = "Questa villa e' stata venduta"

The above does not work because asset is not defined in this script and so asset.Asset fails. To get the test to work with the current template design, you could create an Asset contract first before trying to create the SellAsset.

Example implementation
module Main_I where
import Asset 
import SellAsset

import Daml.Script

sell_asset_test : Script SellAssetId
sell_asset_test = script do

    cms <- allocatePartyWithHint "CMS" (PartyIdHint "CMS")   
    claudia <- allocatePartyWithHint "Claudia" (PartyIdHint "Claudia")  
    christie<- allocatePartyWithHint "Christie" (PartyIdHint "Christie") 
    claudia_Budha <- allocatePartyWithHint "Claudia_Budha" (PartyIdHint "Claudia_Budha") 
    mishconDeReya <- allocatePartyWithHint "MishconDeReya" (PartyIdHint "MishconDeReya")   
    silvia <- allocatePartyWithHint "Silvia" (PartyIdHint "Silvia")  
    time <- getTime

    assetId <- submit claudia do
        createCmd Asset with
          ownerSolicitor = claudia
          owner = claudia
          auctionHouse = christie
          address = "1234 Address"
          idCode = "Asset 2345" 
          a_description = "Asset 2345 description"
          a_documents = []
          a_docLink = ""
          v_description = ""
          v_documents = []
          v_docLink = ""
          date = time
    
    Some asset <- queryContractId claudia assetId

    sellAsset <- submit claudia do 
        createCmd SellAsset with
            asset = asset
            newOwnerSolicitor = mishconDeReya
            newOwner = silvia
            notes = "Questa villa e' stata venduta"
    
    submit claudia do
      exerciseCmd sellAsset AssetDocOffer_GetAsset
    
    return sellAsset

However, you might want to take another look at the overall design. Your SellAsset template includes a member of type Asset. That means, the data for the Asset is stored directly into your SellAsset template. Typically, you would have an Asset contract on the ledger. And then when you create the SellAsset, you would not include the entire Asset instance within the SellAsset. Instead you would reference the asset with either:

  • a ContractId Asset, in which case you could retrieve the Asset with fetch.
  • the values used by the Asset’s key (for example, idCode), in which case you could retrieve the Asset with fetchByKey.

Here is a start at what SellAsset would look like, referencing the Asset by contract id:

template SellAsset
    with
        -- asset : Asset
        assetId : ContractId Asset
        ownerSolicitor : Party
        owner : Party
        auctionHouse : Party

        newOwnerSolicitor:Party
        newOwner:Party
        notes: Text

With the above, you would get the Asset using fetch.

Here is a start at what SellAsset would look like, referencing the Asset by key:

template SellAsset
    with
        -- asset : Asset
        idCode : Text
        ownerSolicitor : Party
        owner : Party
        auctionHouse : Party

        newOwnerSolicitor:Party
        newOwner:Party
        notes: Text

With the above, you would get the Asset using fetchByKey.

I hope that is helpful.

Hi Wallace you are a star!! Of course, it works now (you did it :smile:) but also I got the chance to understand many things thanks to your explanation and code. Thank you thank you thank you! And thank you very much also for replying so quickly it changes my day as I can progress. :pray: :pray: :pray: :pray: :pray: :pray: :pray: