Corda4.4启用Accounts后发起流报Amount反序列化错误如何解决
问题排查与修复方案
核心报错根因
你遇到的反序列化错误是流会话的消息发送顺序被打乱导致的:响应流等待接收Amount类型对象时,实际收到了后续签名流程的SignedTransaction对象,触发类型不匹配异常。该问题仅在启用Accounts后触发,和你的流逻辑中多会话管理、Accounts权限模型适配错误直接相关。
排查与修复步骤
1. 修复CollectSignaturesFlow的多余会话错误(最核心原因)
你发起流中的CollectSignaturesFlow传入了多余的会话对象:
// 错误写法:多了一个指向issuer节点自身的会话 SignedTransaction signedTransaction = subFlow(new CollectSignaturesFlow( selfSignedTransaction, ImmutableList.of(buyerSession, initiateFlow(issuerAccountInfo.getHost())), Collections.singleton(issuerAccountInfo.getHost().getOwningKey())));
issuerAccountInfo.getHost()就是当前发起流的节点本身,你已经在signInitialTransaction阶段用该节点的密钥完成了签名,不需要再给自己发起会话请求签名。多余的会话会打乱buyerSession的消息序列,导致签名请求的SignedTransaction被提前发送到响应端,触发反序列化错误。
修复后写法:
SignedTransaction signedTransaction = subFlow(new CollectSignaturesFlow( selfSignedTransaction, ImmutableList.of(buyerSession), // 仅保留和买家节点的会话 Collections.singleton(issuerAccountInfo.getHost().getOwningKey())));
2. 修复非同质化Token的持有方适配错误
你移动NFT时传入的接收方是买家节点,而非买家Account,不符合Accounts的权限模型:
// 错误写法:接收方是买家节点,不是买家Account MoveTokensUtilities.addMoveNonFungibleTokens(txBuilder, getServiceHub(), ticketState.toPointer(CustomTicket.class), receiverAccountInfo.getHost());
启用Accounts后,Token所有权归Account的匿名身份所有,而非节点本身,这也是未启用Accounts时运行正常的核心原因。
修复后写法:
// 传入你提前生成的买家Account匿名身份 MoveTokensUtilities.addMoveNonFungibleTokens(txBuilder, getServiceHub(), ticketState.toPointer(CustomTicket.class), buyerAccount);
3. 修正NFT所属账户的签名密钥
当前你用节点密钥签名交易,而NFT归issuer的Account所有,需要用Account对应的密钥签名:
// 错误写法:用节点密钥签名 SignedTransaction selfSignedTransaction = getServiceHub() .signInitialTransaction(txBuilder, ImmutableList.of(issuerAccountInfo.getHost().getOwningKey()));
修复后写法:
// 用issuer Account的匿名密钥签名 SignedTransaction selfSignedTransaction = getServiceHub() .signInitialTransaction(txBuilder, ImmutableList.of(issuerAccount.getOwningKey()));
4. 补充响应流交易校验(可选,避免后续异常)
不要留空checkTransaction方法,至少补充基础校验逻辑,避免非法交易上链:
@Override protected void checkTransaction(@NotNull SignedTransaction stx) throws FlowException { // 校验交易中包含的NFT是预期的标的 boolean hasTicket = stx.getTx().getOutputStates().stream() .anyMatch(state -> state instanceof NonFungibleToken); if (!hasTicket) throw new FlowException("交易不含目标NFT"); // 校验付款金额匹配协商的价格 Amount<TokenType> receivedAmount = // 从交易输出中提取你收到的Token金额 if (!receivedAmount.equals(priceToken)) throw new FlowException("付款金额不匹配"); }
验证
完成上述修改后重新部署节点发起流,反序列化异常会消失,NFT和资金流转逻辑也符合Accounts的权限要求。
内容的提问来源于stack exchange,提问作者laplace
相关产品推荐
相关产品推荐

