Hyperledger Composer交易失败:Composer-Playground交易卡住报错求助
我之前在Hyperledger Composer项目里碰到过一模一样的问题,这个报错本质是模型类型校验不通过导致交易卡壳,给你拆解下问题根源和可行的解决办法:
问题根源
你的Commodity资产模型里,company属性被明确限定为org.hcsc.network.Trader(或它的子类),但实际执行交易时,你给这个属性赋值的是org.hyperledger.composer.system.NetworkAdmin类型的参与者。而NetworkAdmin是系统内置的参与者类型,并没有继承自你自定义的Trader,所以Composer的强类型校验直接阻断了交易,导致停滞报错。
解决办法(按推荐优先级排序)
1. 调整参与者继承关系(最符合设计规范)
如果你的业务逻辑确实要求Commodity只能关联Trader,那可以让自定义的Trader继承系统的NetworkAdmin,这样管理员账号就能直接作为Trader使用:
- 打开你的CTO模型文件,修改
Trader的定义:participant Trader extends org.hyperledger.composer.system.NetworkAdmin { // 这里保留你的Trader自定义属性,比如name、address等 } - 修改后重新生成业务网络存档(
.bna文件),重新部署到Playground,之后把原来的NetworkAdmin参与者更新为Trader类型,再执行交易就不会报错了。
2. 放宽资产属性的类型限制(适合业务允许的场景)
如果业务上允许Commodity的company关联任意类型的参与者,直接修改Commodity的属性类型:
- 在CTO模型里,把
company的类型从org.hcsc.network.Trader改为通用的Participant(所有参与者的父类):asset Commodity identified by commodityId { o String commodityId --> Participant company // 替换原来的Trader类型 // 其他属性保持不变 } - 同样重新打包部署,类型校验的限制就解除了。
3. 交易脚本中临时转换参与者类型(应急 workaround)
如果暂时不想修改模型,可以在交易脚本里手动把NetworkAdmin转换成Trader实例(注意:只适合业务逻辑允许的情况):
/** * 示例交易处理脚本 * @param {org.hcsc.network.YourTargetTransaction} tx * @transaction */ async function handleTransaction(tx) { // 获取当前提交交易的参与者(也就是NetworkAdmin) const currentAdmin = getCurrentParticipant(); // 获取Trader参与者注册表 const traderRegistry = await getParticipantRegistry('org.hcsc.network.Trader'); // 创建对应的Trader实例,复用Admin的标识符 const newTrader = factory.newResource('org.hcsc.network', 'Trader', currentAdmin.getIdentifier()); // 复制Admin的属性(如果有需要) newTrader.displayName = currentAdmin.displayName; // 把新Trader添加到注册表 await traderRegistry.add(newTrader); // 关联到Commodity的company属性 tx.targetCommodity.company = newTrader; // 保存更新后的Commodity const commodityRegistry = await getAssetRegistry('org.hcsc.network.Commodity'); await commodityRegistry.update(tx.targetCommodity); }
额外提醒
不管用哪种方案,修改模型或脚本后一定要重新生成.bna并重新部署,还要确保Playground里的参与者、资产数据和新的模型类型匹配,不然可能会出现其他兼容性问题。
内容的提问来源于stack exchange,提问作者Aniruddha Kharabe




