Mauro
Mauro

Reputation: 69

Is there a way to add a spending to a transaction received?

I would like to represent in a single transaction two payments, one from party A (the first to create the transaction) and one from party B (the one supposed to receive the transaction). I've already tried by passing a TransactionBuilder object through a session between A and B but the object is not serializable. How can I do it?

Upvotes: 0

Views: 76

Answers (1)

Joel
Joel

Reputation: 23140

Option 1 - Marking the TransactionBuilder as serialisable

By default, the only objects that can be sent between nodes as part of flows are instances of classes listed in the DefaultWhitelist (https://github.com/corda/corda/blob/release-V2/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/DefaultWhitelist.kt).

You can whitelist additional types for sending between nodes as part of flows as follows:

  • Create your own serialization whitelist which adds TransactionBuilder to the whitelist:

    class TemplateSerializationWhitelist : SerializationWhitelist {
        override val whitelist = listOf(TransactionBuilder::class.java)
    }
    
  • Register the additional whitelist on your node by adding its fully-qualified class name to the src/main/resources/META-INF/services/net.corda.core.serialization.SerializationWhitelist file

N.B.: For classes you've defined yourself, you can achieve the same thing by annotating them as @CordaSerializable instead.

Option 2 - Sending all the transaction components to a single coordinating party

Suppose you want Alice to be the party coordinating the building of the transaction. You might write the following flow pair:

@InitiatingFlow
@StartableByRPC
class AliceFlow(val bob: Party) : FlowLogic<Unit>() {
    @Suspendable
    override fun call() {
        val alicesOutputState = MyState()

        val sessionWithBob = initiateFlow(bob)
        val dataFromBob = sessionWithBob.receive<MyState>()
        val bobsOutputState = dataFromBob.unwrap { it -> it }

        val txBuilder = TransactionBuilder(serviceHub.networkMapCache.notaryIdentities.first())
        txBuilder.addOutputState(alicesOutputState, MyContract.ID)
        txBuilder.addOutputState(bobsOutputState, MyContract.ID)

        ...
    }
}

And:

@InitiatedBy(AliceFlow::class)
class BobFlow(val sessionWithAlice: FlowSession) : FlowLogic<Unit>() {
    @Suspendable
    override fun call() {
        val bobsOutputState = MyState()
        sessionWithAlice.send(bobsOutputState)

        ...
    }
}

Upvotes: 1

Related Questions