实验第七节——用户chaincode相关操作_想学习安全的小白的博客-程序员秘密

技术标签: fabric  # fabric实验  

一、编写一个转账的合约

  1. 创建合约文件,命令:touch /home/test_fabric/chaincodes/test.go
  2. 编写内容
package main

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

// SimpleChaincode example simple Chaincode implementation
type 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 B
		return t.invoke(stub, args)
	} else if function == "delete" {
    
		// Deletes an entity from its state
		return t.delete(stub, args)
	} else if function == "query" {
    
		// the old "Query" is now implemtned in invoke
		return t.query(stub, args)
	}

	return shim.Error("Invalid invoke function name. Expecting \"invoke\" \"delete\" \"query\"")
}

// Transaction makes payment of X units from A to B
func (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 state
func (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 chaincode
func (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)
	}
}
  1. 创建chaincode的打包工具,命令:
touch /home/test_fabric/chaincodes/go.mod
touch /home/test_fabric/chaincodes/go.sum
  1. go.mod内容
module chaincodes
go 1.14
require (
	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
)
  1. 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=
  1. 设置go的环境,进入cli容器的目录/go/src/chaincodes,执行命令
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct
go mod vendor

二、为每个peer安装chaincode

安装流程:

  1. 使用打包工具将go文件打包成.tar.gz文件,由于在此方法中cli只有一个,所以打包执行一次即可,打包命令
peer lifecycle chaincode package test_chaincode.tar.gz --path ${GOPATH}/src/chaincodes --lang golang --label test_chaincode
  1. 将.tar.gz文件上传到每一个peer上进行安装

2.1、为org1-peer0安装chaincode

  1. 进入cli容器,命令:docker exec -it fabric-cli /bin/bash
  2. 进入容器的tmp目录,命令:cd /tmp
  3. 设置环境变量,使用org1-peer0身份
export org=1
export peer=0
export CORE_PEER_LOCALMSPID=Org${org}MSP
export CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/[email protected]${org}.example.com/msp
export 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
  1. 安装chaincode,命令
peer lifecycle chaincode install test_chaincode.tar.gz

2.2、为org1-peer1安装chaincode

  1. 进入cli容器,命令:docker exec -it fabric-cli /bin/bash
  2. 进入容器的tmp目录,命令:cd /tmp
  3. 设置环境变量,使用org1-peer1身份
export org=1
export peer=1
export CORE_PEER_LOCALMSPID=Org${org}MSP
export CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/[email protected]${org}.example.com/msp
export 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
  1. 安装chaincode,命令
peer lifecycle chaincode install test_chaincode.tar.gz

2.3、为org2-peer0安装chaincode

  1. 进入cli容器,命令:docker exec -it fabric-cli /bin/bash
  2. 进入容器的tmp目录,命令:cd /tmp
  3. 设置环境变量,使用org2-peer0身份
export org=2
export peer=0
export CORE_PEER_LOCALMSPID=Org${org}MSP
export CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/[email protected]${org}.example.com/msp
export 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
  1. 安装chaincode,命令
peer lifecycle chaincode install test_chaincode.tar.gz

2.4、为org2-peer1安装chaincode

  1. 进入cli容器,命令:docker exec -it fabric-cli /bin/bash
  2. 进入容器的tmp目录,命令:cd /tmp
  3. 设置环境变量,使用org2-peer1身份
export org=2
export peer=1
export CORE_PEER_LOCALMSPID=Org${org}MSP
export CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/[email protected]${org}.example.com/msp
export 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
  1. 安装chaincode,命令
peer lifecycle chaincode install test_chaincode.tar.gz

三、验证安装

3.1、在org1-peer0上验证安装

  1. 进入cli容器,命令:docker exec -it fabric-cli /bin/bash
  2. 进入容器的tmp目录,命令:cd /tmp
  3. 设置环境变量,使用org1-peer0身份
export org=1
export peer=0
export CORE_PEER_LOCALMSPID=Org${org}MSP
export CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/[email protected]${org}.example.com/msp
export 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
  1. 验证安装chaincode,命令
peer lifecycle chaincode queryinstalled --output json --connTimeout "3s"

3.2、在org2-peer0上验证安装

  1. 进入cli容器,命令:docker exec -it fabric-cli /bin/bash
  2. 进入容器的tmp目录,命令:cd /tmp
  3. 设置环境变量,使用org2-peer0身份
export org=2
export peer=0
export CORE_PEER_LOCALMSPID=Org${org}MSP
export CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/[email protected]${org}.example.com/msp
export 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
  1. 验证安装chaincode,命令
peer lifecycle chaincode queryinstalled --output json --connTimeout "3s"

在这里插入图片描述

四、对已安装的链码进行审批

  1. 对已安装的chaincode进行查询,获取其查询结果的package_id值,这里的是:test_chaincode:6afa06381da3894197917b23017e474470dbb072c80257dc9103b7a214915dae
  2. 分别在org1-peer0以及org2-peer0上对链码进行审批,并指定背书策略

4.1、在org1-peer0上对链码进行审批,并指定背书策略

  1. 进入cli容器,命令:docker exec -it fabric-cli /bin/bash
  2. 进入容器的tmp目录,命令:cd /tmp
  3. 设置环境变量,使用org1-peer0身份
export org=1
export peer=0
export CORE_PEER_LOCALMSPID=Org${org}MSP
export CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/[email protected]${org}.example.com/msp
export 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
  1. 对链码进行审批,并通过属性--signature-policy指定背书策略,命令
#没有开启tls
peer 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
#开启tls
peer 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上对链码进行审批,并指定背书策略

  1. 进入cli容器,命令:docker exec -it fabric-cli /bin/bash
  2. 进入容器的tmp目录,命令:cd /tmp
  3. 设置环境变量,使用org2-peer0身份
export org=2
export peer=0
export CORE_PEER_LOCALMSPID=Org${org}MSP
export CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/[email protected]${org}.example.com/msp
export 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
  1. 对链码进行审批,并通过属性--signature-policy指定背书策略,命令
#没有开启tls
peer 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
#开启tls
peer 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上进行查询

  1. 进入cli容器,命令:docker exec -it fabric-cli /bin/bash
  2. 进入容器的tmp目录,命令:cd /tmp
  3. 设置环境变量,使用org1-peer0身份
export org=1
export peer=0
export CORE_PEER_LOCALMSPID=Org${org}MSP
export CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/[email protected]${org}.example.com/msp
export 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
  1. 查询审批结果,命令
peer lifecycle chaincode queryapproved --peerAddresses ${CORE_PEER_ADDRESS} --tlsRootCertFiles ${CORE_PEER_TLS_ROOTCERT_FILE} --channelID businesschannel --name test_chaincode --output json
  1. 返回该节点org1-peer0审批过的chancode,这里只审批了test_chaincode,所以只有chaincode
    在这里插入图片描述

5.2、在org2-peer0上进行查询

  1. 进入cli容器,命令:docker exec -it fabric-cli /bin/bash
  2. 进入容器的tmp目录,命令:cd /tmp
  3. 设置环境变量,使用org2-peer0身份
export org=2
export peer=0
export CORE_PEER_LOCALMSPID=Org${org}MSP
export CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/[email protected]${org}.example.com/msp
export 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
  1. 查询审批结果,命令
peer lifecycle chaincode queryapproved --peerAddresses ${CORE_PEER_ADDRESS} --tlsRootCertFiles ${CORE_PEER_TLS_ROOTCERT_FILE} --channelID businesschannel --name test_chaincode --output json

六、查询指定chaincode是否可以提交

  1. 查询意义:在chaincode安装时,经历了审批步骤如第四步,并通过属性--signature-policy指定背书策略,所以指定chaincode需要满足了指定的背书策略,才可以提交并使用

6.1、在org1-peer0上查询

  1. 进入cli容器,命令:docker exec -it fabric-cli /bin/bash
  2. 进入容器的tmp目录,命令:cd /tmp
  3. 设置环境变量,使用org1-peer0身份
export org=1
export peer=0
export CORE_PEER_LOCALMSPID=Org${org}MSP
export CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/[email protected]${org}.example.com/msp
export 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
  1. 查询审批结果,命令
peer lifecycle chaincode checkcommitreadiness --channelID businesschannel --name test_chaincode --version 1.0 --output json --sequence 1

七、向通道提交链码

  1. 提交可以在一个peer上完成,这里使用org1-peer0进行操作
  2. 进入cli容器,命令:docker exec -it fabric-cli /bin/bash
  3. 进入容器的tmp目录,命令:cd /tmp
  4. 设置环境变量,使用org1-peer0身份
export org=1
export peer=0
export CORE_PEER_LOCALMSPID=Org${org}MSP
export CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/[email protected]${org}.example.com/msp
export 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
  1. 使用org1-per0以及org2-peer0的证书,将chaincode提交到这两个节点上,命令
# 开启tls
peer 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
# 未开启tls
peer 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')" 

在这里插入图片描述

八、查询指定通道上已经提交的链码

  1. 这里使用org1-peer0的身份进行查询,因为channel在org1与org2之间,所以用一个节点查询即可
  2. 进入cli容器,命令:docker exec -it fabric-cli /bin/bash
  3. 进入容器的tmp目录,命令:cd /tmp
  4. 设置环境变量,使用org1-peer0身份
export org=1
export peer=0
export CORE_PEER_LOCALMSPID=Org${org}MSP
export CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/[email protected]${org}.example.com/msp
export 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
  1. 查询命令
peer lifecycle chaincode querycommitted --channelID businesschannel --output json
  1. 可以看到chaincode_definitions属性里的数组只有一个值:test_chaincode
    在这里插入图片描述

九、操作链码进行初始化以及转账和查询操作

9.1、在org1-peer0上进行初始化操作

  1. 进入cli容器,命令:docker exec -it fabric-cli /bin/bash
  2. 进入容器的tmp目录,命令:cd /tmp
  3. 设置环境变量,使用org1-peer0身份
export org=1
export peer=0
export CORE_PEER_LOCALMSPID=Org${org}MSP
export CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/[email protected]${org}.example.com/msp
export 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
  1. 初始化操作,命令
#开启tls
peer 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
#未开启tls
peer 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上进行初始状态查询操作

  1. 进入cli容器,命令:docker exec -it fabric-cli /bin/bash
  2. 进入容器的tmp目录,命令:cd /tmp
  3. 设置环境变量,使用org1-peer1身份
export org=1
export peer=1
export CORE_PEER_LOCALMSPID=Org${org}MSP
export CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/[email protected]${org}.example.com/msp
export 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
  1. 初始状态查询操作,命令
peer chaincode query -C businesschannel -n test_chaincode -c '{"Args":["query","a"]}'

9.3、在org2-peer0上进行转账操作

  1. 进入cli容器,命令:docker exec -it fabric-cli /bin/bash
  2. 进入容器的tmp目录,命令:cd /tmp
  3. 设置环境变量,使用org2-peer0身份
export org=2
export peer=0
export CORE_PEER_LOCALMSPID=Org${org}MSP
export CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/[email protected]${org}.example.com/msp
export 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
  1. 转账操作,命令
#开启tls
peer 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
#未开启tls
peer chaincode invoke -o orderer0.example.com:7050 --channelID businesschannel --name test_chaincode -c '{"Args":["invoke","a","b","10"]}'

9.2、在org2-peer1上进行转账后状态查询操作

  1. 进入cli容器,命令:docker exec -it fabric-cli /bin/bash
  2. 进入容器的tmp目录,命令:cd /tmp
  3. 设置环境变量,使用org2-peer1身份
export org=2
export peer=1
export CORE_PEER_LOCALMSPID=Org${org}MSP
export CORE_PEER_ADDRESS=peer${peer}.org${org}.example.com:7051
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org${org}.example.com/users/[email protected]${org}.example.com/msp
export 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
  1. 状态查询操作,命令
#查询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"]}'
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_37589805/article/details/121887903

智能推荐

C/C++编程学习 - 第11周 ① 第几天?_水蛙菌的博客-程序员秘密

题目链接题目描述给定一个日期,输出这个日期是该年的第几天。Input输入数据有多组,每组占一行,数据格式为YYYY/MM/DD组成,具体参见sample input ,另外,可以向你确保所有的输入数据是合法的。Output对于每组输入数据,输出一行,表示该日期是该年的第几天。Sample Input1985/1/202006/3/12Sample Output2071思路由于闰年的二月有29天,所以需要判断年份是否为闰年,以及月份是否大于二月,可以用一个数组保存每个月的天数。

详细记录YOLACT实例分割ncnn实现_小白学视觉的博客-程序员秘密

点击上方“小白学视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达链接:https://zhuanlan.zhihu.com/p/128974102本文转载自知乎,作者已授权,未经许可请勿二次转载。0x0 YOLACT实例分割https://urlify.cn/rURFry端到端一阶段完成实例分割速度快,550x550图片在TitanXP上号称达到33FPS开源代码,...

imageView的ScaleType缩放和setImageResource方法_blacop的博客-程序员秘密

activity_main.xml<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_wi

4G全网通模块-MSM8953核心板 (Cortex-A53架构)_counai4985的博客-程序员秘密

核心板特性 A53架构 8核(8*2.2GHz(A53)) 产品尺寸小,便于客户集成,减少产品体积; 支持4G LTE超高速上网,单板兼容移动/联通/电信2G/3G/4G; 支...

深入理解java异常处理机制-exception_NowIWanaBe的博客-程序员秘密

1. 引子       try…catch…finally恐怕是大家再熟悉不过的语句了,而且感觉用起来也是很简单,逻辑上似乎也是很容易理解。不过,我亲自体验的“教训”告诉我,这个东西可不是想象中的那么简单、听话。不信?那你看看下面的代码,“猜猜”它执行后的结果会是什么?不要往后看答案、也不许执行代码看真正答案哦。如果你的答案是正确,那么这篇文章你就不用浪费时间看啦。package Test

随便推点

[转]Dictionary:MAC字典最简解决方案_weixin_30955617的博客-程序员秘密

http://www.5lnb.com/dispbbs.asp?boardid=8&amp;Id=263 很多人工作或上网的时候需要一部优秀的字典,比如wonsore,经常在查看国外网站的时候被生词难倒。苹果MAC OSX虽然内置有简单实用的Dictionary,但他内置的字典很少,尤其是英翻中功能不强,未免成了鸡肋。此外虽然有很多不错的在线字典,比如Dict.cn,可是切换来切换去...

软件测试工作一周的感触_wuyanhong1985的博客-程序员秘密

在学校学习过计算机的一些理论知识,比如C++,JAVA,VB,数据库等等,但都是懂个大概。接触软件测试是从今年九月份开始的,主要是看测试理论以及数据库方面的知识,动手实践很少,所以刚开始对测试一窍不通,感觉很迷茫。后来有机会接触了一个商城的测试,才稍懂软件测试是怎么一回事。   进入公司一周了,为了了解公司现在的项目,首先看了软件需求规格说明书,接着是边熟悉业务边测试。一、经过几天的测试工

vue + element-ui 聊天_vue网页版聊天Vue+ElementUI仿微信界面聊天实例_weixin_39592315的博客-程序员秘密

vue+vuex+vue-cli+vue-router+element-ui+swiper等技术开发仿微信pc端界面聊天应用,实现了发送消息+表情(动图gif)、图片/视频预览、右键长按菜单、红包/朋友圈、截图发送等功能。技术栈vue版本:Vue2.5.6状态管理:Vuex页面路由:Vue-routericonfont图标:阿里巴巴字体图标库自定义滚动条:vue-gemini-scrol...

python flask入门_Python_眉浅穹跪的博客-程序员秘密

FLask 本身“轻”的特点,让你的学习不会那么“重”,掌握核心知识就能进行开发 ,更容易获得成就感,学习也就会更有动力,另外,FLask虽轻,但Flask 很强,内核+扩展的特点,让FLask 拥有“快速”开发各种类型应用的能力。这次课,我们的立意就是"快",快速从Python小白到初级Python工程师以轻量级Python框架Flask,更轻松的完成Python小白的蜕变快速"过渡"从语法回顾...

微服务架构下的数据一致性保证_harleylau的博客-程序员秘密

原文地址: https://cloud.tencent.com/developer/article/1081560今天分享第一篇,主要内容包括:1.传统使用本地事务和分布式事务保证一致性。2.传统分布式事务不是微服务中一致性的最佳选择。3.微服务架构中应满足数据最终一致性原则。4.微服务架构实现最终一致性的三种模式。5.对账是最后的终极防线。一、传统使用本地事务和分布式事务保证一致性传统单机应用一...

调用 from sklearn.datasets import fetch_lfw_people 出现HTTPError 403错误_我才我不难过嘛的博客-程序员秘密

在调用fetch_lfw_people()方法下载LFW(Labled Faces in the Wild)人脸数据集时出现HTTP Error 403: Forbidden 错误。

推荐文章

热门文章

相关标签