2017-09-27 58 views
1

您好我想通過導入作爲QSCC一部分的分類包來查詢這些代碼塊,但在嘗試調用時出現一些錯誤,請澄清這是否是正確的方式。查詢系統chaincode的使用

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 
+0

你爲什麼要從chaincode查詢塊? –

+0

如果我發送一個TxId給chaincode,我需要知道它已經對哪個密鑰採取了行動,哪個是該密鑰的前一個交易,誰是那些以前的交易的創建者,基於這個我會做出一些決定 –

+0

如果這不是合適的執行出處的方式可能是什麼? –

回答

1

所有入手:首先,你是不是想直接從您的chaincode橫木結構進行交互,而是利用提供InvokeChaincodeStubInterface現有的API和Init鏈碼的方法。現在

,你正在努力實現的邏輯,可能的解決方案之一將是利用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,而不是試圖通過執行系統鏈代碼直接從鏈碼訪問分類賬。