【注意】最后更新于 October 16, 2017,文中内容可能已过时,请谨慎使用。
最近在开发chaincode的时候遇到了一个问题,使用GetFunctionAndParameters这个函数会返回一个函数以及参数,但是运行总是出了点问题。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
function, args := stub.GetFunctionAndParameters()
if function != "invoke" {
return shim.Error("Unknown function call")
}
if len(args) < 2 {
return shim.Error("Incorrect number of arguments. Expecting at least 2")
}
if args[0] == "delete" {
// Deletes an entity from its state
return t.delete(stub, args)
}
|
我之前写chaincode的时候,参考官方写的实例,把args[0]
作为要调用的函数,其余的是函数使用的参数,结果总是报一些明明奇妙的错误
1
|
Incorrect number of arguments. Expecting 1 |
或者直接函数数据内容出错。
这个不应该啊,难道数据不是这么传递的?
好吧,查看下源代码。
首先要查看的函数是
1
|
stub.GetFunctionAndParameters()
|
通过传参可以看到stub
是shim.ChaincodeStubInterface
对象(就这么不标准的说吧),去shim
包下找一找,没有看到ChaincodeStubInterface
这个接口函数。
但是有个interfaces.go文件,点开查看,确实有这么个接口,对于这个函数有以下内容
1
2
3
4
5
|
// GetFunctionAndParameters returns the first argument as the function
// name and the rest of the arguments as parameters in a string array.
// Only use GetFunctionAndParameters if the client passes arguments intended
// to be used as strings.
GetFunctionAndParameters() (string, []string)
|
到这个地方,看上面对于接口的解释就可以看明白了。这个函数将传入的参数拆分返回两部分内容,第一个参数作为函数名称,其余的是函数的参数。
但是我还有点虚,既然都看到这了,全部查看完吧。
看看那个struct
实现了这个接口吧。直接找不好找啊,
1
|
grep -r "GetFunctionAndParameters"
|
恩,就在同一个目录下的chaincode.go文件里面。可以看到函数是这么写的
1
2
3
4
5
6
7
8
9
10
11
|
// GetFunctionAndParameters documentation can be found in interfaces.go
func (stub *ChaincodeStub) GetFunctionAndParameters() (function string, params []string) {
allargs := stub.GetStringArgs()
function = ""
params = []string{}
if len(allargs) >= 1 {
function = allargs[0]
params = allargs[1:]
}
return
}
|
真相大白了!获取到所有的参数,然后拆分,返回!
等等!这个stub.GetStringArgs()
是获取到的我所有的参数还是其他的什么内容?来看一下
1
2
3
4
5
6
7
8
9
|
// GetStringArgs documentation can be found in interfaces.go
func (stub *ChaincodeStub) GetStringArgs() []string {
args := stub.GetArgs()
strargs := make([]string, 0, len(args))
for _, barg := range args {
strargs = append(strargs, string(barg))
}
return strargs
}
|
是调用GetArgs()
函数,生成slice
作为数组返回!
继续看下GetArgs()
函数。
1
2
3
4
|
// GetArgs documentation can be found in interfaces.go
func (stub *ChaincodeStub) GetArgs() [][]byte {
return stub.args
}
|
好简单,返回stub
的参数,看来ChaincodeStub
这个结构体里面应该是有这个参数的,果然如此。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
type ChaincodeStub struct {
TxID string
chaincodeEvent *pb.ChaincodeEvent
args [][]byte
handler *Handler
signedProposal *pb.SignedProposal
proposal *pb.Proposal
// Additional fields extracted from the signedProposal
creator []byte
transient map[string][]byte
binding []byte
}
|
好了,问题得解!