Worldstate级别的存储在{key,value}级别工作。显而易见,它仅用于指定键的单个值查找。我认为你正在寻找的是要求更高一级的WorldState抽象 - 称为表结构。 布/例子/ chaincode /去/ 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”,列)可让您检索它,而无需指定所有关键列。
上面的代码是从存在于早些时候在以下路径格里特布料GitHub库文件引用/ src目录/ github.com/hyperledger /面料/ bddtests/chaincode /去/表/ table.go
希望这有助于。
谢谢@Ashishkel这样的详细解释。我现在正在使用表格来解决问题。我设置了2列(ReferenceNumber和Status)作为键列,现在当我使用2个参数进行查询时,将返回表结果,但是当我用2个参数中的任何一个进行查询时,查询无法返回任何行。 我使用的代码与gerrit/src/github.com/hyperledger/fabric/bddtests/chaincode/go/table/table.go –
中描述的一样,可能是当前版本存在问题。我注意到的是,假设你有键A,B(按照相同顺序指定),然后GetRows在我没有指定键时以及指定A时工作。当我单独指定B时,它不起作用。尝试一下。如果你遇到的是同一个问题,那么这是继续前进的一种方式。 – Ashishkel
确切地说,它根本没有任何参数,所有的键或第一个键。我必须扭转密钥的顺序才能创建一个解决方案。尽管非常感谢你的帮助。干杯。 –