Thanks @Luciano. Yes I understand these concepts. But what is stopping any old party from submitting a create Thing contract request on the Ledger’s API? They would appear as the signatory by virtue of putting themselves in the admin field, which is something we don’t want! Maybe I am mistaken in my logic.
So let’s say you have 3 known parties, only one of them is an admin. We don’t want the other two parties to be able to be in the admin field of the Thing contract.
I see your point. This is actually a pretty interesting question!
The short answer would be to add an ensure clause to check the party matches a pre-specified ‘admin’ party.
You can use this in combination with partyFromText : Text -> Party to check for a known identifier. However, this is pretty hacky and not recommended, because in a prod environment, you may not have control over the identifiers used to create the parties - they should be opaque. To work around this, you would need a ‘meta’ user contract, that obfuscates the Party type. But in this case you’re just trading one problem for another (How do you know which is your ‘admin’ contract?).
I’ll have to think about this some more. Perhaps someone else has got a better idea …
If only Things created by the admin are valid, then you have to know this party by name (regardless if it’s an obfuscated party id or not). So your application (UI, backend code) can simply only consider Things that have the correct admin set. You can’t really stop anyone from creating a single-signatory contract, but your application can know which are the valid ones to consider.
Definitely a “no” to the DB question. It would be impossible to make that deterministic and verifiable.
DLTs are usually quite symmetric with respect to nodes. The whole point is that you are trying to remove trusted central parties. The same is not true for all applications running on such platforms. Usually application instances are determined exactly by the party (or address on many Blockchains) that is stored on the contracts as the “admin”. That’s the pattern @georg suggests. Just make sure to only query contracts with the correct admin party.
Hardcoding parties using partyFromText is a hack, but one that is common in the Blockchain world where addresses are quite commonly hardcoded. The reason I’d not recommend that in DAML is that you loose application portability not just between platforms, but between ledgers on a given platform. E.g. you wouldn’t be able to move your application from DABL staging to DABL prod without changing the hardcoded party in the package.
That being said, looking at the docs for Hyperledger Fabric and it seems they have some way of specifying access controls. Maybe that is a different thing to what I am thinking about…
It’s possible (and I think that’s what Fabric does) to restrict user access on a node. So a node could say “I will reject any command submissions that would create a Thing with an admin other than admin.” However, that doesn’t stop another node to create a Thing with a different admin. The node with the restriction may not even know about it.
If the whole ledger is operated by one user, as it is in DABL, it would then be possible to enforce this policy globally. However, such a feature doesn’t exist in DAML/DABL at this point. It would also harm application portability in a serious way. Your application would start relying on a ledger topology where such restrictions can be enforced globally.
Definitely a “no” to the DB question. It would be impossible to make that deterministic and verifiable.
This being said, I do recall hearing about smart contract ‘oracles’; external sources of information that play a role in the control flow of the smart contract code execution. Is that not similar to a DB query? I don’t think oracles exist in DAML.
You must always check the signatories of a contract before you use it.
It’s an important property of the DAML architecture that you can only trust something once you have seen it on the ledger, and that trust is explicitly constrained to the signatories of the associated contract.
What this means is that it is always a bug to fetch a contract without then checking you trust its signatories.
Yes. Anyone can always create any contract at any time provided they are the sole signatory of that contract. So whether you are writing DAML code that just fetched a contract from the ledger, or writing an application that is reading an ACS service. You must always check the signatories of a contract before you use it.
Instead of checking that the party as text meets a certain pattern, wouldn’t it be better to hardcode a code in the contract and make it necessary to enter a key when creating that contract so that its hash (calculated with DA.Text.Sha256) is equal to the code hardcoded?
In this way, only the person who wrote the contract would know the correct key.