Hyperledger Fabric學習(十二)智能合約(鏈碼)使用富查詢

富查詢的使用

      鏈碼中的數據存儲都是基於K-V鍵值對的形式,通常來講,是保存在LevelDB中。可是目前Fabric支持鏈碼使用couchDB進行存儲數據、經過編寫富查詢的方式查詢數據shell

認識第一個富查詢語句

​ 富查詢語句是一種特定的json格式,以下所示:json

{
  "selector": {
    "coin": 100 
  }
}

selector對應一個列表,列表包含多個單元,每一個單元匹配一個字段,譬如上述中匹配的是知足餘額爲100的User數據網絡

在鏈碼中實現富查詢
  • 在first_cc目錄下,建立couchDB索引目錄和索引文件
# 建立索引目錄
mkdir -p META-INF/statedb/couchdb/indexes
# 建立基於coin字段的索引文件
touch META-INF/statedb/couchdb/indexes/indexCoin.json
  • 給索引文件indexCoin.json添加以下內容
{
  "index": {
    "fields": [
      "coin"
    ]
  },
  "ddoc": "indexCoinDoc",
  "name": "indexCoin",
  "type": "json"
}
  • 在first_cc.go文件中實現基於coin值進行富查詢的UserQueryByCoin函數
// 基於coin值進行用戶查詢
func UserQueryByCoin(stub shim.ChaincodeStubInterface, args []string) pb.Response {
  // 判斷參數個數
  if len(args) != 1 {
		return shim.Error("args must be one")
	}

  // 編寫富查詢語句,根據coin值進行匹配查詢
  var queryString = fmt.Sprintf(`{"selector":{"coin": %v}}`, args[0])
  // 查詢結果的變量定義
  var users = make([]User, 0)
  // 富查詢操做,返回一個迭代器
  iterator, err := stub.GetQueryResult(queryString)
  if err != nil {
	fmt.Println(err.Error())
	return shim.Error("data get failed: " + err.Error())
  }
  // defer後面的操做是函數執行退出以前的會進行的操做,這裏是關閉迭代器
  defer iterator.Close()
  
  // 循環獲取迭代器中的值
  for ; iterator.HasNext(); {
	resp, err := iterator.Next()
	if err != nil {
		fmt.Println(err.Error())
		return shim.Error("data get failed: " + err.Error())
	}
   
    // 將迭代器的值取出反序列化,存入查詢結果中
    var user User
    if err := json.Unmarshal(resp.Value, &user); err != nil {
	  fmt.Println(err.Error())
	  return shim.Error("data unmarshal failed: " + err.Error())
    }
    users = append(users, user)
  }

  // 將查詢結果序列化
  data, err := json.Marshal(users)
  if err != nil {
	fmt.Println(err.Error())
	return shim.Error("data marshal failed: " + err.Error())
  }
  fmt.Println(string(data))

  return shim.Success(data)
}
  • 在Invoke中添加函數調用
// 修改以前實現的Invoke()方法
func (t *FirstChainCode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
  /* 獲取參數,分解爲調用方法名,以及傳入的參數列表 而後根據具體的function,調用對應的以前寫過的函數 */
  function, args := stub.GetFunctionAndParameters()
	switch function {
	case "UserRegister":
		return UserRegister(stub, args)
	case "UserQuery":
		return UserQuery(stub, args)
  case "UserQueryByCoin":
    return UserQueryByCoin(stub, args)
	default:
		return shim.Error("no this function name.")
	}
}
測試使用了couchDB的鏈碼

​ MockStub測試不能支持使用了couchDB的鏈碼,所以若是須要測試富查詢的相關函數是否正確,須要模擬搭建一套fabric網絡,peer使用dev調試模式,對鏈碼進行實時調式並測試。相關說明請見
Hyperledger Fabric學習(十)智能合約(鏈碼)devplat工具測試
app

  • 使用devplat搭建fabric平臺,並安裝實例化部署好first_cc鏈碼
  • 調用UserQueryByCoin方法查詢結果
相關文章
相關標籤/搜索