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:
The provided transaction is invalid
Any of the required signing parties cannot be found in the ServiceHub.networkMapCache
of the initiator
If the wrong key has been used by a counterparty to sign the transaction
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))
class CollectSignaturesFlow
,
WireTransaction.requiredSigningKeys
,
class SignedTransaction
,
class FinalityFlow
,
class SignTransactionFlow
,
ServiceHub.keyManagementService
,
class CollectSignaturesFlow
,
subFlow
,
class SignedTransaction
,
ServiceHub.networkMapCache
,
class SignedTransaction
,
class FinalityFlow
@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:
The provided transaction is invalid
Any of the required signing parties cannot be found in the ServiceHub.networkMapCache
of the initiator
If the wrong key has been used by a counterparty to sign the transaction
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))
partiallySignedTx
- Transaction to collect the remaining signatures forsessionsToCollectFrom
- 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.
class CollectSignaturesFlow
,
WireTransaction.requiredSigningKeys
,
class SignedTransaction
,
class FinalityFlow
,
class SignTransactionFlow
,
ServiceHub.keyManagementService
,
class CollectSignaturesFlow
,
subFlow
,
class SignedTransaction
,
ServiceHub.networkMapCache
,
class SignedTransaction
,
class FinalityFlow
@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:
The provided transaction is invalid
Any of the required signing parties cannot be found in the ServiceHub.networkMapCache
of the initiator
If the wrong key has been used by a counterparty to sign the transaction
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))
partiallySignedTx
- Transaction to collect the remaining signatures forsessionsToCollectFrom
- 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.class CollectSignaturesFlow
,
WireTransaction.requiredSigningKeys
,
class SignedTransaction
,
class FinalityFlow
,
class SignTransactionFlow
,
ServiceHub.keyManagementService
,
class CollectSignaturesFlow
,
subFlow
,
class SignedTransaction
,
ServiceHub.networkMapCache
,
class SignedTransaction
,
class FinalityFlow
@JvmOverloads public CollectSignaturesFlow(@NotNull SignedTransaction partiallySignedTx, @NotNull java.util.Collection<? extends net.corda.core.flows.FlowSession> sessionsToCollectFrom, @NotNull ProgressTracker progressTracker)
@JvmOverloads public CollectSignaturesFlow(@NotNull SignedTransaction partiallySignedTx, @NotNull java.util.Collection<? extends net.corda.core.flows.FlowSession> sessionsToCollectFrom)
@Suspendable @NotNull public SignedTransaction call()
This is where you fill out your business logic.
@NotNull public SignedTransaction getPartiallySignedTx()
Transaction to collect the remaining signatures for
@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.
@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.
@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.
class ProgressTracker
@JvmStatic @NotNull public static ProgressTracker tracker()