开始
开始之前,需要检查是否安装了必备的包。
一旦安装了必备的包,就可以准备下载Hyperledger Fabric。在安装Fabric时,我们提供了Sample,Binaries,Docker镜像的安装。脚本会讲镜像下载到本地。
下载完Sample和Docker镜像后,你就可以开始学习文档。
前提条件
下载Git
下载cURL
下载Docker和Docker compose
安装Sample,执行文件,docker镜像
安装可执行文件时,我们提供了一个脚本可以下载并安装sample和可执行文件到系统中。你会发现sample app对于学习和操作Fabric都很有帮助。
注意:windows和mac环境说明,此处不翻译。
找一个目录存放fabric-samples代码。执行以下步骤
1.下载代码:
git clone https://github.com/hyperledger/fabric-samples.git
2.切换到合适的版本
3.安装可执行文件和配置文件到此目录下的 /bin和config
4.下载指定版本的镜像
在将要安装Fabric-sample和执行文件的目录中,继续执行命令下拉二进制文件和图像
如果希望最新版本,则忽略版本验证
curl -sSL https://bit.ly/2ysbOFE | bash -s
因为某些原因无法访问,所以要先做如下处理
1.在https://www.ipaddress.com/查询raw.githubusercontent.com的真实IP
2.修改hosts
sudo vim /etc/hosts
添加如下内容:
199.232.68.133 raw.githubusercontent.com
IP地址是查询的后的地址
注意:如果想要指定版本,传递版本到Fabric,Fabric-ca和第三方Docker镜像。下面命令展示了怎样下载最新版本Fabric v2.1.1和Fabric CA v1.4.7
curl -sSL https://bit.ly/2ysbOFE | bash -s -- <fabric_version> <fabric-ca_version> <thirdparty_version>
curl -sSL https://bit.ly/2ysbOFE | bash -s -- 2.1.1 1.4.7 0.4.20
上述命令会下载并执行一个bash脚本,并下载需要版本的二进制文件,包含如下:
- configtxgen
- configtxlator
- cryptogen
- discover
- idemixgen
- orderer
- peer
- fabric-ca-client
- fabric-ca-server
替换当前目录下的bin目录中的文件。并设置环境变量PATH
export PATH=<path to download location>/bin:$PATH
最后,脚本会从Docker Hub下载Fabric镜像。脚本结束时会列出安装的镜像。
查看每个镜像;这些组件最终包含了Fabric网络。你会发现一个Image ID有两个实例化,一个标识“amd64-1.x.x”,另一个是“latest”。1.2.0以前的镜像下载是由uname -m决定的,并且显示“x86_64-1.x.x”。
注意:不同的系统中,x86_64/amd64会替换成相应的系统。
注意:如果在本文档中没有找到内容,或者遇到了问题。可以访问 Still Have Questions?
使用Fabric测试网络
下载好docker镜像和实例代码后,就可以利用fabric-samples部署一个测试网络。可以将测试网络运行在你的电脑上来学习Fabric。经验丰富的开发者还可以使用测试网络来测试链代码和应用。测试网络只是用来学习和测试。不能作为生产环境的部署模板。在Fabric 2.0中引入的test network会长期替代first-network.
实例中使用Docker Compose部署Fabric。因为节点孤立在Docker Compose的网络中,因此测试网络不能配置链接到其它Fabric节点上。
注意:这些说明已经在最新的稳定版Docker镜像中验证。但如果你在主分支的镜像上使用这些命令,可能会遭遇error
开始之前
请确保已经下载了fabric-samples,docker镜像。安装了所需的一切程序。
启动测试网络
在fabric-samples里test-network目录中可以找到启动脚本。切换到目录
cd fabric-samples/test-network
找到启动脚本network.sh。使用./network.sh -h来显示帮助内容
Usage:
network.sh <Mode> [Flags]
<Mode>
- 'up' - bring up fabric orderer and peer nodes. No channel is created
- 'up createChannel' - bring up fabric network with one channel
- 'createChannel' - create and join a channel after the network is created
- 'deployCC' - deploy the fabcar chaincode on the channel
- 'down' - clear the network with docker-compose down
- 'restart' - restart the network
Flags:
-ca <use CAs> - create Certificate Authorities to generate the crypto material
-c <channel name> - channel name to use (defaults to "mychannel")
-s <dbtype> - the database backend to use: goleveldb (default) or couchdb
-r <max retry> - CLI times out after certain number of attempts (defaults to 5)
-d <delay> - delay duration in seconds (defaults to 3)
-l <language> - the programming language of the chaincode to deploy: go (default), java, javascript, typescript
-v <version> - chaincode version. Must be a round number, 1, 2, 3, etc
-i <imagetag> - the tag to be used to launch the network (defaults to "latest")
-cai <ca_imagetag> - the image tag to be used for CA (defaults to "1.4.6")
-verbose - verbose mode
network.sh -h (print this message)
Possible Mode and flags
network.sh up -ca -c -r -d -s -i -verbose
network.sh up createChannel -ca -c -r -d -s -i -verbose
network.sh createChannel -c -r -d -verbose
network.sh deployCC -l -v -r -d -verbose
Taking all defaults:
network.sh up
Examples:
network.sh up createChannel -ca -c mychannel -s couchdb -i 2.0.0
network.sh createChannel -c channelName
network.sh deployCC -l javascript
运行以下命令,初始化条件(关闭之前运行的容器和脚本等):
./network.sh down
开启网络
./network.sh up
会启动一个Fabric网络,由2个peer节点,一个order节点组成。但还没有创建通道。如果执行成功会看到如下输出
Creating network "net_test" with the default driver
Creating volume "net_orderer.example.com" with default driver
Creating volume "net_peer0.org1.example.com" with default driver
Creating volume "net_peer0.org2.example.com" with default driver
Creating orderer.example.com ... done
Creating peer0.org2.example.com ... done
Creating peer0.org1.example.com ... done
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8d0c74b9d6af hyperledger/fabric-orderer:latest "orderer" 4 seconds ago Up Less than a second 0.0.0.0:7050->7050/tcp orderer.example.com
ea1cf82b5b99 hyperledger/fabric-peer:latest "peer node start" 4 seconds ago Up Less than a second 0.0.0.0:7051->7051/tcp peer0.org1.example.com
cd8d9b23cb56 hyperledger/fabric-peer:latest "peer node start" 4 seconds ago Up 1 second 7051/tcp, 0.0.0.0:9051->9051/tcp peer0.org2.example.com
如果没有看到如下结果,跳转到 Troubleshooting来找原因。默认的,测试网络使用cryptogen工具来启动网络。当然,你也可以bring up the network with Certificate Authorities
包含的组件
测试网络部署后,你可以检查一下各组件。运行下面命令列出机器上运行的所有容器。你会看到被network.sh创建的三个节点
docker ps -a
每个节点和测试网络上的User都需要属于一个组织,组织是网络的成员。网络成员组成的联盟。这个测试网络有两个联盟成员Org1和Org2。网络也包含了一个排序组织,维护了网络的排序服务。
Peer是Fabric网络的基本组件。Peers储存了区块链账本并验证提交的交易。Peer上运行智能合约,管理账本数据。
每个peer都属于联盟中某个成员。在测试网络中,每个组织有一个peer节点,peer0.org1.example.com
和peer0.org2.example.com。
每个Fabric网络也包含一个排序服务。当peer验证了交易并要增加区块时,peer不决定交易的顺序和增加交易到区块到账本中,在分布式网络中,各个peer可能相距很远,对交易时间不能达成一致。对交易顺序达成一致需要高昂的进程开销。
排序节点服务可以让peer集中精力在验证交易和提交交易上。排序节点在从客户端接收到交易背书后,他们会对交易排序达成一致,并将交易加入区块。新增区块再分发给各处peer节点,各peer节点再将区块加入账本中。排序节点也可以操作系统通道,系统通道定义了Fabric网络的各项能力,例如怎样产生区块什么版本的Fabric节点可以使用。系统通道定义了联盟内有哪些组织。
示例网路使用了一个节点的Raft排序服务(被排序组织操作)。以orderer.example.com为地址运行的排序节点,测试网络这里只使用一个排序节点,在真实网络中排序节点必须有多个,并且被一个或多个排序组织操控。不同的排序节点使用Raft排序算法来达成一致。
创建通道
现在peer和orderer都已经运行,此时可以为Org1和Org2之间的交易创建一个通道。通道是联盟内某些成员的私有数据,通道可以只能被某些组织使用,而其它成员不可见。每个通道都有一个单独的区块链账本。那些使peer加入通道的组织,存储账本并验证交易。
使用network.sh来创建一个Org1和Org2之间的通道,并将它们的peer加入到通道中。运行下面代码会创建一个默认名为mychannel的通道
./network.sh createChannel
执行成功会看到如下日志输出
========= Channel successfully joined ===========
你也可以自定义通道名称,例如,如下会创建一个通道名称为channel1:
./network.sh createChannel -c channel1
如果想启动网络和创建通道一起执行,可以执行如下命令
./network.sh up createChannel
运行链码
当创建了通道后,就可以使用智能合约来和账本交互。智能合约包含了区块链上管理资产的业务逻辑。联盟成员的应用调用链码来管理数据资产。应用也可以查询账本上的数据。
为保证交易验证成功,智能合约产生的交易需要多个组织签名才能提交到区块链中。多方签名是Fabric构建信任的一部分方法。多方背书交易阻止了一个组织篡改数据或者使用大家不同意的商业逻辑。签名交易需要每个组织都在自己的peer上调用并执行智能合约,其后对输出结果进行签名。如果输出结果有了足够多的签名,交易就可以提交到账本中。指定哪些组织需要执行链码的策略被成为背书策略。背书策略作为链码定义的一部分,为每个链码单独设置。
在Fabric中智能合约以链码包的形式部署在网络中。链码安装在组织的peer中并部署到通道上,这样就可以对交易背书和账本交互。在链码部署到通道之前,通道成员需要对链码的定义达成一致,以实现对链码的管理。当有足够数量的组织对链码定义达成一致,链码定义就可以提交到通道上,此时即可使用链码。
在使用network.sh创建通道之后,你可以启动一个链码,命令如下
./network.sh deployCC
deployCC子命令会安装fabcar链码到peer0.org1.example.com和peer0.org2.example.com,且在通道中部署链码使用通道标签(如果没有通道被指定则使用mychannel)。如果是第一次部署链码,脚本会安装依赖包。默认的,脚本会安装Go版本的fabcar链码。然而你可以使用标签-l来指定安装的java或者js版本的链码。可以在目录chaincode下找到Fabcar链码。
当fabcar链码定义已经提交到通道中,初始化链码调用init函数,接着调用链码invoke来将一系列汽车数据放入其中。最后查询链码验证是否添加执行成功。如果链码安装,部署,调用成功,你可以看到如下的输出:
[{"Key":"CAR0", "Record":{"make":"Toyota","model":"Prius","colour":"blue","owner":"Tomoko"}},
{"Key":"CAR1", "Record":{"make":"Ford","model":"Mustang","colour":"red","owner":"Brad"}},
{"Key":"CAR2", "Record":{"make":"Hyundai","model":"Tucson","colour":"green","owner":"Jin Soo"}},
{"Key":"CAR3", "Record":{"make":"Volkswagen","model":"Passat","colour":"yellow","owner":"Max"}},
{"Key":"CAR4", "Record":{"make":"Tesla","model":"S","colour":"black","owner":"Adriana"}},
{"Key":"CAR5", "Record":{"make":"Peugeot","model":"205","colour":"purple","owner":"Michel"}},
{"Key":"CAR6", "Record":{"make":"Chery","model":"S22L","colour":"white","owner":"Aarav"}},
{"Key":"CAR7", "Record":{"make":"Fiat","model":"Punto","colour":"violet","owner":"Pari"}},
{"Key":"CAR8", "Record":{"make":"Tata","model":"Nano","colour":"indigo","owner":"Valeria"}},
{"Key":"CAR9", "Record":{"make":"Holden","model":"Barina","colour":"brown","owner":"Shotaro"}}]
===================== Query successful on peer0.org1 on channel 'mychannel' =====================
和测试网络交互
当启动了测试网络,你可以使用peer的CLI来和网络进行交互。peer CLI允许你调用部署链码,修改通道,或者安装部署新的链码。
确保在test-network目录中操作。如果你看了说明install the Samples, Binaries and Docker Images,你会在bin文件加下找到peer。使用如下命令将bin目录增加到CLI Path中:
export PATH=${PWD}/../bin:$PATH
还需要设置FABRIC_CFG_PATH指向包含core.yaml的文件目录
export FABRIC_CFG_PATH=$PWD/../config/
可以通过环境变量的设置来以Org1的身份来运行peer
# Environment variables for Org1
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051
CORE_PEER_TLS_ROOTCERT_FILE
和CORE_PEER_MSPCONFIGPATH
环境变量指向了Org1的加密文件目录。
如果使用./network.sh deployCC来安装和开始fabcar链码,你可以查询链码账本通过CLI。运行下面的代码来获取cars的数据
peer chaincode query -C mychannel -n fabcar -c '{"Args":["queryAllCars"]}'
如果执行成功了,你可以看到下面的输出:
[{"Key":"CAR0", "Record":{"make":"Toyota","model":"Prius","colour":"blue","owner":"Tomoko"}},
{"Key":"CAR1", "Record":{"make":"Ford","model":"Mustang","colour":"red","owner":"Brad"}},
{"Key":"CAR2", "Record":{"make":"Hyundai","model":"Tucson","colour":"green","owner":"Jin Soo"}},
{"Key":"CAR3", "Record":{"make":"Volkswagen","model":"Passat","colour":"yellow","owner":"Max"}},
{"Key":"CAR4", "Record":{"make":"Tesla","model":"S","colour":"black","owner":"Adriana"}},
{"Key":"CAR5", "Record":{"make":"Peugeot","model":"205","colour":"purple","owner":"Michel"}},
{"Key":"CAR6", "Record":{"make":"Chery","model":"S22L","colour":"white","owner":"Aarav"}},
{"Key":"CAR7", "Record":{"make":"Fiat","model":"Punto","colour":"violet","owner":"Pari"}},
{"Key":"CAR8", "Record":{"make":"Tata","model":"Nano","colour":"indigo","owner":"Valeria"}},
{"Key":"CAR9", "Record":{"make":"Holden","model":"Barina","colour":"brown","owner":"Shotaro"}}]
使用invoke调用链码改变账本数据。使用下面的命令来改变汽车的所有者:
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n fabcar --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"changeCarOwner","Args":["CAR9","Dave"]}'
如果执行成功,你会看到如下返回
2019-12-04 17:38:21.048 EST [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200
因为交易需要Org1和Org2同时背书。链码需要通过参数--peerAddresses来指定,调用peer0.org1.example.com
和 peer0.org2.example.com。因为启用了
TLS,所以调用时需要TLS证书,参数是--tlsRootCertFiles
调用链码后,我们可以使用另一种查询来看数据的改变。我们已经使用Org1的peer来查询,接下来使用Org2的peer来查询,设置Org2的环境变量:
# Environment variables for Org2
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=localhost:9051
现在你可以查看peer0.org2.example.com的数据:
peer chaincode query -C mychannel -n fabcar -c '{"Args":["queryCar","CAR9"]}'
结果可以看出"CAR9"已经交易到Dave了:
{"make":"Holden","model":"Barina","colour":"brown","owner":"Dave"}
关闭网络
当测试网络使用完毕后,你可以关掉网络,命令如下:
./network.sh down
这个命令会停止且移除节点和链码容器,删除组织加密证书,删除链码镜像。此命令还删除了通道 镜像遗留文件,允许再次运行./network.sh up。
下一步
现在已经在本机上部署了Hyperledger Fabric,你可以使用文档那个来开始开发自己的产品。
使用CA启动网络
Hyperledger Fabric使用PKI来验证所有的网络参与者。每个节点,网络管理员,交易提交者都需要有个亿公钥证书和私钥来验证身份。这些身份需要一个有效的信任根,确保证书是有网络内的组织签发。network.sh脚本创建了所需的秘钥材料。
默认的,脚本使用cryptogen工具来创建证书和秘钥。这个工具是用于开发和测试,可以迅速的为组织创建秘钥素材。当运行./network.sh up,你可以看到cryptogen工具创建了证书和秘钥,组织有:Org1,Org2,Orderer Org
creating Org1, Org2, and ordering service organization with crypto from 'cryptogen'
/Usr/fabric-samples/test-network/../bin/cryptogen
##########################################################
##### Generate certificates using cryptogen tool #########
##########################################################
##########################################################
############ Create Org1 Identities ######################
##########################################################
+ cryptogen generate --config=./organizations/cryptogen/crypto-config-org1.yaml --output=organizations
org1.example.com
+ res=0
+ set +x
##########################################################
############ Create Org2 Identities ######################
##########################################################
+ cryptogen generate --config=./organizations/cryptogen/crypto-config-org2.yaml --output=organizations
org2.example.com
+ res=0
+ set +x
##########################################################
############ Create Orderer Org Identities ###############
##########################################################
+ cryptogen generate --config=./organizations/cryptogen/crypto-config-orderer.yaml --output=organizations
+ res=0
+ set +x
然而测试网络依然提供选项以CA的方式启动。在生产网络中,每个组织操作CA创建属于本组织的身份。所有通过CA创建的身份共享一样的身份信任根。尽管这需要花费更多时间,但以CA的方式启动网络可以介绍生产环境下网络是如何部署的。部署CA也需要使用SDK登陆客户端并为你的应用创建一个证书及私钥。
如果你使用 Fabric CA部署网络,第一步关掉运行的任何网络
./network.sh down
启动网络,使用CA标签
./network.sh up -ca
执行完之后,你会看到启动了三个CA,网络中每个组织一个。
##########################################################
##### Generate certificates using Fabric CA's ############
##########################################################
Creating network "net_default" with the default driver
Creating ca_org2 ... done
Creating ca_org1 ... done
Creating ca_orderer ... done
./network.sh执行后部署CA了, 花时间去查看日志。测试网络使用Fabric CA客户端来注册节点和用户。这个脚本使用登陆命令为每个身份生成MSP目录。MSP目录包含了每个身份的证书和私钥,确立身份在组织中的角色和关系。可以使用如下命令来检查Org1的admin用户的MSP目录
tree organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/
命令揭示了MSP文件结构和配置文件。
organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/
└── msp
├── IssuerPublicKey
├── IssuerRevocationPublicKey
├── cacerts
│ └── localhost-7054-ca-org1.pem
├── config.yaml
├── keystore
│ └── 58e81e6f1ee8930df46841bf88c22a08ae53c1332319854608539ee78ed2fd65_sk
├── signcerts
│ └── cert.pem
└── user
你可以在signcerts中找到证书,在keystore文件夹中找到私钥。
cryptogen和Fabric CA都会为每个组织产生秘钥素材。