手写查询和交易go链码

myfirstcc.go

链码代码myfirstcc.go,并上传至chaincode/go中

package main

import (
   "github.com/hyperledger/fabric/core/chaincode/shim"
   pb "github.com/hyperledger/fabric/protos/peer"
   "strconv"
   "fmt"
)

type MyFirstCc struct {
}

/*
  传两个字段name,age,以及对应的值
  e.g.: name:hallen,age:18
*/
// 存储初始化后的值
var map_data map[string]interface{} = make(map[string]interface{})

func (m *MyFirstCc)Init(stub shim.ChaincodeStubInterface) pb.Response {
   _,args := stub.GetFunctionAndParameters()

   // 判断参数长度
   if len(args) != 4 {
       return shim.Error("除了函数参数,其他参数长度必须为4个长度")
  }

   key1 := args[0]
   key1_value := args[1]
   key2 := args[2]
   key2_value := args[3]

   key2_value_new,err := strconv.Atoi(key2_value)

   if err != nil {
       return shim.Error("第四个参数必须是整形")
  }

   fmt.Printf("{%s:%s,%s:%d}\n",key1,key1_value,key2,key2_value_new)
   //fmt.Printf("hello %s,您的年龄是:%d\n",key1_value,key2_value_new)
   //k1 = key1
   //k1_value = key1_value
   //k2 = key2
   //k2_value = key2_value_new

   map_data[key1] = key1_value
   map_data[key2] = key2_value_new

   ret := fmt.Sprintf("初始化成功,值为:%v",map_data)
   return shim.Success([]byte(ret))
}

func (m *MyFirstCc)query(stub shim.ChaincodeStubInterface,args []string)pb.Response {
   if len(args) != 1 {
       return shim.Error("除了函数参数,其他参数长度必须为1个长度")
  }

   k := args[0]
   k_value := map_data[k]

   fmt.Printf("%s 的值是:%v",k,k_value)
   ret := fmt.Sprintf("查询成功,%s 的值是:%v",k,k_value)

   return shim.Success([]byte(ret))
}

func (m *MyFirstCc)Invoke(stub shim.ChaincodeStubInterface)  pb.Response{
   f,args := stub.GetFunctionAndParameters()

   if f == "query"{
       return m.query(stub,args)
  }
   
   return shim.Error("函数参数必须为query")
}

func main() {
   err := shim.Start(new(MyFirstCc))

   if err != nil {
       fmt.Println("shim启动失败")
  }
}

进入容器

docker exec -it cli /bin/bash 

安装链码

peer chaincode install -n myfcc1 -p github.com/hyperledger/fabric/examples/chaincode/go/mycc -v 1.0.0

链码实例化

peer chaincode instantiate 
-o orderer.example.com:7050
-C zlktchannel
-c '{"Args":["init","name","hallen","age","13"]}'
-n myfcc1
-P "OR ('Org1.member','Org2.member')"
-v 1.0.0
--tls true
--cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
peer chaincode instantiate -o orderer.example.com:7050 -C zlktchannel -c '{"Args":["init","name","hallen","age","13"]}' -n myfcc1 -P "OR ('Org1.member','Org2.member')" -v 1.0.0 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

直接安装部署错误收集

1. main redeclared in this block   同一个包中不能出现两个main函数(将不同链码放在不同路径下)

2. Failed to execute transaction (Timeout expired while executing transaction)
  docker logs 容器id
同一个通道中可以安装多个链码,链码名不能一致,版本号可以一样
只要代码改动了,就得重新上传,重新安装,重新实例化

验证是否有新增容器

exit
docker ps -a

链码操作

//查询账户状态
peer chaincode query -C zlktchannel -n myfcc1 -c '{"Args":["query","name"]}'
//账户转账
-c '{"Args":["invoke","a","b","1"]}'
//删除指定账户:
-c '{"Args":["delete","a"]}'

升级链码,适用于链码升级

1.把代码放到chaincode挂载的目录中,然后替换原来的旧代码
  或者直接从宿主机将chaincode拷贝进cli容器
  docker cp myfirstcc.go cli:/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go

2.安装新版本chaincode
  docker exec -it cli bash
  peer chaincode install -n myfcc1 -p github.com/hyperledger/fabric/examples/chaincode/go/mycc -v 2.0.0
      -n 一定要之前的保持一致,只需要改版本号
3.更新
  peer chaincode upgrade
  -o orderer.example.com:7050  
  --tls true
  --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
  -C zlktchannel
  -n myfcc1
  -v 2.0.0
  -c '{"Args":["init"]}'
  -P "OR ('Org1.member','Org2.member')"
 

mytxcc.go

package main

import (
"github.com/hyperledger/fabric/core/chaincode/shim"
pb "github.com/hyperledger/fabric/protos/peer"
"strconv"
"fmt"
)

/*
初始化:两个账户对应两个账户金额,需要四个参数,init函数

Invoke:invoke和query函数名,三个参数

invoke:三个参数,前两个参数表示账户,第三个参数表示转账金额,第一个账户给第二个账户转钱

query:一个参数,表示账户的key,返回的是查询结果
*/
type MyTxCc struct {}

// a:100,b:200
func (m *MyTxCc) Init(stub shim.ChaincodeStubInterface) pb.Response {
_,args := stub.GetFunctionAndParameters()

if len(args) != 4 {
return shim.Error("除了函数参数外还需要四个参数")
}

a := args[0]
a_value := args[1]
a_value_new,err := strconv.Atoi(a_value)

if err != nil {
return shim.Error("第二个参数必须是整数")
}


b := args[2]
b_value := args[3]
b_value_new,err := strconv.Atoi(b_value)
if err != nil {
return shim.Error("第四个参数必须是整数")
}


// 把接收的数据初始化到账本中
err = stub.PutState(a,[]byte(strconv.Itoa(a_value_new)))
if err != nil {
return shim.Error("往账本中写入a账户出错")
}
err = stub.PutState(b,[]byte(strconv.Itoa(b_value_new)))
if err != nil {
return shim.Error("往账本中写入b账户出错")
}

return shim.Success([]byte("初始化账户成功"))

}


func (m *MyTxCc) invoke(stub shim.ChaincodeStubInterface,args []string) pb.Response{
if len(args) != 3 {
return shim.Error("除了函数参数外需要三个参数")
}

a := args[0]
b := args[1]
// 转账金额
v := args[2]
v_int,err := strconv.Atoi(v)

if err != nil {
return shim.Error("除了函数参数外第三个参数必须是整型")
}

source_a,err_a := stub.GetState(a)
source_b,err_b := stub.GetState(b)

if err_a != nil {
ret_a := fmt.Sprintf("没有该 %s 账户",a)
return shim.Error(ret_a)
}

if err_b != nil {
ret_a := fmt.Sprintf("没有该 %s 账户",b)
return shim.Error(ret_a)
}

source_a_int,_ := strconv.Atoi(string(source_a))
source_b_int,_ := strconv.Atoi(string(source_b))
source_a_int = source_a_int - v_int
source_b_int = source_b_int + v_int

err = stub.PutState(a,[]byte(strconv.Itoa(source_a_int)))
err = stub.PutState(b,[]byte(strconv.Itoa(source_b_int)))

if err != nil {
return shim.Error("转账失败")
}

return shim.Success([]byte("转账成功"))

}

func (m *MyTxCc) query(stub shim.ChaincodeStubInterface,args []string) pb.Response{

if len(args) != 1 {
return shim.Error("除了函数参数外,只能有一个参数,表示账户的key")
}

a := args[0]

a_byte,err := stub.GetState(a)

if err != nil {
return shim.Error("没有查询到该账户")
}

ret := fmt.Sprintf("查询结果,%s账户下有%s金额",a,string(a_byte))
return shim.Success([]byte(ret))


}

func (m *MyTxCc) Invoke(stub shim.ChaincodeStubInterface) pb.Response{
f,args := stub.GetFunctionAndParameters()

if f == "invoke" {
return m.invoke(stub,args)
}

if f == "query" {
return m.query(stub,args)
}
return shim.Error("第一个参数必须是invoke和query中的一个")
}

func main() {

err := shim.Start(new(MyTxCc))

if err != nil {
fmt.Println(shim.Error("启动失败"))
}
}

进入容器

docker exec -it cli /bin/bash 

安装链码

peer chaincode install -n mytxcc -p github.com/hyperledger/fabric/examples/chaincode/go/mytxcc -v 1.0.0

链码实例化

peer chaincode instantiate 
-o orderer.example.com:7050
-C zlktchannel
-c '{"Args":["init","zs","200","ls","300"]}'
-n mytxcc
-P "OR ('Org1.member','Org2.member')"
-v 1.0.0
--tls true
--cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
peer chaincode instantiate -o orderer.example.com:7050 -C zlktchannel -c '{"Args":["init","zs","200","ls","300"]}' -n mytxcc -P "OR ('Org1.member','Org2.member')" -v 1.0.0 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

链码操作

//查询
peer chaincode query -C zlktchannel -n mytxcc -c '{"Args":["query","zs"]}'
//转账交易
peer chaincode invoke -C zlktchannel -n mytxcc -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -c '{"Args":["invoke","zs","ls","20"]}'
 
posted @ 2022-04-21 10:16  开飞机的二娃  阅读(101)  评论(0)    收藏  举报