I have started working on Corda recently. We have got the requirements not to show State properties for specific status.
While going through the document I have found some reference below but could not find any suitable example.
https://solutions.corda.net/corda-modelling-notation/views/views-common-concepts.html
Properties
These are the properties of the State whilst in the particular status. Not all properties need to be shown, just the ones salient to the behaviour of the State in this Status.
Could you be able to point me to any relevant example for the same?
Corda States are available to participants on a need-to-know basis and as a whole. The participant list returned by the getParticipants() method of a state defines the participants who should be aware of that state. You could update the participant list (add or remove) to grant or revoke access to a state but it's not possible to grant/revoke access to a part of the state.
To cater to your scenario below possible approaches can be taken:
Refactor your entire state into separate states and make them available to parties depending on the status.
Handle this on the application layer, after fetching the state from the Corda node and restrict visibility on the basis of the state.
Update the state variables to null based on the status, this may not be very feasible but just in case your use-case allows this.
Related
The goal is to generate events on every participating node when a state is changed that includes the business action that caused the change. In our case, Business Action maps to the Transaction command and provides the business intent or what the user is doing in business terms. So in our case, where we are modelling the lifecycle of a loan, an action might be to "Close" the loan.
We model Event at a state level as follows: Each Event encapsulates a Transaction Command and is uniquely identified by a (TxnHash, OutputIndex) and a created/consumed status.
We would prefer a polling mechanism to generate events on demand, but an asynch approach to generate events on ledger changes would be acceptable. Either way our challenge is in getting the Command from the Transaction.
We considered querying the States using the Vault Query API vaultQueryBy() for the polling solution (or vaultTrackBy() for the asynch Obvservalble Stream solution). We were able to create a flow that gets the txn for a state. This had to be done in a flow, as Corda deprecated the function that would have allowed us to do this in our Springboot client. In the client we use vaultQueryBy() to get a list of States. Then we call a flow that iterates over the states, gets txHash from each StateRef and then calls serviceHub.validatedTransactions.getTransaction(txHash) to get signedTransaction from which we can ultimately retrieve the Command. Is this the best or recommended approach?
Alternatively, we have also thought of generating events of the Transaction by querying for transactions and then building the Event for each input and output state in the transaction. If we go this route what's the best way to query transactions from the vault? Is there an Observable Stream-based option?
I assume this mapping of states to command is a common requirement for observers of the ledger because it is standard to drive contract logic off the transaction command and quite natural to have the command map to the user intent.
What is the best way to generate events that encapsulate the transaction command for each state created or consumed on the ledger?
If I understand correctly you're attempting to get a notified when certain types of ledger updates occur (open, approved, closed, etc).
First: Asynchronous notifications are best practice in Corda, polling should be avoided due to the added weight it puts on the node for constant querying and delays. Corda provides several mechanisms for Observables which you can use: https://docs.corda.net/api/kotlin/corda/net.corda.core.messaging/-corda-r-p-c-ops/vault-track-by.html
Second: Avoid querying transactions from the database as these are intended to be internal to the node. See this answer for background on why to avoid transaction querying. In general only tables that begin with "VAULT_*" are intended to be queried.
One way to solve your use case would be a "status" field which reflects the command that was used to produce the current state. For example: if a "Close" command was used to produce the state it's status field could be "closed". This way you could use the above vaultTrackBy to look at each state's status field and infer the action that occured.
Just to finish up on my comment: While the approach met the requirements, The problem with this solution is that we have to add and maintain our own code across all relevant states to capture transaction-level information that is already tracked by the platform. I would think a better solution would be for the platform to provide consumers access to transaction-level information (selectively perhaps) just as it does for states. After all, the transaction is, in part, a business/functional construct that is meaningful at the client application level. For example, If I am "transferring" a loan, that may be a complex business transaction that involves many input and output states and may be an important construct/notion for the client application to manage.
I'm currently tying to make a CordApp That will be used for DVP, but I'm having trouble understanding some key concepts. For instance, I understand that Contracts apply to one type of state in particular. What I don't really get is if the contract validation logic should apply to only that state object or all the states that will be in the given transaction.
The typical example would be the issuance of a sell order :
The input of a transaction the state of the stock account of the issuer and the outputs are the sell Order and the modified stock account.
Basically my question is were do I do checks like : I don't sell more than I own, the sum of the number of stocks in the sell order and what is left in the account is equal to what was initially in the account, ... ?
I have followed the Corda tutorials but I'm still not clear on that logic.
It boils down to the Orchestration Layer (flows or APIs, what the user intends to do) vs the Ledger layer (what the user can do. IE - guaranteed shared logic).
Contract code absolutely must be adhered to, so in your case not being able to sell more than you own would be part of the explicit contract.
The CMN guide here helped me conceptualise.
Flows are better described as business logic, so anything can be achieved within a flow as long as it adheres to the contract.
A security consideration: Anybody may create a flow, and they are equally able to use any Asset (and thus it's state) within their third-party flow.
It is the relevant contract that ensures that your asset is used for the purpose you imagine, and that it isn't used malevolently.
https://docs.corda.net/api-vault-query.html specifies that "TrackBy updates do not take into account the full criteria specification due to different and more restrictive syntax in observables filtering (vs full SQL-92 JDBC filtering as used in snapshot views). Specifically, dynamic updates are filtered by contractStateType and stateType (UNCONSUMED, CONSUMED, ALL) only" (edited)
Does that mean that i cannot track a particular record ( state) in my vault based on its properties other than stateType? (edited)
This is what i have noticed also. I used a LinearStateQueryCriteria based on externalID but instead of updates of that one record, i got updates for all the records of the particular contractStateType.
Looking for confirmation so i can try another strategy.
To achieve what you want, you could use trackBy to monitor the state type you need and in the observable filter to only include states with the externalId that you desire. This might not be ideal but will achieve the goal you are looking for.
I have a state with a global ID. I want to check whether the state is already issued by other node before I issue the state.
Is there a way I can check the state on the whole chain or I have to notify all of the nodes about issuing new state?
Corda's privacy model means that there is no central "chain" that can be checked for an existing state with the same ID.
If you simply need a unique ID for your state, use something like UniqueIdentifier, ideally by implementing the LinearState interface (https://docs.corda.net/api-states.html#linearstate). UniqueIdentifier contains a 128-bit unique identifier. This is large enough to avoid collisions between all the LinearStates on the network, despite there being no centralised repository of allocated IDs.
If this is not good enough, and the IDs have to be allocated based on some scheme instead of randomly, you'll need to create some centralised oracle node that tracks issued IDs and only signs transactions where the ID being allocated has not been used before.
A strategic question… When a state is going to have one to many type of data, should we always create a collection under the parent state object or create a separate state object for the child with the reference to parent? Example (Employer 1:M Employee) or (Employer 1:M Location) …. When to decide which strategy? I've listed some PROS & CONS for each. Not sure when to use what strategy. Looking for some feedback
Adding child as collection
PROS
=====
- Easier to manage from coding standpoint
- Easy access to child data as it will always be available when querying parent from vault
CONS
=====
- As each collection object is going to be represented as separate table in the database, Each time a new state is created child data is also replicated even though there may not be update on child which will cause database to grow unessential
- If we have too many of such collection objects then serialized transaction size could be huge so performance could be worst
Adding child as Separate State Object
PROS
=====
- Child data is not replicated with each time a new parent state is updated
- When there is an update on any of the Child data only that state needs to be communicated other participant
CONS
=====
- More coding needed in order to manage child state object separately
- Child data won't be available when querying parent from vault
- Each state needs to have its own contract so child objects can't be validated on the same parent contract
Since states are linked to persisting to a single table on the backend, it is difficult to manage child collections. At present, I think you would need to leave the collection property unbound (i.e. not mapped to a database column and marked as transient so that the class can still be serializable) and then do a separate filtered query for the child records that can be assigned to the collection property of the state. Then when any change is persisted, it will not try to persist the child records. Changes to child records should be done individually through their own state transactions. It would be nice if Corda had a feature that would support the JPA feature of doing joins between tables such as #OneToMany. This would facilitate queries, but persisting state changes would still need to be handled separately. There may be a way of doing this that I am unaware of.
It's an old question, but there does not seem to be an accepted answer, so I'll have a go.
Firstly, the Corda node is not just a back-end for your application, it's a node in a decentralised transaction processing system. The latter must be key requirement for you, otherwise you wouldn't use Corda.
Secondly, Corda implements UTXO (Unspent Transaction Output) paradigm for evolving distributed state through a series of transaction whereby a collection of objects representing input states are 'spent' (or consumed, become unavailable) and replaced by another collection of objects representing output states. The state objects themselves may have complex structures, but when they evolve they meant to be swapped as a whole. That is unlike, say, Ethereum or Hyperledger, where the global state is basically a large collection of unrelated key-value pairs that can change arbitrarily. UTXO model allows to easily implement features that are very hard to achieve with the global state model, such as transaction privacy. Important point here is that Corda can be made to emulate global state model, but it will be inefficient at it and lose most of its benefits.
Because of this, the way states are modelled must be based on the intended evolution of the distributed state of a CorDapp. The questions to ask yourself therefore are probably the following:
Will the child states 'live their own life', i.e. evolve
independently from the parent states? An example of a 'yes' would be
Corda Token SDK, whereby token type and tokens themselves are
separate states despite obvious parent-child relationship. Network
participants can trade the child states without controlling the
parent state.
Will there be a need to withhold the information in
a parent state but not the child, or vice versa from a party
participating in a transaction? An example of a 'yes' would be the
use of Oracle to sign off a child state object output without being
shown the parent. Corda IRS example does something similar with
transaction tear-offs when the Oracle fixes the interest rate.
Will there be a situation whereby a network participant may need to
know (i.e. keep in the vault) the child state, but not the parent
state. An example of a 'yes' would be an off-ledger settlement
workflow similar to the Corda Settler example, whereby paying agents
can be settling obligations without necessarily knowing the details
of the agreements that led to the obligations to arise.
If the answer to any of the above questions is 'yes', then you have to represent the children as separate states, otherwise it is better to leave them embedded into the parent state.