I am developing a dApp following specifications outlined in, amongst other things, graphical data models. This is part of an individual MSc project. The app allows producers to create product records. These products should be associated to some known product type.
Is it ‘correct’ that these product types should be stored on a ledger (along with all the other contracts)? (e.g. in a ProductType contract)
Usually I’d stored this kind of stuff in a database but this app is supposed to be decentralised. My uncertainty arises partly from my unfamiliarity with DAML (and blockchain in general). The ProductType ‘contracts’ would need to be observable to everyone who wants to create a Product (so that they can select a known product type from a dropdown in the UI).
Is it possible/advisable to create ‘contracts’ observable to many users?
Lastly any app built with DAML is distributed among multiple parties but not decentralized as the parties that operate the ledger ultimately have collective control over the state of the ledger and could even up and delete the entire thing if they all collectively chose to, not that they would, and it’s more fault tolerant than say regular old SQL but it’s still always an option
I am familiar with the idea not to store big stuff on the ledger. Fortunately all the stuff I want to store on the ledger is small. His ‘article’ addresses the problems with having to do stuff with large assets on the ledger.
I don’t understand how the aliases guide solves the problem, but maybe that arises from my own lack of understanding.
Oh, well distributed is fine. There is no specification for it to be decentralised, just a smart contract blockchain application!
For 1, the short answer is yes you would store all of the information you described on ledger since it is a core part of the operation of your ledger.
For 2 if I understand correctly the question is whether you can know all of your ProductTypes ahead of time and make a data type or if you need people using the ledger creating new Products at runtime.
If they can be known ahead of time like a data type (ex. data ProductType = Car | Boat | Train) or a series of templates then in these cases anyone interacting with the ledger should know about every type of template and data type (they’re all in the DAR file).
However if they won’t be known until during runtime and productTypes are going to be added/removed over time then you can do something like:
module Example where
productType : String
operator : Party
observers : [Party]
controller operator can
Update_Observers : ContractId Product
with newObserver : Party
create this with observers = observers ++ [newObserver]
Here you’d have an operator party that monitors for new Parties being created and exercises a choice like Update_Observers to update that contract whenever it happens. Then every Party can query for this type of contract and get back one or more Product contracts that will tell them the productTypes that exist on ledger.
Yes I am somewhat familiar with this design pattern, but unless I am mistaken this will require that a new contract has to be created every time a new party wants to view the contract?
Maybe I can give an ‘easier to visualise’ scenario. Let’s say you have some Product contracts on the ledger. Imagine that the UI had a page where you could view all the products (like an online store). There would be a great many parties interested in viewing a given product. Surely this design pattern is not scalable? What do you think?
You are right, DAML currently lacks a good mechanism for public data or data that should be shared with a large number of parties. There’s a long discussion on a potential mechanism to enable this (for some topologies): Query and Create Exercise as multiple parties
The fundamental problem with public data is this:
DAML Ledgers are assumed to be fully decentralized with data shared at transaction time on a need-to-know basis.
Nodes need not know about the existence of other nodes.
Nodes can join and leave the network dynamically.
How do you distribute public data? You certainly can’t do it transactionally. There’s also no central place where nodes can “pick up” that public data.
While we are working on solutions for this problem, there are some possible workarounds:
Publish public data “out of band”. E.g. create a special party public, make that an observer on all public data, and proxy the JSON API such that you always pass in a token for public in read-only. That way anyone can query the ledger as public, albeit on a different endpoint.
“Broadcast” the data over the ledger using subscriptions. This is abusing divulgence to make contracts available to other parties. With some simple automation, this would allow you to distribute the Product contract to a set of parties, but scalability will become an issue with very large sets of parties or fast-changing products. ex-models/broadcast at master · digital-asset/ex-models · GitHub
Thank you @bernhard. I expected I would have to do something similar to option 1.
I was watching this video: ‘Solving Supply Chain’s Big Problems…’ https://www.youtube.com/watch?v=evYzVl1bmB0&t=2704s . There is a part of the app where users can place buy orders for known products (33:40). I guess the difference here is that the list of known products is small and probably just stored in the UI, as opposed to being publicly visible chain data. EDIT: The product info is actually visible in the project:DABL view. So I guess it is on the chain. I guess the buyer is an observer on the product contract?