先描述一個層次關(guān)系如圖,org2 和org1是 org50 下級

簡單一個層級關(guān)系
初始化一個系統(tǒng)層級結(jié)構(gòu)
./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-org和wx-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 這個如果是同一個系統(tǒng),都是一樣的)
最后生成的文件目錄如下
├── 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
合約編寫
合約需要注意,以下方法必須存在,且是默認(rèn)的,不需要修改
//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)
}
}
將以上合約方法復(fù)制到你的合約中,save_params() 將各組織中的params 參數(shù)上鏈,findParamsByOrgId 查詢組織的params 參數(shù)
真正存儲密文的方法如下
//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 關(guān)鍵字,其他都不需要改,將合約部署在鏈上
go-sdk編寫
基本流程如下 代碼在chainmaker-sdk-go/sdk_hibe_test.go
params 參數(shù)上鏈,如果是多組織的話 所有組織的params都要上鏈,也就是所有組織都要調(diào)用save_hibe_params方法
fmt.Println("====================== 調(diào)用合約 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
}
加密數(shù)據(jù)上鏈,這里可以配置 允許哪些組織查看,我這里設(shè)置了就是 只有自己和默認(rèn)的上級組織可以查看,其他組織不能查看
fmt.Println("====================== 調(diào)用合約 加密數(shù)據(jù)上鏈(異步)======================")
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 {
// 上鏈的數(shù)據(jù)有那些組織可以解,這里表示
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("====================== 執(zhí)行合約 加密數(shù)據(jù)查詢接口 ======================")
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))
}