shim.ChaincodeStubInterface
提供了一些API,使chaincode与底层区块链网络进行交互。
在上一篇文章中,我们已经简单的使用了一些shim.ChaincodeStubInterface
的接口,完成了一个简单的读写账本的chaincode,本章会继续就shim.ChaincodeStubInterface
的一些常用接口进行一些练习。
- 获得调用参数
shim.ChaincodeStubInterface
提供了多种获取参数的方法:
GetArgs() [][]byte //以 [][]byte 形式获取参数列表
GetStringArgs() []string //以 []string形式获取参数列表
GetFunctionAndParameters() (string, []string) //将字符串数组分为两部分,第一个参数是函数名,第二个参数是函数参数,这个函数在chaincode中最为常用
GetArgsSlice() ([]byte, error) //以byte切片的形式获取参数列表
- 增删改查state DB
这是chaincode的核心操作
PutState(string,[]byte) error //增改DB,第一个参数为key,第二个参数为value。
GetState(string) ([]byte,error) //读取DB,参数为key,返回value
DelState(string) error //删除DB中key对应的数据,参数为key
- 历史数据查询
GetHistoryForKey(string) (HistoryQueryIteratorInterface,error) // 查询对某个key的所有操作
/* an example for traversal HistoryQueryIteratorInterface */
func queryHistory(results shim.HistoryQueryIteratorInterface) ([]byte, error) {
defer results.Close()
var buffer bytes.Buffer
buffer.WriteString("[")
bWrittenFlag := false
for results.HasNext() {
queryResponse, err := results.Next()
if err != nil {
return nil, err
}
if bWrittenFlag == true {
buffer.WriteString(",")
}
item, _ := json.Marshal(queryResponse)
buffer.Write(item)
bWrittenFlag = true
}
buffer.WriteString("]")
fmt.Printf("queryQresult:\n%s\n", buffer.String())
return buffer.Bytes(), nil
}
- 调用其它chaincode
//以调用example02为例
trans := [][]byte{[]byte("invoke"), []byte("a"), []byte("b"), []byte("11")} //example 02的invoke命令
res := stub.InvokeChaincode("mycc", trans, "mychannel") //1st param: install指令的-n参数;2st parm:指令 3st param:所在channel
- 获取当前用户身份
/* 获取调用这个chaincode的用户的证书。 */
func testCert(stub shim.ChaincodeStubInterface) (string, error) {
creatorByte, _ := stub.GetCreator()
certStart := bytes.IndexAny(creatorByte, "-----BEGIN")
if certStart == -1 {
return "", fmt.Errorf("invalid cert")
}
certText := creatorByte[certStart:]
bl, _ := pem.Decode(certText)
if bl == nil {
return "", fmt.Errorf("pem decode error")
}
cert, err := x509.ParseCertificate(bl.Bytes)
if err != nil {
return "", fmt.Errorf("x509 parse error")
}
uname := cert.Subject.CommonName
fmt.Printf("name = %s", uname)
return uname, nil
}