查询系统链码的用法 [英] Usage of Query System chaincode

查看:100
本文介绍了查询系统链码的用法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过导入作为QSCC一部分的分类帐包来查询这些代码块,但是尝试调用时会出现一些错误,请澄清这是否是正确的方法.

Hi I am trying to query a block by with these piece of code by importing ledger package which is part of QSCC but there are some errors when try to invoke please clarify whether this is correct way of doing it.

func (t *SimpleChaincode) expt(stub shim.ChaincodeStubInterface, args      []string) pb.Response{

var plp ledger.PeerLedgerProvider
var pl ledger.PeerLedger
lId,err:=plp.List()
if err != nil {
    return shim.Error("Invalid transaction amount, expecting a integer value")
}
fmt.Println(" List lists the ids of the existing ledgers")
fmt.Println(lId)

yesNO,err:=plp.Exists(lId[0])
if err != nil {
    return shim.Error("Invalid transaction amount, expecting a integer value")
}
fmt.Println(" tells whether the ledger with given id exists")
fmt.Println(yesNO)

txid:=args[0]
tx,err:=pl.GetTransactionByID(txid)
if err != nil {
    return shim.Error("Invalid transaction amount, expecting a integer value")
}
fmt.Println("transaction")
fmt.Println(tx)

return shim.Success(nil)
}

错误是

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x38 pc=0x40301b]
goroutine 7 [running]:
panic(0x9eb1a0, 0xc420016040)
/opt/go/src/runtime/panic.go:500 +0x1a1
 main.(*SimpleChaincode).expt(0xfaa000, 0xf71120, 0xc42016ae80, 0xc4202faad0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, ...)
/chaincode/input/src/github.com/example_cc/example_cc.go:191 +0x5b
main.(*SimpleChaincode).Invoke(0xfaa000, 0xf71120, 0xc42016ae80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
/chaincode/input/src/github.com/example_cc/example_cc.go:98 +0x430
github.com/hyperledger/fabric/core/chaincode/shim.(*Handler).handleTransaction.func1(0xc4202389a0, 0xc4200119a0)
/opt/gopath/src/github.com/hyperledger/fabric/core/chaincode/shim/handler.go:317 +0x483
created by github.com/hyperledger/fabric/core/chaincode/shim.(*Handler).handleTransaction
/opt/gopath/src/github.com/hyperledger/fabric/core/chaincode/shim/handler.go:328 +0x49

推荐答案

首先,您不应与链代码中的分类帐结构直接交互,而应利用现有的ChaincodeStubInterface API用于链码的InvokeInit方法.

First of all to start with, you are not suppose to interact directly with a ledger structure from your chaincode, but rather to leverage existing APIs of ChaincodeStubInterface provided for Invoke and Init methods of chaincode.

现在,关于您要实现的逻辑,一种可能的解决方案是利用

Now, about the logic you are trying to achieve, one of the possible solutions would be to make use of CreateCompositeKey in the following way:

func (smartContract) Invoke(stub shim.ChaincodeStubInterface) peer.Response {

    funcName, params := stub.GetFunctionAndParameters()

    indexName := "txID~key"

    if funcName == "addNewKey" {

        key := params[0]
        value := params[1]

        keyTxIdKey, err := stub.CreateCompositeKey(indexName, []string{stub.GetTxID(), key})
        if err != nil {
            return shim.Error(err.Error())
        }

        creator, _ := stub.GetCreator()

        // Add key and value to the state
        stub.PutState(key, []byte(value))
        stub.PutState(keyTxIdKey, creator)

    } else if funcName == "checkTxID" {
        txID := params[0]

        it, _ := stub.GetStateByPartialCompositeKey(indexName, []string{txID})

        for it.HasNext() {
            keyTxIdRange, err := it.Next()
            if err != nil {
                return shim.Error(err.Error())
            }

            _, keyParts, _ := stub.SplitCompositeKey(keyTxIdRange.Key)
            key := keyParts[1]
            fmt.Printf("key affected by txID %s is %s\n", txID, key)
            txIDCreator := keyTxIdRange.Value

            sId := &msp.SerializedIdentity{}
            err := proto.Unmarshal(txIDCreator, sId)
            if err != nil {
                return shim.Error(fmt.Sprintf("Could not deserialize a SerializedIdentity, err %s", err))
            }

            bl, _ := pem.Decode(sId.IdBytes)
            if bl == nil {
                return shim.Error(fmt.Sprintf("Could not decode the PEM structure"))
            }
            cert, err := x509.ParseCertificate(bl.Bytes)
            if err != nil {
                return shim.Error(fmt.Sprintf("ParseCertificate failed %s", err))
            }

            fmt.Printf("Certificate of txID %s creator is %s", txID, cert)
        }
    }

    return shim.Success(nil)
}

当然,这只是一个例子,很多细节都遗漏了,但是关键思想是利用整个ChaincodeStubInterface中可用的API,而不是尝试通过执行系统链码直接从链码访问分类帐.

Of course this is only an example and a lot of details missed, but the key idea is to leverage APIs available throughout the ChaincodeStubInterface rather than trying to access ledger directly from the chaincode by executing system chaincodes.

这篇关于查询系统链码的用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆