Can either side of a Corda flow exist in separate Cordapps?

前端 未结 1 1004
挽巷
挽巷 2021-01-07 07:47

If a node wants to perform their own specific business logic within one side of a flow, how can this be implemented?

For example if a company wants to call an intern

相关标签:
1条回答
  • 2021-01-07 08:29

    Sure. I wrote a whole bunch of stuff on this I can paste here!

    Structuring CorDapps

    CorDapps can be split into shared and private elements:

    Shared CorDapp elements

    Typically, the shared elements of a CorDapp will include:

    • Data structures and custom types which are composed into state objects or used as payloads to send data between flows
    • State and contract definitions must be available to all nodes which may have to verify a transaction containing one or more of the CorDapp's state objects
    • Abstract flow definitions are used to define a common representation of a flow whilst hiding the actual implementation of it (which can be private). This is because InitiatedBy flow annotations require the FlowLogic sub-type for the corresponding InitatingFlow on the class path, so a flow initiator can be registered
    • Shared utility functions that use node services are typically used from flows and take a ServiceHub parameter - often it makes more sense to do to this than writing another flow or cluttering your existing flows with repetitions of the same method
    • Shared flows are often required in situations where a simple workflow is required that doesn't require any customisation and will be carried out by all parties running the CorDapp

    It is generally advisable to keep the shared CorDapp JARs as small as possible, this is because the JAR containing the state and contract definitions travels around the network with transactions containing states of the type defined in the JAR. Downstream verifiers of transactions may need to verify transactions containing states they do not transact with, so they don't need the flows on their class path. As such, it makes sense to package up the state and contract definitions (and any dependencies) separately to everything else.

    Private CorDapp elements

    Private elements of a corDapp usually comprise:

    • Bespoke flow implementations
    • Corda services
    • Any type definitions required for the above

    As mentioned above, CorDapp developers can share abstract representations of their flows and keep the implementation private. The flow framework allows parties to implement their own flows providing they conform to a common interface, this is, both the InitiatingFlow and the InitiatedBy flow send and receive the same types at the expected points in the flow.

    As long as the flows do this, the rest of the implementation can be customised. For example, custom, private implementations might reach out to internal systems or use proprietary types, and as such, they should not be packaged with the shared elements of the CorDapp.

    Flow versioning

    In addition to the evolution of the platform, flows that run on top of the platform can also evolve. Any flow from which you want to initiate other flows must be annotated with the @InitiatingFlow annotation, which is defined as:

    annotation class InitiatingFlow(val version: Int = 1)
    

    Note, the optional version property, which defaults to 1, to specify the version of the flow. This integer value, which for the moment, exists purely to guide developers, should be incremented whenever there is a release of a flow which has changes that are not backwards compatible with previous versions. A non-backwards compatible change is one that changes the interface of the flow.

    Currently, handling flow versioning is left to the CorDapp developers. However, in the future the platform will implement prescribed rules.

    What is the interface for a set of flows?

    The flow interface defines the sequence of sends and receives between an InitiatingFlow and an InitiatedBy flow as well as the types sent and received. It is best illustrated with a sequence diagram:

    In the diagram above, the InitiatingFlow:

    1. Sends an Int
    2. Receives a String
    3. Sends a String
    4. Receives a CustomType

    The InitiatedBy flow does the opposite:

    1. Receives an Int
    2. Sends a String
    3. Receives a String
    4. Sends a CustomType

    Providing both the IntiatingFlow and the InitiatedBy flows conform to the sequence defined by interface, the rest of the flows can be implemented in any way and can include proprietary business logic that is not shared with other parties. Indeed, this is the intended way to write flows.

    For a example of actually how one would go about doing this, please look here: https://github.com/sollecitom/corda-foreign-exchange-example/blob/master/buyer-api/src/main/kotlin/net/corda/examples/fx/buyer/BuyCurrencyFlowDefinitions.kt

    This was written by one of the Corda developers and in the file above, there is an abstract flow definition which has a private implementation known only to the buyer.

    0 讨论(0)
提交回复
热议问题