如何只更新 daml 合同中的地图值?

how can update only Map values in daml contract?

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

现在需要用多个键值的新详细信息(地图文本数据类型)更新合同旧详细信息(地图文本数据类型)。如何在不进行多个合同更新或任何其他解决方案的情况下使用合并来实现这一点?

您可以使用DA.Next.Map中的函数来操作地图。这是一个完整的工作示例,我希望它可以阐明语法和简单 use-cases:

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 上测试。

我最近也回答了 a possibly related question on the DAML forum,其中我有更多使用 DA.Next.Map 中函数的示例。也许这也能有所帮助。