我目前正在Hyperledger作曲器中开发一个事务。此交易将创建 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"}, false
(节点:17( 未处理的承诺拒绝警告:未处理的承诺拒绝(拒绝 ID:2(:错误:使用 id assetAIdValue 创建资产 A 时出错
错误: [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
}
这是我的逻辑.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"
}
]
}
如果有人知道这种错误的原因,他会拯救我的一天!
另一个问题: 此错误仅在我查看链码容器时可见。有人知道我如何使它们从作曲家 REST 服务器可见吗?
看起来您在承诺链中的代码中缺少return
语句的视图,但 TP 函数支持 async/await,我强烈建议您使用它而不是承诺链,因为它使代码更容易阅读。例如(注意,未测试(
/** * 创建资产资产 B 和资产 A * @param {mynamespace.createAssetA} createAssetA - 要创建的 AssetA * @transaction */async function createAssetA(createAssetA( { 尝试 { const assetBRegistry = await getAssetRegistry('mynamespace.资产B'(; await assetBRegistry.addAll(createAssetA.assetB(; await addAssetA(createAssetA(; } catch(error( { 抛出新错误("创建资产 B 时出错"+""+ 错误(; } }/** * 将资产添加到注册表的功能 * @param {*} createAssetA - 包含 assetA 信息的 createAssetA 事务 */async function addAssetA(createAssetA({ 尝试 { const assetARegistry = await getAssetRegistry('mynamespace.资产A'(; const newAssetA = castcreateAssetATxToAsset(createAssetA(; await assetARegistry.add(newAssetA(; } catch(error( { 抛出新错误("创建 id 为 createAssetA.id + + ' + 错误的资产 A 时出错(; } }/** * 将创建资产 A 事务转换为资产 A 资产 * @param {*} createAssetA - 事务创建要强制转换的资产A * @returns {mynamespace.AssetA} 具有来自 createAssetA 参数的信息的资产 A 资产 */function castcreateAssetATxToAsset(createAssetA({ const factory = getFactory((; 从 mynamespace 命名空间创建一个 AssetA 类的新实例,ID 为 createAssetA.id let newAssetA = factory.newResource('mynamespace', 'AssetA', createAssetA.id(; newAssetA.assetAFieldX = createAssetA.assetAFieldX; newAssetA.assetB = []; for (let i = 0; i