通过值获取世界状态
Getting world state by value
我是区块链新手,正在使用 hyperledger fabric(目前为 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从状态中获取交易了。但是,如果我想根据 'Status' 从状态中获取交易,比如分类账上有多少交易的状态为 'reconciled'.
有什么方法可以不根据键而是根据值来查询状态吗?
Worldstate 级存储在 {key,value} 级工作。很明显,它仅用于指定键的单个值查找。我认为您正在寻找的是更高级别的 WorldState 抽象 - 称为 Table 构造。
fabric/examples/chaincode/go/asset_management_interactive/asset_management.go 有一个关于如何创建包含所需列的 table 的示例。 在定义数据结构的主键以保存交易时,您将 Status 作为键之一,您也可以根据 Status 检索数据。
创建 table 的一些示例代码如下
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)
}
现在将数据插入此 table,如图所示
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 stub.GetRows("tableTwo", columns) 允许您检索它而无需指定所有关键列。
以上代码引用自 Fabric github 存储库中的一个文件,位于以下路径 gerrit/src/github.com/hyperledger/fabric/bddtests/chaincode/go/table/table.go
希望这对您有所帮助。
在 Hyperledger Fabric v1.0 中,您可以将数据建模为 JSON 并使用 CouchDB 作为状态数据库。在这种情况下,您可以直接查询 JSON.
的任何字段
marbles02 chaincode 中有此类数据模式的示例。
There are various other ledger and state database options in v1.0.
我是区块链新手,正在使用 hyperledger fabric(目前为 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从状态中获取交易了。但是,如果我想根据 'Status' 从状态中获取交易,比如分类账上有多少交易的状态为 'reconciled'.
有什么方法可以不根据键而是根据值来查询状态吗?
Worldstate 级存储在 {key,value} 级工作。很明显,它仅用于指定键的单个值查找。我认为您正在寻找的是更高级别的 WorldState 抽象 - 称为 Table 构造。 fabric/examples/chaincode/go/asset_management_interactive/asset_management.go 有一个关于如何创建包含所需列的 table 的示例。 在定义数据结构的主键以保存交易时,您将 Status 作为键之一,您也可以根据 Status 检索数据。
创建 table 的一些示例代码如下
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)
}
现在将数据插入此 table,如图所示
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 stub.GetRows("tableTwo", columns) 允许您检索它而无需指定所有关键列。
以上代码引用自 Fabric github 存储库中的一个文件,位于以下路径 gerrit/src/github.com/hyperledger/fabric/bddtests/chaincode/go/table/table.go
希望这对您有所帮助。
在 Hyperledger Fabric v1.0 中,您可以将数据建模为 JSON 并使用 CouchDB 作为状态数据库。在这种情况下,您可以直接查询 JSON.
的任何字段marbles02 chaincode 中有此类数据模式的示例。
There are various other ledger and state database options in v1.0.