As Cais says, the limitation of using tear-offs to hide part of a transaction from a counterparty is that the counterparty will probably be unwilling to sign the transaction because they can't tell exactly what they're signing over. What if one of the torn-off inputs is cash belonging to them and being transferred to someone else?
However, with any torn-off transaction, you at least have the ability to check whether or not all of the components of a certain group (inputs, outputs, commands, attachments...) have been torn off. You can use this to, for example, check that no inputs have been torn off the transaction before signing:
@InitiatingFlow
@StartableByRPC
class Initiator(val counterparty: Party) : FlowLogic<Unit>() {
@Suspendable
override fun call() {
val notary = serviceHub.networkMapCache.notaryIdentities[0]
val txBuilder = TransactionBuilder(notary)
.addOutputState(TemplateState(), TemplateContract.ID)
.addCommand(TemplateContract.Commands.Action(), ourIdentity.owningKey)
val partlySignedTx = serviceHub.signInitialTransaction(txBuilder)
// We filter out the outputs, which are of type `TransactionState<ContractState>`.
val filteredTx = partlySignedTx.buildFilteredTransaction(Predicate {
when (it) {
is TransactionState<ContractState> -> false
else -> true
}
})
val session = initiateFlow(counterparty)
val signature = session.sendAndReceive<TransactionSignature>(filteredTx).unwrap { it }
val fullySignedTx = partlySignedTx.withAdditionalSignature(signature)
subFlow(FinalityFlow(fullySignedTx))
}
}
@InitiatedBy(Initiator::class)
class Responder(val session: FlowSession) : FlowLogic<Unit>() {
@Suspendable
override fun call() {
val filteredTx = session.receive<FilteredTransaction>().unwrap { it }
// We check that all inputs are visible before accidentally signing something away.
filteredTx.checkAllComponentsVisible(ComponentGroupEnum.INPUTS_GROUP)
val signature = serviceHub.createSignature(filteredTx)
session.send(signature)
}
}
You are still not able to verify the transaction's smart contracts, but you can at least be sure that you are not consuming any of your own inputs by signing.
You can use this approach in different ways. For example, you can check that only attachments have been torn off, where the attachments may contain secret data that the counterparty is not allowed to see.