HIBE 应用配置

先描述一个层次关系如图,org2 和org1是 org50 下级


简单一个层级关系

初始化一个系统层级结构

./cmc hibe init -o wx-org50-chainmaker-org  -l 5 -s ./hibe-data

生成各组织私钥

./cmc hibe genPrvKey -m 1 \
-i wx-topL \
-k ./hibe-data/wx-org50-chainmaker-org/wx-org50-chainmaker-org.masterKey \
-p ./hibe-data/wx-org50-chainmaker-org/wx-org50-chainmaker-org.params \
-o wx-org50-chainmaker-org \
-s ./hibe-data

我们基于上面wx-org50-chainmaker-org生成的私钥为直接下属wx-org1-chainmaker-orgwx-org2-chainmaker-org 分别生成私钥

####生成wx-org1-chainmaker-org
./cmc hibe genPrvKey -m 0 \
-i wx-topL/secondL \
-k ./hibe-data/wx-org50-chainmaker-org/privateKeys/wx-topL.privateKey \
-p ./hibe-data/wx-org50-chainmaker-org/wx-org50-chainmaker-org.params \
-o wx-org1-chainmaker-org \
-s ./hibe-data

####生成wx-org2-chainmaker-org
./cmc hibe genPrvKey -m 0 \
-i wx-topL/second1L \
-k ./hibe-data/wx-org50-chainmaker-org/privateKeys/wx-topL.privateKey \
-p ./hibe-data/wx-org50-chainmaker-org/wx-org50-chainmaker-org.params \
-o wx-org2-chainmaker-org \
-s ./hibe-data

注(其中-k 表示上级私钥,-p 这个如果是同一个系统,都是一样的)
最后生成的文件目录如下

├── hibe-data
│   ├── wx-org1-chainmaker-org
│   │   └── privateKeys
│   │       └── wx-topL#secondL.privateKey
│   ├── wx-org2-chainmaker-org
│   │   └── privateKeys
│   │       └── wx-topL#second1L.privateKey
│   └── wx-org50-chainmaker-org
│       ├── privateKeys
│       │   └── wx-topL.privateKey
│       ├── wx-org50-chainmaker-org.masterKey
│       └── wx-org50-chainmaker-org.params

合约编写

合约需要注意,以下方法必须存在,且是默认的,不需要修改


//export save_hibe_params
func save_params() {
    params := Args()
    itemMap := make(map[string]string, 0)
    itemMap = EasyCodecItemToParamsMap(params)
    itemBytes := EasyMarshal(params)
    PutState("hibe_params", itemMap["org_id"], string(itemBytes))
}

//export find_params_by_org_id
func findParamsByOrgId() {
    org_id, _ := Arg("org_id")
    if result, resultCode := GetStateByte("hibe_params", org_id); resultCode != SUCCESS {
        ErrorResult("错误提示 , orgId:" + org_id)
    } else {
        LogMessage("get val:" + string(result))
        SuccessResultByte(result)
    }
}

将以上合约方法复制到你的合约中,save_params() 将各组织中的params 参数上链,findParamsByOrgId 查询组织的params 参数
真正存储密文的方法如下


//export save_hibe_msg
func saveHibeMsg() {
    parameters := Args()

    stones := make(map[string]string)
    for _, elem := range parameters {
        stones[elem.Key] = elem.Value.(string)
    }

    items := ParamsMapToEasyCodecItem(stones)
    itemsBytes := EasyMarshal(items)
    logMessage(string(itemsBytes))

    PutState("hibe", stones["tx_id"], string(itemsBytes))
}

其中能修改的仅仅只有saveHibeMsg方法名,和hibe 关键字,其他都不需要改,将合约部署在链上

go-sdk编写

基本流程如下 代码在chainmaker-sdk-go/sdk_hibe_test.go
params 参数上链,如果是多组织的话 所有组织的params都要上链,也就是所有组织都要调用save_hibe_params方法


    fmt.Println("====================== 调用合约 params 上链 (异步)======================")
    invokeUserHibeContractParams(manager_client.GetClient(),"test","save_hibe_params",txId,false)
// 上传Hibe Params
    func invokeUserHibeContractParams(client *sdk.ChainClient, contractName, method, txId string, withSyncResult bool) error {
    localParams, err := sdk.ReadHibeParamsWithFilePath(localHibeParamsFilePath)
    if err != nil {
        return err
    }
    payloadParams, err := client.CreateHibeInitParamsTxPayloadParams(orgId1, localParams)
    resp, err := client.InvokeContract(contractName, method, txId, payloadParams, -1, withSyncResult)
    if err != nil {
        return err
    }

    if resp.Code != common.TxStatusCode_SUCCESS {
        return fmt.Errorf("invoke contract failed, [code:%d]/[msg:%s]\n", resp.Code, resp.Message)
    }

    if !withSyncResult {
        fmt.Printf("invoke contract success, resp: [code:%d]/[msg:%s]/[txId:%s]\n", resp.Code, resp.Message, resp.ContractResult.Result)
    } else {
        fmt.Printf("invoke contract success, resp: [code:%d]/[msg:%s]/[contractResult:%s]\n", resp.Code, resp.Message, resp.ContractResult)
    }

    return nil
}

加密数据上链,这里可以配置 允许哪些组织查看,我这里设置了就是 只有自己和默认的上级组织可以查看,其他组织不能查看

    fmt.Println("====================== 调用合约 加密数据上链(异步)======================")
    txId = sdk.GetRandTxId()
    invokeUserHibeContractMsg(manager_client.GetClient(),"test","save_hibe_msg",txId,false)
func invokeUserHibeContractMsg( client *sdk.ChainClient, contractName, method, txId string, withSyncResult bool) error {
    // 上链的数据有那些组织可以解,这里表示
    receiverId := make([]string, 1)
    receiverId[0] = localSecond1LevelId
    // fetch orgId []string from receiverId []string
    org := make([]string, len(receiverId))
    org[0] = "wx-org2-chainmaker-org"

    // query params
    paramsBytesList := make([][]byte, 0)
    for _, id := range org {
        hibeParamsBytes, err := client.QueryHibeParamsWithOrgId(hibeContractName, findParamsByOrgId, id, -1)
        if err != nil {
            //t.Logf("QUERY hibe-contract-go-1 contract resp: %+v\n", hibeParams)
            return fmt.Errorf("client.QueryHibeParamsWithOrgId(hibeContractName, id, -1) failed, err: %v\n", err)
        }

        if len(hibeParamsBytes) == 0 {
            return fmt.Errorf("no souch params of %s's org, please check it", id)
        }

        paramsBytesList = append(paramsBytesList, hibeParamsBytes)
    }

    // 加密类型
    keyType := crypto.SM4
    params, err := client.CreateHibeTxPayloadParamsWithHibeParams([]byte(msg), receiverId, paramsBytesList, txId, keyType)
    if err != nil {
        return err
    }

    resp, err := client.InvokeContract(contractName, method, txId, params, -1, withSyncResult)
    if err != nil {
        return err
    }

    if resp.Code != common.TxStatusCode_SUCCESS {
        return fmt.Errorf("invoke contract failed, [code:%d]/[msg:%s]\n", resp.Code, resp.Message)
    }

    if !withSyncResult {
        fmt.Printf("invoke contract success, resp: [code:%d]/[msg:%s]/[txId:%s]\n", resp.Code, resp.Message, resp.ContractResult.Result)
    } else {
        fmt.Printf("invoke contract success, resp: [code:%d]/[msg:%s]/[contractResult:%s]\n", resp.Code, resp.Message, resp.ContractResult)
    }

    return nil
}

解密,特别注意解密时,并不是读取合约读写集,而是通过交易ID 来遍历交易来获取密文

    fmt.Println("====================== 执行合约 加密数据查询接口 ======================")
    func testUserHibeContractMsgGoQuery(t *testing.T, client *sdk.ChainClient,txId string) {
    //解密算法
    keyType := crypto.SM4
    localParams, err := sdk.ReadHibeParamsWithFilePath(localHibeParamsFilePath)
    require.Nil(t, err)
    topHibePrvKey, err := sdk.ReadHibePrvKeysWithFilePath(localTopLevelHibePrvKeyFilePath)
    require.Nil(t, err)
    msgBytes1, err := client.DecryptHibeTxByTxId(localTopLevelId, localParams, topHibePrvKey, txId, keyType)
    require.Nil(t, err)
    t.Logf("QUERY hibe-contract-go-1 contract resp DecryptHibeTxByBizId [Decrypt Msg By TopLevel privateKey] message: %s\n", string(msgBytes1))
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容