DAML: ссылка и задание условий для предварительно определенного списка в отдельном шаблоне - PullRequest
1 голос
/ 04 марта 2020

Я новичок в DAML и почесал голову над этим два solid дня. В этой системе голосования, указанной в «шаблоне голосования», актер имеет возможность добавить партию избирателя в список избирателей, указанный как «выбор Добавить». Этот список избирателей (я предполагаю, что список) определен как "избиратели: партия набора" (из которых я, кажется, не могу найти определение), и некоторые условия определены в "Выбор голосования" и "Выбор решить".

Я пытаюсь убрать возможность «Добавить выбор» и вместо этого заранее определить всех избирателей в списке, определенном в отдельном шаблоне. Если я правильно понимаю, эти предопределенные избиратели должны быть объявлены в виде списка: [Сторона] Я создал шаблон под названием «Создание», содержащий некоторые переменные в сочетании с пользовательским типом под названием «CreationRights», содержащий список избирателей, на который нужно ссылаться из шаблон голосования. Тем не менее, я не могу ссылаться на этот список в любом случае. Изменение типа данных избирателей на [Партия] также приводит к ошибке для «избирателей» в «Выбор решения» и «Выбор голосования». делает указанные условия непригодными для использования:

Не удалось сопоставить ожидаемый тип 'Set a1' с фактическим типом '[Party]'

Как я могу ссылаться на предопределенный список избирателей (VoteRight), пока еще применяя набор условий? Любые советы приветствуются!

Код:

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

1 Ответ

2 голосов
/ 04 марта 2020

Вам не нужно ничего делать для создания экземпляра Voting без использования Add. Voting определяет своих подписантов как actor, voted, поэтому, если voted является пустым или содержит одноэлементную запись, содержащую одну и ту же сторону, то у исходного экземпляра Voting есть только одна подписавшая сторона. Это означает, что он может быть создан непосредственно actor без дальнейшего взаимодействия. Я включил упрощенную демонстрацию этого в конце этого ответа.

Учитывая, что вы создали экземпляр Creation, вы будете иметь копию своего списка избирателей в главной книге. В этот момент, если вы хотите использовать этот список, вам придется либо выполнить выбор по этому контракту, либо прочитать этот контракт из бухгалтерской книги. Последнее можно сделать с помощью fetch, fetchByKey, lookup и lookupByKey в рамках выбора другого контракта (хотя вам необходимо будет указать либо ключ, либо идентификатор контракта). Однако, так как этот экземпляр шаблона представляет полномочия для создания Voting экземпляров, рекомендуется представлять эти полномочия непосредственно как выбор для Creation.

Наконец, если вы измените тип данных voters с Set на 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 = []
...