1

我是 DAML 的新手,并且已经为此苦苦思索了两天。在“模板投票”中指定的这个投票系统中,参与者有能力将投票方添加到指定为“选择添加”的投票者列表中。这个选民名单(我假设是一个名单)被定义为“voters : Set Party”,(我似乎找不到定义),并且在“Choice Vote”和“Choice Decide”中定义了一些条件。

我正在尝试删除“选择添加”功能,而是在单独模板中定义的列表中预定义所有选民。如果我理解正确,这些预定义的选民必须声明为一个列表:[Party] 我创建了一个名为“Creation”的模板,其中包含一些变量以及一个名为“CreationRights”的自定义类型,其中包含必须从投票模板。但是,我似乎无法以任何方式引用此列表。将 voters 数据类型更改为 [Party] 也会在 Choice Decide 和 Choice Vote 中为“voters”提供错误。使指定的条件不可用:

无法将预期类型“Set a1”与实际类型“[Party]”匹配

如何在仍然应用条件集的同时引用预定义的选民 (votingRight) 列表?非常欢迎任何提示!

代码:

data CreationRights = CreationRights
  with 
    votingRight : [Party]
  deriving (Eq, Show)

template Creation
  with 
    actor       : Party
    creationId  : Text
    title       : Text
    votingRight : CreationRights
  where
    signatory actor

template Voting
  with
    actor : Party
    claim : Claim
    voters : Set Party
    voted : Set Party
    votes : [Bool]

  where
    signatory actor, voted
    observer voters

    key (actor, claim) : VotingKey
    maintainer key._1

    ---choice Add : ()
      ---with voter : Party
      ---controller actor
      ---do
        ---create this with voters = S.insert voter voters
        ---pure ()

    choice Decide : ContractId Decision
      controller actor
      do
        assertMsg "At least 60% must have voted" $ ((size voters / 100) * 60) <= length votes
        let approvals = length $ L.filter (\v -> v) votes
        let disapprovals = length $ L.filter (\v -> not v) votes
        let accept = approvals > disapprovals
        create Decision with ..

    choice Vote : ()
      with
        voter : Party
        accept : Bool
      controller voter
      do
        assertMsg "Voter not added" $ member voter voters
        assertMsg "Voter already voted" $ not $ member voter voted
        create this with voted = S.insert voter voted; votes = accept :: votes
        pure ()

template Decision
  with
    actor : Party
    claim : Claim
    voters : Set Party
    accept : Bool
  where
    signatory actor, voters
4

1 回答 1

2

您无需执行任何操作即可在Voting不使用Add. Voting将其签名者定义为actor, voted,因此如果voted为空或包含同一方的单例,则初始Voting实例只有一个签名者。这意味着它可以直接创建而actor无需进一步的交互。我在这个答案的末尾包含了一个简化的演示。

鉴于您已经创建了 的实例Creation,您将在账本上拥有一份选民名单的副本。那时,如果您想使用该列表,您将不得不对该合约进行选择或从分类账中读取该合约。fetch您可以使用, fetchByKey, lookup, 和在另一个合同的选择中执行后者lookupByKey(尽管您需要提供密钥或 contractId)。但是,由于此模板实例代表创建Voting实例的权限,因此建议直接将此权限表示为选项Creation

最后,如果您将数据类型voters从 a更改Set为 a,List那么您还必须更改使用该参数的相应函数。因此,例如,S.insert voter voted必须成为voter :: voted或类似。

daml 1.2
module Voting where

import DA.Next.Set as S
import DA.List as L

type Claim = Text

type VotingKey = (Party, Claim)

template Voting
  with
    actor : Party
    claim : Claim
    voters : Set Party
    voted : Set Party
    votes : [Bool]

  where
    signatory actor, voted
    observer voters

    key (actor, claim) : VotingKey
    maintainer key._1

    choice Decide : ContractId Decision
      controller actor
      do
        assertMsg "At least 60% must have voted" $ ((size voters / 100) * 60) <= length votes
        let approvals = length $ L.filter identity votes
        let disapprovals = length $ L.filter not votes
        let accept = approvals > disapprovals
        create Decision with actor; claim; voters; accept

    choice Vote : ContractId Voting
      with
        voter : Party
        accept : Bool
      controller voter
      do
        assertMsg "Voter not added" $ member voter voters
        assertMsg "Voter already voted" . not $ member voter voted
        create this with voted = S.insert voter voted; votes = accept :: votes

template Decision
  with
    actor : Party
    claim : Claim
    voters : Set Party
    accept : Bool
  where
    signatory actor, voters

test = scenario do
    alice <- getParty "Alice"
    bob <- getParty "Bob"
    charlie <- getParty "Charlie"

    alice `submit` create
        Voting with
            actor = alice
            claim = "Pizza"
            voters = fromList [ alice, bob, charlie ]
            voted = empty
            votes = []
于 2020-03-04T05:58:39.820 回答