生成Fabric证书 #
Hyperledger Fabric通过证书文件来配置组织、节点以及用户。证书文件(实际上,数字证书就是经过CA认证过的公钥)的标准为X.509,编码格式为PEM,以—–BEGIN开头,以—–END结尾。X.509 数字证书不但包括用户名和公共密钥,而且还包括有关该用户的其他信息。除了扩展名为PEM的还有以下这些:
- CRT :应该是certificate的三个字母,还是证书的意思。打开看也是PEM编码格式。
- KEY: 用来存放一个公钥或私钥,并非X.509证书。打开看依然PEM格式。
证书的默认签名算法为ECDSA,Hash算法为SHA-256。Fabric中设计中考虑了三种类型证书:
- 登记证书(ECert):颁发给提供了注册凭证的用户或节点实体,长期有效。(主要就是通ECert对实体身份检验)
- 通信证书(TLSCert):TLS证书用来保障通信链路安全,控制对网络层的接入访问,可以对远端实体身份校验,防止窃听。
- 交易证书(TCert):颁发给用户,控制每个交易的权限,一般针对某个交易,短期有效。
1.证书的文件的编写 #
首先我们使用以下命令在进入~/hyperledger
目录并创建一个项目目录solotest
。
cd ~/hyperledger
mkdir solotest
cd solotest
我们可以使用以下命令来查看生成证书文件的模板文件。
cryptogen showtemplate
使用以下命令将模板文件复制到当前目录下。
cryptogen showtemplate > crypto-config.yaml
配置文件的模板如下:
OrdererOrgs:
- Name: Orderer
Domain: example.com
Specs:
- Hostname: orderer
- Hostname: orderer2
PeerOrgs:
- Name: Org1
Domain: org1.example.com
EnableNodeOUs: true
Template:
Count: 2
Users:
Count: 2
- Name: Org2
Domain: org2.example.com
EnableNodeOUs: true
Template:
Count: 2
Specs:
- Hostname: hello
Users:
Count: 1
-
OrdererOrgs
排序节点组织信息Name: Orderer
排序节点组织的名字Domain: example.com
根域名, 排序节点组织的根域名Specs
:Hostname: orderer
访问这台orderer对应的域名为: orderer.example.comHostname: orderer2
访问这台orderer对应的域名为: order2.example.com
-
PeerOrgs
:对等节点组织信息-
Name: Org1
第一个组织的名字, 自己指定 -
Domain: org1.example.com
访问第一个组织用到的根域名 -
EnableNodeOUs: true
是否支持node.js,一般填写为true -
Template
模板, 根据默认的规则生成peer存储数据的节点Count: 2
生成的节点个数为两个节点的名称按数字顺序排序,如:1. peer0.org1.example.com 2. peer1.org1.example.com
-
Users
创建普通用户的数量Count: 2
创建普通用户数量为2
-
我们在这部分课程中创建一个单节点网络,所以只需要在PeerOrgs
下配置一个组织,在Template
下填写1
,表示这个组织只有一个节点,在Users
下填写1
表示只有一个用户。在vim
中修改当前目录下的配置文件crypto-config.yaml
如下:
OrdererOrgs:
- Name: Orderer
Domain: test.com
EnableNodeOUs: true
Specs:
- Hostname: orderer
PeerOrgs:
- Name: org1
Domain: org1.test.com
EnableNodeOUs: true
Template:
Count: 1
Users:
Count: 1
2.证书文件的生成 #
使用以下命令生成证书文件。
cryptogen generate --config=crypto-config.yaml
使用ls
命令查看生成的文件,可以看到生成了crypto-config
文件,这里存放所有的证书文件。
ls
crypto-config crypto-config.yaml
使用ls
命令查看crypto-config
目录下文件,会发现有两个组织的文件夹分别是orderer
组织以及peer
组织。
ls crypto-config
ordererOrganizations peerOrganizations
我们以peer
组织为例,查看其文件夹下的目录,由于我们只创建了一个组织,所以看到只有org1.test.com
。
cd crypto-config
ls peerOrganizations
org1.test.com
继续查看org1.test.com
下的目录,可以看到分别有ca
msp
peers
tlsca
users
五个文件夹。
cd peerOrganizations
ls org1.test.com
ca msp peers tlsca users
-
ca
:存放了组织的根证书和对应的私钥文件,采用的是EC算法,证数为自签名(自已签发自己的公钥)。组织内的实体将基于该证数作为证数根。 -
msp
:存放代表该组织的身份信息。msp文件夹下还有三个目录分别是:-
admincerts
:被根证书签名的组织管理员的身份验证证书。 -
cacerts
:组织的根证书,和ca
目录下的文件相同。 -
tlscacerts
:用于TLS的CA证书,证书为自签名。
-
-
peers
:存放该组织下所有peer
节点的证书,我们只创建了一个组织,所以在peers
文件下只有peer0.org1.test.com
一个目录,在此目录下还有两个目录分别是:-
msp
,其下有五个目录:admincerts
:组织管理员的身份验证证书,用于验证交易签名者是否为管理员身份。cacerts
:存放组织的根证书。keystore
:本节点的身份私钥,用来签名。signcerts
: 验证本节点签名的证书,被组织根证书签名。tlscacerts
:TLS连接用的身份证书,即组织TLS证书。
-
tls
:存放TLS相关的证书和私钥,其下有三个文件:ca.crt
:组织的根证书。server.crt
:验证本节点签名的证书,被组织根证书签名。server.key
:本节点的身份私钥,用来签名。
-
-
users
:存放属于该组织的用户实体,其下有两个文件夹分别为Admin@org1.test.com
以及User1@org1.test.com
(我们只创建了一个用户),其中Admin@org1.test.com
是保存管理员用户的信息,包括其MSP证书和TLS证书。User1@org1.test.com
保存第一个用户的信息,结构和admin
相同,包括MSP证书和TLS证书不再赘述。我们以admin
为例:-
msp
下有:-
admincerts
:管理员身份证书。 -
cacerts
:存放组织的根证书。 -
keystore
:本用户的身份私钥,用来签名。 -
signcerts
: 管理员用户的身份验证证书,由组织根证书签名,要放到Peer的msp/admincerts
下才会被这个Peer认可。 -
tlscacerts
:TLS连接用的身份证书,即组织TLS证书。
-
-
tls
下有:(可以看出与我们上述的tls
文件下目录相同)-
ca.crt
:组织的根证书。 -
server.crt
: 管理员用户的身份验证证书,由组织根证书签名。 -
server.key
:管理员的身份私钥,用来签名。
-
-
最后我们使用以下命令回到项目路径。
cd ~/hyperledger/solotest
创世块文件和通道文件 #
yaml相关语法:<<
合并到当前数据,-
数组,*
别名(类似于指针),&
锚点(类似于取址) 。
1 创始块文件的编写 #
首先我们可以参考官方示例项目test-network
中的configtx.yaml
配置文件,使用以下命令进入其目录。
CD /root/hyperledger/fabric-samples/test-network/configtx
使用ls
命令查看文件。
ls
configtx.yaml
使用以下命令将这个配置文件复制到我们的项目路径中。
cp * ~/hyperledger/solotest
使用以下命令回到我们的项目路径。
cd ~/hyperledger/solotest
可以使用cat
命令查看configtx.yaml
配置文件。
cat configtx.yaml
Organizations:
- &OrdererOrg
Name: OrdererOrg
ID: OrdererMSP
MSPDir: ../organizations/ordererOrganizations/example.com/msp
Policies:
Readers:
Type: Signature
Rule: "OR('OrdererMSP.member')"
Writers:
Type: Signature
Rule: "OR('OrdererMSP.member')"
Admins:
Type: Signature
Rule: "OR('OrdererMSP.admin')"
OrdererEndpoints:
- orderer.example.com:7050
- &Org1
Name: Org1MSP
ID: Org1MSP
MSPDir: ../organizations/peerOrganizations/org1.example.com/msp
Policies:
Readers:
Type: Signature
Rule: "OR('Org1MSP.admin', 'Org1MSP.peer', 'Org1MSP.client')"
Writers:
Type: Signature
Rule: "OR('Org1MSP.admin', 'Org1MSP.client')"
Admins:
Type: Signature
Rule: "OR('Org1MSP.admin')"
Endorsement:
Type: Signature
Rule: "OR('Org1MSP.peer')"
AnchorPeers:
- Host: peer0.org1.example.com
Port: 7051
-
Organizations配置段,这一部分定义了不同的组织身份包括orderer以及其他组织
-
Name
:组织名称 -
ID
:MSP的ID -
MSPDir
:MSP配置文件的路径 -
Policies
:组织策略, 其中Rule
定义了规则,OR
为或,AND
为并 -
AnchorPeers
:锚节点
-
Capabilities:
Channel: &ChannelCapabilities
V2_0: true
Orderer: &OrdererCapabilities
V2_0: true
Application: &ApplicationCapabilities
V2_0: true
- Capabilities配置段,capability直接翻译是能力,这里可以理解为对Fabric网络中组件版本的控制,通过版本进而控制相应的特性。新更新的特性旧版本的组件不支持,就可能无法验证或提交transaction从而导致不同版本的节点上有不同的账本,因此使用Capabilities来使不支持特性的旧组件终止处理transaction直到其更新升级。Channel表示orderers和peers同时都要满足,Orderer只需要orderers满足,Application只需要peers满足即可。
Application: &ApplicationDefaults
Organizations:
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
LifecycleEndorsement:
Type: ImplicitMeta
Rule: "MAJORITY Endorsement"
Endorsement:
Type: ImplicitMeta
Rule: "MAJORITY Endorsement"
Capabilities:
<<: *ApplicationCapabilities
- Application配置段,一些和应用有关的将会编进创世区块或配置transaction的应用相关的参数,其中organizations:在此处不进行配置,在后面profiles配置段中,根据需要生成的文件类型进行配置。
Orderer: &OrdererDefaults
OrdererType: etcdraft
Addresses:
- orderer.example.com:7050
EtcdRaft:
Consenters:
- Host: orderer.example.com
Port: 7050
ClientTLSCert: ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
ServerTLSCert: ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
BatchTimeout: 2s
BatchSize:
MaxMessageCount: 10
AbsoluteMaxBytes: 99 MB
PreferredMaxBytes: 512 KB
Organizations:
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
BlockValidation:
Type: ImplicitMeta
Rule: "ANY Writers"
-
Orderer配置段,关于orderer的一些参数
-
OrdererType
:共识机制 排序算法solo或者raft -
Addresses
:Orderer地址 -
BatchTimeout
:区块生成时间(达到时间就会生成区块) -
MaxMessageCount
:区块消息数量( 交易的最大数据量, 数量达到之后会产生区块) -
AbsoluteMaxBytes
:区块绝对最大字节数(数据量达到这个值, 会产生一个区块) -
PreferredMaxBytes
:建议消息字节数
-
Channel: &ChannelDefaults
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
Capabilities:
<<: *ChannelCapabilities
- Channel配置段
Profiles:
TwoOrgsOrdererGenesis:
<<: *ChannelDefaults
Orderer:
<<: *OrdererDefaults
Organizations:
- *OrdererOrg
Capabilities:
<<: *OrdererCapabilities
Consortiums:
SampleConsortium:
Organizations:
- *Org1
- *Org2
TwoOrgsChannel:
Consortium: SampleConsortium
<<: *ChannelDefaults
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
- *Org2
Capabilities:
<<: *ApplicationCapabilities
- Profiles配置段,profiles配置段相当于configtxgen工具的统一入口,通过设置不同的configtxgen -profile参数决定要使用configtxgen生成什么文件,profiles配置段通过使用上面准备好的配置段来根据需要配置不同的文件(虽然可以显示配置但是最好采用引用默认配置的方式,有封装的意思)。first-network案例中相应配置段如下所示。
现在我们可以按照下面来修改配置文件:(主要修改的是MSP文件路径以及组织节点名称,策略都不需要更改)。
Organizations:
- &OrdererOrg
Name: OrdererOrg
ID: OrdererMSP
MSPDir: crypto-config/ordererOrganizations/test.com/msp
Policies:
Readers:
Type: Signature
Rule: "OR('OrdererMSP.member')"
Writers:
Type: Signature
Rule: "OR('OrdererMSP.member')"
Admins:
Type: Signature
Rule: "OR('OrdererMSP.admin')"
OrdererEndpoints:
- orderer.test.com:7050
- &Org1
Name: Org1MSP
ID: Org1MSP
MSPDir: crypto-config/peerOrganizations/org1.test.com/msp
Policies:
Readers:
Type: Signature
Rule: "OR('Org1MSP.admin','Org1MSP.peer','Org1MSP.client')"
Writers:
Type: Signature
Rule: "OR('Org1MSP.admin','Org1MSP.client')"
Admins:
Type: Signature
Rule: "OR('Org1MSP.admin')"
Endorsement:
Type: Signature
Rule: "OR('Org1MSP.peer')"
AnchorPeers:
- Host: peer0.org1.test.com
Port: 7051
Capabilities:
Channel: &ChannelCapabilities
V2_0: true
Orderer: &OrdererCapabilities
V2_0: true
Application: &ApplicationCapabilities
V2_0: true
Application: &ApplicationDefaults
Organizations:
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
LifecycleEndorsement:
Type: ImplicitMeta
Rule: "MAJORITY Endorsement"
Endorsement:
Type: ImplicitMeta
Rule: "MAJORITY Endorsement"
Capabilities:
<<: *ApplicationCapabilities
Orderer: &OrdererDefaults
OrdererType: solo
Addresses:
- orderer.test.com:7050
BatchTimeout: 2s
BatchSize:
MaxMessageCount: 10
AbsoluteMaxBytes: 99 MB
PreferredMaxBytes: 512 KB
Organizations:
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
BlockValidation:
Type: ImplicitMeta
Rule: "ANY Writers"
Channel: &ChannelDefaults
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
Capabilities:
<<: *ChannelCapabilities
Profiles:
soloOrgsOrdererGenesis:
<<: *ChannelDefaults
Orderer:
<<: *OrdererDefaults
Organizations:
- *OrdererOrg
Capabilities:
<<: *OrdererCapabilities
Consortiums:
SampleConsortium:
Organizations:
- *Org1
soloOrgsChannel:
Consortium: SampleConsortium
<<: *ChannelDefaults
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
Capabilities:
<<: *ApplicationCapabilities
2 创世块文件通道文件的生成 #
命令介绍
configtxgen --help
# 输出创始块区块文件的路径和名字
`-outputBlock string`
# 指定创建的channel的名字, 如果没指定系统会提供一个默认的名字.
`-channelID string`
# 表示输通道文件路径和名字
`-outputCreateChannelTx string`
# 指定配置文件中的节点
`-profile string`
# 更新channel的配置信息
`-outputAnchorPeersUpdate string`
# 指定所属的组织名称
`-asOrg string`
生成创始块文件,其中-profile
后面对应的是我们在前面配置文件中所定义的名称,-outputBlock
指定生成的创世块文件路径以及名称,-channelID
为通道的名称(通道的名称随意起,但是注意要与下面生成通道文件时的通道名称不同)。使用以下命令在当前目录下的channel-artifacts目录下得到一个文件genesis.block
。
configtxgen -profile soloOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block -channelID fabric-channel
生成通道文件,其中-profile
后面对应的是我们在前面配置文件中所定义的名称,-outputBlock
指定生成的通道文件路径以及名称,-channelID
为通道的名称。通道的名称随意起,但是注意要与上面生成创世块文件时的通道名称不同)。使用以下命令在当前目录下的channel-artifacts
目录下得到一个文件channel.tx
。
configtxgen -profile soloOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID mychannel
生成锚节点更新文件,其中-profile
后面对应的是我们在前面配置文件中所定义的名称,-outputBlock
指定生成的锚节点文件路径以及名称,-channelID
为通道的名称(要与上面生成通道文件时的通道名称相同)。使用以下命令在当前目录下的channel-artifacts
目录下得到一个文件Org1MSPanchors.tx
。
configtxgen -profile soloOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID mychannel -asOrg Org1MSP
使用ls
命令查看刚刚生成的文件。
ls channel-artifacts
channel.tx Org1MSPanchors.tx genesis.block
docker-compose文件的编写 #
Hyperledger Fabric的节点都运行在Docker容器里,我们使用docker-compose
文件配置各个节点的通信网络,挂载目录等信息,然后开启所有节点。
首先我们首先我们可以参考官方示例项目test-network
中的docker-compose-test-net.yaml
配置文件,使用以下命令进入其目录。
cd /root/hyperledger/fabric-samples/test-network/docker
使用ls
命令查看路径下的文件。
ls
docker-compose-ca.yaml docker-compose-test-net.yaml docker-compose-couch.yaml
使用cp
命令将docker-compose-test-net.yaml
配置文件拷贝到我们的项目路径下。
cp docker-compose-test-net.yaml ~/hyperledger/solotest
使用以下命令回到我们的项目目录。
cd ~/hyperledger/solotest
1 客户端角色需要使用的环境变量 #
- GOPATH=/opt/gopath
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_LOGGING_LEVEL=INFO
- CORE_PEER_ID=cli
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_PEER_TLS_ENABLED=true
- 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/Admin@org1.example.com/msp
GOPATH
:客户端docker容器启动之后, go的工作目录,不需要修改CORE_VM_ENDPOINT
:docker容器启动之后, 对应的守护进程的本地套接字, 不需要修改CORE_LOGGING_LEVEL
:日志级别CORE_PEER_ID
:当前客户端节点的ID, 自己指定CORE_PEER_ADDRESS
:客户端连接的peer节点地址CORE_PEER_LOCALMSPID
:组织IDCORE_PEER_TLS_ENABLED
:通信是否使用tls加密CORE_PEER_TLS_CERT_FILE
:证书文件路径CORE_PEER_TLS_KEY_FILE
:私钥文件路径CORE_PEER_TLS_ROOTCERT_FILE
:根证书文件路径CORE_PEER_MSPCONFIGPATH
:MSP配置文件路径
2 orderer节点需要使用的环境变量 #
- ORDERER_GENERAL_LOGLEVEL=INFO
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
- ORDERER_GENERAL_GENESISMETHOD=file
- ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
- ORDERER_GENERAL_LOCALMSPID=OrdererMSP
- ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
- ORDERER_GENERAL_TLS_ENABLED=true
- 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]
CORE_LOGGING_LEVEL
:日志级别ORDERER_GENERAL_LISTENADDRESS
:orderer节点监听的地址ORDERER_GENERAL_GENESISMETHOD
:创始块的来源ORDERER_GENERAL_GENESISFILE
:创始块对应的文件路径ORDERER_GENERAL_LOCALMSPID
:orderer节点所属的组的IDORDERER_GENERAL_LOCALMSPDIR
:当前节点的msp账号路径ORDERER_GENERAL_TLS_ENABLED
:通信是否使用tls加密ORDERER_GENERAL_TLS_CERTIFICATE
:证书文件路径ORDERER_GENERAL_TLS_PRIVATEKEY
:私钥文件路径ORDERER_GENERAL_TLS_ROOTCAS
:根证书文件路径
3 peer节点需要使用的环境变量 #
- CORE_PEER_ID=peer0.org1.example.com.com
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051
- 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=network_default
- CORE_LOGGING_LEVEL=INFO
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_PROFILE_ENABLED=true
- 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
-
CORE_PEER_ID
:当前客户端节点的ID, 自己指定 -
CORE_PEER_ADDRESS
:peer节点地址 -
CORE_PEER_GOSSIP_BOOTSTRAP
:启动时指定连接的地址,一般写自己 -
CORE_PEER_GOSSIP_EXTERNALENDPOINT
:为了被其他节点感知到, 如果不设置别的节点不知有该节点的存在 -
CORE_PEER_LOCALMSPID
:组织ID -
CORE_VM_ENDPOINT
:docker的本地套接字地址 -
CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE
:创建的网络名称 -
CORE_LOGGING_LEVEL
:日志级别 -
CORE_PEER_TLS_ENABLED
:通信是否使用tls加密 -
CORE_PEER_GOSSIP_USELEADERELECTION
:释放自动选举leader节点 -
CORE_PEER_GOSSIP_ORGLEADER
:当前是否leader节点 -
CORE_PEER_PROFILE_ENABLED
:在peer节点中有一个profile服务 -
CORE_PEER_TLS_CERT_FILE
:证书文件路径 -
CORE_PEER_TLS_KEY_FILE
:私钥文件路径 -
CORE_PEER_TLS_ROOTCERT_FILE
:根证书文件路径
4 相关配置文件 #
将docker-compose.yaml
文件按照如下修改,主要需要修改容器名称,挂载目录以及网络端口号。
version: '2'
volumes:
orderer.test.com:
peer0.org1.test.com:
networks:
test:
services:
orderer.test.com:
container_name: orderer.test.com
image: hyperledger/fabric-orderer:latest
environment:
- FABRIC_LOGGING_SPEC=INFO
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
- ORDERER_GENERAL_LISTENPORT=7050
- ORDERER_GENERAL_GENESISMETHOD=file
- ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
- ORDERER_GENERAL_LOCALMSPID=OrdererMSP
- ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
# enabled TLS
- ORDERER_GENERAL_TLS_ENABLED=true
- 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]
- ORDERER_KAFKA_TOPIC_REPLICATIONFACTOR=1
- ORDERER_KAFKA_VERBOSE=true
- ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=/var/hyperledger/orderer/tls/server.crt
- ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=/var/hyperledger/orderer/tls/server.key
- ORDERER_GENERAL_CLUSTER_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/test.com/orderers/orderer.test.com/msp:/var/hyperledger/orderer/msp
- ./crypto-config/ordererOrganizations/test.com/orderers/orderer.test.com/tls:/var/hyperledger/orderer/tls
- orderer.test.com:/var/hyperledger/production/orderer
ports:
- 7050:7050
networks:
- test
peer0.org1.test.com:
container_name: peer0.org1.test.com
image: hyperledger/fabric-peer:latest
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=solotest_test
- FABRIC_LOGGING_SPEC=INFO
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_PROFILE_ENABLED=true
- 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
- CORE_PEER_ID=peer0.org1.test.com
- CORE_PEER_ADDRESS=peer0.org1.test.com:7051
- CORE_PEER_LISTENADDRESS=0.0.0.0:7051
- CORE_PEER_CHAINCODEADDRESS=peer0.org1.test.com:7052
- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.test.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.test.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
volumes:
- /var/run/:/host/var/run/
- ./crypto-config/peerOrganizations/org1.test.com/peers/peer0.org1.test.com/msp:/etc/hyperledger/fabric/msp
- ./crypto-config/peerOrganizations/org1.test.com/peers/peer0.org1.test.com/tls:/etc/hyperledger/fabric/tls
- peer0.org1.test.com:/var/hyperledger/production
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
ports:
- 7051:7051
- 7053:7053
networks:
- test
cli:
container_name: cli
image: hyperledger/fabric-tools:latest
tty: true
environment:
- GOPATH=/opt/gopath
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- FABRIC_LOGGING_SPEC=INFO
- GODEBUG=netdns=go
- CORE_PEER_ID=cli
- CORE_PEER_ADDRESS=peer0.org1.test.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.test.com/peers/peer0.org1.test.com/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.test.com/peers/peer0.org1.test.com/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.test.com/peers/peer0.org1.test.com/tls/ca.crt
- CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.test.com/users/Admin@org1.test.com/msp
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
volumes:
- /var/run/:/host/var/run/
- ./chaincode:/opt/gopath/src/github.com/chaincode
- ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
- ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
networks:
- test
5 启动docker-compose #
使用以下命令启动docker compose并使用-d
启动守护进程。
docker-compose up -d
启动成功会输出:
Creating network "solotest_test" with the default driver
Creating cli ... done
Creating peer0.org1.test.com ... done
Creating orderer.test.com ... done
使用以下命令检测网络是否正常启动了:
# 在当前文件目录下执行下边命令
docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------------
cli /bin/sh Up
orderer.test.com orderer Up 0.0.0.0:7050->7050/tcp
peer0.org1.test.com peer node start Up 0.0.0.0:7051->7051/tcp,
0.0.0.0:7053->7053/tcp
注意 : 注意 在这之后 所有的test我改成了example 例如orderer.test.com-orderer.example.com实际操作不用改。
通道操作 #
本节主要介绍的peer channel
命令,peer channel
命令主要是用于创建通道以及节点加入通道。
1 创建通道 #
使用docker exec
命令进入客户端容器。
docker exec -it cli bash
使用以下命令在客户端容器中创建通道。
peer channel create -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/channel.tx --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/msp/tlscacerts/tlsca.example.com-cert.pem
-o
,--orderer
: orderer节点的地址-c
,--channelID
: 要创建的通道的ID, 必须小写, 在250个字符以内-f
,-file
: 由configtxgen
生成的通道文件, 用于提交给orderer-t
,--timeout
: 创建通道的超时时长, 默认为5s--tls
: 通信时是否使用tls加密--cafile
: 当前orderer节点pem格式的tls证书文件, 要使用绝对路径.- orderer节点pem格式的tls证书文件路径为:
crypto-config/ordererOrganizations/test.com/orderers/orderer.test.com/msp/tlscacerts/tlsca.test.com-cert.pem
注意:设置的通道名称必须与创建通道交易配置文件时指定的通道名称相同
使用ls
命令查看生成的文件,
ls
channel-artifacts crypto mychannel.block
2 加入通道 #
将每个组织的每个节点都加入到通道中需要客户端来完成,一个客户端同时只能连接一个peer节点, 如果想要该客户端连接其他节点, 那么就必须修改当前客户端中相关的环境变量。我们当前在docker-compose.yaml
文件中所配置的cli连接的是Go组织的peer0节点。
使用以下命令让peer0节点加入通道。
peer channel join -b mychannel.block
-b
, --blockpath
: block
文件路径(通过 peer channel create 命令生成的通道文件)
输出如下,此时Org1组织的peer0已经加入通道。
-> INFO 002 Successfully submitted proposal to join channel
3更新锚节点 #
使用以下命令来更新锚节点。
peer channel update -o orderer.example.com:7050 -c mychannel -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
-
-o
,--orderer
: orderer节点的地址 -
-c
,--channelID
: 要创建的通道的ID, 必须小写, 在250个字符以内 -
-f
,-file
: 由cryptogen
生成的锚节点文件
exit 退出 搞完要退到 solotest 目录
为什么要创建节点并将其加入应用通道中?
创建应用通道交易配置文件,可以指定创建的应用通道中可以有哪些组织加入及指定相应的权限;网络上的每个交易都需要在一个指定的通道中执行;在通道中,交易必须通过通道的认证和授权。要加入一个通道的每个节点都必须有自己的通过MSP获得的身份标识,用于鉴定每个节点在通道中的是什么节点和服务。
安装调用智能合约 #
从Hyperledger Fabric 2.0版本开始,链码的安装命令与过程与之前版本略有不同,2.0版本开始链码的安装命令引入lifecycle
,整体的安装流程可以分为四个步骤:打包、安装、机构审批、链码提交。
1.打包智能合约 #
首先我们使用以下命令在项目路径下创建一个文件夹名为chaincode
mkdir chaincode
然后使用以下命令将官方示例的智能合约复制到我们刚刚创建的chaincode
文件夹中
cd ~/hyperledger/fabric-samples/chaincode
cp -r sacc ~/hyperledger/solotest/chaincode
我们回到客户端容器中进入链码所在的目录
cd /opt/gopath/src/github.com/chaincode/sacc
使用以下命令设置go语言依赖包
go env -w GOPROXY=https://goproxy.cn,direct
go env -w GO111MODULE=on
go mod init sacc
go mod tidy
go mod vendor
go env -w GO111MODULE=off
回到peer目录下
cd /opt/gopath/src/github.com/hyperledger/fabric/peer
Fabric生命周期将chaincode打包在易于阅读的tar文件中,方便协调跨多个组织的安装,使用以下命令打包链码
peer lifecycle chaincode package sacc.tar.gz \
--path github.com/chaincode/sacc/ \
--label sacc_1
sacc.tar.gz
为包文件名path
:智能合约路径lang
:智能合约语言,支持Golang、NodeJs、Javalabel
:智能合约标签,可以标记chaincode源代码的版本
使用ls
命令查看生成的压缩文件
ls
channel-artifacts crypto sacc.tar.gz
2.安装智能合约 #
使用以下命令来安装智能合约。
peer lifecycle chaincode install sacc.tar.gz
使用以下命令查询已安装的链码。
peer lifecycle chaincode queryinstalled
Installed chaincodes on peer:
Package ID: sacc_1:0b6ac7f5af4b129ec288b71b14dcd05e55b04f252cfabb7747781332bd073e96, Label: sacc_1
根据默认策略,需要超过半数的机构审批链码后才能向通道提交链码,使用以下命令向组织申请审批。
peer lifecycle chaincode approveformyorg --channelID mychannel --name sacc --version 1.0 --init-required --package-id sacc_1:0b6ac7f5af4b129ec288b71b14dcd05e55b04f252cfabb7747781332bd073e96 --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
tls
是否启动tlscafile orderer
的ca证书路径channelID
智能合约安装的channelname
合约名version
合约版本init-required
合约是否必须执行initpackage-id
queryinstalled查询的合约IDsequence
序列号waitForEvent
等待peer提交交易返回
4.检查智能合约是否就绪 #
合约的生命周期背书策略在channel配置中定义,需要大多数组织同意,使用以下命令查看。
peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name sacc --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
"approvals": {
"Org1MSP": true
}
5.提交智能合约定义 #
peer lifecycle chaincode commit -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 --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 --channelID mychannel --name sacc --version 1.0 --sequence 1 --init-required
peerAddresses
节点地址tlsRootCertFiles
节点ca根证书路径(–peerAddresses
--tlsRootCertFiles
可使用多个节点,将合约部署到这些节点上)
6.调用智能合约 #
使用以下命令调用chaincode的Init
方法,设置初始值:
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 mychannel -n sacc --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 --isInit -c '{"Args":["name","ab"]}' --waitForEvent
使用以下命令查询链码。
peer chaincode query -C mychannel -n sacc -c '{"Args":["get","name"]}'
输出:
ab