SignTransactionFlow
Keywords: net.corda.core.flows.SignTransactionFlow class
Date: 2023-09-18

net.corda.core.flows

## Class SignTransactionFlow

- net.corda.core.flows.FlowLogic<T>
- - net.corda.core.flows.SignTransactionFlow

-     public class SignTransactionFlow
      extends FlowLogic<T>

  The `class SignTransactionFlow` should be called in response to the `class CollectSignaturesFlow`. It automates the signing of a transaction providing the transaction:

  1. Should actually be signed by the `class Party` invoking this flow

  2. Is valid as per the contracts referenced in the transaction

  3. Has been, at least, signed by the counterparty which created it

  4. Conforms to custom checking provided in the `checkTransaction` method of the `class SignTransactionFlow`

  Usage:

  - Subclass `class SignTransactionFlow` - this can be done inside an existing flow (as shown below)

  - Override the `checkTransaction` method to add some custom verification logic

  - Call the flow via `FlowLogic.subFlow`

  - The flow returns the transaction signed with the additional signature.

  Example - checking and signing a transaction involving a net.corda.core.contracts.DummyContract, see CollectSignaturesFlowTests.kt for further examples:

  `

          class Responder(val otherPartySession: FlowSession): FlowLogic() {
               @Suspendable override fun call(): SignedTransaction {
                   // [SignTransactionFlow] sub-classed as a singleton object.
                   val flow = object : SignTransactionFlow(otherPartySession) {
                       @Suspendable override fun checkTransaction(stx: SignedTransaction) = requireThat {
                           val tx = stx.tx
                           val magicNumberState = tx.outputs.single().data as DummyContract.MultiOwnerState
                           "Must be 1337 or greater" using (magicNumberState.magicNumber >= 1337)
                       }
                   }

                   // Invoke the subFlow, in response to the counterparty calling [CollectSignaturesFlow].
                   val expectedTxId = subFlow(flow).id

                   return subFlow(ReceiveFinalityFlow(otherPartySession, expectedTxId))
               }
           }

  `
  See Also:
    `class SignTransactionFlow`, `class CollectSignaturesFlow`, `class Party`, `checkTransaction`, `class SignTransactionFlow`, `class SignTransactionFlow`, `checkTransaction`, `FlowLogic.subFlow`, net.corda.core.contracts.DummyContract

- - ### Field Detail

    - #### Companion

          public static net.corda.core.flows.SignTransactionFlow.Companion Companion

  - ### Constructor Detail

    - #### SignTransactionFlow

          @JvmOverloads
          public SignTransactionFlow(@NotNull
                                                   FlowSession otherSideSession,
                                                   @NotNull
                                                   ProgressTracker progressTracker)

      The `class SignTransactionFlow` should be called in response to the `class CollectSignaturesFlow`. It automates the signing of a transaction providing the transaction:

      1. Should actually be signed by the `class Party` invoking this flow

      2. Is valid as per the contracts referenced in the transaction

      3. Has been, at least, signed by the counterparty which created it

      4. Conforms to custom checking provided in the `checkTransaction` method of the `class SignTransactionFlow`

      Usage:

      - Subclass `class SignTransactionFlow` - this can be done inside an existing flow (as shown below)

      - Override the `checkTransaction` method to add some custom verification logic

      - Call the flow via `FlowLogic.subFlow`

      - The flow returns the transaction signed with the additional signature.

      Example - checking and signing a transaction involving a net.corda.core.contracts.DummyContract, see CollectSignaturesFlowTests.kt for further examples:

      `

              class Responder(val otherPartySession: FlowSession): FlowLogic() {
                   @Suspendable override fun call(): SignedTransaction {
                       // [SignTransactionFlow] sub-classed as a singleton object.
                       val flow = object : SignTransactionFlow(otherPartySession) {
                           @Suspendable override fun checkTransaction(stx: SignedTransaction) = requireThat {
                               val tx = stx.tx
                               val magicNumberState = tx.outputs.single().data as DummyContract.MultiOwnerState
                               "Must be 1337 or greater" using (magicNumberState.magicNumber >= 1337)
                           }
                       }

                       // Invoke the subFlow, in response to the counterparty calling [CollectSignaturesFlow].
                       val expectedTxId = subFlow(flow).id

                       return subFlow(ReceiveFinalityFlow(otherPartySession, expectedTxId))
                   }
               }

      `
      Parameters:
        `otherSideSession` - The session which is providing you a transaction to sign.
        `progressTracker` -

        Override this to provide a `class ProgressTracker`. If one is provided and stepped, the framework will do something helpful with the progress reports e.g record to the audit service. If this flow is invoked as a subflow of another, then the tracker will be made a child of the current step in the parent. If it's null, this flow doesn't track progress.

        Note that this has to return a tracker before the flow is invoked. You can't change your mind half way through.

      See Also:
        `class SignTransactionFlow`, `class CollectSignaturesFlow`, `class Party`, `checkTransaction`, `class SignTransactionFlow`, `class SignTransactionFlow`, `checkTransaction`, `FlowLogic.subFlow`, net.corda.core.contracts.DummyContract

    - #### SignTransactionFlow

          @JvmOverloads
          public SignTransactionFlow(@NotNull
                                                   FlowSession otherSideSession)

      The `class SignTransactionFlow` should be called in response to the `class CollectSignaturesFlow`. It automates the signing of a transaction providing the transaction:

      1. Should actually be signed by the `class Party` invoking this flow

      2. Is valid as per the contracts referenced in the transaction

      3. Has been, at least, signed by the counterparty which created it

      4. Conforms to custom checking provided in the `checkTransaction` method of the `class SignTransactionFlow`

      Usage:

      - Subclass `class SignTransactionFlow` - this can be done inside an existing flow (as shown below)

      - Override the `checkTransaction` method to add some custom verification logic

      - Call the flow via `FlowLogic.subFlow`

      - The flow returns the transaction signed with the additional signature.

      Example - checking and signing a transaction involving a net.corda.core.contracts.DummyContract, see CollectSignaturesFlowTests.kt for further examples:

      `

              class Responder(val otherPartySession: FlowSession): FlowLogic() {
                   @Suspendable override fun call(): SignedTransaction {
                       // [SignTransactionFlow] sub-classed as a singleton object.
                       val flow = object : SignTransactionFlow(otherPartySession) {
                           @Suspendable override fun checkTransaction(stx: SignedTransaction) = requireThat {
                               val tx = stx.tx
                               val magicNumberState = tx.outputs.single().data as DummyContract.MultiOwnerState
                               "Must be 1337 or greater" using (magicNumberState.magicNumber >= 1337)
                           }
                       }

                       // Invoke the subFlow, in response to the counterparty calling [CollectSignaturesFlow].
                       val expectedTxId = subFlow(flow).id

                       return subFlow(ReceiveFinalityFlow(otherPartySession, expectedTxId))
                   }
               }

      `
      Parameters:
        `otherSideSession` - The session which is providing you a transaction to sign.
      See Also:
        `class SignTransactionFlow`, `class CollectSignaturesFlow`, `class Party`, `checkTransaction`, `class SignTransactionFlow`, `class SignTransactionFlow`, `checkTransaction`, `FlowLogic.subFlow`, net.corda.core.contracts.DummyContract

  - ### Method Detail

    - #### call

          @Suspendable
           @NotNull
          public SignedTransaction call()

      This is where you fill out your business logic.

    - #### checkTransaction

          @Suspendable
          protected void checkTransaction(@NotNull
                                                       SignedTransaction stx)

      The `checkTransaction` method allows the caller of this flow to provide some additional checks over the proposed transaction received from the counterparty. For example:

      - Ensuring that the transaction you are receiving is the transaction you EXPECT to receive. I.e. is has the expected type and number of inputs and outputs

      - Checking that the properties of the outputs are as you would expect. Linking into any reference data sources might be appropriate here

      - Checking that the transaction is not incorrectly spending (perhaps maliciously) one of your asset states, as potentially the transaction creator has access to some of your state references

      WARNING: If appropriate checks, such as the ones listed above, are not defined then it is likely that your node will sign any transaction if it conforms to the contract code in the transaction's referenced contracts.

      IllegalArgumentException, IllegalStateException and AssertionError will be caught and rethrown as flow exceptions i.e. the other side will be given information about what exact check failed.

      Parameters:
        `stx` - a partially signed transaction received from your counterparty.
      Throws:
        `FlowException` - if the proposed transaction fails the checks.
      See Also:
        `checkTransaction`, IllegalArgumentException, IllegalStateException, AssertionError

    - #### getOtherSideSession

          @NotNull
          public FlowSession getOtherSideSession()

      The session which is providing you a transaction to sign.

    - #### getProgressTracker

          @NotNull
          public ProgressTracker getProgressTracker()

      Override this to provide a `class ProgressTracker`. If one is provided and stepped, the framework will do something helpful with the progress reports e.g record to the audit service. If this flow is invoked as a subflow of another, then the tracker will be made a child of the current step in the parent. If it's null, this flow doesn't track progress.

      Note that this has to return a tracker before the flow is invoked. You can't change your mind half way through.

      See Also:
        `class ProgressTracker`

    - #### tracker

          @JvmStatic
           @NotNull
          public static ProgressTracker tracker()