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 个单位,它只会创建一个。作曲家的工作方式有什么问题吗,或者我的某些承诺解决方案是错误的?任何解决此问题的帮助将不胜感激
(更新):
你不能(在同一个交易中 - 上面)update
新的 token
资产(在之前的 add
之后)(add
) 尚未提交到账本。但是您可以简单地等待批处理“添加”完成,然后执行一个单数操作:
let tokenAssetRegistry = await getAssetRegistry('org.myOrganization.Token');
await tokenAssetRegistry.add(token);
您的代码在使用 new Date()
时是不确定的 - 它在背书同行之间不会相同(得到不同的结果)。看不到您是否 'pare' 其他地方的日期字符串(以减少不确定性因素)。为什么不使用`事务时间戳(下面的link)。
同样的不确定性适用于代码的 unitToken
部分。关于非确定性——建议看这个获取确定性日期时间的例子。
我建议阅读这篇文章,了解如何处理 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()
方法).
我正在尝试创建一批项目(单位)。我希望用户在一个批次中指示他们想要的单位数,然后事务首先创建该批次,然后创建所需的单位数。这是我的代码:
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 个单位,它只会创建一个。作曲家的工作方式有什么问题吗,或者我的某些承诺解决方案是错误的?任何解决此问题的帮助将不胜感激
(更新):
你不能(在同一个交易中 - 上面)
update
新的token
资产(在之前的add
之后)(add
) 尚未提交到账本。但是您可以简单地等待批处理“添加”完成,然后执行一个单数操作:let tokenAssetRegistry = await getAssetRegistry('org.myOrganization.Token'); await tokenAssetRegistry.add(token);
您的代码在使用
new Date()
时是不确定的 - 它在背书同行之间不会相同(得到不同的结果)。看不到您是否 'pare' 其他地方的日期字符串(以减少不确定性因素)。为什么不使用`事务时间戳(下面的link)。同样的不确定性适用于代码的
unitToken
部分。关于非确定性——建议看这个获取确定性日期时间的例子。我建议阅读这篇文章,了解如何处理 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 singularunitAssetRegistry.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()
方法).