当然。我在这方面写了一大堆东西,我可以粘贴在这里!
构建 CorDapps
CorDapps 可以分为共享和私有元素:
共享 CorDapp 元素
通常,CorDapp 的共享元素包括:
- 组成状态对象或用作在流之间发送数据的有效负载的数据结构和自定义类型
- 状态和合约定义必须可供所有节点使用,这些节点可能必须验证包含一个或多个 CorDapp 状态对象的交易
- 抽象流定义用于定义流的通用表示,同时隐藏它的实际实现(可以是私有的)。这是因为 InitiatedBy 流注释需要类路径上相应 InitatingFlow 的 FlowLogic 子类型,因此可以注册流启动器
- 使用节点服务的共享实用程序函数通常从流中使用并采用 ServiceHub 参数 - 通常这样做比编写另一个流或通过重复相同的方法来扰乱现有流更有意义
- 在需要简单工作流程的情况下,通常需要共享流程,该工作流程不需要任何自定义,并且将由运行 CorDapp 的所有各方执行
通常建议保持共享 CorDapp JAR 尽可能小,这是因为包含状态和合约定义的 JAR 在网络中传输,交易包含 JAR 中定义的类型的状态。交易的下游验证者可能需要验证包含他们不进行交易的状态的交易,因此他们不需要其类路径上的流。因此,将状态和契约定义(以及任何依赖项)与其他所有内容分开打包是有意义的。
私有 CorDapp 元素
corDapp 的私有元素通常包括:
- 定制流程实施
- Corda服务
- 上述所需的任何类型定义
如上所述,CorDapp 开发人员可以共享其流程的抽象表示并保持实现的私有性。流程框架允许各方实现自己的流程,前提是它们符合通用接口,即,双方InitiatingFlow
和InitiatedBy
流在流中的预期点发送和接收相同的类型。
只要流程做到了这一点,其余的实现就可以定制。例如,自定义、私有实现可能会触及内部系统或使用专有类型,因此,它们不应与 CorDapp 的共享元素打包在一起。
流程版本控制
除了平台的发展之外,在平台之上运行的流程也可以发展。您想要启动其他流的任何流都必须使用@InitiatingFlow
注解,其定义为:
annotation class InitiatingFlow(val version: Int = 1)
请注意,可选的 version 属性(默认为 1)用于指定流的版本。目前,该整数值纯粹是为了指导开发人员而存在的,只要发布的流程具有与先前版本不向后兼容的更改,就应该增加该整数值。非向后兼容的更改是更改流接口的更改。
目前,处理流程版本控制的工作留给了 CorDapp 开发人员。不过,未来该平台将执行规定的规则。
一组流的接口是什么?
流接口定义了 InitiatingFlow 和 InitiatedBy 流之间的发送和接收序列以及发送和接收的类型。最好用序列图来说明:
在上图中,InitiatingFlow:
- 发送一个 Int
- 接收一个字符串
- 发送一个字符串
- 接收自定义类型
InitiatedBy 流程则执行相反的操作:
- 收到一个 Int
- 发送一个字符串
- 接收一个字符串
- 发送自定义类型
提供两个IntiatingFlow
和InitiatedBy
流程符合接口定义的顺序,其余流程可以以任何方式实现,并且可以包括不与其他方共享的专有业务逻辑。事实上,这是编写流程的预期方式。
有关如何实际执行此操作的示例,请查看此处:https://github.com/sollecitom/corda-foreign-exchange-example/blob/master/buyer-api/src/main/kotlin/net/corda/examples/fx/buyer/BuyCurrencyFlowDefinitions.kt https://github.com/sollecitom/corda-foreign-exchange-example/blob/master/buyer-api/src/main/kotlin/net/corda/examples/fx/buyer/BuyCurrencyFlowDefinitions.kt
这是由一位 Corda 开发人员编写的,在上面的文件中,有一个抽象流定义,其中有一个只有买方知道的私有实现。