1、生成证书文件
(1.1)环境清理
接上一篇,已跑通e2e_cli案例,此处需要执行以下命令进行环境清理:
cd /opt/gopath/src/github.com/hyperledger/fabric/examples/e2e_cli
bash network_setup.sh down
然后依次执行以下命令查看环境:
# docker ps -a
# docker images
# docker-compose version
# go version
最终结果如图:
(1.2)在Fabric源码下创建aberic目录,来作为即将运行的单机多节点项目目录。最终目录如图:
(1.3)将前面下载的hyperledger-fabric-linux-amd64-1.1.0.tar.gz(内含二进制文件)包上传至该目录并解压,得到bin和config。删除config目录,只保留bin。然后从fabric1.0版本中复制examples/e2e_cli目录下的configtx.yaml和crypto-config.yaml文件到aberic目录(此处注意我的bin为1.1.0版本的,而configtx.yaml和crypto-config.yaml为1.0版本的,因为1.0的启动类型是solo,而1.1之后启动类型为kafka,这里选用solo进行单机部署),最后tree一下目录结构如图:
(1.4)生成证书文件
进入aberic目录:
cd /opt/gopath/src/github.com/hyperledger/fabric/aberic
执行以下命令来生成项目所需文件,如图:
# ./bin/cryptogen generate --config=./crypto-config.yaml
(若提示权限不足,如图:
对二进制文件进行授权操作:
chmod +x ./bin/cryptogen
然后查看:
ll ./bin/cryptogen
再执行文件生成命令:./bin/cryptogen generate --config=./crypto-config.yaml)
在ftp中会看到生成一个新目录crypto-config,其中包含ordererOrganizations和peerOrganizations两个目录。如图:
(1.5)为configtxgen工具指定configtx.yaml文件的路径,设置环境变量,执行以下命令:
设置环境变量:
export FABRIC_CFG_PATH=$PWD
然后查看该目录是否正确:
echo $PWD
最终结果如图:
(1.6)在aberic文件夹下创建文件夹channel-artifacts。
(1.6)根据configtx.yaml生成chua创世块以及频道认证文件:
# ./bin/configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block
通过ftp可以看到已创建成功:
生成channelID为mychannel(可自定义)的tx文件:
./bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/mychannel.tx -channelID mychannel
再看channel-artifacts目录多了mychannel.tx文件:
2、部署orderer节点,编写docker-order.yaml文件,如下(注意空格):
version: '2'
services:
orderer.example.com:
container_name: orderer.example.com
image: hyperledger/fabric-orderer
environment:
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=aberic_default
# - ORDERER_GENERAL_LOGLEVEL=error
- OEDERER_GENERAL_LOGLEVEL=debug
- OEDERER_GENERAL_LISTENADDRESS=0.0.0.0
- OEDERER_GENERAL_LISTENPORT=7050
#- OEDERER_GENERAL_GENESISPROFILE=AntiMothOrdererGenesis
- OEDERER_GENERAL_GENESISMETHOD=file
- OEDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
- OEDERER_GENERAL_LOCALMSPID=OrdererMSP
- OEDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
# enabled TLS
- ORDERER_GENERAL_TLS_ENABLED=false
- ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key
- ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt
- ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
working_dir: /opt/gopath/src/github.com/hyperledger/fabric
command: orderer
volumes:
- ./channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
- ./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp:/var/hyperledger/orderer/msp
- ./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/:/var/hyperledger/orderer/tls
networks:
default:
aliases:
- aberic
ports:
- 7050:7050
3、部署peer0.org1jied节点,编写docker-peer.yaml文件如下(注意空格):
version: '2'
services:
couchdb:
container_name: couchdb
image: hyperledger/fabric-couchdb
ports:
- "5984:5984"
ca:
container_name: ca
image: hyperledger/fabric-ca
environment:
- FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
- FABRIC_CA_SERVER_CA_NAME=ca
- FABRIC_CA_SERVER_TLS_ENABLED=false
- FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem
- FABEIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/8ae7bc9222d051e43cd7f0354c3ba027be91efc1b6c5e9b3619a0988ae6929c1_sk
ports:
- "7054:7054"
command: sh -c 'fabric-ca-server start --ca.certfile /etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem --ca.keyfile /etc/hyperledger/fabric-ca-server-config/8ae7bc9222d051e43cd7f0354c3ba027be91efc1b6c5e9b3619a0988ae6929c1_sk -b admin:adminpw -d'
volumes:
- ./crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config/
peer0.org1.example.com:
container_name: peer0.org1.example.com
image: hyperledger/fabric-peer
environment:
- CORE_LEDGER_STATE_STATEDATABASE=CouchDB
- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb:5984
- CORE_PEER_ID=peer0.org1.example.com
- CORE_PEER_NETWORKID=aberic
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_CHAINCODELISTENADDRESS=peer0.org1.example.com:7052
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=aberic
- CORE_LOGGING_LEVEL=DEBUG
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=aberic_default
- CORE_PEER_GOSSIP_SKIPHANDSHAKE=true
- CORE_PEER_GOSSIP_USELEADERELECTTON=true
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_PROFILE_ENABLED=false
- CORE_PEER_TLS_ENABLED=false
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
volumes:
- /var/run/:/host/var/run/
- ./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/etc/hyperledger/fabric/msp
- ./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls:/etc/hyperledger/fabric/tls
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
ports:
- 7051:7051
- 7052:7052
- 7053:7053
depends_on:
- couchdb
networks:
default:
aliases:
- aberic
cli:
container_name: cli
image: hyperledger/fabric-tools
tty: true
environment:
- GOPATH=/opt/gopath
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_LOGGING_LEVEL=DEBUG
- CORE_PEER_ID=cli
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_PEER_TLS_ENABLED=false
- CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
- CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
volumes:
- /var/run/:/host/var/run/
- ./chaincode/go/:/opt/gopath/src/github.com/hyperledger/fabric/aberic/chaincode/go
- ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
- ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
depends_on:
- peer0.org1.example.com
注意:CA有两部分需要修改,一个是FABEIC_CA_SERVER_TLS_KEYFILE,另一处是command中最后一部分。这两处的_sk文件名称需要替换成之前生成是文件名称。其实这里的主要目的是创建CA并登录CA用户。文件路径为:/opt/gopath/src/github.com/hyperledger/fabric/aberic/crypto-config/peerOrganizations/org1.example.com/ca,如图:
将两处_sk替换即可。
4、搭建Fabric网络
(4.1)将编写好的docker-orderer.yaml和docker-peer.yaml文件上传至aberic目录下。
(4.2)在aberic目录下创建文件夹chaincode,再在chaincode文件夹下创建文件夹go。将官方demo(我用的fabric1.0版本)中的chaincode_example02示例上传到go目录下。最终结果如图:
(4.3)分别执行以下命令启动orderer和peer(按照顺序应该先启动排序服务),如图:
docker-compose -f docker-orderer.yaml up -d
docker-compose -f docker-peer.yaml up -d
我这里有个警告,没影响后面执行就暂时先me启动没管它。接下来执行docker ps查看容器是否启动,如图:
可以看到所有容器都已成功启动,接下来是对channel和chaincode执行操作了。
(4.4)进入客户端对channel进行相关操作:
docker exec -it cli bash
注:上述命令是对docker容器的常规操作,cli则是YAML启动文件中定义的container_name(容器名称),通过修改上述命令中的cli为其它容器名称,可以开启所写容器的内部服务。(退出容器的操作为ctrl+p+q)
(4.5)创建channel:
peer channel create -o orderer.example.com:7050 -c mychannel -t 50 -f ./channel-artifacts/mychannel.tx
(4.6)通过channel.block文件来加入该channel,以便后续可以安装实例化并测试只能合约。
peer channel join -b mychannel.block
至此,已经完成了channel的创建并成功加入该channel,即一个最小单位的Fabric网络已经成功搭建起来了。
5、智能合约安装部署测试
(5.1)安装智能合约,如图表示安装成功:
peer chaincode install -n mychannel -p github.com/hyperledger/fabric/aberic/chaincode/go/chaincode_example02 -v 1.0
(5.2)实例化chaincode,如图表示实例化成功:
peer chaincode instantiate -o orderer.example.com:7050 -C mychannel -n mychannel -c '{"Args":["init","A","10","B","10"]}' -P "OR ('Org1MSP.member')" -v 1.0
由命令可以看出,调用init方法,接受A,10,B,10四个参数。意思是创建一个key为A的账户,并给该账户一个值为10的资产。同时创建一个key为B的账户,也给该账户一个值为10的资产。
(5.3)执行query方法,该方法接收且仅能接收一个参数,所接收的参数为zhin智能合约中所创建账户的key值,返回内容为该账户下的资产。如图,表示查询成功:
peer chaincode query -C mychannel -n mychannel -c '{"Args":["query","A"]}'
同理,查询B账户,资产也是10:
peer chaincode query -C mychannel -n mychannel -c '{"Args":["query","B"]}'
(5.4)invoke方法,需要传入三个参数,第一个和第二个参数分别是不同的账户名,第三个参数是资产值。方法的核心是第一个账户将自己资产中第三个参数值的资产转移到第二个账户名下。如A账户转移2个资产单位到B账户下,执行命令如下:
peer chaincode invoke -C mychannel -n mychannel -c '{"Args":["invoke", "A", "B", "2"]}'
这里会执行打印很长的一段日志,这里只截取最后显示成功的部分,如图,可以看到打印Chaincode invoke successful. result: status:200字样的日志信息:
此时在查询A账户的资产,发现少了两个:
而查询B账户资产多了两个:
6、部署peer0.org2节点
(6.1)为org2节点准备docker-peer1.yaml启动文件,具体内容如下:
version: '2'
services:
peer0.org2.example.com:
container_name: peer0.org2.example.com
image: hyperledger/fabric-peer
environment:
- CORE_PEER_ID=peer0.org2.example.com
- CORE_PEER_NETWORKID=aberic
- CORE_PEER_ADDRESS=peer0.org2.example.com:7051
- CORE_PEER_CHAINCODELISTENADDRESS=peer0.org2.example.com:7052
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:7051
- CORE_PEER_LOCALMSPID=Org2MSP
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
# the following setting starts chaincode containers on the same
# bridge network as the peers
# https://docs.docker.com/compose/networking/
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=aberic
# - CORE_LOGGING_LEVEL=ERROR
- CORE_LOGGING_LEVEL=DEBUG
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=aberic_default
- CORE_PEER_GOSSIP_SKIPHANDSHAKE=true
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_PROFILE_ENABLED=false
- CORE_PEER_TLS_ENABLED=false
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
volumes:
- /var/run/:/host/var/run/
- ./crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/msp:/etc/hyperledger/fabric/msp
- ./crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls:/etc/hyperledger/fabric/tls
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
ports:
- 8051:8051
- 8052:8052
- 8053:8053
networks:
default:
aliases:
- aberic
(6.2)将docker-peer1.yaml文件上传至aberic目录,如图:
(6.3)退出docker cli容器,如图:ctrl+p+q(若已退出,忽略此步)
(6.3)进入该目录,并启动docker-peer1.yaml,如图,警告先不管:
cd /opt/gopath/src/github.com/hyperledger/fabric/aberic
docker-compose -f docker-peer1.yaml up -d
(6.4)执行docker ps查看启动的docker容器:
如图所示,peer0org2已成功启动。接下来会针对peer0org2执行频道加入、安装合约、测试合约以及背书验证等操作。
(6.5)首先进入cli客户端进行一些全局变量的更改,使得cli可以对peer0org2进行相关操作。命令如下:
docker exec -it cli bash
(6.6)进入容器后,进行一系列当前容器全局变量赋值操作,命令分别如下:
CORE_PEER_ID=peer0.org2.example.com
CORE_PEER_ADDRESS=peer0.org2.example.com:7051
CORE_PEER_CHAINCODELISTENADDRESS=peer0.org2.example.com:7052
CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:7051
CORE_PEER_LOCALMSPID=Org2MSP
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp
(6.6)执行peer0org2加入频道的操作:
peer channel join -b mychannel.block
安装智能合约:
peer chaincode install -n mychannel -p github.com/hyperledger/fabric/aberic/chaincode/go/chaincode_example02 -v 1.0
(6.7)在peer0org2加入频道并安装智能合约之后,可执行以下命令测试合约是否已成功运行:
peer chaincode query -C mychannel -n mychannel -c '{"Args":["query","A"]}'
如图,查出来账户A资产为8
(6.8)在当前cli容器中再次执行一次转账命令,这次让B给A转账2个资产:
peer chaincode invoke -C mychannel -n mychannel -c '{"Args":["invoke", "B", "A", "2"]}'
如图,显示invoke成功。
(6.9)再次查询A和B账户的资产,如图:
此时发现,A和B的资产并未发生变化。原因是在实例化智能合约操作的时候,选择的背书组织为Org1,而后加入的节点组织为Org2,这说明来自Org2的对资产变更的操作都未经过背书,即不具备任何效力。但是因为Org2组织加入了该频道且安装了合法的合约,所以可以对区块链中的数据进行检索。
(6.10)执行exit(或者ctrl+p+q)退出当前cli:
重新进入cli(这时cli容器默认是对peer0org1节点的操作):
docker exec -it cli bash
再次执行账户B转账2个资产给账户A的操作:
peer chaincode invoke -C mychannel -n mychannel -c '{"Args":["invoke", "B", "A", "2"]}'
成功之后再次查询A账户的资产,如图,已变为10个:
peer chaincode query -C mychannel -n mychannel -c '{"Args":["query","A"]}'
查询B账户资产,也已变为10个:
peer chaincode query -C mychannel -n mychannel -c '{"Args":["query","B"]}'