【问题标题】:Hyperledger Composer returns error No ledger context for GetStateHyperledger Composer 返回错误没有 GetState 的分类帐上下文
【发布时间】:2018-10-10 15:13:19
【问题描述】:

我目前正在 Hyperledger composer 中开发交易。该交易将创建 2 个不同的资产:资产 A 和资产 B。 资产 A 有一个类型为资产 B 的字段。所以我首先需要创建资产 B,然后创建具有资产 B 链接的资产 A。经过几次努力,我已经设法实现了逻辑。现在对等端返回以下错误:

2018-10-10T14:06:14.022Z [5ad2a944] 调试:NodeDataCollection :add() >assetAIdValue,{“$class”:“mynamespace.assetA”,“assetAId”:“assetAIdValue”,“assetAFieldX”: "assetAFieldXValue","assetB": ["resource:mynamespace.assetB#assetBIdValue1", "resource:mynamespace.assetB#assetBIdValue2"]},"$registryType":"Asset","$registryId":"mynamespace.assetA" },错误

(node:17) UnhandledPromiseRejectionWarning: UnhandledPromiseRejectionWarning: Unhandled Promise Rejection (rejection id: 2): Error: Error when created AssetA with idassetAIdValue

错误:[5ad2a944]GetState 没有分类帐上下文。发送错误

这是我的模型

namespace mynamespace

/**
 * Definition of createAssetA transaction
 */
transaction createAssetA{
  o String assetAId
  o String assetAFieldX
  o AssetB[] assetB
}

/**
 * Definition of AssetA asset
 */
asset AssetA identified by assetAId{
  o String assetAId
  o String assetAFieldX
  --> AssetB[] assetB
}

/**
 * Definition of assetB asset
 */
asset AssetB identified by AssetBId{
  o String assetBId
  o String assetBFieldX
  o String assetBFieldY
}

这是我的 logic.js

/**
* Creates the assets assetB and assetA
* @param {mynamespace.createAssetA} createAssetA - the AssetA to create
* @transaction
*/
function createAssetA(createAssetA) {
    return getAssetRegistry('mynamespace.AssetB')
        .then(function (assetBRegistry) {
            // Add all the AssetBs to the AssetB registry
            assetBRegistry.addAll(createAssetA.assetB)
                .then(function(){
                    addAssetA(createAssetA);
                }, function(error) {
                    throw new Error ('Error while creating AssetBs' + '\n' + error);
                } );
        });
}

/**
 * Function to add assetA asset to registry
 * @param {*} createAssetA - The createAssetA Transaction containing the assetA info
 */
function addAssetA(createAssetA){
    return getAssetRegistry('mynamespace.AssetA')
        .then(function (assetARegistry) {
            var newAssetA = castcreateAssetATxToAsset(createAssetA);
            return assetARegistry.add(newAssetA).catch(function (error) {
                throw new Error ('Error when creating AssetA with id ' + createAssetA.id + '\n' + error);
            });
        });
}

/**
 * Casts the createAssetA transaction as a AssetA Asset
 * @param {*} createAssetA - The transaction createAssetA to cast
 * @returns {mynamespace.AssetA} the AssetA Asset with the info from the createAssetA param
 */
function castcreateAssetATxToAsset(createAssetA){
    var factory = getFactory();
    // Create a new instance of AssetA class from the mynamespace namespace with the id createAssetA.id
    var newAssetA = factory.newResource('mynamespace', 'AssetA', createAssetA.id);
    newAssetA.assetAFieldX = createAssetA.assetAFieldX;
    newAssetA.assetB = [];
    for (var i = 0; i < createAssetA.assetB.length; i++) {
        var assetB = factory.newRelationship('mynamespace', 'assetB', createAssetA.assetB[i].id);
        newAssetA.assetB[i] = assetB;
    }
    return newAssetA;
}

这是我请求的内容

{
 "$class": "mynamespace.createAssetA",
 "assetAId": "assetAIdValue",
 "assetAFieldX": "assetAFieldXValue",
 "assetB": [
  {
   "$class": "mynamespace.assetB",
   "assetBId": "assetBIdValue1",
   "assetBFieldX": "assetBFieldXValue",
   "assetBFieldY": "assetBFieldYValue"
  },
  {
   "$class": "mynamespace.assetB",
   "assetBId": "assetBIdValue2",
   "assetBFieldX": "assetBFieldXValue",
   "assetBFieldY": "assetBFieldYValue"
  }
 ]
}

如果有人知道这种错误的原因,他会拯救我的一天!

另一个问题: 这个错误只有在我查看链码容器时才可见。任何人都知道如何让它们在 Composer REST 服务器上可见?

【问题讨论】:

    标签: hyperledger hyperledger-composer


    【解决方案1】:

    看起来您在 Promise 链中的代码中缺少视图 return 语句,但 TP 函数支持 async/await,我强烈建议您使用它而不是 Promise 链,因为它使代码更容易读。例如(注意,未测试)

    /** * 创建资产assetB和assetA * @param {mynamespace.createAssetA} createAssetA - 要创建的 AssetA * @交易 */ 异步函数 createAssetA(createAssetA) { 尝试 { 常量assetBRegistry = 等待getAssetRegistry('mynamespace.AssetB'); 等待assetBRegistry.addAll(createAssetA.assetB); 等待 addAssetA(createAssetA); } 捕捉(错误){ throw new Error ('Error while creating AssetBs' + '\n' + error); } } /** * 将assetA资产添加到注册表的功能 * @param {*} createAssetA - 包含资产信息的 createAssetA 交易 */ 异步函数 addAssetA(createAssetA){ 尝试 { 常量assetARegistry = 等待getAssetRegistry('mynamespace.AssetA'); 常量 newAssetA = castcreateAssetATxToAsset(createAssetA); 等待assetARegistry.add(newAssetA); } 捕捉(错误){ throw new Error ('使用 id 创建 AssetA 时出错' + createAssetA.id + '\n' + 错误); } } /** * 将 createAssetA 交易转换为 AssetA 资产 * @param {*} createAssetA - 要转换的交易 createAssetA * @returns {mynamespace.AssetA} 带有来自 createAssetA 参数的信息的 AssetA 资产 */ 函数 castcreateAssetATxToAsset(createAssetA){ 常量工厂 = getFactory(); // 从 mynamespace 命名空间创建 AssetA 类的新实例,id 为 createAssetA.id 让 newAssetA = factory.newResource('mynamespace', 'AssetA', createAssetA.id); newAssetA.assetAFieldX = createAssetA.assetAFieldX; 新资产A.资产B = []; for (让 i = 0; i

    【讨论】:

    • 非常感谢!确实这个合成器更容易阅读,我不知道它是否被支持,因为所有教程都是用我之前使用的那个编写的
    猜你喜欢
    • 2020-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-06
    • 2017-12-24
    • 2014-02-21
    相关资源
    最近更新 更多