2017-03-08 7 views
0

저는 원근법 학습을위한 응용 프로그램을 만들기 위해 하이브리드 패브릭 (v : 0.6)을 사용하여 블록 체인을하고 새 작업을했습니다.값으로 세계 상태 가져 오기

트랜잭션이 발생하면 블록 체인에 금융 거래의 원장을 두는 중입니다. 웹 기반 구성 요소는 트랜잭션 발생을 알리고 체인 코드를 호출합니다.

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

내가 보안관이 JSON과 키로 ReferenceNumber와 상태로 저장 :

거래의 구조는 다음과 같이 보인다.

이제 ReferenceNumber에 기초하여 상태에서 트랜잭션을 가져올 수 있습니다. 그러나 원장의 거래가 '조정 된'상태 인 상태와 같은 '상태'라고 가정 할 때 거래를 상태에서 가져 오려면 어떻게해야합니까?

키를 기준으로하지 않고 상태를 쿼리 할 수있는 방법이 있습니까?

답변

1

세계 상태 수준 저장은 {key, value} 수준에서 작동합니다. 그리고 명백한 것만이 지정된 키에 대한 단일 값 검색을위한 것입니다. 제 생각에 당신이 찾고있는 것은 WorldState의 추상화의 한 단계 높은 수준 - Table 구조라고 부름을 요구합니다. fabric/examples/chaincode/go/asset_management_interactive/asset_management.go에는 원하는 열이있는 테이블을 만드는 방법에 대한 예제가 있습니다. 트랜잭션을 보유하기 위해 데이터 구조의 기본 키를 정의 할 때 Status를 키 중 하나로 포함하면 Status를 기준으로 데이터를 검색 할 수 있습니다 (). 이제

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의의의 repo에 있던 파일에서 인용/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를 지정할 때 작동한다는 것입니다. B만을 지정하면 작동하지 않습니다. 시도 해봐. 당신이 마주 치고있는 것이 같은 문제라면, 이것이 앞으로 나아갈 수있는 하나의 방법입니다. – Ashishkel

+0

정확히 모든 인수 또는 모든 키 또는 첫 번째 키와 함께 작동합니다. 작업 환경을 만들기 위해 키의 명령을 취소해야합니다. 그래도 도움을 주셔서 감사합니다. 건배. –