查询系统链码的用法 [英] Usage of Query System chaincode
问题描述
我正在尝试通过导入作为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用于链码的Invoke
和Init
方法.
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屋!