Hyperledger Composer返回错误GetState没有分类帐上下文

时间:2018-10-10 15:13:20

标签: hyperledger hyperledger-composer

我目前正在Hyperledger作曲家中开发事务。此事务将创建两个不同的资产:资产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”:[“资源:mynamespace.assetB#assetBIdValue1”,“资源:mynamespace.assetB#assetBIdValue2”]},“ $ registryType”:“资产”,“ $ registryId”:“ mynamespace.assetA” },错误

     

(节点:17)UnhandledPromiseRejectionWarning:未处理的承诺拒绝(拒绝ID:2):错误:创建ID为assetAIdValue的AssetA时出错

     

错误:[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"
  }
 ]
}

如果有人发现此类错误的原因,他将挽救我的生命!

另一个问题: 仅当我查看chaincode容器时,此错误才可见。谁知道我该如何从Composer REST Server中看到它们?

1 个答案:

答案 0 :(得分:0)

您似乎在承诺链中的代码中缺少视图return语句,但是TP函数支持async / await,我强烈建议您使用而不是承诺链,因为它会使代码变得如此多更容易阅读。例如(注意,未经测试)

/**
 * Creates the assets assetB and assetA
 * @param {mynamespace.createAssetA} createAssetA - the AssetA to create
 * @transaction
 */
async function createAssetA(createAssetA) {
    try {
        const assetBRegistry = await getAssetRegistry('mynamespace.AssetB');
        await assetBRegistry.addAll(createAssetA.assetB);
        await addAssetA(createAssetA);
    } catch(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
 */
async function addAssetA(createAssetA){
    try {
        const assetARegistry = await getAssetRegistry('mynamespace.AssetA');
        const newAssetA = castcreateAssetATxToAsset(createAssetA);
        await assetARegistry.add(newAssetA);
    } catch(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){
    const factory = getFactory();
    // Create a new instance of AssetA class from the mynamespace namespace with the id createAssetA.id
    let newAssetA = factory.newResource('mynamespace', 'AssetA', createAssetA.id);
    newAssetA.assetAFieldX = createAssetA.assetAFieldX;
    newAssetA.assetB = [];
    for (let i = 0; i