今天我们来简单谈一下链码中stub.GetFunctionAndParameters()和stub.GetStringArgs()的区别:
stub.GetFunctionAndParameters()表示的是在链码指令中的args后面接受函数名称和参数变量,而stub.GetStringArgs()指的是在args后面直接接受参数变量,默认不是传入一个函数名称,往往用在init函数中:
首先我们测试fabric官方的链码文件,即是stub.GetFunctionAndParameters()函数的:
这里指的是,在初始化链码的时候,接收到传进去的函数名和参数,但是,函数名我们并没有使用,注意!我们不使用函数名不代表我们在实例化链码的时候不需要传入函数名参数!以下我会演示如果不传入函数名即会初始化链码错误!
按照链码规则,初始化链码的需要传入一个函数名参数和四个字符串参数,如果我们不传入函数名,直接传入后面的四个字符串参数:
他就会报错!
那么如果我们输入了函数名:
即可初始化成功!
后来我又发现,把init改成任何其他字符串也是可以初始化成功的!因为在链码中,本来就是使用stub.GetFunctionAndParameters()的时候接收函数名的时候其实就是接受了一个string类型的字符串,只要接受了这个字符串就行,不管是什么字符串都可以的,只不过我们在链码中没有使用字符串而已!
测试:我们把init换掉去:
显示是成功的!
接下来,我们测试stub.GetStringArgs(),前面说到,这个函数是直接接受参数的,并不需要传入函数名称:
我们进行另外链码的测试:
首先进行安装链码:
直接传入两个参数就可以进行链码的实例化了,这个意思是,把A作为key,后面的10作为value,传入到peer的账本数据中去!
最后,我们进行一个小结,其实stub.GetFunctionAndParameters()也能当成stub.GetStringArgs()来用,只不过最前面的参数不要使用就好了,不过要记住!哪怕我们不用最前面的参数,在cli容器中进行链码指令的时候也是要传入一个函数名的,这个函数名可以是任意的字符串!
以上图为例,其实stub.GetFunctionAndParameters()只是比stub.GetStringArgs()多了一个函数名的参数而已!其他都是一样的,具体用什么取决你自己要写的链码函数。
下面贴上我的两个函数部分:
//stub.GetStringArgs()函数部分
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response { fmt.Println("ex02 Init") ages := stub.GetStringArgs() if len(ages) != 2{ return shim.Error("初始化的参数只能为2个,分别代表名称与状态数据") } err := stub.PutState(ages[0], []byte(ages[1])) if err != nil{ return shim.Error("在保存状态时出现错误!") } return shim.Success(nil) }
//stub.GetFunctionAndParameters()函数部分
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response { fmt.Println("ex02 Init") _, args := stub.GetFunctionAndParameters() var A, B string // Entities var Aval, Bval int // Asset holdings var err error if len(args) != 4 { return shim.Error("Incorrect number of arguments. Expecting 4") } // Initialize the chaincode A = args[0] Aval, err = strconv.Atoi(args[1]) if err != nil { return shim.Error("Expecting integer value for asset holding") } B = args[2] Bval, err = strconv.Atoi(args[3]) if err != nil { return shim.Error("Expecting integer value for asset holding") } fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval) // Write the state to the ledger err = stub.PutState(A, []byte(strconv.Itoa(Aval))) if err != nil { return shim.Error(err.Error()) } err = stub.PutState(B, []byte(strconv.Itoa(Bval))) if err != nil { return shim.Error(err.Error()) } return shim.Success(nil) }