Corda:预定活动中StateRef的使用

时间:2018-11-03 20:00:03

标签: corda

在哪里提供构造函数输入作为错误消息状态?我不确定在安排活动时StateRef的正确用法。我成功运行了Heartbeat CorDapp,以测试基本用法。

ForwardState:

data class ForwardState(val initiator: Party, val acceptor: Party, val asset: String, val deliveryPrice: BigDecimal, val startDate: Instant, val settlementDate: Instant, val buySell: String) : SchedulableState {
    override val participants get() = listOf(initiator, acceptor)

    override fun nextScheduledActivity(thisStateRef: StateRef, flowLogicRefFactory: FlowLogicRefFactory): ScheduledActivity? {
        return ScheduledActivity(flowLogicRefFactory.create("com.template.ForwardSettleFlow"), settlementDate)
}

ForwardFlow:

@InitiatingFlow
@StartableByRPC
class ForwardFlow(val initiator: Party, val acceptor: Party, val asset: String, val deliveryPrice: BigDecimal,
              val startDate: Instant, val settlementDate: Instant, val buySell: String) : FlowLogic<Unit>() {

companion object {
    object GENERATING_TRANSACTION : ProgressTracker.Step("Generating transaction")
    object SIGNING_TRANSACTION : ProgressTracker.Step("Signing transaction with our private key")
    object FINALISING_TRANSACTION : ProgressTracker.Step("Recording transaction") {
        override fun childProgressTracker() = FinalityFlow.tracker()
    }

    fun tracker() = ProgressTracker(
            GENERATING_TRANSACTION,
            SIGNING_TRANSACTION,
            FINALISING_TRANSACTION
    )
}

override val progressTracker = tracker()

@Suspendable
override fun call() { 
    // Adapted from hello world pt 1/2
}
}

ForwardSettleFlow:

@InitiatingFlow
@SchedulableFlow
@StartableByRPC
class ForwardSettleFlow(val initiator: Party, val acceptor: Party, val asset: String, val deliveryPrice: BigDecimal,
                    val startDate: Instant, val settlementDate: Instant, val buySell: String,
                    val thisStateRef: StateRef) : FlowLogic<Unit>() {

// progress tracker redacted

@Suspendable
override fun call() {
    progressTracker.currentStep = GENERATING_TRANSACTION
    val input = serviceHub.toStateAndRef<ForwardState>(thisStateRef)
    val output = ForwardState(initiator, acceptor, asset, deliveryPrice, startDate, settlementDate, buySell)
    val beatCmd = Command(ForwardContract.Commands.Settle(), ourIdentity.owningKey)
    val txBuilder = TransactionBuilder(serviceHub.networkMapCache.notaryIdentities.first())
            .addInputState(input)
            .addOutputState(output, FORWARD_CONTRACT_ID)
            .addCommand(beatCmd)

    progressTracker.currentStep = SIGNING_TRANSACTION
    val signedTx = serviceHub.signInitialTransaction(txBuilder)

    progressTracker.currentStep = FINALISING_TRANSACTION
    subFlow(FinalityFlow(signedTx))
}
}
  1. ForwardFlow启动,并为双方签名提供Responder
  2. 计划的活动设置,以在通过ForwardSettleFlowResponder到达解决日期后作出响应。该流在类构造函数中接受thisStateRef。测试表明,忽略这一点对错误输出没有影响。这个过程有两个流程和两个响应者。

ForwardFlow期间,甲方的崩溃外壳在FINALISING_TRANSACTION期间冻结。

rx.exceptions.OnErrorNotImplementedException: A FlowLogicRef cannot be 
constructed for FlowLogic of type com.template.ForwardSettleFlow: due 
to missing constructor for arguments: [class 
net.corda.core.contracts.StateRef]

我相信这可以阻止这种活动的发生,包括在无条件的测试过程中合同为空的情况。

1 个答案:

答案 0 :(得分:1)

FlowLogicRefFactory.create()具有以下构造函数:

override fun create(flowClass: Class<out FlowLogic<*>>, vararg args: Any?): FlowLogicRef {

FlowLogicRefFactory.create()中调用ForwardState.nextScheduledActivity()时,您根本不会传递任何参数:

flowLogicRefFactory.create("com.template.ForwardSettleFlow")

但是没有ForwardSettleFlow构造函数采用零参数:

class ForwardSettleFlow(val initiator: Party, val acceptor: Party, val asset: String, 
    val deliveryPrice: BigDecimal, val startDate: Instant, val settlementDate: Instant, 
    val buySell: String, val thisStateRef: StateRef) : FlowLogic<Unit>() {

因此,您会收到“缺少构造函数”异常。您需要更新ForwardSettleFlow使其具有零参数构造函数,或者需要将一些参数传递给FlowLogicRefFactory.create()