I’ve realized that in a couple of our projects now, it would be really nice to have fields on contracts and choices that are only visible to signatories of the contract and not other observers.
This would especially enable (some) observers to be effectively anonymized from one another, by putting a list of observers (say) in a blind field. You’d also pretty shortly want the same for choices, so that you could, say, have a choice with a flexible controller whose Party was in a blind field of the choice so their identity would only be revealed to signatories, and not anyone else who could see the action taking place.
For example, this might be useful to enable anonymous negotiations between clients of a broker, where a broker creates a contract for the negotiating parties to interact with, and they each can see it, and can take actions on it without revealing their identities to each other, only to the broker.
For example, using the new keyword ‘blind’ as analogous to ‘with’:
template Negotiation
with
broker : Party
terms : Terms
blind
clients : Set Party
accepted : Set Party
where
signatory broker
observer clients
choice Counter : ContractId Negotiation
with
newTerms : Terms
blind
actor : Party
controller actor
do
assertMsg "Must be a client of this negotiation" (Set.member actor clients)
create this with
terms = newTerms
accepted = Set.singleton actor
choice Accept : Either (ContractId Negotiation) (ContractId Deal)
blind
actor : Party
controller actor
do
assertMsg "Must be a client of this negotiation" (Set.member actor clients)
let newAccepted = Set.insert actor accepted
if newAccepted == clients
then Right <$> create Deal with
broker
terms
clients
else Left <$> create this with
accepted = Set.insert actor accepted
This is intentionally a bit simplistic, especially with the single signatory and no reporting of status at all to the participants before the end, but hopefully the idea is clear enough. Any of the clients can counter with new terms (resetting the acceptance to just include themselves), or accept, adding themselves to the set of accepted clients, and if that set becomes the entire set of clients, a new Deal is created (and presumably agreeing parties are revealed to one another at that point and can reconfirm to become signatories of something). The broker has insight into everything which is going on, but while each client sees that this Negotiation contract exists, and so can infer that they must belong to its clients set, they can’t actually see the contents of that set directly, or who has accepted the terms so far.
Currently, anyone who can see a contract can compute who all the observers are, and so if taking some choice on a contract is meant to require disclosing information to a party who is meant to be anonymous with respect to any of its observers, this typically involves some off-ledger component, and you may miss out on the contractual guarantee that it actually takes place as it should, as well as atomicity. One of the key selling points of Daml is to be able to nicely handle the logic about visibility and rights like this, and so I think a feature along these lines could help further strengthen that point.
One weakness of this design as proposed can be seen in the above example: it might be nice for it to be possible to collect the delegated authority of the accepting clients to create a Deal in the end on which they’d all be signatories from the outset, and not merely observers, still without revealing them to one another before the end. At the same time, to allow that would involve allowing parties to agree to things and end up as signatories on contracts before they were aware of with whom they were entering into an agreement, which might also be inappropriate in many cases.