如何根据对手方分散FilteredTransaction

时间:2018-08-21 15:16:52

标签: corda

我对使用FilteredTransactions有一个可能不重要的问题;让我们看看我能否向您解释...

我有一个流程,它定义了更大流程中的最后一步;在此流程中,我必须构建一个事务,该事务要在其他状态(某些处于消耗状态,另一些状态已更改为所有者)之中,更改几个两方(预计会增加到三个)的列表中的特定方({1}} (发起流程的一方是被更改的一方;另一方是执行其他操作的一种监管者)。 麻烦的是,流中有多个LinearState,每个{@ 1}都有一个可能不同的另一方,而这些其他方都必须(显然)仅看到与它们相关的那些方。 LinearStates

为简化起见,您可以将其视为两方FilteredTransaction的集合,其中其中一个就像LinearState中的所有者,而您–所有者–必须更改所有权。 目前,我不确定所需的签名数量...我认为所有者应该足够,但不要认为这是理所当然的。

我的问题基本上是在代码方面寻求帮助(可能不拆分事务),因为在这方面,文档和代码文档(目前)都非常差(例如, IRS演示),而我发现的唯一另一个示例(在Slack上)使用的是OwnableStatesession的{​​{1}}(基于类型的过滤器) Send;虽然我需要基于特定属性的过滤器)和FilteredTransaction的{​​{1}};前者是没有用的,而后者似乎并没有吸引眼球,也没有效率,因为按顺序使用了几个(提前知道的数字)会话。 你有什么建议?

谢谢!

1 个答案:

答案 0 :(得分:0)

Let's use the following as a simple example of a state involving two parties (the logic is the same for more complex LinearStates):

data class TwoPartyState(val partyOne: Party, val partyTwo: Party) : ContractState {
    override val participants = listOf(partyOne, partyTwo)
}

Here is a flow that will filter the transaction to only send to each party the TwoPartyStates that are relevant to them:

@InitiatingFlow
@StartableByRPC
class ScatterFlow : FlowLogic<Unit>() {
    override fun call() {
        // TODO: Build the transaction.

        val signedTransaction = serviceHub.signInitialTransaction(transactionBuilder)

        // We create the flow sessions for all the parties we want to send data to.
        val outputs = signedTransaction.toLedgerTransaction(serviceHub).outputsOfType<TwoPartyState>()
        val parties = outputs.flatMap { it.participants }
        val sessions = mutableMapOf<Party, FlowSession>()
        parties.forEach {
            if ((it) !in sessions) sessions[it] = initiateFlow(it)
        }

        // For each session, we filter the transaction to only contain the relevant states.
        sessions.forEach { (party, session) ->
            val filteredTransaction = signedTransaction.buildFilteredTransaction(Predicate {
                when (it) {
                    is TransactionState<*> -> {
                        if (it.data !is TwoPartyState) false
                        else party in (it.data as TwoPartyState).participants
                    }
                    else -> false
                }
            })
            session.send(filteredTransaction)
        }
    }
}