Advice on creating a mutable flag
Hi, I’m trying to use a mutable flag template (create/archived by bigUser) to control what another relatively immutable template can do (I prefer not to put the flag on TestLookup as this can happen frequently).
I want smolUser to be able to call the ChangeUserIfNoFlag function, while being permissioned by a mutable flag set by bigUser. I’m not sure which maintainer to use as visibleByKey seem to require authorization by bigUser. What’s the best way to achieve this?
module Test.TestLookup where
import Daml.Script
template LookupFlag
with
bigUser: Party
smolUser: Party
smolUserId: Text
where
signatory bigUser
observer smolUser
key (bigUser, smolUser): (Party, Party)
maintainer [key._1]
template TestLookup
with
bigUser: Party
smolUser: Party
smolUserId: Text
where
signatory smolUser
observer bigUser
choice ChangeUserIfNoFlag
: ContractId TestLookup
with
newSmol : Party
newSmolId : Text
controller smolUser
do
isDisabled <- visibleByKey @LookupFlag (bigUser, smolUser)
assertMsg "Disabled by bigUser" (not isDisabled)
create this with
smolUser = newSmol
smolUserId = newSmolId
testChangeLookup = do
big <- allocateParty "BIG"
smol1 <- allocateParty "SMOL1"
smol2 <- allocateParty "SMOL2"
testLookupCid <- submit smol1 do
createCmd TestLookup with
bigUser = big
smolUser = smol1
smolUserId = "user1"
smol2LookupCid <- submit smol1 do
exerciseCmd testLookupCid ChangeUserIfNoFlag with
newSmol = smol2
newSmolId = "user2"
pure ()
You need to get authorization from the maintainers somehow. In your example, one option could be to get the authorization by making bigUser a signatory on the contract. For test purposes, we can create the contract via submitMulti but in a real system you probably want some propose accept or something similar.
The second issue once you fixed that is the issue on the create in ChangeUserIfNoFlag. newSmol is a signatory on the new contract so you need to get their authorization somehow. This is a relatively standard problem on transfers. Usually, you solve this by making both smolUser and newSmol controllers of the choice so they both need to agree. You could wrap it in a propose-accept to actually get that exercise but for testing purposes let’s also use submitMulti here.
That leaves us with this example:
import Daml.Script
template LookupFlag
with
bigUser: Party
smolUser: Party
smolUserId: Text
where
signatory bigUser
observer smolUser
key (bigUser, smolUser): (Party, Party)
maintainer [key._1]
template TestLookup
with
bigUser: Party
smolUser: Party
smolUserId: Text
where
signatory smolUser, bigUser
choice ChangeUserIfNoFlag
: ContractId TestLookup
with
newSmol : Party
newSmolId : Text
controller smolUser, newSmol
do
isDisabled <- visibleByKey @LookupFlag (bigUser, smolUser)
assertMsg "Disabled by bigUser" (not isDisabled)
create this with
smolUser = newSmol
smolUserId = newSmolId
testChangeLookup = do
big <- allocateParty "BIG"
smol1 <- allocateParty "SMOL1"
smol2 <- allocateParty "SMOL2"
testLookupCid <- submitMulti [smol1, big] [] do
createCmd TestLookup with
bigUser = big
smolUser = smol1
smolUserId = "user1"
smol2LookupCid <- submitMulti [smol1, smol2] [] do
exerciseCmd testLookupCid ChangeUserIfNoFlag with
newSmol = smol2
newSmolId = "user2"
pure ()