Hyperledger composer 在 for 循环中创建多个资产

Hyperledger composer creating multiple assets in a for loop

我正在尝试创建一批项目(单位)。我希望用户在一个批次中指示他们想要的单位数,然后事务首先创建该批次,然后创建所需的单位数。这是我的代码:

async function createBatch(batchTx) {
// get a code from the generator
let now = new Date();
let tokenData = {
    brand: batchTx.brand,
    unitCount: batchTx.unitCount,
    created: now,
    expiry: batchTx.expiryDate
}
let code = _generate_code(tokenData, 'Batch');

// create a new Batch token and add it to the registry
let factory = getFactory();
let token = factory.newResource('org.myOrganization', 'Token', String(code));
token.created = now;
token.updated = now;

let tokenAssetRegistry = await getAssetRegistry('org.myOrganization.Token');
await tokenAssetRegistry.add(token);

// create a batch using the token and code created above
let batch = factory.newResource('org.myOrganization', 'Batch', token.code);
batch.brand = batchTx.brand;
batch.expiryDate = batchTx.expiryDate;
batch.token = token;
batch.owner = batchTx.owner;
batch.created = now;
batch.updated = now;

let batchAssetRegistry = await getAssetRegistry('org.myOrganization.Batch');
await batchAssetRegistry.add(batch);

// update token  with new batch
let tokenAssetRegistry1 = await getAssetRegistry('org.myOrganization.Token');
token.batch = batch;
tokenAssetRegistry1.update(token);

// CREATE UNITS
// get a code from the generator
let i;
for(i=0; i < batchTx.unitCount; i++) {
    let unitTokenData = {
        batch: batch,
        created: now
    };

    let unitCode = _generate_code(unitTokenData, 'Unit');
    // create a new Unit token and add it to the registry
    let unitToken = factory.newResource('org.myOrganization', 'Token', String(unitCode));
    unitToken.created = now;
    unitToken.updated = now;

    let tokenAssetRegistry2 = await getAssetRegistry('org.myOrganization.Token');
    await tokenAssetRegistry2.add(unitToken);

    // create units
    let unit = factory.newResource('org.myOrganization', 'Unit', String(unitToken.code));
    unit.batch = batch;
    unit.token = unitToken;
    unit.owner = batchTx.owner;
    unit.created = now;
    unit.updated = now;

    let unitAssetRegistry = await getAssetRegistry('org.myOrganization.Unit');
    await unitAssetRegistry.add(unit);
    }

}

问题是批次创建没问题,但是当涉及到单位时,如果 batchTx.unitCount 是 3,它不会创建 3 个单位,它只会创建一个。作曲家的工作方式有什么问题吗,或者我的某些承诺解决方案是错误的?任何解决此问题的帮助将不胜感激

(更新):

  1. 你不能(在同一个交易中 - 上面)update 新的 token 资产(在之前的 add 之后)(add) 尚未提交到账本。但是您可以简单地等待批处理“添加”完成,然后执行一个单数操作:

    let tokenAssetRegistry = await getAssetRegistry('org.myOrganization.Token');
    await tokenAssetRegistry.add(token);
    
  2. 您的代码在使用 new Date() 时是不确定的 - 它在背书同行之间不会相同(得到不同的结果)。看不到您是否 'pare' 其他地方的日期字符串(以减少不确定性因素)。为什么不使用`事务时间戳(下面的link)。

  3. 同样的不确定性适用于代码的 unitToken 部分。关于非确定性——建议看这个获取确定性日期时间的例子。

  4. 我建议阅读这篇文章,了解如何处理 for 循环中的承诺 -> https://medium.com/@antonioval/making-array-iteration-easy-when-using-async-await-6315c3225838 to manage the promises returned (I think yes, this is why your loop isn't completing)|. Your code is inefficient, if that's of any value in that you can instead create units as an array of resources then use one singular unitAssetRegistry.addAll() - after the for loop completes. An example of this is in this sample network here -> https://github.com/hyperledger/composer-sample-networks/blob/master/packages/fund-clearing-network/lib/clearing.js#L191(在这种情况下使用 updateArray,注册表 .updateAll()方法).