2017-03-08 7 views
0

私はブロックスケーリングとhyperledgerファブリック(現在はv:0.6)を使って学習の視点のためのアプリケーションを作成するのが初めてです。値で世界の状態を取得する

トランザクションが発生するとすぐにブロックチェーン上に金融取引の元帳を保管しています(Webベースのコンポーネントがトランザクションの発生を通知してチェーンコードを呼び出す)。私はこれをマーシャリングし、キーとしてReferenceNumberと述べるためにそれを保存し、JSON

type Transactions struct { 
    ReferenceNumber string `json:"ReferenceNumber"` 
    BillNumber string `json:"BillNumber"` 
    BillingCompany string `json:"BillingCompany"` 
    Amount string `json:"Amount"` 
    Status string `json:"Status"` 
} 

取引の構造は次のようになります。

今、私はReferenceNumberに基づいて州からの取引を得ることができます。しかし、もし私が州からの取引を取得したいのであれば、元帳上の取引の数が「調整済み」のような「ステータス」と言いましょう。

キーを基にして状態を照会する方法はありますか?

答えて

1

世界州レベルのストレージは{key、value}レベルで動作します。また、明示的には、指定されたキーの単一の値の検索のみを対象としています。私はあなたが探しているものは、WorldStateの抽象概念の次のレベルのより高いレベルを要求していると思います。これはTableコンストラクトと呼ばれます。 fabric/examples/chaincode/go/asset_management_interactive/asset_management.goには、必要な列を含むテーブルを作成する方法の例があります。 トランザクションを保持するためにデータ構造の主キーを定義しているときに、ステータスをキーの1つとして含めると、ステータスに基づいてデータを取得することもできます。

func createTableTwo(stub shim.ChaincodeStubInterface) error { 
    var columnDefsTableTwo []*shim.ColumnDefinition 
    columnOneTableTwoDef := shim.ColumnDefinition{Name: "colOneTableTwo", 
     Type: shim.ColumnDefinition_STRING, Key: true} 
    columnTwoTableTwoDef := shim.ColumnDefinition{Name: "colTwoTableTwo", 
     Type: shim.ColumnDefinition_INT32, Key: false} 
    columnThreeTableTwoDef := shim.ColumnDefinition{Name: "colThreeTableThree", 
     Type: shim.ColumnDefinition_INT32, Key: true} 
    columnFourTableTwoDef := shim.ColumnDefinition{Name: "colFourTableFour", 
     Type: shim.ColumnDefinition_STRING, Key: true} 
    columnDefsTableTwo = append(columnDefsTableTwo, &columnOneTableTwoDef) 
    columnDefsTableTwo = append(columnDefsTableTwo, &columnTwoTableTwoDef) 
    columnDefsTableTwo = append(columnDefsTableTwo, &columnThreeTableTwoDef) 
    columnDefsTableTwo = append(columnDefsTableTwo, &columnFourTableTwoDef) 
    return stub.CreateTable("tableTwo", columnDefsTableTwo) 
} 

下には、このテーブルにデータを挿入するようにすべてのキーを指定しないことによって、このデータを照会するために今

if len(args) < 4 { 
      return nil, errors.New("insertRowTableTwo failed. Must include 4 column values") 
     } 

     col1Val := args[0] 
     col2Int, err := strconv.ParseInt(args[1], 10, 32) 
     if err != nil { 
      return nil, errors.New("insertRowTableTwo failed. arg[1] must be convertable to int32") 
     } 
     col2Val := int32(col2Int) 
     col3Int, err := strconv.ParseInt(args[2], 10, 32) 
     if err != nil { 
      return nil, errors.New("insertRowTableTwo failed. arg[2] must be convertable to int32") 
     } 
     col3Val := int32(col3Int) 
     col4Val := args[3] 

     var columns []*shim.Column 
     col1 := shim.Column{Value: &shim.Column_String_{String_: col1Val}} 
     col2 := shim.Column{Value: &shim.Column_Int32{Int32: col2Val}} 
     col3 := shim.Column{Value: &shim.Column_Int32{Int32: col3Val}} 
     col4 := shim.Column{Value: &shim.Column_String_{String_: col4Val}} 
     columns = append(columns, &col1) 
     columns = append(columns, &col2) 
     columns = append(columns, &col3) 
     columns = append(columns, &col4) 

     row := shim.Row{Columns: columns} 
     ok, err := stub.InsertRow("tableTwo", row) 
     if err != nil { 
      return nil, fmt.Errorf("insertRowTableTwo operation failed. %s", err) 
     } 
     if !ok { 
      return nil, errors.New("insertRowTableTwo operation failed. Row with given key already exists") 
     } 

に示すよう

テーブルを作成するためのいくつかのサンプルコードは、ありますあなたがデータを挿入したら

if len(args) < 1 { 
      return nil, errors.New("getRowsTableTwo failed. Must include at least key values") 
     } 

     var columns []shim.Column 

     col1Val := args[0] 
     col1 := shim.Column{Value: &shim.Column_String_{String_: col1Val}} 
     columns = append(columns, col1) 

     if len(args) > 1 { 
      col2Int, err := strconv.ParseInt(args[1], 10, 32) 
      if err != nil { 
       return nil, errors.New("getRowsTableTwo failed. arg[1] must be convertable to int32") 
      } 
      col2Val := int32(col2Int) 
      col2 := shim.Column{Value: &shim.Column_Int32{Int32: col2Val}} 
      columns = append(columns, col2) 
     } 

     rowChannel, err := stub.GetRows("tableTwo", columns) 
     if err != nil { 
      return nil, fmt.Errorf("getRowsTableTwo operation failed. %s", err) 
     } 

     var rows []shim.Row 
     for { 
      select { 
      case row, ok := <-rowChannel: 
       if !ok { 
        rowChannel = nil 
       } else { 
        rows = append(rows, row) 
       } 
      } 
      if rowChannel == nil { 
       break 
      } 
     } 

     jsonRows, err := json.Marshal(rows) 
     if err != nil { 
      return nil, fmt.Errorf("getRowsTableTwo operation failed. Error marshaling JSON: %s", err) 
     } 

     return jsonRows, nil 

以下のようにしてください、API スタブ.GetRows( "tableTwo"、columns)を使用すると、すべてのキー列を指定せずに取得できます。上記のコード

は、ファブリックのGitHubリポジトリに存在したファイルから引用された先に次のパスヘリット/ SRC/github.com/hyperledger /ファブリック/ bddtests/chaincode /行く/テーブル/ table.goで

これが役立つことを願っています。

+0

このような詳細な説明は@Ashishkelありがとうございます。私は現在、テーブルを使って作業しています。私は2つの列(ReferenceNumberとStatus)をキー列として設定しました.2つの引数を使用してクエリを実行すると、テーブルの結果が返されますが、2つの引数のいずれかを使用してクエリを実行すると、 gerrit/src/github.com/hyperledger/fabric/bddtests/chaincode/go/table/table.goに記載されているのと同じコードを使用しています –

+0

現在のバージョンに問題があるかもしれません。私が気づいたのは、キーA、B(同じ順序で指定されている)を持っていて、GetRowsがキーを指定していないときとAを指定しているときです。それを試してみてください。あなたが遭遇していることが同じ問題であれば、これは先に進める一つの方法です。 – Ashishkel

+0

まったく引数なし、すべてのキー、または最初のキーで動作します。私は回避策を作るためにキーの順序を逆にする必要があります。でも、助けてくれてありがとう。乾杯。 –

関連する問題