首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >按价值获得世界状态

按价值获得世界状态
EN

Stack Overflow用户
提问于 2017-03-08 08:38:45
回答 2查看 1.4K关注 0票数 1

我是新的区块链,并与超级分类账结构(v:0.6,目前),以创建一个应用程序的学习视角。

我在区块链上保存财务交易的分类账,一旦交易发生(基于web的组件会通知交易发生并调用链码)。

事务的结构如下所示:

代码语言:javascript
运行
复制
type Transactions struct { 
    ReferenceNumber string `json:"ReferenceNumber"`
    BillNumber string `json:"BillNumber"`
    BillingCompany string `json:"BillingCompany"`
    Amount string `json:"Amount"`
    Status string `json:"Status"`
}

我将其封送,并将其保存到以ReferenceNumber作为密钥的状态。

现在,我可以在ReferenceNumber的基础上从状态获取事务。但是,如果我想在“状态”( status )的基础上从状态获得交易,那又如何呢?就像分类账上有多少交易的状态是“已调节的”一样。

是否有任何方法来查询状态不是基于键,而是基于值?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-03-08 12:26:12

Worldstate级存储在{key,value}级别工作。很明显,它只适用于指定键的单个值查找。我认为您所要寻找的是一个更高层次的WorldState抽象--称为表构造。fabric/examples/chaincode/go/asset_management_interactive/asset_management.go有一个关于如何创建包含所需列的表的示例。在定义数据结构的主键以保存事务时,可以将状态作为键之一,并且还可以根据状态检索数据。

创建表的一些示例代码如下所示

代码语言:javascript
运行
复制
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)
}

现在将数据插入到此表中,如下所示

代码语言:javascript
运行
复制
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")
        }

现在,若要通过未指定所有键来查询此数据,请执行以下操作

代码语言:javascript
运行
复制
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",列)允许您检索它,而无需指定所有键列。

上面的代码引用于下面的路径gerrit/src/github.com/hyperledger/fabric/bddtests/chaincode/go/table/table.go中的中的一个文件

希望这能有所帮助。

票数 2
EN

Stack Overflow用户

发布于 2017-07-28 02:51:12

在HyperledgerFabricv1.0中,您可以将数据建模为JSON,并使用CouchDB作为状态数据库。在本例中,您可以直接查询JSON的任何字段。

marbles02链码中有这样的数据模式的一个例子。

在1.0版中还有其他各种分类账和状态数据库选项

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42666568

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档