【我的区块链之路】- Hyperledger fabric的简单入门(二)单机演示fabric网络启动全过程

     【转载请标明出处】:https://blog.csdn.net/qq_25870633/article/details/81144847

我们接着上一篇文章 【我的区块链之路】- Hyperledger fabric的简单入门(一)接着讲fabric-samples/first-network目录中来快速启动我们的第一个fabric网络;在上篇文章中我们只是使用了 ./byfn.sh 文件来把fabric网络示例跑起来,我们也可以从日志中查看到 从启动前的准备工作、怎么启动网络及启动网络后如何去安装链码、实例化链码,调用链码等全过程。那么,今天我们来讲解下,这些详细的步骤并通过手动启动网络来实践下整个过程:

      首先,我们在启动网络之前需要做一下准备工作,在前一篇文章中我们一笔带过了说在 fabric-samples/bin目录中有几个我们需要的工具 configtxgen 、configtxlator 、cryptogen ;【a】其中 cryptogen 用来生成组织的拓扑结构和相关身份证书生成的文件都放置到 crypto-config目录下(没有的话会自动创建);【b】configtxgen 用来生成 创世区块 genesis.block【创世块 为同道中所有交易的起始块】及生成通道的交易配置文件(主要用来创建通道用 xxxchannel.tx) 及各个组织的锚节点的更新配置文件(如: Org1MspAnchors.tx,生成锚节点配置文件 需要根据组织来生成 如有N个组织那个需要生成N个,包活后面的更新锚节点配置的操作也是一样,需要执根据不同的组织来执行N次);【c】configtxlator 用来解读配置信息及动态网正在运行的网络中添加 新组织;然后下面我们先来说一说 使用  fabric  网络的整个大体的流程。

fabric网络使用流程步骤:

                                               【我的区块链之路】- Hyperledger fabric的简单入门(二)单机演示fabric网络启动全过程_第1张图片

以下命令均是需要在配了环境变量  ~/fabric-samples/bin的情况下执行的哦

【一】cryptogen:生成网络组织及相应的身份证书

进入fabric-samples/first-network目录中,执行

cryptogen generate --config=./crypto-config.yaml

或者

cryptogen generate --config=./crypto-config.yaml  --output    ./crypto-config   

【其中  --config=./crypto-config.yaml (关于配置文件的内容我们后续再讨论)为指定使用配置文件默认会使用当前目录的 ; --output    ./crypto-config 不指定的话会默认在当前文件夹生成 crypto-config 目录;里面生成了 ordererOrganizations 和 peerOrganizations】我们通过 tree 查看里面的内容为:

  

.
├── ordererOrganizations
│   │
│   │   ## Orderer的参考 Peer的讲解,因为他们二者差不多的
│   └── example.com
│       ├── ca
│       │   ├── 56d9c0c46acdda38a174a5ba3ffc44726a2c027e16bb22b460413acbcb9b3a90_sk
│       │   └── ca.example.com-cert.pem
│       ├── msp
│       │   ├── admincerts
│       │   │   └── [email protected]
│       │   ├── cacerts
│       │   │   └── ca.example.com-cert.pem
│       │   └── tlscacerts
│       │       └── tlsca.example.com-cert.pem
│       ├── orderers
│       │   └── orderer.example.com
│       │       ├── msp
│       │       │   ├── admincerts
│       │       │   │   └── [email protected]
│       │       │   ├── cacerts
│       │       │   │   └── ca.example.com-cert.pem
│       │       │   ├── keystore
│       │       │   │   └── 2ec1193fe048848eaa8e20666e26c527b791c4fb127d69cae65095bd31b6c80e_sk
│       │       │   ├── signcerts
│       │       │   │   └── orderer.example.com-cert.pem
│       │       │   └── tlscacerts
│       │       │       └── tlsca.example.com-cert.pem
│       │       └── tls
│       │           ├── ca.crt
│       │           ├── server.crt
│       │           └── server.key
│       ├── tlsca
│       │   ├── 2d66be83c519da67bb36b0972256a3b24357fa7f5b3a61f11405bc8b1f4d7c53_sk
│       │   └── tlsca.example.com-cert.pem
│       └── users
│           └── [email protected]
│               ├── msp
│               │   ├── admincerts
│               │   │   └── [email protected]
│               │   ├── cacerts
│               │   │   └── ca.example.com-cert.pem
│               │   ├── keystore
│               │   │   └── a3c1d7e1bc464faf2e3a205cb76ea231bd3ee7010655d3cd31dc6cb78726c4d0_sk
│               │   ├── signcerts
│               │   │   └── [email protected]
│               │   └── tlscacerts
│               │       └── tlsca.example.com-cert.pem
│               └── tls
│                   ├── ca.crt
│                   ├── client.crt
│                   └── client.key
└── peerOrganizations
	│ 
	│   ## 组织1的
    ├── org1.example.com
    │   ├── ca  	##  存放组织Org1的 【根证书】 和 对应的私钥文件,默认采用EC算法,证书为自签名。组织内的实体将基于该根证书作为证书根。
    │   │   ├── 496d6a41ae5f66bf120df3eab3a9d2dc4d268b2ab9a22af891d33d323bbdb5c8_sk
    │   │   └── ca.org1.example.com-cert.pem
    │   ├── msp 	##  存放代表该组织的身份信息 
    │   │   ├── admincerts  	## 组织管理员的身份验证证书,被根证书签名
    │   │   │   └── [email protected]
    │   │   ├── cacerts  ## 组织的根证书,同ca目录下文件
    │   │   │   └── ca.org1.example.com-cert.pem
    │   │   ├── config.yaml
    │   │   └── tlscacerts  	## 用于TLS的CA证书,自签名
    │   │       └── tlsca.org1.example.com-cert.pem
    │   ├── peers  ## 存放属于该组织的所有Peer节点
    │   │   │
    │   │   ├── peer0.org1.example.com   	## 第一个peer的信息,包括其msp证书和tls证书两类
    │   │   │   |
    │   │   │   ├── msp		## msp相关证书
    │   │   │   │   ├── admincerts		## 组织管理员的身份验证证书。Peer将基于这些证书来认证交易签署者是否为管理员身份
    │   │   │   │   │   └── [email protected]
    │   │   │   │   ├── cacerts		## 存放组织的根证书
    │   │   │   │   │   └── ca.org1.example.com-cert.pem
    │   │   │   │   ├── config.yaml
    │   │   │   │   ├── keystore	## 本节点的身份私钥,用来签名
    │   │   │   │   │   └── 0f0c2e1835086161f6a10c4bb38c2d89b2cee4e1128cee0fcda4433feb6eb6f8_sk
    │   │   │   │   ├── signcerts	## 验证本节点签名的证书,被组织根证书签名
    │   │   │   │   │   └── peer0.org1.example.com-cert.pem
    │   │   │   │   └── tlscacerts	## TLS连接用到身份证书,即组织TLS证书
    │   │   │   │       └── tlsca.org1.example.com-cert.pem
    │   │   │   └── tls 	## tls相关证书
    │   │   │       ├── ca.crt 	## 组织的根证书
    │   │   │       ├── server.crt 	## 验证本节点签名的证书,被组织根证书签名
    │   │   │       └── server.key 	## 本节点的身份私钥,用来签名
    │   │   │
    │   │   │
    │   │   └── peer1.org1.example.com
    │   │       
    │   │      
    │   │           
    │   ├── tlsca 	## 存放tls相关的证书和私钥
    │   │   ├── 3d39ea82dd5343c261b0480bc13d645a3cee13b7e7aa8c54fd2b5162f709671f_sk
    │   │   └── tlsca.org1.example.com-cert.pem
    │   │
    │   └── users 	## 存放属于该组织的用户的实体
    │   	│
    │       ├── [email protected] 		## 管理员用户的信息,其中包括msp证书和tls证书两类
    │       │   │ 
    │       │   │   
    │       │   ├── msp 	## msp相关证书
    │       │   │   |
    │       │   │   ├── admincerts  	## 组织根证书作为管理员身份验证证书
    │       │   │   │   └── [email protected]
    │       │   │   ├── cacerts 		## 存放组织的根证书
    │       │   │   │   └── ca.org1.example.com-cert.pem
    │       │   │   ├── keystore 		## 本用户的身份私钥,用来签名
    │       │   │   │   └── 2b933c0740d857284be98ff218bf279261e55eff2b89d973e0a1f435f7c7d28b_sk
    │       │   │   ├── signcerts 		## 管理员用户的身份验证证书,被组织根证书签名。要被某个Peer认可,则必须放到该Peer的msp/admincerts目录下
    │       │   │   │   └── [email protected]
    │       │   │   └── tlscacerts 		## TLS连接用的身份证书,即组织TLS证书
    │       │   │       └── tlsca.org1.example.com-cert.pem
    │   	│   |
    │       │   └── tls 	## 存放tls相关的证书和私钥
    │       │       ├── ca.crt 	## 组织的根证书
    │       │       ├── client.crt 	## 管理员的用户身份验证证书,被组织根证书签名
    │       │       └── client.key 	## 管理员用户的身份私钥,被组织根证书签名
    │       │
    │       └── [email protected]   	## 第一个用户的信息,包括msp证书和tls证书两类
    │           │ 
    │           ├── msp 	## msp证书相关信息
    │           │   ├── admincerts 	## 组织根证书作为管理者身份验证证书
    │           │   │   └── [email protected]
    │           │   ├── cacerts 	## 存放组织的根证书
    │           │   │   └── ca.org1.example.com-cert.pem
    │           │   ├── keystore 	## 本用户的身份私钥,用来签名
    │           │   │   └── 11ebc5afac42348f84a8882f329d18beee079efd4fd5d9b30389dc82053fc0c9_sk
    │           │   ├── signcerts 	## 验证本用户签名的身份证书,被组织根证书签名
    │           │   │   └── [email protected]
    │           │   └── tlscacerts 	## TLS连接用的身份证书,被组织根证书签名
    │           │       └── tlsca.org1.example.com-cert.pem
    │           └── tls  ## tls的根证书
    │               ├── ca.crt  ## 组织的根证书
    │               ├── client.crt  ## 验证用户签名的身份证书,被根组织证书签名
    │               └── client.key  ## 用户的身份私钥用来签名
    └── org2.example.com
        

好了现在相应的组织结构及结构下的相应的身份证书都已经依照相应的目录生成存放好了

身份的各种证书文件,一般包括:

- admincerts :管理员的身份证书文件
- cacerts :信任的根证书文件
- key store :节点的签名私钥文件
- signcerts :节点的签名身份证书文件
- tlscacerts: TLS 连接用的证书
- intermediatecerts (可选):信任的中间证书
- crls (可选):证书撤销列表
- config.yaml (可选):记录OrganizationalUnitldentifiers 信息,包括根证书位置和ID信息

这些身份文件随后可以分发到对应的Orderer 节点和Peer 节点上,并放到对应的MSP路径下,用于签名使用

 

【二】configtxgen:生成Orderer的创世块、生成通道的配置交易文件、生成各个组织的锚节点配置更新文件

生成Orderer的创世块

configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block

或者 

## 先配置临时环境变量  FABRIC_CFG_PATH 来制定 config.yaml的路径

export FABRIC_CFG_PATH=$PWD/first-network   【因为我是在 first-network的上一级目录配置的】

configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block

或者

configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./first-network/channel-artifacts/mygenesis.block --configPath /home/gavin/fabric/fabric-samples/first-network/

【注意:--configPath  为可选项,用来指定使用的 config.yaml 文件;其中 configtxgen  默认需要用到当前目录下的 config.yaml 配置文件(关于配置文件的内容我们后续在讨论),且命令行中的 TwoOrgsOrdererGenesis 是读取了config.yaml 文件中的 Profiles 部分中定义的配置内容】,正常执行完成后我们会在命令的指定输出目录(这里是命令中指定的 channel-artifacts目录)看到genesis.block 创世块,我们可以通过   configtxgen --inspectBlock ./genesis.block  来使用json的形式把 创世块的内容打印出来

 

生成通道的配置交易文件

export CHANNEL_NAME=mychannel      ##  最好是先配置个临时的环境变量方便后面引用,当然后面选择手打也是可以的

configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME

【可选项和上面生成创世块一致,貌似不指定 channelID 默认就是  mychannel ?? 】然后我们可以在指定的目录下(这里是 /home/gavin/fabric/fabric-samples/first-network/channel-artifacts 查看到 channel.tx )同样也有查看交易文件的方式: 

configtxgen --inspectChannelCreateTx ./channel.tx  和查看创世块内容一样只是命令选项不一样 具体可以 --help 去查看,我们可以以json的形式打印到控制台 

生成各个组织的锚节点配置更新文件

【注意】:生成组织的锚节点配置更新文件的时候,我们需要注意的是美哥组织都需要分别取生成对应的锚节点,详细是哪个为锚节点请查看 config.yaml 中自然清楚了;如我们的  config.yaml 中有这一段指定了每个组织的锚节点,

【我的区块链之路】- Hyperledger fabric的简单入门(二)单机演示fabric网络启动全过程_第2张图片

则,我们需要分别执行如下命令:【注意:生成组织锚节点所用的 profile选项值 和 生成 通道配置交易文件所用的一样哦~

configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP

以及

configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP

【其中,-asOrg  所携带的值  Org1MSP 等是 上图中所示的 org的ID 的值】执行完后我们可以在 ~/fabric-samples/first-network/channel-artifacts 目录产看到两个文件   Org1MSPanchors.tx   和  Org2MSPanchors.tx 这就是我们需要的两个组织各自的锚节点配置更新文件了

OK,到目前为止我们在启动网络前的所有准备工作都已经做完了,下面我们就来把网络启动起来  【本操作是属于 单机版的演示,现实生产环境启动网络可以使 逐个去不同服务器上启动的哦~

 

【三】启动fabric网络:使用 docker-compose 来批量启动网络

【注意】:我们本示例中启动网络是使用了docker-compose 来直接启动网络架构中所有的资源,这里使用的底层原理是:通过指定的 docker-compose.yaml 来对之前我们下好的Orderer、Peer等镜像及 我们生成好的组织结构及对应的身份证书、配置文件等来搭建我们的fabric网络,具体做了些什么需要查看 所指定的docker-compose.yaml 中配置了些什么。(docker-compose.yaml 我们后续再讲解),现在我们只需要用一下命令即可启动这个我们配置好的网络

docker-compose -f docker-compose-cli.yaml up -d  【注意: -d 是可选项,加了的话就不会打印详细的启动过程日志,个人建议不要加】

 

【我的区块链之路】- Hyperledger fabric的简单入门(二)单机演示fabric网络启动全过程_第3张图片

这只是开始的一小部分日志,往下我们还可以看到不同节点的启动过程日志,比如:

 

【我的区块链之路】- Hyperledger fabric的简单入门(二)单机演示fabric网络启动全过程_第4张图片

最后是:

【我的区块链之路】- Hyperledger fabric的简单入门(二)单机演示fabric网络启动全过程_第5张图片启动完之后我们可以使用  docker logs -f   容器ID/容器名称  来查看各个容器的启动控制台日志,看看是否正常启动了容器 【注意 这时候还是无法确保 当前节点是否 没有问题的哦~】

首先我们先 docker ps 查看下起了几个容器:

【我的区块链之路】- Hyperledger fabric的简单入门(二)单机演示fabric网络启动全过程_第6张图片

我们可以看到一共起了 一个Order 、4个peer、一个cli 共6个容器,我们不放心的话可以逐一的进入容器中【使用  docker logs -f   容器ID/容器名称 】查看启动日志~

有一点需要注意的是,

CLI容器将闲置1000秒。如果在需要时它消失了,可以用一个简单的命令重新启动它:

docker start cli

【四】创建应用通道:使用 cli 创建应用通道

        Peer节点启动后, 默认情况下没有加入网络中的任何应用通道, 也不会与Orderer服务建立连接.需要通过客户端对其进行操作, 让它加入网络和指定的应用通道中

       我们进入cli容器来操作下面所有动作【严格来说后续的操作均是需要cli来和各个节点进行交互,主要是Peer节点】

docker exec -ti cli bash

或者

docker exec -ti cli /bin/bash  【本人更倾向这种】

【我的区块链之路】- Hyperledger fabric的简单入门(二)单机演示fabric网络启动全过程_第7张图片l

为了以防万一,我们优先检查下临时环境变量是否配置了 【刚进去cli容器中是没有这个变量的】

echo $CHANNEL_NAME 没有设置的话需要设置  export CHANNEL_NAME=mychannel
 

进去之后直接在 cli 容器的这个目录下: /opt/gopath/src/github.com/hyperledger/fabric/peer  ,然后我们可以看到

        l                         

里面有三个目录 channel-artifacts 中放置的是我们准备工作中生成的 配置文件 (创世块、通道配置交易文件 等)、crypto 中放置着生成的组织结构及对应的身份证书、scripts 中是某些启动脚本;

创建通道】:

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   ##  --cafile 携带的是 orderer 的root cert的本地路径,允许我们去验证TLS握手

在执行完后会在当前目录下 有一个  通道名.block 的文件【本例子中为:mychannel.block

注意了 这个文件在 peer加入通道后,或者 cli  停止运行/重启 后 就不见了,因为他是在cli 容器里面生成的,生命伴随着 cli 容器,而 其他三个目录的内容时从外部Linux 挂载进来的,不一样~,但是我们可以使用  peer channel fetch 来从正在运行的网络中 捕获最新的  xxxchannel.block 文件

【五】加入通道:使用 cli 依次更换指向环境,逐个把peer加入到指定同道中

peer channel join -b mychannel.block

【注意:当前 cli 默认就是 Org1的 peer0 请查看 docker-compose-cli.yaml 中的配置自然明白】

切换身份(其实还是在 cli 中,只不过会以 指定的组织下的身份去 操作该组织下的资源 ,因为是由 cli  来和各个peer 等做交互的,我们可以把 cli 认为是个跳板机 ),去把其他的节点也加入 通道中:

CORE_PEER_LOCALMSPID="Org2MSP"       ##  指定组织
CORE_PEER_ADDRESS=peer0.org2.example.com:7051      ##   指定资源的 服务地址
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp     ##  指定 资源的管理员身份信息
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     ##  指定 该组织的该资源 tls根证书

【这里有个小技巧,想要知道 cli 容器当前所指的 身份环境是谁,我们可以】

echo $CORE_PEER_LOCALMSPID      ##  查看 当前的组织

echo $CORE_PEER_ADDRESS           ##   查看 当前peer的服务地址

echo $CORE_PEER_MSPCONFIGPATH   ##  查看  当前资源的管理员MSP 身份信息

echo $CORE_PEER_TLS_ROOTCERT_FILE    ##  查看  当前资源的TLS根证书

如我们默认 docker-compose-cli.yaml 中配置了 org1的 peer0  作为 cli 容器的默认指向环境,那么我们第一次进入 cli 就依次执行上述 命令得到:

【我的区块链之路】- Hyperledger fabric的简单入门(二)单机演示fabric网络启动全过程_第8张图片

好,我们现在先切换 cli 的环境指向到 org0 的 peer1 【由于相同组织 则,组织和 管理员身份不需要切换,只有资源服务地址 和 资源的 tls根证书 需要切换

CORE_PEER_ADDRESS=peer1.org1.example.com:7051

CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt

如下:  【注意 每一次新开进入的 cli 的终端 都是默认指向 org1 的 peer0 环境的哦】

【我的区块链之路】- Hyperledger fabric的简单入门(二)单机演示fabric网络启动全过程_第9张图片

OK,我们只需要依次更换cli 指向的环境,并逐个把对应的peer 加入通道中即可

【六】更新组织锚节点:使用 cli 依次更换指向环境,逐个把peer加入到指定同道中

同样我们需要依次更换 环境身份逐个去对应组织的对应peer上把它更新为 该组织的锚节点

如:【注意 锚节点必须是 之前config.yaml 中所指定的哦】

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
 

到这里为止我们整个 fabric 网络结构就算搭建起来了,那么下面我们就可以使用它来跑我们的链码了。

【七】安装链码:使用 cli 依次更换指向环境,把ChainCode安装到指定的Peer节点中

注意了,我们这里只是把ChainCode安装到指定的 Peer 上哦 (感觉是只需要背书节点安装即可),我没有说 所有的Peer都需要安装ChainCode

如: 我们只在Org1 的 Peer0 上安装了链码:

peer chaincode install -n mycc -v 1.0 -p \
github.com/chaincode/chaincode_example02/go/

【注意:链码的起始 目录为 GOPATH 的src 中的 项目目录,我们这里就是 github.com 目录

这样纸就是链码安装成功了

【八】实例化链码:使用 cli 随便一个已安装有该链码环境,把已经安装的ChainCode 进行实例化

 

peer chaincode instantiate -o orderer.example.com:7050 --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 \
-C $CHANNEL_NAME -n mycc -v 1.0 -c '{"Args":["init","a", "100", "b","200"]}'
-P "OR  ('Org1MSP.member','Org2MSP.member')"

【注意:我们必须在安装有链码的节点去实例化链码,不然的话会失败;其中链码是严格区分名称版本号,这个要和安装的时候一致;其中 -P 后面跟的是 指定调用链码时的 背书策略  其实Peer的 Endorser 节点也就是在 实例化链码时 通过背书策略 来指定的,上述背书策略表示,该链码需要Org1 或者Org2 的随意成员签名的交易均可调用该链码,如果把 member 改成peer 那么就是 随意peer 签名

安装成功如下:

其中,在没有安装链码的节点上执行实例化而失败的结果,如:

【九】测试链码:使用 cli 随便一个相同通道的节点,测试调用链码

 

查询:

peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args": ["query","a"]}'

执行事务:

peer chaincode invoke -o orderer.example.com:7050 --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  \
-C $CHANNEL_NAME -n mycc -c '{"Args":["invoke","a","b","10"]}'

查询:

peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args": ["query","a"]}'

 

【注意】:这里需要说一下,链码的执行原理,我们之前只在 org1 的 peer0 上安装并且实例化了链码之后,然后来到 其他三个节点 做链码 Query 发现提示错误信息

再做 事务操作,提示:

那么这是什么回事呢?这个会涉及到这个 transaction flow (交易流程) 了,因为peer会在客户端把交易proposal提交过来的时候本地启动一个链码容器模拟交易过程且签名结果返回给客户端的,所以本地没有链码怎么行呢?在这里我们只需要记得,只能在已安装了链码的节点实例化链码且相同名称相同版本的链码只需要实例化一次即可,然后其他节点可以在本次实例化之前或者之后 安装相同的链码都没有问题,且调用链码只能是在安装了链码的节点调用;所以,后面到org1的peer1和org2的peer1上面各自安装了链码,这时候调用成功(当然在 org2的peer0上面是不能调用生成的)

好了,手动执行一个简单的fabric网络及链码的调用全过程这里就结束了,今天下午我也懒得再写了,后续我们继续深入,其他的一些操作,比如: 往正在运行的网络中添加 新的组织,添加新的通道等等,Bye~

你可能感兴趣的:(区块链,Hyperledger,fabric,联盟链,超级账本)