You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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. 放宽资产属性的类型限制(适合业务允许的场景)

如果业务上允许Commoditycompany关联任意类型的参与者,直接修改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

火山引擎 最新活动