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

如何在Hyperledger Fabric Go链码中获取指定State的创建者证书

Hyperledger Fabric Go链码获取指定State创建者证书的实现方案

原生Fabric Go链码没有提供直接查询指定State对应创建者证书的内置接口,底层账本存储State时仅保留键、值、版本三个核心字段,不会默认存储创建者身份信息,你需要自行在链码逻辑中实现身份关联存储,具体实现方式如下:

  • 方案1:将创建者信息嵌入State结构体
    在State首次写入的创建逻辑中,将当前调用者的证书存入State的自定义结构中,后续查询时直接读取即可,示例代码:
// 自定义资产结构体,新增创建者证书字段
type CustomAsset struct {
    ID          string `json:"id"`
    Content     string `json:"content"`
    CreatorCert []byte `json:"creator_cert"`
}

// 资产创建方法
func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface, assetId string, content string) error {
    // 获取当前交易提交者(即资产创建者)的身份信息
    creator, err := ctx.GetClientIdentity().GetCreator()
    if err != nil {
        return fmt.Errorf("failed to get creator identity: %v", err)
    }

    asset := CustomAsset{
        ID:          assetId,
        Content:     content,
        CreatorCert: creator,
    }

    assetJson, err := json.Marshal(asset)
    if err != nil {
        return fmt.Errorf("failed to marshal asset: %v", err)
    }

    return ctx.GetStub().PutState(assetId, assetJson)
}

// 自定义GetStateCreator方法
func (s *SmartContract) GetStateCreator(ctx contractapi.TransactionContextInterface, key string) ([]byte, error) {
    assetJson, err := ctx.GetStub().GetState(key)
    if err != nil {
        return nil, fmt.Errorf("failed to get state: %v", err)
    }
    if assetJson == nil {
        return nil, fmt.Errorf("state %s not found", key)
    }

    var asset CustomAsset
    if err = json.Unmarshal(assetJson, &asset); err != nil {
        return nil, fmt.Errorf("failed to unmarshal asset: %v", err)
    }

    return asset.CreatorCert, nil
}
  • 方案2:通过复合键单独存储State与创建者的映射
    如果不希望证书字段占用State的存储体积,可以使用Fabric的复合键单独存映射关系,避免每次查询State都返回冗余的证书信息:
// 创建资产时同步写入映射关系
func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface, assetId string, content string) error {
    // 获取创建者身份
    creator, err := ctx.GetClientIdentity().GetCreator()
    if err != nil {
        return fmt.Errorf("failed to get creator identity: %v", err)
    }

    // 写入资产本身
    asset := map[string]string{
        "id":      assetId,
        "content": content,
    }
    assetJson, err := json.Marshal(asset)
    if err != nil {
        return err
    }
    if err = ctx.GetStub().PutState(assetId, assetJson); err != nil {
        return err
    }

    // 创建复合键存储创建者映射
    creatorMapKey, err := ctx.GetStub().CreateCompositeKey("creatorMapping", []string{assetId})
    if err != nil {
        return err
    }
    return ctx.GetStub().PutState(creatorMapKey, creator)
}

// 自定义GetStateCreator方法
func (s *SmartContract) GetStateCreator(ctx contractapi.TransactionContextInterface, key string) ([]byte, error) {
    creatorMapKey, err := ctx.GetStub().CreateCompositeKey("creatorMapping", []string{key})
    if err != nil {
        return nil, err
    }
    creator, err := ctx.GetStub().GetState(creatorMapKey)
    if err != nil {
        return nil, err
    }
    if creator == nil {
        return nil, fmt.Errorf("creator info for state %s not found", key)
    }
    return creator, nil
}

注意:如果是已经上线且历史State未关联存储创建者信息的场景,无法通过链码接口直接回溯获取创建者身份,仅能通过解析区块交易的读写集来关联State与对应交易的提交者。

内容的提问来源于stack exchange,提问作者Shuhan Mirza

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 12:15:06