Java版CordApp添加附件报错AttachmentResolutionException求助
解决CordApp中AttachmentResolutionException的问题
这个net.corda.core.contracts.AttachmentResolutionException异常的核心原因很明确:你添加到交易中的附件仅存在于本地节点,而交易的其他参与节点(比如对手方、公证人)的附件存储中没有这个哈希对应的文件,导致他们在验证交易时无法解析附件,进而抛出错误。
下面是具体的解决步骤和代码示例:
1. 先确保所有参与节点都已上传目标附件
不管是手动操作还是通过代码自动同步,第一步必须保证交易涉及的所有节点(发起方、接收方、相关参与方)都拥有该附件的副本。
手动上传方式(适合测试场景)
你可以通过Corda节点的shell命令上传附件:
upload-attachment --file "/绝对路径/你的附件文件.pdf"
执行后会返回该附件的SecureHash值,这个值就是你代码里要用的fileHash。记得在每个参与节点上都执行这个命令。
代码自动同步方式(适合生产/自动化场景)
如果不想手动操作,可以在交易发起流程中,先通过Corda内置的文件传输流程把附件发送给所有参与节点,让他们先导入到本地附件存储:
发起方流程片段
// 定义交易的其他参与方集合 List<Party> otherParties = Arrays.asList(partyA, partyB); File attachmentFile = new File("/path/to/your/attachment.file"); // 给每个参与方发送附件 for (Party party : otherParties) { // SendFileFlow会自动传输文件,第三个参数true表示传输完成后删除临时文件 subFlow(new SendFileFlow(party, attachmentFile, true)); }
接收方流程片段
在接收方的响应流程中,先接收并导入附件:
// 接收文件 ReceivedFile receivedFile = subFlow(new ReceiveFileFlow()); // 将文件导入到节点的附件存储 SecureHash attachmentHash = getServiceHub().getAttachmentStorage().importAttachment( new FileInputStream(receivedFile.getFile()), receivedFile.getFilename(), receivedFile.getUploader() ); // 可以把这个哈希存储下来,后续交易使用
2. 交易构建的代码注意事项
你当前的交易构建代码是正确的,但要确保fileHash是所有节点都已上传的附件哈希:
final TransactionBuilder txBuilder = new TransactionBuilder(notary) .addInputState(oldState) .addOutputState(dealState, IDEAL_CONTRACT_ID) .addCommand(txCommand) .addAttachment(fileHash); // 这里的fileHash必须是所有节点都存在的附件哈希
另外,发起交易前可以先检查本地节点是否存在该附件(避免自己节点都没上传的低级错误):
Attachment localAttachment = getServiceHub().getAttachmentStorage().openAttachment(fileHash); if (localAttachment == null) { throw new IllegalStateException("本地节点未找到指定附件,请先上传"); }
3. 合约验证时的附件检查
如果你的合约逻辑需要读取附件内容,记得在verify方法中添加检查,确保附件存在:
@Override public void verify(@NotNull LedgerTransaction tx) throws IllegalArgumentException { // 获取附件哈希(可以从命令或状态中传递,或者直接硬编码如果是固定附件) SecureHash attachmentHash = SecureHash.parse("你的附件哈希"); Attachment attachment = tx.getAttachment(attachmentHash); if (attachment == null) { throw new IllegalArgumentException("交易缺少必需的附件"); } // 读取并处理附件内容 try (InputStream is = attachment.open()) { // 处理逻辑,比如读取文件内容验证签名等 } catch (IOException e) { throw new IllegalArgumentException("读取附件失败", e); } }
总结一下:解决这个问题的核心就是让交易的所有参与节点都拥有该附件的副本,要么手动上传,要么通过流程自动同步,这样每个节点在验证交易时都能找到对应的附件,就不会抛出AttachmentResolutionException了。
内容的提问来源于stack exchange,提问作者Pe4eN
相关产品推荐
相关产品推荐

