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

net.corda.core.flows

## Class CollectSignaturesFlow

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

-     public class CollectSignaturesFlow
      extends FlowLogic<T>

  The `class CollectSignaturesFlow` is used to automate the collection of counterparty signatures for a given transaction.

  You would typically use this flow after you have built a transaction with the TransactionBuilder and signed it with your key pair. If there are additional signatures to collect then they can be collected using this flow. Signatures are collected based upon the `WireTransaction.requiredSigningKeys` property which contains the union of all the PublicKeys listed in the transaction's commands as well as a notary's public key, if required. This flow returns a `class SignedTransaction` which can then be passed to the `class FinalityFlow` for notarisation. The other side of this flow is the `class SignTransactionFlow`.

  WARNING: This flow ONLY works with ServiceHub.legalIdentityKeys and WILL break if used with randomly generated keys by the `ServiceHub.keyManagementService`.

  Usage:

  - Call the `class CollectSignaturesFlow` flow as a `subFlow` and pass it a `class SignedTransaction` which has at least been signed by the transaction creator (and possibly an oracle, if required)

  - The flow expects that the calling node has signed the provided transaction, if not the flow will fail

  - The flow will also fail if:

  1. The provided transaction is invalid

  2. Any of the required signing parties cannot be found in the `ServiceHub.networkMapCache` of the initiator

  3. If the wrong key has been used by a counterparty to sign the transaction

  4. The counterparty rejects the provided transaction

  - The flow will return a `class SignedTransaction` with all the counterparty signatures (but not the notary's!)

  - If the provided transaction has already been signed by all counterparties then this flow simply returns the provided transaction without contacting any counterparties

  - Call the `class FinalityFlow` with the return value of this flow

  Example - issuing a multi-lateral agreement which requires N signatures:

  `

          val builder = TransactionBuilder(notaryRef)
          val issueCommand = Command(Agreement.Commands.Issue(), state.participants)

          builder.withItems(state, issueCommand)
          builder.toWireTransaction().toLedgerTransaction(serviceHub).verify()

          // Transaction creator signs transaction.
          val ptx = serviceHub.signInitialTransaction(builder)

          // Call to CollectSignaturesFlow.
          // The returned signed transaction will have all signatures appended apart from the notary's.
          val stx = subFlow(CollectSignaturesFlow(ptx))

  `
  See Also:
    `class CollectSignaturesFlow`, `WireTransaction.requiredSigningKeys`, `class SignedTransaction`, `class FinalityFlow`, `class SignTransactionFlow`, `ServiceHub.keyManagementService`, `class CollectSignaturesFlow`, `subFlow`, `class SignedTransaction`, `ServiceHub.networkMapCache`, `class SignedTransaction`, `class FinalityFlow`

- - ### Field Detail

    - #### Companion

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

  - ### Constructor Detail

    - #### CollectSignaturesFlow

          @JvmOverloads
          public CollectSignaturesFlow(@NotNull
                                                     SignedTransaction partiallySignedTx,
                                                     @NotNull
                                                     java.util.Collection<? extends net.corda.core.flows.FlowSession> sessionsToCollectFrom,
                                                     @Nullable
                                                     java.lang.Iterable<? extends java.security.PublicKey> myOptionalKeys,
                                                     @NotNull
                                                     ProgressTracker progressTracker)

      The `class CollectSignaturesFlow` is used to automate the collection of counterparty signatures for a given transaction.

      You would typically use this flow after you have built a transaction with the TransactionBuilder and signed it with your key pair. If there are additional signatures to collect then they can be collected using this flow. Signatures are collected based upon the `WireTransaction.requiredSigningKeys` property which contains the union of all the PublicKeys listed in the transaction's commands as well as a notary's public key, if required. This flow returns a `class SignedTransaction` which can then be passed to the `class FinalityFlow` for notarisation. The other side of this flow is the `class SignTransactionFlow`.

      WARNING: This flow ONLY works with ServiceHub.legalIdentityKeys and WILL break if used with randomly generated keys by the `ServiceHub.keyManagementService`.

      Usage:

      - Call the `class CollectSignaturesFlow` flow as a `subFlow` and pass it a `class SignedTransaction` which has at least been signed by the transaction creator (and possibly an oracle, if required)

      - The flow expects that the calling node has signed the provided transaction, if not the flow will fail

      - The flow will also fail if:

      1. The provided transaction is invalid

      2. Any of the required signing parties cannot be found in the `ServiceHub.networkMapCache` of the initiator

      3. If the wrong key has been used by a counterparty to sign the transaction

      4. The counterparty rejects the provided transaction

      - The flow will return a `class SignedTransaction` with all the counterparty signatures (but not the notary's!)

      - If the provided transaction has already been signed by all counterparties then this flow simply returns the provided transaction without contacting any counterparties

      - Call the `class FinalityFlow` with the return value of this flow

      Example - issuing a multi-lateral agreement which requires N signatures:

      `

              val builder = TransactionBuilder(notaryRef)
              val issueCommand = Command(Agreement.Commands.Issue(), state.participants)

              builder.withItems(state, issueCommand)
              builder.toWireTransaction().toLedgerTransaction(serviceHub).verify()

              // Transaction creator signs transaction.
              val ptx = serviceHub.signInitialTransaction(builder)

              // Call to CollectSignaturesFlow.
              // The returned signed transaction will have all signatures appended apart from the notary's.
              val stx = subFlow(CollectSignaturesFlow(ptx))

      `
      Parameters:
        `partiallySignedTx` - Transaction to collect the remaining signatures for
        `sessionsToCollectFrom` - A session for every party we need to collect a signature from. Must be an exact match.
        `myOptionalKeys` - set of keys in the transaction which are owned by this node. This includes keys used on commands, notjust in the states. If null, the default well known identity of the node is used.
        `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 CollectSignaturesFlow`, `WireTransaction.requiredSigningKeys`, `class SignedTransaction`, `class FinalityFlow`, `class SignTransactionFlow`, `ServiceHub.keyManagementService`, `class CollectSignaturesFlow`, `subFlow`, `class SignedTransaction`, `ServiceHub.networkMapCache`, `class SignedTransaction`, `class FinalityFlow`

    - #### CollectSignaturesFlow

          @JvmOverloads
          public CollectSignaturesFlow(@NotNull
                                                     SignedTransaction partiallySignedTx,
                                                     @NotNull
                                                     java.util.Collection<? extends net.corda.core.flows.FlowSession> sessionsToCollectFrom,
                                                     @Nullable
                                                     java.lang.Iterable<? extends java.security.PublicKey> myOptionalKeys)

      The `class CollectSignaturesFlow` is used to automate the collection of counterparty signatures for a given transaction.

      You would typically use this flow after you have built a transaction with the TransactionBuilder and signed it with your key pair. If there are additional signatures to collect then they can be collected using this flow. Signatures are collected based upon the `WireTransaction.requiredSigningKeys` property which contains the union of all the PublicKeys listed in the transaction's commands as well as a notary's public key, if required. This flow returns a `class SignedTransaction` which can then be passed to the `class FinalityFlow` for notarisation. The other side of this flow is the `class SignTransactionFlow`.

      WARNING: This flow ONLY works with ServiceHub.legalIdentityKeys and WILL break if used with randomly generated keys by the `ServiceHub.keyManagementService`.

      Usage:

      - Call the `class CollectSignaturesFlow` flow as a `subFlow` and pass it a `class SignedTransaction` which has at least been signed by the transaction creator (and possibly an oracle, if required)

      - The flow expects that the calling node has signed the provided transaction, if not the flow will fail

      - The flow will also fail if:

      1. The provided transaction is invalid

      2. Any of the required signing parties cannot be found in the `ServiceHub.networkMapCache` of the initiator

      3. If the wrong key has been used by a counterparty to sign the transaction

      4. The counterparty rejects the provided transaction

      - The flow will return a `class SignedTransaction` with all the counterparty signatures (but not the notary's!)

      - If the provided transaction has already been signed by all counterparties then this flow simply returns the provided transaction without contacting any counterparties

      - Call the `class FinalityFlow` with the return value of this flow

      Example - issuing a multi-lateral agreement which requires N signatures:

      `

              val builder = TransactionBuilder(notaryRef)
              val issueCommand = Command(Agreement.Commands.Issue(), state.participants)

              builder.withItems(state, issueCommand)
              builder.toWireTransaction().toLedgerTransaction(serviceHub).verify()

              // Transaction creator signs transaction.
              val ptx = serviceHub.signInitialTransaction(builder)

              // Call to CollectSignaturesFlow.
              // The returned signed transaction will have all signatures appended apart from the notary's.
              val stx = subFlow(CollectSignaturesFlow(ptx))

      `
      Parameters:
        `partiallySignedTx` - Transaction to collect the remaining signatures for
        `sessionsToCollectFrom` - A session for every party we need to collect a signature from. Must be an exact match.
        `myOptionalKeys` - set of keys in the transaction which are owned by this node. This includes keys used on commands, notjust in the states. If null, the default well known identity of the node is used.
      See Also:
        `class CollectSignaturesFlow`, `WireTransaction.requiredSigningKeys`, `class SignedTransaction`, `class FinalityFlow`, `class SignTransactionFlow`, `ServiceHub.keyManagementService`, `class CollectSignaturesFlow`, `subFlow`, `class SignedTransaction`, `ServiceHub.networkMapCache`, `class SignedTransaction`, `class FinalityFlow`

    - #### CollectSignaturesFlow

          @JvmOverloads
          public CollectSignaturesFlow(@NotNull
                                                     SignedTransaction partiallySignedTx,
                                                     @NotNull
                                                     java.util.Collection<? extends net.corda.core.flows.FlowSession> sessionsToCollectFrom,
                                                     @NotNull
                                                     ProgressTracker progressTracker)

    - #### CollectSignaturesFlow

          @JvmOverloads
          public CollectSignaturesFlow(@NotNull
                                                     SignedTransaction partiallySignedTx,
                                                     @NotNull
                                                     java.util.Collection<? extends net.corda.core.flows.FlowSession> sessionsToCollectFrom)

  - ### Method Detail

    - #### call

          @Suspendable
           @NotNull
          public SignedTransaction call()

      This is where you fill out your business logic.

    - #### getPartiallySignedTx

          @NotNull
          public SignedTransaction getPartiallySignedTx()

      Transaction to collect the remaining signatures for

    - #### getSessionsToCollectFrom

          @NotNull
          public java.util.Collection<net.corda.core.flows.FlowSession> getSessionsToCollectFrom()

      A session for every party we need to collect a signature from.

      Must be an exact match.

    - #### getMyOptionalKeys

          @Nullable
          public java.lang.Iterable<java.security.PublicKey> getMyOptionalKeys()

      set of keys in the transaction which are owned by this node.

      This includes keys used on commands, notjust in the states. If null, the default well known identity of the node is used.

    - #### 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()