一、编写一个转账的合约
- 创建合约文件,命令:
touch /home/test_fabric/chaincodes/test.go - 编写内容
package mainimport ( "fmt" "github.com/hyperledger/fabric-chaincode-go/shim" "github.com/hyperledger/fabric-protos-go/peer" "strconv")// SimpleChaincode example simple Chaincode implementationtype SimpleChaincode struct {}func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) peer.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)}func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) peer.Response { fmt.Println("ex02 Invoke") function, args := stub.GetFunctionAndParameters() if function == "invoke" {// Make payment of X units from A to Breturn t.invoke(stub, args) } else if function == "delete" {// Deletes an entity from its statereturn t.delete(stub, args) } else if function == "query" {// the old "Query" is now implemtned in invokereturn t.query(stub, args) } return shim.Error("Invalid invoke function name. Expecting \"invoke\" \"delete\" \"query\"")}// Transaction makes payment of X units from A to Bfunc (t *SimpleChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) peer.Response { var A, B string// Entities var Aval, Bval int // Asset holdings var X int// Transaction value var err error if len(args) != 3 {return shim.Error("Incorrect number of arguments. Expecting 3") } A = args[0] B = args[1] // Get the state from the ledger // TODO: will be nice to have a GetAllState call to ledger Avalbytes, err := stub.GetState(A) if err != nil {return shim.Error("Failed to get state") } if Avalbytes == nil {return shim.Error("Entity not found") } Aval, _ = strconv.Atoi(string(Avalbytes)) Bvalbytes, err := stub.GetState(B) if err != nil {return shim.Error("Failed to get state") } if Bvalbytes == nil {return shim.Error("Entity not found") } Bval, _ = strconv.Atoi(string(Bvalbytes)) // Perform the execution X, err = strconv.Atoi(args[2]) if err != nil {return shim.Error("Invalid transaction amount, expecting a integer value") } Aval = Aval - X Bval = Bval + X fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval) // Write the state back 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)}// Deletes an entity from statefunc (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) peer.Response { if len(args) != 1 {return shim.Error("Incorrect number of arguments. Expecting 1") } A := args[0] // Delete the key from the state in ledger err := stub.DelState(A) if err != nil {return shim.Error("Failed to delete state") } return shim.Success(nil)}// query callback representing the query of a chaincodefunc (t *SimpleChaincode) query(stub shim.ChaincodeStubInterface, args []string) peer.Response { var A string // Entities var err error if len(args) != 1 {return shim.Error("Incorrect number of arguments. Expecting name of the person to query") } A = args[0] // Get the state from the ledger Avalbytes, err := stub.GetState(A) if err != nil {jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}"return shim.Error(jsonResp) } if Avalbytes == nil {jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}"return shim.Error(jsonResp) } jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}" fmt.Printf("Query Response:%s\n", jsonResp) return shim.Success(Avalbytes)}func main() { err := shim.Start(new(SimpleChaincode)) if err != nil {fmt.Printf("Error starting Simple chaincode: %s", err) }} - 创建chaincode的打包工具,命令:
touch /home/test_fabric/chaincodes/go.modtouch /home/test_fabric/chaincodes/go.sum - go.mod内容
module chaincodesgo 1.14require ( github.com/hyperledger/fabric-chaincode-go v0.0.0-20201119163726-f8ef75b17719 github.com/hyperledger/fabric-protos-go v0.0.0-20201028172056-a3136dde2354 google.golang.org/grpc v1.24.0 // indirect) - go.sum内容
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=github.com/hyperledger/fabric-chaincode-go v0.0.0-20201119163726-f8ef75b17719 h1:FQ9AMLVSFt5QW2YBLraXW5V4Au6aFFpSl4xKFARM58Y=github.com/hyperledger/fabric-chaincode-go v0.0.0-20201119163726-f8ef75b17719/go.mod h1:N7H3sA7Tx4k/YzFq7U0EPdqJtqvM4Kild0JoCc7C0Dc=github.com/hyperledger/fabric-protos-go v0.0.0-20190919234611-2a87503ac7c9/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0=github.com/hyperledger/fabric-protos-go v0.0.0-20201028172056-a3136dde2354 h1:6vLLEpvDbSlmUJFjg1hB5YMBpI+WgKguztlONcAFBoY=github.com/hyperledger/fabric-protos-go v0.0.0-20201028172056-a3136dde2354/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0=github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco=golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542 h1:6ZQFf1D2YYDDI7eSwW8adlkkavTB9sw5I24FVtEvNUQ=golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=google.golang.org/genproto v0.0.0-20180831171423-11092d34479b h1:lohp5blsw53GBXtLyLNaTXPXS9pJ1tiTw61ZHUoE9Qw=google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A=google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=google.golang.org/grpc v1.24.0 h1:vb/1TCsVn3DcJlQ0Gs1yB1pKI6Do2/QNwxdKqmc/b0s=google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= - 设置go的环境,进入cli容器的目录/go/src/chaincodes,执行命令
go env -w GO111MODULE=ongo env -w GOPROXY=https://goproxy.cn,directgo mod vendor 二、为每个peer安装chaincode 安装流程:- 使用打包工具将go文件打包成.tar.gz文件,由于在此方法中cli只有一个,所以打包执行一次即可,打包命令
peer lifecycle chaincode package test_chaincode.tar.gz --path ${GOPATH}/src/chaincodes --lang golang --label test_chaincode - 将.tar.gz文件上传到每一个peer上进行安装
- 进入cli容器,命令:
docker exec -it fabric-cli /bin/bash - 进入容器的tmp目录,命令:
cd /tmp - 设置环境变量,使用org1-peer0身份
export org=1export peer=0export CORE_PEER_LOCALMSPID=Org${org}MSPexport CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/Admin@org${org}.example.com/mspexport CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/peers/peer${peer}.org${org}.example.com/tls/ca.crt - 安装chaincode,命令
peer lifecycle chaincode install test_chaincode.tar.gz 2.2、为org1-peer1安装chaincode - 进入cli容器,命令:
docker exec -it fabric-cli /bin/bash - 进入容器的tmp目录,命令:
cd /tmp - 设置环境变量,使用org1-peer1身份
export org=1export peer=1export CORE_PEER_LOCALMSPID=Org${org}MSPexport CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/Admin@org${org}.example.com/mspexport CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/peers/peer${peer}.org${org}.example.com/tls/ca.crt - 安装chaincode,命令
peer lifecycle chaincode install test_chaincode.tar.gz 2.3、为org2-peer0安装chaincode - 进入cli容器,命令:
docker exec -it fabric-cli /bin/bash - 进入容器的tmp目录,命令:
cd /tmp - 设置环境变量,使用org2-peer0身份
export org=2export peer=0export CORE_PEER_LOCALMSPID=Org${org}MSPexport CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/Admin@org${org}.example.com/mspexport CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/peers/peer${peer}.org${org}.example.com/tls/ca.crt - 安装chaincode,命令
peer lifecycle chaincode install test_chaincode.tar.gz 2.4、为org2-peer1安装chaincode - 进入cli容器,命令:
docker exec -it fabric-cli /bin/bash - 进入容器的tmp目录,命令:
cd /tmp - 设置环境变量,使用org2-peer1身份
export org=2export peer=1export CORE_PEER_LOCALMSPID=Org${org}MSPexport CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/Admin@org${org}.example.com/mspexport CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/peers/peer${peer}.org${org}.example.com/tls/ca.crt - 安装chaincode,命令
peer lifecycle chaincode install test_chaincode.tar.gz 三、验证安装 3.1、在org1-peer0上验证安装 - 进入cli容器,命令:
docker exec -it fabric-cli /bin/bash - 进入容器的tmp目录,命令:
cd /tmp - 设置环境变量,使用org1-peer0身份
export org=1export peer=0export CORE_PEER_LOCALMSPID=Org${org}MSPexport CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/Admin@org${org}.example.com/mspexport CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/peers/peer${peer}.org${org}.example.com/tls/ca.crt - 验证安装chaincode,命令
peer lifecycle chaincode queryinstalled --output json --connTimeout "3s" 3.2、在org2-peer0上验证安装 - 进入cli容器,命令:
docker exec -it fabric-cli /bin/bash - 进入容器的tmp目录,命令:
cd /tmp - 设置环境变量,使用org2-peer0身份
export org=2export peer=0export CORE_PEER_LOCALMSPID=Org${org}MSPexport CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/Admin@org${org}.example.com/mspexport CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/peers/peer${peer}.org${org}.example.com/tls/ca.crt - 验证安装chaincode,命令
peer lifecycle chaincode queryinstalled --output json --connTimeout "3s"四、对已安装的链码进行审批
- 对已安装的chaincode进行查询,获取其查询结果的package_id值,这里的是:
test_chaincode:6afa06381da3894197917b23017e474470dbb072c80257dc9103b7a214915dae - 分别在org1-peer0以及org2-peer0上对链码进行审批,并指定背书策略
- 进入cli容器,命令:
docker exec -it fabric-cli /bin/bash - 进入容器的tmp目录,命令:
cd /tmp - 设置环境变量,使用org1-peer0身份
export org=1export peer=0export CORE_PEER_LOCALMSPID=Org${org}MSPexport CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/Admin@org${org}.example.com/mspexport CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/peers/peer${peer}.org${org}.example.com/tls/ca.crt - 对链码进行审批,并通过属性
--signature-policy指定背书策略,命令
#没有开启tlspeer lifecycle chaincode approveformyorg --peerAddresses ${CORE_PEER_ADDRESS} --channelID businesschannel --name test_chaincode --version 1.0 --init-required --package-id test_chaincode:6afa06381da3894197917b23017e474470dbb072c80257dc9103b7a214915dae --sequence 1 --signature-policy "OR ('Org1MSP.member','Org2MSP.member')" --waitForEvent --orderer orderer0.example.com:7050#开启tlspeer lifecycle chaincode approveformyorg --peerAddresses ${CORE_PEER_ADDRESS} --tlsRootCertFiles ${CORE_PEER_TLS_ROOTCERT_FILE} --channelID businesschannel --name test_chaincode --version 1.0 --init-required --package-id test_chaincode:6afa06381da3894197917b23017e474470dbb072c80257dc9103b7a214915dae --sequence 1 --signature-policy "OR ('Org1MSP.member','Org2MSP.member')" --waitForEvent --orderer orderer0.example.com:7050 --tls true --cafile /etc/hyperledger/fabric/crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/tls/ca.crt 4.1、在org2-peer0上对链码进行审批,并指定背书策略 - 进入cli容器,命令:
docker exec -it fabric-cli /bin/bash - 进入容器的tmp目录,命令:
cd /tmp - 设置环境变量,使用org2-peer0身份
export org=2export peer=0export CORE_PEER_LOCALMSPID=Org${org}MSPexport CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/Admin@org${org}.example.com/mspexport CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/peers/peer${peer}.org${org}.example.com/tls/ca.crt - 对链码进行审批,并通过属性
--signature-policy指定背书策略,命令
#没有开启tlspeer lifecycle chaincode approveformyorg --peerAddresses ${CORE_PEER_ADDRESS} --channelID businesschannel --name test_chaincode --version 1.0 --init-required --package-id test_chaincode:6afa06381da3894197917b23017e474470dbb072c80257dc9103b7a214915dae --sequence 1 --signature-policy "OR ('Org1MSP.member','Org2MSP.member')" --waitForEvent --orderer orderer0.example.com:7050#开启tlspeer lifecycle chaincode approveformyorg --peerAddresses ${CORE_PEER_ADDRESS} --tlsRootCertFiles ${CORE_PEER_TLS_ROOTCERT_FILE} --channelID businesschannel --name test_chaincode --version 1.0 --init-required --package-id test_chaincode:6afa06381da3894197917b23017e474470dbb072c80257dc9103b7a214915dae --sequence 1 --signature-policy "OR ('Org1MSP.member','Org2MSP.member')" --waitForEvent --orderer orderer0.example.com:7050 --tls true --cafile /etc/hyperledger/fabric/crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/tls/ca.crt 五、查询指定peer上审批过的chaincode 5.1、在org1-peer0上进行查询 - 进入cli容器,命令:
docker exec -it fabric-cli /bin/bash - 进入容器的tmp目录,命令:
cd /tmp - 设置环境变量,使用org1-peer0身份
export org=1export peer=0export CORE_PEER_LOCALMSPID=Org${org}MSPexport CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/Admin@org${org}.example.com/mspexport CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/peers/peer${peer}.org${org}.example.com/tls/ca.crt - 查询审批结果,命令
peer lifecycle chaincode queryapproved --peerAddresses ${CORE_PEER_ADDRESS} --tlsRootCertFiles ${CORE_PEER_TLS_ROOTCERT_FILE} --channelID businesschannel --name test_chaincode --output json - 返回该节点org1-peer0审批过的chancode,这里只审批了test_chaincode,所以只有chaincode
- 进入cli容器,命令:
docker exec -it fabric-cli /bin/bash - 进入容器的tmp目录,命令:
cd /tmp - 设置环境变量,使用org2-peer0身份
export org=2export peer=0export CORE_PEER_LOCALMSPID=Org${org}MSPexport CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/Admin@org${org}.example.com/mspexport CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/peers/peer${peer}.org${org}.example.com/tls/ca.crt - 查询审批结果,命令
peer lifecycle chaincode queryapproved --peerAddresses ${CORE_PEER_ADDRESS} --tlsRootCertFiles ${CORE_PEER_TLS_ROOTCERT_FILE} --channelID businesschannel --name test_chaincode --output json 六、查询指定chaincode是否可以提交 - 查询意义:在chaincode安装时,经历了审批步骤如第四步,并通过属性
--signature-policy指定背书策略,所以指定chaincode需要满足了指定的背书策略,才可以提交并使用
- 进入cli容器,命令:
docker exec -it fabric-cli /bin/bash - 进入容器的tmp目录,命令:
cd /tmp - 设置环境变量,使用org1-peer0身份
export org=1export peer=0export CORE_PEER_LOCALMSPID=Org${org}MSPexport CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/Admin@org${org}.example.com/mspexport CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/peers/peer${peer}.org${org}.example.com/tls/ca.crt - 查询审批结果,命令
peer lifecycle chaincode checkcommitreadiness --channelID businesschannel --name test_chaincode --version 1.0 --output json --sequence 1 七、向通道提交链码 - 提交可以在一个peer上完成,这里使用org1-peer0进行操作
- 进入cli容器,命令:
docker exec -it fabric-cli /bin/bash - 进入容器的tmp目录,命令:
cd /tmp - 设置环境变量,使用org1-peer0身份
export org=1export peer=0export CORE_PEER_LOCALMSPID=Org${org}MSPexport CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/Admin@org${org}.example.com/mspexport CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/peers/peer${peer}.org${org}.example.com/tls/ca.crt - 使用org1-per0以及org2-peer0的证书,将chaincode提交到这两个节点上,命令
# 开启tlspeer lifecycle chaincode commit -o orderer0.example.com:7050 --channelID businesschannel --name test_chaincode --version 1.0 --init-required --sequence 1 \--peerAddresses peer0.org1.example.com:7051 \--tlsRootCertFiles /etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \--peerAddresses peer0.org2.example.com:7051 \--tlsRootCertFiles /etc/hyperledger/fabric/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \--waitForEvent \--signature-policy "OR ('Org1MSP.member','Org2MSP.member')" \--tls true \--cafile /etc/hyperledger/fabric/crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/tls/ca.crt# 未开启tlspeer lifecycle chaincode commit -o orderer0.example.com:7050 --channelID businesschannel --name test_chaincode --version 1.0 --init-required --sequence 1 \--peerAddresses peer0.org1.example.com:7051 \--tlsRootCertFiles /etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \--peerAddresses peer0.org2.example.com:7051 \--tlsRootCertFiles /etc/hyperledger/fabric/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \--waitForEvent \--signature-policy "OR ('Org1MSP.member','Org2MSP.member')" 八、查询指定通道上已经提交的链码
- 这里使用org1-peer0的身份进行查询,因为channel在org1与org2之间,所以用一个节点查询即可
- 进入cli容器,命令:
docker exec -it fabric-cli /bin/bash - 进入容器的tmp目录,命令:
cd /tmp - 设置环境变量,使用org1-peer0身份
export org=1export peer=0export CORE_PEER_LOCALMSPID=Org${org}MSPexport CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/Admin@org${org}.example.com/mspexport CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/peers/peer${peer}.org${org}.example.com/tls/ca.crt - 查询命令
peer lifecycle chaincode querycommitted --channelID businesschannel --output json - 可以看到
chaincode_definitions属性里的数组只有一个值:test_chaincode
- 进入cli容器,命令:
docker exec -it fabric-cli /bin/bash - 进入容器的tmp目录,命令:
cd /tmp - 设置环境变量,使用org1-peer0身份
export org=1export peer=0export CORE_PEER_LOCALMSPID=Org${org}MSPexport CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/Admin@org${org}.example.com/mspexport CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/peers/peer${peer}.org${org}.example.com/tls/ca.crt - 初始化操作,命令
#开启tlspeer chaincode invoke -o orderer0.example.com:7050 --channelID businesschannel --name test_chaincode --peerAddresses ${CORE_PEER_ADDRESS} --tlsRootCertFiles ${CORE_PEER_TLS_ROOTCERT_FILE} --isInit -c '{"Args":["init","a","100","b","200"]}' --tls --cafile /etc/hyperledger/fabric/crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/msp/tlscacerts/tlsca.example.com-cert.pem#未开启tlspeer chaincode invoke -o orderer0.example.com:7050 --channelID businesschannel --name test_chaincode --peerAddresses ${CORE_PEER_ADDRESS} --tlsRootCertFiles ${CORE_PEER_TLS_ROOTCERT_FILE} --isInit -c '{"Args":["init","a","100","b","200"]}' 9.2、在org1-peer1上进行初始状态查询操作 - 进入cli容器,命令:
docker exec -it fabric-cli /bin/bash - 进入容器的tmp目录,命令:
cd /tmp - 设置环境变量,使用org1-peer1身份
export org=1export peer=1export CORE_PEER_LOCALMSPID=Org${org}MSPexport CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/Admin@org${org}.example.com/mspexport CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/peers/peer${peer}.org${org}.example.com/tls/ca.crt - 初始状态查询操作,命令
peer chaincode query -C businesschannel -n test_chaincode -c '{"Args":["query","a"]}' 9.3、在org2-peer0上进行转账操作 - 进入cli容器,命令:
docker exec -it fabric-cli /bin/bash - 进入容器的tmp目录,命令:
cd /tmp - 设置环境变量,使用org2-peer0身份
export org=2export peer=0export CORE_PEER_LOCALMSPID=Org${org}MSPexport CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/Admin@org${org}.example.com/mspexport CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/peers/peer${peer}.org${org}.example.com/tls/ca.crt - 转账操作,命令
#开启tlspeer chaincode invoke -o orderer0.example.com:7050 --channelID businesschannel --name test_chaincode -c '{"Args":["invoke","a","b","10"]}' --tls --cafile /etc/hyperledger/fabric/crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/tls/ca.crt#未开启tlspeer chaincode invoke -o orderer0.example.com:7050 --channelID businesschannel --name test_chaincode -c '{"Args":["invoke","a","b","10"]}' 9.2、在org2-peer1上进行转账后状态查询操作 - 进入cli容器,命令:
docker exec -it fabric-cli /bin/bash - 进入容器的tmp目录,命令:
cd /tmp - 设置环境变量,使用org2-peer1身份
export org=2export peer=1export CORE_PEER_LOCALMSPID=Org${org}MSPexport CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/Admin@org${org}.example.com/mspexport CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/peers/peer${peer}.org${org}.example.com/tls/ca.crt - 状态查询操作,命令
#查询a账户peer chaincode query -C businesschannel -n test_chaincode -c '{"Args":["query","a"]}'#查询b账户peer chaincode query -C businesschannel -n test_chaincode -c '{"Args":["query","b"]}'
- 春季老年人吃什么养肝?土豆、米饭换着吃
- 三八妇女节节日祝福分享 三八妇女节节日语录
- 老人谨慎!选好你的“第三只脚”
- 校方进行了深刻的反思 青岛一大学生坠亡校方整改校规
- 脸皮厚的人长寿!有这特征的老人最长寿
- 长寿秘诀:记住这10大妙招 100%增寿
- 春季老年人心血管病高发 3条保命要诀
- 眼睛花不花要看四十八 老年人怎样延缓老花眼
- 香槟然能防治老年痴呆症? 一天三杯它人到90不痴呆
- 老人手抖的原因 为什么老人手会抖
