目录
介绍1、启动测试网络2、创建通道补充 3、在通道上启动链码4、与网络交互4.1、调用资产初始化链码4.2、调用资产转移链码4.3 具体化解释4.4 peer命令相关 5、关闭网络6、关于cryptogen与CA7、test-network网络的幕后
介绍
Fabric官方文档中有一部分使用Fabric测试网络的教程,是帮助新手快速上手fabric的范例。下面动手复现一下。在阅读本文前,默认你已阅读官方文档中对Fabric关键概念的解释。同时安装好运行fabric的环境以及fabric-samples。如果还没安装看我博客中的安装教程
1、启动测试网络
fabric-samples文件下有个test-network文件夹,其中有一个network.sh脚本,使用它可以在本地Docker上建立镜像。
#先导航到测试网络目录下cd fabric-samples/test-network
再开始运行前,可以先运行以下命令删除以前运行中的容器和组件
官方文档中解释会删除一下内容
remove the artifacts, crypto material, containers, volumes, and chaincode images
./network.sh down
启动网络
./network.sh up
网络启动后,可以在docker-desktop中看到:
此命令创建一个由两个peer节点和一个orderer节点组成的 Fabric 网络,且运行时不会创建任何通道
如图每个节点都有对应的端口号,这些端口号在之后可以帮助我们定位节点
当然也可以通过命令查看
#查看当前运行的所有Docker容器docker ps -a
2、创建通道
使用脚本为 Org1 组织和 Org2 组织之间的事务创建 Fabric 通道。并将其peer节点加入该通道。运行以下命令创建一个默认名称为mychannel的通道:
./network.sh createChannel
出现channel ‘mychannel’ joined就说明通道被建立了。
补充
您还可以使用通道标志来创建具有自定义名称的频道。例如,以下命令将创建一个名为channel1的通道:
./network.sh createChannel -c channel1
通道标志还允许您通过指定不同的通道名称来创建多个通道。创建mychannel或后channel1,您可以使用以下命令创建第二个名为channel2的通道:
./network.sh createChannel -c channel2
通道命名规范:
仅包含小写 ASCII 字母数字、点“.”和破折号“-”少于 250 个字符以字母开头如果您想一步启动网络并创建通道,您可以同时使用up和createChannel模式:
./network.sh up createChannel
3、在通道上启动链码
在fabric-samples中它提供的有实现各种业务的链码
在这里我们使用其中的资产转移(基本)链码asset-transfer-basic
使用network.sh创建通道后,可以使用以下命令在通道上启动链码:
#-ccn(chaincodename)表示链码名称#-ccp(chaincodepath)表示链码的文件路径#-ccl(chaincodelanguage)表示链码部署的编程语言./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go
运行过程中的日志节选系统
#先使用docker下载运行go的环境依赖。Finished vendoring Go dependencies#⭐下载完成后将智能合约(链码)打包Chaincode is packaged#⭐将链码安装到网络组织的peer节点上Chaincode is installed on peer0.org1Chaincode is installed on peer0.org2#在将节点上的链码部署到通道前,先查询在通道上的peer0.org1是否安装成功 Query installed successful on peer0.org1 on channel#⭐在将链码部署到通道之前,通道成员需要就建立链码治理的链码定义达成一致#peer所在的通道mychannel批准了peer上定义的链码Chaincode definition approved on peer0.org1 on channel 'mychannel'Chaincode definition approved on peer0.org2 on channel 'mychannel'#⭐当所需数量的组织同意时,可以将链码定义提交到通道#在通道'mychannel'上提交的链码定义Chaincode definition committed on channel 'mychannel'#在mychannel通道上的peer节点上查询到了到定义的链码Query chaincode definition successful on peer0.org1 on channel 'mychannel'Query chaincode definition successful on peer0.org2 on channel 'mychannel'
4、与网络交互
启动测试网络后,您可以使用peer CLI (peer命令行工具)对网络中的组件进行一些操作。peer CLI允许您从 CLI (当前命令行)调用已部署的智能合约(链码)、更新通道或安装和部署新的智能合约(链码)。
为了能使用peer的相关命令,你需要把peer的二进制文件添加到当前CLI中。这样你就可以在当前命令行中使用peer的相关命令了。
#在执行下列命令前需确保在test-network目录下#将fabric-samples/bin下的peer二进制文件导入到当前CLI环境中export PATH=${PWD}/../bin:$PATH#将fabric-samples/config文件夹下的core.yaml导入export FABRIC_CFG_PATH=$PWD/../config/
以上这些环境变量配置好后,就可以通过peer CLI命令在刚才启动的测试网络里进行操作了。
我们要知道我们当前是在一台计算机上模拟了一个fabric网络,现在计算机上同时拥有3个节点。但现实情况一般是分布在不同计算机上的。现在我们想要通过peer命令对网络进行一些操作,那我们在操作之前就必须先确定到底是哪个节点在执行操作。于是我们通过设置下面的这些环境变量,指定当前执行操作的peer节点。
#设置了一系列的环境变量指定了peer节点的MSP ID、TLS证书的位置、用户的MSP配置路径以及peer节点的地址export CORE_PEER_TLS_ENABLED=true#指定了peer节点的MSP ID、export CORE_PEER_LOCALMSPID="Org1MSP"#指定了peer节点TLS证书的位置export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt#指定了用户的MSP配置路径export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp#指定了peer节点的地址export CORE_PEER_ADDRESS=localhost:7051
注意
export命令是用于设置或导出环境变量,刚才我们是在当前会话中设置的变量,如果您关闭了当前会话窗口或打开了一个新的窗口,您可能需要重新设置这些环境变量。
在.bashrc配置文件中添加export命令设置的环境变量属于全局变量,在Linux的任意目录下都有效。不过因为咱们这个只是学习一下fabric的范例,就没必要设置成全局变量了。
4.1、调用资产初始化链码
在3、在通道上启动链码步骤中,我们已经将asset-transfer-basic智能合约(链码)部署在通道上。
下面我们就可以使用peer命令来调用这个链码。不过在调用链码之前,让我们先看看这个链码的详情。
打开asset-transfer-basic\chaincode-go\chaincode文件下的smartcontract.go
通过smartcontract的代码我们可以看到其中定义了资产Asset的类型和初始化账本的InitLedger函数。
下面我们使用peer命令调用这个InitLedger函数来初始化账本(请注意,CLI 不会访问 Fabric Gateway peer,因此命令中必须指定每个认可的peer。)
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 basic --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":"InitLedger","Args":[]}'
如果成功,您应该看到类似于以下示例的输出:
0001 INFO [chaincodeCmd] chaincodeInvokeOrQuery -> Chaincode invoke successful. result: status:200
您现在可以从 CLI 查询Ledger(账本)。运行以下命令以获取已添加到通道Ledger(账本)的资产列表:
peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'
如果成功,您应该看到以下输出:
[ {"ID": "asset1", "color": "blue", "size": 5, "owner": "Tomoko", "appraisedValue": 300}, {"ID": "asset2", "color": "red", "size": 5, "owner": "Brad", "appraisedValue": 400}, {"ID": "asset3", "color": "green", "size": 10, "owner": "Jin Soo", "appraisedValue": 500}, {"ID": "asset4", "color": "yellow", "size": 10, "owner": "Max", "appraisedValue": 600}, {"ID": "asset5", "color": "black", "size": 15, "owner": "Adriana", "appraisedValue": 700}, {"ID": "asset6", "color": "white", "size": 15, "owner": "Michel", "appraisedValue": 800}]
4.2、调用资产转移链码
下面我们调用smartcontract.go中的TransferAsset方法,来实现更改账本上资产的所有者。
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 basic --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":"TransferAsset","Args":["asset6","Christopher"]}'
如果命令成功,您应该看到以下响应:
0001 INFO [chaincodeCmd] chaincodeInvokeOrQuery -> Chaincode invoke successful. result: status:200 payload:"Michel"
这个时候我们再次调用查询命令,查询当前账本的所有资产
#查询当前账本中的所有资产peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'#从输出可以看出原来的asset6的所有者由Michel变成了Christopher[{"AppraisedValue":300,"Color":"blue","ID":"asset1","Owner":"Tomoko","Size":5},{"AppraisedValue":400,"Color":"red","ID":"asset2","Owner":"Brad","Size":5},{"AppraisedValue":500,"Color":"green","ID":"asset3","Owner":"Jin Soo","Size":10},{"AppraisedValue":600,"Color":"yellow","ID":"asset4","Owner":"Max","Size":10},{"AppraisedValue":700,"Color":"black","ID":"asset5","Owner":"Adriana","Size":15},{"AppraisedValue":800,"Color":"white","ID":"asset6","Owner":"Christopher","Size":15}]
4.3 具体化解释
我们用下方的示例图来代表当前test-network的环境:
P1、P2表示组织的peer节点;O表示oderer(排序节点);S5表示smartcontract(智能合约);C1表示我们创建的channel(通道)
从图中我们看到我们刚才在两个peer上都部署了智能合约;在两个peer和oderer上都有整个通道的账本(Ledger)。
也就是说刚才我们在端口为7051的peer上对Ledger执行的操作。在操作完成时,其他端口也会同步修改后的状态。
我们可以通过export命令切换到9051端口的peer,然后调用查询方法,查询一下当前的Ledger
#切换到9051端口下的peerexport CORE_PEER_TLS_ENABLED=trueexport CORE_PEER_LOCALMSPID="Org2MSP"export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crtexport CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/mspexport CORE_PEER_ADDRESS=localhost:9051#查询运行在peer0.org2.example.com上的链代码peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'#可以看到输出结果与运行在peer0.org1.example.com上的相同[{"AppraisedValue":300,"Color":"blue","ID":"asset1","Owner":"Tomoko","Size":5},{"AppraisedValue":400,"Color":"red","ID":"asset2","Owner":"Brad","Size":5},{"AppraisedValue":500,"Color":"green","ID":"asset3","Owner":"Jin Soo","Size":10},{"AppraisedValue":600,"Color":"yellow","ID":"asset4","Owner":"Max","Size":10},{"AppraisedValue":700,"Color":"black","ID":"asset5","Owner":"Adriana","Size":15},{"AppraisedValue":800,"Color":"white","ID":"asset6","Owner":"Christopher","Size":15}]
4.4 peer命令相关
peer命令的完整用法可以查看官方文档。
这里简单说明一下刚才我们使用到的peer命令中的一些参数含义
#指定了要连接的 orderer 节点的地址-o#用于在 TLS 握手期间覆盖 orderer 证书中的主机名。这在证书的主机名和实际连接的主机名不匹配时非常有用#例如,使用代理或端口转发时。在这个例子中,即使实际连接到的是 localhost:7050,客户端也会期望 orderer 的 TLS 证书呈现主机名 orderer.example.com--ordererTLSHostnameOverride#表明启用了 TLS,意味着与 orderer 的通信将被加密--tls#用于指定 TLS CA(证书颁发机构)的证书。这个证书用于验证 orderer 节点的 TLS 证书-cafile#用于指定一个或多个peer节点的地址,这些地址在执行特定的链码调用(如安装、实例化、查询或执行链码)时被用来确定与哪些peer节点进行交云。--peerAddresses #用于指定TLS根证书文件的路径。当您的Fabric网络启用了TLS(传输层安全性)功能时,TLS提供了加密通信和身份验证,确保了数据传输的安全性。--tlsRootCertFiles
5、关闭网络
使用完测试网络后,可以使用以下命令关闭网络:
./network.sh down
该命令将停止并删除节点和链代码容器,删除组织加密材料,并从 Docker 注册表中删除链代码映像。该命令还会删除以前运行中的通道工件和 docker 卷,以便您在遇到任何问题时可以再次运行
6、关于cryptogen与CA
从Fabric基础知识我们知道,Hyperledger Fabric 使用公钥基础设施 (PKI) 来验证所有网络参与者的操作。每个节点、网络管理员和提交交易的用户都需要拥有公共证书和私钥来验证其身份。这些身份需要具有有效的信任根,确定证书是由网络成员组织颁发的。但是我们上面创建的网络,并不是使用CA来为节点颁发证书的,而是使用fabric提供的cryptogen工具来生成节点的证书和密钥。这是因此我们当前是在测试环境,而不是在实际的生产环境中,使用cryptogen工具可以快速生成所需的加密材料。当然对于生产环境,还是推荐使用更强大和灵活的CA(证书颁发机构)。
在生产网络中,每个组织都运行一个 CA(或多个中间 CA),用于创建属于其组织的身份。由组织运行的 CA 创建的所有身份都共享相同的信任根。部署 CA 还允许您使用 Fabric SDK 注册客户端身份,并为您的应用程序创建证书和私钥。
如果你想使用CA启动网络,请首先运行以下命令来关闭任何正在运行的网络:
./network.sh down
然后您可以使用 CA 标志启动网络:
./network.sh up -ca
发出命令后,您可以看到脚本启动了三个 CA,网络中的每个组织各一个。
Generating certificates using Fabric CA[+] Running 4/4 ✔ Network fabric_test Created 0.1s ✔ Container ca_org2 Started 0.1s ✔ Container ca_org1 Started 0.1s ✔ Container ca_orderer Started
如果对比之前默认启动测试网络,可以发现使用CA启动网络会为每个组织创建一个CA容器
下面我们来详细了解一下通过-ca启动网络时,幕后都发生了什么。这对于你了解CA大有裨益。
#⭐首先生成了Fabric CA服务器,从上图或者下方日志信息我们可以看到,脚本为两个组织和一个排序服务提供者创建属于自己的CA服务器。#这些CA服务器作为该组织的根或中间证书颁发机构,负责生成和签发证书。Generating certificates using Fabric CA[+] Running 4/4 ✔ Network fabric_test Created ✔ Container ca_org2 Started ✔ Container ca_org1 Started ✔ Container ca_orderer Started#接着脚本创建网络参与者org1的身份Creating Org1 Identities#以下操作都是脚本通过控制fabric-ca-client客户端来执行相关操作#⭐通过enroll命令创建CA的管理员:CA 管理员负责管理 CA,包括注册新的用户和节点,并为它们颁发证书。#此过程是fabric-ca-client客户端通过预先配置的凭据(用户名、密码)向CA服务器发出请求,以获取CA管理员的证书和密钥。#Fabric CA响应注册请求,并为CA管理员生成一对公钥和私钥,以及相应的X.509证书。Enrolling the CA admin#CA管理员注册成功,他们就可以使用这个身份来进一步设置网络。以下就是CA管理员进行的操作#⭐以下是3个注册新身份:注册过程涉及到在CA数据库中创建一个新的身份记录,包括用户名和密码。#在CA中注册新身份-peer节点。为后续的证书生成做准备。Registering peer0#在CA中注册新身份-用户。在 Fabric 网络中,用户可以代表组织执行特定的链码操作。Registering user#在CA中注册新身份-组织管理员。这个管理员身份用于管理组织内的资源和策略。Registering the org admin#⭐接下来由CA执行生成加密材料,如MSP(成员服务提供者)证书和TLS(传输层安全)证书。#为 peer0 生成 MSP(成员服务提供者)证书。MSP 证书用于验证节点或用户的身份。Generating the peer0 msp#Generating the peer0-tls certificates, use --csr.hosts to specify Subject Alternative Names#为普通用户生成 MSP 证书,用于身份验证和权限控制。Generating the user msp#为组织管理员生成 MSP 证书,这是管理组织资源和操作的关键身份。Generating the org admin msp
以上过程可以总结为5步
1、先生成各个组织的CA服务器
2、 创建各个组织的身份
3、为组织所对应的CA设置管理员
4、在CA中注册节点、用户、组织管理员
5、为注册的节点、用户、组织管理员生成对应的MSP
下面我们通过以下命令查看org1管理员用户的MSP文件夹
tree organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/
其中signcerts为管理员的证书,keystore为私钥
如果你仔细查看
7、test-network网络的幕后
经过上述的学习,我们已经可以启动测试网络、创建通道、部署链码、调用链码。下面我们进一步了解一下,在我们进行这些操作的时候,幕后是如何进行的。
1、默认情况下,脚本./network.sh使用organizations/cryptogen文件夹中的配置文件即cryptogen工具,为两个对等组织和订购方组织创建证书和密钥。如果使用-ca标志来创建证书颁发机构,脚本将使用Fabric CA服务器配置文件和位于organizations/ Fabric -ca文件夹中的registerEnroll.sh脚本。cryptogen和Fabric ca都在organizations文件夹中为所有三个组织创建加密材料和MSP文件夹。
一旦生成了组织加密材料,network.sh就可以调出网络的节点。该脚本使用docker- composition -test-net。在docker文件夹中的Yaml文件中创建peer和orderer节点。docker文件夹中还包含docker- composer -e2e文件。yaml文件,该文件将显示网络节点以及三个Fabric ca。该文件用于运行Fabric SDK的端到端测试。
如果使用createChannel子命令,./network.sh将运行scripts文件夹中的createcchannel .sh脚本,使用提供的通道名称创建通道。该脚本使用configtxgen工具根据configtx/configtx中的TwoOrgsApplicationGenesis通道配置文件创建通道生成块。创建通道后,脚本使用peer cli将peer0.org1.example.com和peer0.org2.example.com加入到通道中,并使两个对等点都成为锚点。
如果发出deployCC命令,./network.sh将运行deployCC.sh脚本,在两个对等体上安装资产转移(基本)链码,然后在通道上定义该链码。一旦链码定义提交给通道,对等端就会启动