Когда вы спрашиваете об ограничениях типа «один в день» в DAML, нужно подумать о сфере действия этого ограничения и о том, кто его гарантирует.
Простейший возможный шаблон в DAML -
template Daily
with
holder : Party
where
signatory holder
Экземпляр этого шаблона известен только holder
. Не существует ни одной стороны или группы сторон, которые могли бы гарантировать, что существует только один такой экземпляр договора между Alice
и Bob
. В некоторых топологиях главной книги Alice
и Bob
могут даже не знать друг о друге, и при этом ни одна из сторон не знает об обоих.
Необходим набор сторон, гарантирующих уникальность:
template Daily
with
holder : Party
uniquenessGuarantors : [Party]
...
Гаранты уникальности должны иметь возможность разрешить или заблокировать создание Daily
. Другими словами, они должны быть подписавшими.
template Daily
with
holder : Party
uniquenessGuarantors : [Party]
where
signatory holder, uniquenessGuarantors
Теперь самый простой способ гарантировать любую уникальность в DAML - это использовать контрактные ключи . Поскольку нам нужно по одному в день, нам нужно поле Date
.
template Daily
with
holder : Party
uniquenessGuarantors : [Party]
date : Date
where
signatory holder, uniquenessGuarantors
key (uniquenessGuarantors, date) : ([Party], Date)
maintainer key._1
Это означает, что для каждого ключа существует уникальная копия Daily
, а гаранты в key._1
ответственность за то, чтобы сделать это так.
Наконец, вам нужен механизм для реального создания этих вещей, своего рода DailyFactory
, предоставленный гарантами. Эта фабрика также может позаботиться о том, чтобы date
всегда было установлено на текущую дату в регистре.
template DailyFactory
with
uniquenessGuarantors : [Party]
holder : Party
where
signatory uniquenessGuarantors
controller holder can
nonconsuming FabricateDaily
: ContractId Daily
do
now <- getTime
let date = toDateUTC now
create Daily with ..
Простой тест показывает, как это работает, с уникальностью, гарантированной одной стороной Charlie
:
test_daily = scenario do
[alice, bob, charlie] <- mapA getParty ["Alice", "Bob", "Charlie"]
fAlice <- submit charlie do
create DailyFactory with
holder = alice
uniquenessGuarantors = [charlie]
fBob <- submit charlie do
create DailyFactory with
holder = bob
uniquenessGuarantors = [charlie]
-- Alice can get hold of a `Daily`
submit alice do
exercise fAlice FabricateDaily
-- Neither can create a second
submitMustFail alice do
exercise fAlice FabricateDaily
submitMustFail bob do
exercise fBob FabricateDaily
-- The next day bob can create one
pass (days 1)
submit bob do
exercise fBob FabricateDaily
-- But neither can create a second
submitMustFail alice do
exercise fAlice FabricateDaily
submitMustFail bob do
exercise fBob FabricateDaily
Обратите внимание, что с точки зрения конфиденциальности Alice
и Bob
не знают друг о друге или Daily
или DailyFactory
другого, но uniquenessGuarantors
знаютвсе стороны, для которых сохраняется уникальность, и знают все Daily
случаи, для которых они гарантируют уникальность. Они должны!
Для запуска приведенных выше фрагментов необходимо импортировать DA.Time
и DA.Date
.