【问题标题】:Multiple interconnected object types in Hyperledger FabricHyperledger Fabric 中的多种互连对象类型
【发布时间】:2020-01-23 08:45:07
【问题描述】:

我正在构建一个基于 Hyperledger Fabric 的系统,该系统需要存储以下相关信息:

  1. 资金清单
  2. 投资这些基金的合作伙伴(投资者)名单,以及
  3. 订阅列表,代表基金与合作伙伴之间的关系

每一个都是单独的对象类型,有自己的一组字段,需要独立存储和查询。基金对象和合作伙伴对象都应该包含它们相关的订阅数组。

但是,我发现很难找到具有这种结构的链码示例。所有的对象都是强互连的(一个对象数据的修改直接意味着其他对象的修改),所以我希望它们存储在一个链码上,但是它们使用的操作是非常不同的。命名空间是否打算以这种方式使用?

我尝试将它们作为单独的合约存储在同一个链码上(使用来自this 问题的最佳答案):

papercontract.js

class FundContext extends Context {
    constructor() {
        super();
        this.subList = new SubList(this);
        this.fundList = new FundList(this);
        this.partnerList = new PartnerList(this);
    }
}

class PartnerContext extends Context...
class SubContext extends Context...


class FundContract extends Contract {
    constructor() {
        super('fund');
    }
    async createFund(ctx, id, name, amount_committed, amount_raised) {
        ...
    }
}
...
class SubContract extends Contract...
class PartnerContract extends Contract...
...
module.exports.FundContract = FundContract;
module.exports.PartnerContract = PartnerContract;
module.exports.SubContract = SubContract;

index.js

const SubContract = require('./lib/papercontract').SubContract;
const FundContract = require('./lib/papercontract').FundContract;
const PartnerContract = require('./lib/papercontract').PartnerContract;
module.exports.SubContract = SubContract;
module.exports.FundContract = FundContract;
module.exports.PartnerContract = PartnerContract;
module.exports.contracts = [ SubContract, FundContract, PartnerContract ];

问题.js

const contract = await network.getContract('papercontract','FundContract');
await contract.submitTransaction('createFund', data._id, data.name, data.amount_committed, data.amount_raised);

但这会返回错误:

Error: Contract name is not known: FundContract

我可以通过将对象类型(以字符串形式)存储为“类”字段来解决这个问题,并通过搜索 id 和类来查找对象,这...有效,但感觉 非常在一个数组中存储一堆完全不同的对象类型很麻烦。我怀疑这是打算使用它的方式。

我不确定为什么会出现上述错误,或者这是否是处理核心问题的最佳方式。任何帮助将不胜感激。

【问题讨论】:

  • 在您的基金合约构造函数中,您将合约注册为fund 而不是FundContract。所以尝试const contract = await network.getContract('papercontract','fund'); 或将super('fund') 替换为super('FundContract')
  • 但是关于您更广泛的问题,您是否有需要更新多种状态的单独操作?
  • @GariSingh 是的,这就是想法 - 操作需要一次更新多个对象(订阅更新还必须在单个链码调用中更新其关联的基金和合作伙伴)。

标签: hyperledger-fabric hyperledger


【解决方案1】:

我建议你在不同的文件中实现不同的智能合约,这有助于组织你的代码:

const SubContract = require('./lib/SubContract.js');
const FundContract = require('./lib/FundContract.js');
const PartnerContract = require('./lib/PartnerContract.js');
module.exports.contracts = [SubContract,FundContract,PartnerContract];

关于您的组织问题,如果您在合同中实现您正在操作的对象(状态和状态列表)的抽象,如图所示here,您可以将不同的对象保存在不同的数组中。通过这种方式,查询您的世界状态将更加直接。

清楚吗?

【讨论】:

  • 如果我这样做,是否可以从特定合约中查询其他对象类型?即如果 FundContract 有 findById() 函数,PartnerContract 中的函数是否可以调用 FundContract.findById() 通过 id 查找基金?
  • 取决于实现:如果 findById 查询世界状态并检索结果,那么 PartnerContract 可以只导入 FundContract 并使用其原语。尽管如此,如果您使用上下文,事情就会发生变化。保存“StateList”的上下文对于每个智能合约实例都是唯一的。我相信您会在合同中失去上下文。
  • 是否可以在单个函数中调用不同的上下文,并使用该方法更新不同类型的对象? (即 Fund 和 Partners 有一个订阅列表,而 SubContract 有一个添加订阅的功能,它应该同时将其 ID 添加到与其关联的基金和合作伙伴对象中。)
  • 这是一个很好的问题。我不这么认为——上下文允许你跨同一个智能合约的交易管理数据。我不确定,让我检查一下,我会回复你的
  • 您不能以您希望的方式使用上下文。您必须使用适当的抽象从您的智能合约中查询其他对象,然后在那里执行更新
猜你喜欢
  • 1970-01-01
  • 2013-09-03
  • 2019-02-06
  • 2019-10-23
  • 2017-12-24
  • 2022-11-14
  • 2012-10-11
  • 2018-02-28
  • 1970-01-01
相关资源
最近更新 更多