You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Hyperledger Composer中实现资产ID自动递增?

在Hyperledger Composer里实现资产ID自动递增,我整理了几个在实际项目中验证过的最优方案,你可以根据业务场景挑合适的:

1. 专用计数器资产方案(最常用、易实现)

这是最直观的方案——创建一个专门的Counter资产来存储当前的ID序列值,每次创建目标资产时,先读取计数器、递增数值,再把新ID赋值给目标资产,最后更新计数器。

实现步骤:

首先在CTO模型里定义计数器资产:

namespace org.example

asset Counter identified by counterId {
  o String counterId = "default"  // 固定ID,方便全局获取
  o Integer currentValue = 0      // 初始计数从0开始
}

asset MyAsset identified by assetId {
  o String assetId
  o String name
  // 其他资产属性...
}

transaction CreateAsset {
  o String name
}

然后编写事务处理函数(JavaScript),确保操作的原子性:

/**
 * 创建带递增ID的资产
 * @param {org.example.CreateAsset} tx
 * @transaction
 */
async function createAsset(tx) {
    try {
        // 获取计数器资产注册表
        const counterRegistry = await getAssetRegistry('org.example.Counter');
        let counter = await counterRegistry.get('default');

        // 递增计数并生成新ID
        counter.currentValue += 1;
        const newAssetId = `ASSET-${counter.currentValue.toString().padStart(6, '0')}`; // 补零保证格式统一

        // 创建新资产
        const assetRegistry = await getAssetRegistry('org.example.MyAsset');
        const newAsset = getFactory().newResource('org.example', 'MyAsset', newAssetId);
        newAsset.name = tx.name;
        // 赋值其他属性...

        // 原子更新计数器和保存新资产
        await counterRegistry.update(counter);
        await assetRegistry.add(newAsset);
    } catch (err) {
        // 处理计数器未初始化的情况
        if (err.message.includes('Object with ID default does not exist')) {
            // 初始化计数器
            const counterRegistry = await getAssetRegistry('org.example.Counter');
            const initCounter = getFactory().newResource('org.example', 'Counter', 'default');
            initCounter.currentValue = 1;
            await counterRegistry.add(initCounter);
            
            // 重新创建第一个资产
            const assetRegistry = await getAssetRegistry('org.example.MyAsset');
            const newAsset = getFactory().newResource('org.example', 'MyAsset', 'ASSET-000001');
            newAsset.name = tx.name;
            await assetRegistry.add(newAsset);
        } else {
            throw err;
        }
    }
}

优缺点:

  • ✅ 优点:逻辑简单、易维护,能保证ID严格递增;
  • ❌ 缺点:高并发场景下,计数器会成为性能瓶颈(因为每次创建资产都要读写同一个计数器)。
2. 时间戳+随机数/节点标识方案(高并发友好)

如果对ID的严格连续性要求不高,只是需要唯一且近似递增,这个方案更适合。ID格式可以是YYYYMMDDHHMMSS-xxxx,其中xxxx可以是随机数、节点ID或者参与者ID的哈希值。

实现示例:

/**
 * 生成基于时间戳的资产ID
 * @param {org.example.CreateAsset} tx
 * @transaction
 */
async function createAsset(tx) {
    // 生成时间戳部分(精确到秒)
    const timestamp = new Date().toISOString().replace(/[-T:\.Z]/g, '').slice(0, 14);
    // 生成4位随机数
    const randomSuffix = Math.floor(Math.random() * 9000) + 1000;
    const newAssetId = `${timestamp}-${randomSuffix}`;

    // 创建并保存资产
    const assetRegistry = await getAssetRegistry('org.example.MyAsset');
    const newAsset = getFactory().newResource('org.example', 'MyAsset', newAssetId);
    newAsset.name = tx.name;
    await assetRegistry.add(newAsset);
}

优缺点:

  • ✅ 优点:不需要额外的计数器资产,并发性能好,ID天然唯一;
  • ❌ 缺点:ID不是严格递增的(如果同一秒生成多个ID,随机数会打乱顺序),且ID长度较长。
3. 参与者专属计数器方案(多租户/多参与者场景)

如果你的业务是多参与者模式(比如每个企业用户创建自己的资产),可以给每个参与者维护独立的计数器,ID格式为参与者ID-序号(比如org.example.User#user1-001)。

实现思路:

  1. 在参与者模型里添加assetCount属性,或者创建ParticipantCounter资产;
  2. 创建资产时,读取对应参与者的计数器,递增后生成ID;
  3. 更新参与者的计数器值。

示例代码片段:

/**
 * 为特定参与者生成递增资产ID
 * @param {org.example.CreateAsset} tx
 * @transaction
 */
async function createAsset(tx) {
    // tx.owner是创建资产的参与者(需要在事务定义里添加这个字段)
    const participantRegistry = await getParticipantRegistry('org.example.User');
    let owner = await participantRegistry.get(tx.owner.$identifier);

    // 递增参与者的资产计数
    owner.assetCount = (owner.assetCount || 0) + 1;
    const newAssetId = `${owner.$identifier}-${owner.assetCount.toString().padStart(4, '0')}`;

    // 创建并保存资产
    const assetRegistry = await getAssetRegistry('org.example.MyAsset');
    const newAsset = getFactory().newResource('org.example', 'MyAsset', newAssetId);
    newAsset.name = tx.name;
    newAsset.owner = tx.owner;

    // 更新参与者计数器和保存资产
    await participantRegistry.update(owner);
    await assetRegistry.add(newAsset);
}

优缺点:

  • ✅ 优点:分散了并发压力,每个参与者的计数器独立,性能更好;
  • ❌ 缺点:ID是分段递增的,全局范围内不连续。
4. 底层链码自定义生成方案(高性能场景)

如果Composer的事务函数满足不了高并发、低延迟的需求,可以直接在Hyperledger Fabric的链码(Go语言)里实现ID生成逻辑,然后在Composer里调用这个链码。

核心思路:

利用Fabric链码的PutState和GetState的原子性,在链码层维护计数器,生成递增ID后返回给Composer使用。这种方式的并发控制更可靠,性能也更高。

优缺点:

  • ✅ 优点:性能最优,适合高并发生产环境;
  • ❌ 缺点:需要掌握Fabric链码开发,复杂度较高,和Composer的集成需要额外适配。
总结建议
  • 低到中并发、需要严格递增ID:选专用计数器资产方案;
  • 高并发、对ID连续性要求不高:选时间戳+随机数方案;
  • 多参与者/多租户场景:选参与者专属计数器方案;
  • 超高并发、高性能要求:选底层链码自定义方案。

内容的提问来源于stack exchange,提问作者zaheer ud deen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:34:17