前面咱们学习了区块链是什么、还有自动搭建学习东西咱们就要从简单到深刻(入门到放弃),如今自动部署已经跑通了接下来就是手动搭建Fabric 网络能够更好的理解为何要这么作。html
# crypto-config.yaml 文件结构 OrdererOrgs: #定义一个Order组织 - Name: Orderer #order节点的名称,当前网络模式为solo类型,因此只定义了一个Order节点 Domain: example.com #order节点的域 Specs: #暂时用不到 - Hostname: orderer - Hostname: orderer2 - Hostname: orderer3 - Hostname: orderer4 - Hostname: orderer5 PeerOrgs: #定义Peer组织 - Name: Org1 #声明Peer组织名称为Org1 Domain: org1.example.com #Org1组织的域 EnableNodeOUs: true #暂时没搞清楚该字段的意义 Template: #在这里能够定义所生成的Org1组织中的Peer节点证书数量,不包括Admin Count: 2 #代表须要生成两个Peer节点的证书,若是须要其余数量的Peer节点,只须要更改这里的数量。 Users: #在这里能够定义所生成的Org1组织中类型为User的证书数量,不包括Admin Count: 1 #生成用户的证书的数量 - Name: Org2 #声明第二个Peer组织名称为Org2,若是须要更多的Peer组织证书,只须要按该模板添加便可。 Domain: org2.example.com #与以上相同 EnableNodeOUs: true Template: Count: 2 Users: Count: 1
# 会根据crypto-config.yaml文件配置生成两个锚节点交易,一个对应一个Peer组织 cryptogen generate --config=./crypto-config.yaml #生成系统通道创世区块genesis.block生成的配置组件位于channel-artifacts目录下 configtxgen -profile SampleMultiNodeEtcdRaft -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block #经过环境变量设定通道名称 export CHANNEL_NAME=mychannel #建立 通道配置 事务 configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME #建立 更新组织Org1在该通道上的锚节点(锚节点为某组织对order可见的节点) 的事务 configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP #建立 更新组织Org2在该通道上的锚节点 的事务 configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP
#启动fabric网络 -d用于不显示网络的实时日志,若想查看日志流,则后续命令须要打开另外一个终端来执行 #首先将first-network目录下的docker-compose-cli.yaml文件中cli容器配置信息中的FABRIC_LOGGING_SPEC=INFO修改成FABRIC_LOGGING_SPEC=DEBUG以看到更多的执行过程信息 docker-compose -f docker-compose-cli.yaml -f docker-compose-etcdraft2.yaml up -d
启动网络以后咱们能够看到docker启动的容器
进入容器 建立并加入通道,并指定(更新)组织的锚节点git
#进入cli容器内部 docker exec -it cli bash #配置CLI容器做为peer0.org1.example.com节点执行命令的环境变量 CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp CORE_PEER_ADDRESS=peer0.org1.example.com:7051 CORE_PEER_LOCALMSPID="Org1MSP" 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 #以环境变量形式设定通道名称,必须所有小写,长度小于250个字符,并与正则表达式[a-z][a-z0-9.-]*匹配 export CHANNEL_NAME=mychannel #将通道配置事务发送给order节点以建立通道,指定order节点的证书以进行TLS握手,执行结束后该节点将收到来自order节点的对应于所建立通道的创世区块$CHANNEL_NAME.block peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
#将peer0.org1.example.com加入通道,注意命令中的$CHANNEL_NAME.block,根据通道名称而变化 peer channel join -b mychannel.block #指定peer0.org1.example.com做为组织Org1的锚节点 peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org1MSPanchors.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem #配置CLI容器做为peer0.org2.example.com节点执行命令的环境变量 CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp CORE_PEER_ADDRESS=peer0.org2.example.com:9051 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 #将peer0.org2.example.com加入通道,注意命令中的$CHANNEL_NAME.block,根据通道名称而变化 peer channel join -b mychannel.block #指定peer0.org2.example.com做为组织Org2的锚节点 peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org2MSPanchors.tx --tls --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 lifecycle chaincode package mycc.tar.gz --path github.com/hyperledger/fabric-samples/chaincode/abstore/go/ --lang golang --label mycc_1
#安装链码 CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp CORE_PEER_ADDRESS=peer0.org1.example.com:7051 CORE_PEER_LOCALMSPID="Org1MSP" 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 #安装链码 peer lifecycle chaincode install mycc.tar.gz #查询已安装的链码 peer lifecycle chaincode queryinstalled #后续命令将须要链码包的ID,所以咱们将它保存为一个环境变量,这个ID是动态的(上面查询出来的) CC_PACKAGE_ID=mycc_1:3a8c52d70c36313cfebbaf09d8616e7a6318ababa01c7cbe40603c373bcfe173 #制定链码初始化链码TLS后面的命令是要权限才能初始化 #通道中的组织须要就链码的定义达成一致,如下命令用于批准一个chaincode定义,--init-required用于初始化chaincode时使init函数被调用,--package-id指定链码包的ID,咱们还能够提供--signature-policy或--channel-config-policy参数来设置chaincode背书策略,若未提供将使用默认设置-大多数通道成员背书,这种状况下若在该渠道中添加或删除新组织,背书策略将自动更新,以要求更多或更少的背书。在本例中,默认策略将须要来自属于Org1和Org2的peer的背书(即两个背书) peer lifecycle chaincode approveformyorg --channelID $CHANNEL_NAME --name mycc --version 1.0 --init-required --package-id $CC_PACKAGE_ID --sequence 1 --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 #更改CLI容器的环境变量后,在其它节点上安装链码 CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp CORE_PEER_ADDRESS=peer0.org2.example.com:9051 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 #安装链码 peer lifecycle chaincode install mycc.tar.gz #制定链码初始化链码TLS后面的命令是要权限才能初始化 #通道中的组织须要就链码的定义达成一致,如下命令用于批准一个chaincode定义,--init-required用于初始化chaincode时使init函数被调用,--package-id指定链码包的ID,咱们还能够提供--signature-policy或--channel-config-policy参数来设置chaincode背书策略,若未提供将使用默认设置-大多数通道成员背书,这种状况下若在该渠道中添加或删除新组织,背书策略将自动更新,以要求更多或更少的背书。在本例中,默认策略将须要来自属于Org1和Org2的peer的背书(即两个背书) peer lifecycle chaincode approveformyorg --channelID $CHANNEL_NAME --name mycc --version 1.0 --init-required --package-id $CC_PACKAGE_ID --sequence 1 --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 #一旦足够多的通道成员组织批准了chaincode定义,一个成员组织就能够将定义提交给通道。能够经过发出如下查询来检查chaincode定义是否已准备好提交,并查看当前组织的批准状况 #查看各组织对chaincode定义的批准情况 peer lifecycle chaincode checkcommitreadiness --channelID $CHANNEL_NAME --name mycc --version 1.0 --init-required --sequence 1 --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 --output json #一旦就链码定义达成一致,把两个组织中的链码提交到order组织--通知给其余节点我加入了 peer lifecycle chaincode commit -o orderer.example.com:7050 --channelID $CHANNEL_NAME --name mycc --version 1.0 --sequence 1 --init-required --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 --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt #调用chaincode 将--isInit标志传递给链码的第一次调用,并将参数提供给Init函数。第一个调用将启动chaincode容器。咱们可能须要等待容器启动。(确保通道名称和链码名称正确) peer chaincode invoke -o orderer.example.com:7050 --isInit --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 $CHANNEL_NAME -n mycc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["Init","a","100","b","100"]}' --waitForEvent #查询chaincode peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}' #调用链码的invoke函数,a向b转帐十元 peer chaincode invoke -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 $CHANNEL_NAME -n mycc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["invoke","a","b","10"]}' --waitForEvent #注:若通道成员组织的其它节点想和区块链网络进行交互,只须要加入通道并安装链码包便可,而不须要提交链码定义(每一个组织批准一次链码定义便可)。