R3 Corda中如何在Flow内触发其他节点运行指定Flow并复用其输出
解决方案实现步骤
1. 定义审批结果实体与审批Flow
首先需要创建可序列化的审批结果类,用于节点间传输审批状态;同时实现审批方的响应逻辑,处理发起方的审批请求并返回结果。
// 审批结果实体,需实现Serializable接口以支持节点间传输 public class ApprovalResult implements Serializable { private boolean approved; private String approvalId; public ApprovalResult(boolean approved, String approvalId) { this.approved = approved; this.approvalId = approvalId; } public boolean isApproved() { return approved; } public String getApprovalId() { return approvalId; } }
2. 修改发起方的IssuanceInitiator Flow
在原发起流程中新增审批交互步骤,先触发审批方的逻辑、获取审批结果,只有审批通过后才继续后续交易构建:
@InitiatingFlow @StartableByRPC public static class IssuanceInitiator extends FlowLogic<SignedTransaction> { private Amount<Currency> amount; public IssuanceInitiator(Amount<Currency> amount) { this.amount = amount; } // 新增审批相关进度步骤 private final ProgressTracker.Step REQUEST_APPROVAL = new ProgressTracker.Step("向审批方发起请求"); private final ProgressTracker.Step WAIT_APPROVAL = new ProgressTracker.Step("等待审批结果"); private final ProgressTracker.Step GENERATE_TRX = new ProgressTracker.Step("生成交易"); private final ProgressTracker.Step VERIFY_TRX = new ProgressTracker.Step("验证交易"); private final ProgressTracker.Step SIGN_TRX = new ProgressTracker.Step("签署交易"); private final ProgressTracker.Step GATHER_SIGN = new ProgressTracker.Step("收集其他签署方签名") { @Override public ProgressTracker childProgressTracker() { return CollectSignaturesFlow.Companion.tracker(); } }; private final ProgressTracker.Step FINALIZE_TRX = new ProgressTracker.Step("公证并记录交易") { @Override public ProgressTracker childProgressTracker() { return FinalityFlow.Companion.tracker(); } }; public ProgressTracker progressTracker = new ProgressTracker( REQUEST_APPROVAL, WAIT_APPROVAL, GENERATE_TRX, VERIFY_TRX, SIGN_TRX, GATHER_SIGN, FINALIZE_TRX ); @Override public ProgressTracker getProgressTracker() { return progressTracker; } @Suspendable @Override public SignedTransaction call() throws FlowException { final Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0); Party approver = getServiceHub().getNetworkMapCache().getPeerByLegalName(CordaX500Name.parse("O=Approver,L=Jakarta,C=ID")); // 触发审批方流程并获取结果 progressTracker.setCurrentStep(REQUEST_APPROVAL); FlowSession approverSession = initiateFlow(approver); approverSession.send(amount); // 发送发行金额给审批方 progressTracker.setCurrentStep(WAIT_APPROVAL); ApprovalResult approvalResult = approverSession.receive(ApprovalResult.class).unwrap(data -> data); // 审批不通过则终止流程 if (!approvalResult.isApproved()) { throw new FlowException("发行请求未通过审批,审批ID:" + approvalResult.getApprovalId()); } // 构建包含审批信息的输出状态(需提前修改IssuanceState类,新增approvalId字段) progressTracker.setCurrentStep(GENERATE_TRX); UniqueIdentifier linearID = new UniqueIdentifier(); Date issuanceDate = new Date(); IssuanceState newIssuance = new IssuanceState(linearID, this.amount, this.getOurIdentity(), approver, issuanceDate, approvalResult.getApprovalId()); // 后续交易构建、验证、签名流程保持原有逻辑 TransactionBuilder transactionBuilder = new TransactionBuilder(notary) .addOutputState(newIssuance) .addCommand(new IssuanceContract.Commands.Issue(), Arrays.asList(getOurIdentity().getOwningKey(), approver.getOwningKey())); progressTracker.setCurrentStep(VERIFY_TRX); transactionBuilder.verify(getServiceHub()); progressTracker.setCurrentStep(SIGN_TRX); final SignedTransaction partiallySign = getServiceHub().signInitialTransaction(transactionBuilder); progressTracker.setCurrentStep(GATHER_SIGN); final SignedTransaction fullySign = subFlow(new CollectSignaturesFlow(partiallySign, Arrays.asList(approverSession))); progressTracker.setCurrentStep(FINALIZE_TRX); final SignedTransaction finalityFlow = subFlow(new FinalityFlow(fullySign, Arrays.asList(approverSession))); return finalityFlow; } }
3. 调整审批方的IssuanceResponder Flow
将审批逻辑与签名逻辑合并到同一个响应Flow中,先处理审批请求,再完成交易签名与最终化:
@InitiatedBy(IssuanceFlow.IssuanceInitiator.class) public static class IssuanceResponder extends FlowLogic<Void> { private FlowSession otherPartySession; public IssuanceResponder(FlowSession otherPartySession) { this.otherPartySession = otherPartySession; } @Override @Suspendable public Void call() throws FlowException { // 第一步:处理审批请求 Amount<Currency> requestAmount = otherPartySession.receive(Amount.class).unwrap(data -> data); // 此处替换为真实业务审批逻辑,示例默认通过 boolean isApproved = true; String approvalId = UUID.randomUUID().toString(); otherPartySession.send(new ApprovalResult(isApproved, approvalId)); // 第二步:处理交易签名与最终化 SignedTransaction signedTransaction = subFlow(new SignTransactionFlow(otherPartySession) { @Override @Suspendable protected void checkTransaction(@NotNull SignedTransaction stx) throws FlowException { // 验证交易中的审批ID与本地生成的一致 IssuanceState issuanceState = stx.getTx().getOutputsOfType(IssuanceState.class).get(0); if (!issuanceState.getApprovalId().equals(approvalId)) { throw new FlowException("交易审批ID与记录不符"); } } }); subFlow(new ReceiveFinalityFlow(otherPartySession, signedTransaction.getId())); return null; } }
关键注意事项
- 需确保
IssuanceState类新增approvalId字段,并同步更新对应的Contract验证逻辑,确保交易包含合法的审批信息。 - 审批逻辑可根据业务需求扩展,例如查询审批方本地数据、调用外部审批接口等。
内容的提问来源于stack exchange,提问作者bagassprtm
相关产品推荐
相关产品推荐

