查询系统链码的使用
Usage of Query System chaincode
您好,我正在尝试通过导入作为 QSCC 一部分的分类帐包来使用这些代码查询块,但是在尝试调用时出现一些错误,请说明这是否是正确的方法。
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
为 Invoke
和 [=13] 提供的现有 API =] 链码方法。
现在,关于您要实现的逻辑,一种可能的解决方案是按以下方式使用 CreateCompositeKey
:
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,而不是尝试通过执行系统链代码直接从链代码访问分类帐。
您好,我正在尝试通过导入作为 QSCC 一部分的分类帐包来使用这些代码查询块,但是在尝试调用时出现一些错误,请说明这是否是正确的方法。
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
为 Invoke
和 [=13] 提供的现有 API =] 链码方法。
现在,关于您要实现的逻辑,一种可能的解决方案是按以下方式使用 CreateCompositeKey
:
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,而不是尝试通过执行系统链代码直接从链代码访问分类帐。