как можно обновить только значения карты в контракте daml?

#daml

#daml

Вопрос:

 Datatype detail:
  type1: Text
  type2: [detail2]

Datatype detail2:
  type1: Text

template A
with 
    consumerName: Text
    producerName : Text
    details : Map Text detail

create A with consumerName,producerName,details
  

теперь необходимо обновить старые детали контракта (текстовые типы данных карты) новыми деталями (текстовые типы данных карты) с несколькими ключевыми значениями.как можно добиться этого с помощью слияния, не выполняя обновление нескольких контрактов или возможно любое другое решение?

Ответ №1:

Вы можете использовать функции DA.Next.Map для управления картами. Вот полный рабочий пример, который, я надеюсь, может пролить некоторый свет на синтаксис и простые варианты использования:

 module Main where

import Daml.Script
import qualified DA.Next.Map as Map
import DA.Next.Map (Map)

template Comments
  with
    producer: Party
    consumer: Party
    productComments: Map Text [Text]
  where
    signatory producer
    observer consumer
    preconsuming choice AddComment: ContractId Comments
      with productName: Text, comment: Text
      controller consumer
      do
        create this with productComments = addComment productComments productName comment
    nonconsuming choice ReadComments: Map Text [Text]
      with reader: Party
      controller reader
      do return productComments

addComment: Map Text [Text] -> Text -> Text -> Map Text [Text]
addComment prev item newComment = case Map.lookup item prev of
  -- If the key is not in the map yet, we just add the comment
  None -> Map.insert item [newComment] prev
  -- If there are comments already, add to the end
  Some existingComments -> Map.insert item (existingComments    [newComment]) prev

setup : Script ()
setup = script do
  alice <- allocatePartyWithHint "Alice" (PartyIdHint "Alice")
  bob <- allocatePartyWithHint "Bob" (PartyIdHint "Bob")

  id1 <- submit bob do
    createCmd Comments
      with producer = bob
           consumer = alice
           productComments = mempty -- start with an empty map
  map1 <- submit alice do exerciseCmd id1 (ReadComments alice)
  assert $ map1 == Map.fromList []

  id2 <- submit alice do exerciseCmd id1 (AddComment "item1" "it was not very good")
  map2 <- submit alice do exerciseCmd id2 (ReadComments alice)
  assert $ map2 == Map.fromList [("item1", ["it was not very good"])]

  id3 <- submit alice do exerciseCmd id2 (AddComment "item2" "this is great!")
  map3 <- submit alice do exerciseCmd id3 (ReadComments alice)
  assert $ map3 == Map.fromList [("item1", ["it was not very good"]),
                                 ("item2", ["this is great!"])]

  id4 <- submit alice do exerciseCmd id3 (AddComment "item2" "I can't stop raving about it")
  map4 <- submit alice do exerciseCmd id4 (ReadComments alice)
  assert $ map4 == Map.fromList [("item1", ["it was not very good"]),
                                 ("item2", ["this is great!", "I can't stop raving about it"])]
  

Протестировано на SDK 1.6.0.

Я также недавно ответил на, возможно, связанный с этим вопрос на форуме DAML, где у меня есть еще несколько примеров использования функций в DA.Next.Map. Возможно, это тоже может помочь.