分步详解 Fabric 区块链网络的部署 部署一个示例的 Fabric 区块链网络

£神魔★判官ぃ 2022-12-23 14:24 259阅读 0赞
  1. ## 分步详解 Fabric 区块链网络的部署 部署一个示例的 Fabric 区块链网络
  2. 前言
  3. 区块链(Blockchain)技术正在迅速发展,在银行、保险、物流、新闻出版、食品安全等很多领域都开始了实际应用。可以预见,将来会有越来越多的行业会应用它。
  4. Hyperledger Fabric 是其中一个非常重要的区块链技术平台。它是一个开源的、企业级的、有许可的分布式账本技术平台,它是为用于企业环境而设计的,与一些其他流行的分布式账本技术或区块链平台相比,它提供了一些非常关键的差异化的能力。
  5. 本系列文章从 Fabric 实践入手,对之进行学习与研究,进而进行基于 Fabric 的区块链应用开发,再深入研究它的数据结构、源代码与安全机制。期望能通过此系列文章,使读者能快速了解它的全貌。
  6. 本文是此系列文章的第一篇。主要内容是分步骤讲解如何部署一个示例的 Fabric 区块链网络,并初步了解 Fabric 中的一些基础内容。本文以 Fabric 1.3 为基础。
  7. 系统环境
  8. Fabric 可以被部署在 LinuxUnixWindowsMacOS 等系统上,本文以 Ubuntu 16.04 为基础进行讲解,读者如需了解其他系统上的使用情况,请参考 Fabric 原始文档
  9. 我们需要先行安装这些软件:curldockerdocker-composeGo langPythonNode.js
  10. 有些软件如果在系统中已经存在,且版本合适,则请略过相关步骤。
  11. 如无特殊说明,下文中所有命令都以 root 用户执行。如果为非 root 用户,可能有些命令需要加 sudo
  12. 确认 Ubuntu 版本
  13. cat / etc / issue
  14. 安装 curl
  15. apt install curl
  16. 安装 docker 17.06.2-ce 或更高版本
  17. curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  18. add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu
  19. $(lsb_release -cs) stable"
  20. apt update
  21. apt install docker-ce
  22. usermod -aG docker $(whoami)
  23. docker --version
  24. 显示更多
  25. 安装 docker-compose 1.14.0 或更高版本
  26. curl -L "https://github.com/docker/compose/releases/download/1.23.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
  27. chmod +x /usr/local/bin/docker-compose
  28. docker-compose --version
  29. 显示更多
  30. 安装 Go 语言 1.11.x 版本
  31. curl -O https://dl.google.com/go/go1.11.2.linux-amd64.tar.gz
  32. tar -C /usr/local -xzf go1.11.2.linux-amd64.tar.gz
  33. 显示更多
  34. 设置 Go 语言环境变量
  35. vi ~/.bashrc
  36. 在.bashrc 文件中增加以下内容
  37. export PATH=$PATH:/usr/local/go/bin
  38. 执行 .bashrc 文件,使之生效
  39. source ~/. bashrc
  40. 安装 Node.js 8.9.x 或更高版本
  41. 请注意 Fabric 目前不支持 Node.js 9.x 版本。
  42. curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
  43. apt install nodejs
  44. 安装 Node.js 后,npm 应该被同时自动安装,执行以下命令确认。
  45. npm install npm -g
  46. 安装 Python 2.7
  47. apt install python
  48. 下载 fabric 可执行文件、示例与 docker 镜像
  49. cd ~
  50. mkdir fabric
  51. cd fabric
  52. curl -sSL http://bit.ly/2ysbOFE | bash -s 1.3.0
  53. 如果提示错误,请尝试使用 https
  54. curl -sSL https://bit.ly/2ysbOFE | bash -s 1.3.0
  55. 下载、安装成功后,当前目录下会增加一个 fabric-samples 目录。 并在 docker repository 中会增加一些 docker 镜像。可以通过 docker images 命令查看。
  56. docker images
  57. 应该显示类似如下内容。
  58. 1. docker images 命令查看显示
  59. REPOSITORY TAG IMAGE ID CREATED SIZE
  60. hyperledger/fabric-javaenv 1.3.0 2476cefaf833 5 weeks ago 1.7GB
  61. hyperledger/fabric-javaenv latest 2476cefaf833 5 weeks ago 1.7GB
  62. hyperledger/fabric-ca 1.3.0 5c6b20ba944f 5 weeks ago 244MB
  63. hyperledger/fabric-ca latest 5c6b20ba944f 5 weeks ago 244MB
  64. hyperledger/fabric-tools 1.3.0 c056cd9890e7 5 weeks ago 1.5GB
  65. hyperledger/fabric-tools latest c056cd9890e7 5 weeks ago 1.5GB
  66. hyperledger/fabric-ccenv 1.3.0 953124d80237 5 weeks ago 1.38GB
  67. hyperledger/fabric-ccenv latest 953124d80237 5 weeks ago 1.38GB
  68. hyperledger/fabric-orderer 1.3.0 f430f581b46b 5 weeks ago 145MB
  69. hyperledger/fabric-orderer latest f430f581b46b 5 weeks ago 145MB
  70. hyperledger/fabric-peer 1.3.0 f3ea63abddaa 5 weeks ago 151MB
  71. hyperledger/fabric-peer latest f3ea63abddaa 5 weeks ago 151MB
  72. hyperledger/fabric-zookeeper 0.4.13 e62e0af39193 5 weeks ago 1.39GB
  73. hyperledger/fabric-zookeeper latest e62e0af39193 5 weeks ago 1.39GB
  74. hyperledger/fabric-kafka 0.4.13 4121ea662c47 5 weeks ago 1.4GB
  75. hyperledger/fabric-kafka latest 4121ea662c47 5 weeks ago 1.4GB
  76. hyperledger/fabric-couchdb 0.4.13 1d3266e01e64 5 weeks ago 1.45GB
  77. hyperledger/fabric-couchdb latest 1d3266e01e64 5 weeks ago 1.45GB
  78. hyperledger/fabric-baseos amd64-0.4.13 f0fe49196c40 5 weeks ago 124MB
  79. Fabric 可执行文件目录加入系统路径
  80. vi ~/.bashrc
  81. 在. bashrc 文件中增加以下内容:
  82. export PATH=$PATH:~/fabric/fabric-samples/bin
  83. 执行. bashrc 文件,使之生效。
  84. source ~/.bashrc
  85. 现在,Fabric 必需的系统环境与软件就全部准备好了,我们就要开始下载、部署第一个 Fabric 区块链网络了。
  86. 区块链网络示例 byfnBuilding Your First Network.)
  87. 安装的 sample 中有一个示例区块链网络 first-network,位于目录 fabric/fabric-samples/first-network,它提供了 byfn.sh 脚本以启动示例网络,但本文会跳过这个过程,而按详细步骤分解执行这个示例网络启动过程,以讲解 Fabric 中的基础文件、运行过程。
  88. 读者如果对 byfn.sh 有兴趣,可以前往 Fabric 官方文档 查看详细内容。
  89. byfn 启动过程详解
  90. 下面,我们开始按步骤详细解释这个示例的初始化与启动过程。这些详细步骤正是以 byfn.sh 为基础的。
  91. 准备
  92. 为保证一个干净的运行环境,我们需要先清理之间测试遗留下来的 docker 环境。
  93. 注意:本文假定当前系统完全为 Fabric 测试部署,没有其他 docker 容器、镜像存在或运行。如果系统中有其他容器、镜像,请不要执行以下命令,并选择执行适当的命令,以避免不当删除。
  94. 进入 first-network
  95. cd fabric/fabric-samples/first-network
  96. 清理临时文件、docker 容器、镜像及网络
  97. ./byfn.sh down
  98. 设置环境变量
  99. 清单 1. 环境变量
  100. export PATH=${PWD}/../bin:${PWD}:$PATH
  101. export FABRIC_CFG_PATH=${PWD}
  102. export CLI_TIMEOUT=10
  103. export CLI_DELAY=3
  104. export CHANNEL_NAME="mychannel"
  105. export COMPOSE_FILE=docker-compose-cli.yaml
  106. export COMPOSE_FILE_COUCH=docker-compose-couch.yaml
  107. export COMPOSE_FILE_ORG3=docker-compose-org3.yaml
  108. export LANGUAGE=golang
  109. export IMAGETAG="latest"
  110. export VERBOSE=true
  111. 显示更多
  112. CHANNEL_NAME 是将要建立的 Blockchain Channel 的名字,默认值是 mychannel”,也可以设置为你所期望的其他值,我们在以后的步骤中,一般会直接引用 $CHANNEL_NAME
  113. 证书
  114. 我们利用 cryptogen 命令,生成这个区块链网络所需要的一系列证书及相关文件。证书是基于 PKI 体系的 x509 格式证书,内容包括:自签名 CA 根证书、节点 (OrdererPeer) 证书、管理员证书、证书对应的私钥、TLS 证书等。
  115. 这个操作需要一个配置文件 crypto-config.yaml,示例中已经存在。crypto-config.yaml 中主要定义了:
  116. 1 Orderer 节点:orderer.example.com
  117. 4 Peer 节点:peer0.org1.example.com peer1.org1.example.com peer0.org2.example.com peer1.org2.example.com
  118. 在此请注意 2 点:
  119. 执行前请先确认当前目录下没有 crypto-config 目录,如果已经存在,请先删除。
  120. cryptogen 仅用作测试目的,可以方便快速的生成网络所需要的所有节点的证书。但一般情况下,cryptogen 不应被用于生产环境。(我们会在以后讲解如何添加节点,加入 Channel,并处理相关证书问题。)
  121. 生成证书
  122. cryptogen generate --config=./crypto-config.yaml
  123. 证书目录结构
  124. 执行成功后,会在当前目录下增加一个新目录 crypto-config,包含有这个网络节点的证书、私钥等加密、签名相关元素。其基本结构如下:
  125. 1. 证书目录结构
  126. 证书目录结构
  127. 在这个示例网络中,有一个 CACertificate Authority),即证书颁发机构,名字是 example.com。它给自己颁发了一个自签名根证书 ca.example.com-cert.pem,在生成的多个目录中都包含了这个 CA 根证书,而其他节点证书(除了 TLS 证书)都由此 CA 颁发。
  128. 我们查看其中的一个目录 crypto-config/ordererOrganizations/example.com/ca,有两个文件:
  129. 2. CA 自签名根证书与私钥
  130. CA 自签名根证书与私钥
  131. 其中,ca.example.com-cert.pem CA 自签名根证书。4a7d8de29b3597d425494254605833721a6f121d4941b1ca7611c1364c1436ff_sk 是根证书对应的私钥。
  132. 证书中的私钥文件名是随机产生,每次执行 cryptogen 都会产生不一样的文件名,在后续引用中请注意将之改成实际测试中产生的文件名
  133. CA 根证书
  134. 显示证书内容
  135. openssl x509 -in ca.example.com-cert.pem -text -noout
  136. 显示证书内容如下:
  137. 清单 2. CA 根证书内容
  138. Certificate:
  139. Data:
  140. Version: 3 (0x2)
  141. Serial Number:
  142. 81:0a:27:99:0a:db:06:c0:34:0f:d1:c3:9a:d5:9f:ed
  143. Signature Algorithm: ecdsa-with-SHA256
  144. Issuer: C=US, ST=California, L=San Francisco, O=example.com, CN=ca.example.com
  145. Validity
  146. Not Before: Oct 7 13:15:00 2018 GMT
  147. Not After : Oct 4 13:15:00 2028 GMT
  148. Subject: C=US, ST=California, L=San Francisco, O=example.com, CN=ca.example.com
  149. Subject Public Key Info:
  150. Public Key Algorithm: id-ecPublicKey
  151. Public-Key: (256 bit)
  152. pub:
  153. 04:49:52:eb:47:10:b5:ce:cb:8a:9e:d1:96:6e:92:
  154. 77:6d:f5:1f:53:a6:66:a0:98:be:a9:18:f5:53:e8:
  155. fc:dd:1d:fc:58:88:0c:84:2d:40:2f:b6:93:94:54:
  156. 62:8b:26:df:d6:0f:ac:17:58:70:47:66:5a:14:de:
  157. 8d:f0:85:c2:11
  158. ASN1 OID: prime256v1
  159. NIST CURVE: P-256
  160. X509v3 extensions:
  161. X509v3 Key Usage: critical
  162. Digital Signature, Key Encipherment, Certificate Sign, CRL Sign
  163. X509v3 Extended Key Usage:
  164. Any Extended Key Usage
  165. X509v3 Basic Constraints: critical
  166. CA:TRUE
  167. X509v3 Subject Key Identifier:
  168. 4A:7D:8D:E2:9B:35:97:D4:25:49:42:54:60:58:33:72:1A:6F:12:1D:49:41:B1:CA:76:11:C1:36:4C:14:36:FF
  169. Signature Algorithm: ecdsa-with-SHA256
  170. 30:44:02:20:08:e5:a2:bb:54:bf:37:01:b4:60:c8:38:1f:4f:
  171. 7c:0e:1a:21:45:31:a2:45:1f:35:03:3e:70:c4:6a:75:a0:2e:
  172. 02:20:14:5a:e3:36:33:82:20:88:33:d0:e7:b3:33:e3:8e:07:
  173. a3:b7:eb:55:83:7c:ce:22:73:5c:c8:84:4b:94:7c:bd
  174. 显示较少
  175. 其中第六行:Signature Algorithm: ecdsa-with-SHA256ECDSA 的全名是 Elliptic Curve DSA,即椭圆曲线 DSA。它是 Digital Signature Algorithm (DSA) 应用了椭圆曲线加密算法的变种。ecdsa-with-SHA256 使用 SHA256 算法对内容先计算摘要,再应用签名算法对摘要进行签名。
  176. 查看 Issuer Subject,可以看到这是一个自签名证书。
  177. PKI 相关内容是区块链技术中的一个重要环节,建议读者对 PKI 并结合 openssl 进行更详细的学习。这里顺便列举一些常用的 openssl 操作,以进一步理解证书体系。
  178. 从证书中提取公钥:
  179. openssl x509 -pubkey -in ca.example.com-cert.pem -noout > pubkey.pem cat pubkey.pem
  180. 输出内容如下:
  181. —– BEGIN PUBLIC KEY-----
  182. MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAESVLrRxC1zsuKntGWbpJ3bfUfU6Zm
  183. oJi+qRj1U+j83R38WIgMhC1AL7aTlFRiiybf1g+sF1hwR2ZaFN6N8IXCEQ==
  184. —– END PUBLIC KEY—–
  185. 为方便使用,将私钥文件复制一个文件名比较短的:
  186. cp 4a7d8de29b3597d425494254605833721a6f121d4941b1ca7611c1364c1436ff_sk key.pem
  187. 从私钥中输出公钥部分:
  188. openssl ec -in key.pem -pubout
  189. 输出内容如下:
  190. read EC key
  191. writing EC key
  192. -----BEGIN PUBLIC KEY-----
  193. MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAESVLrRxC1zsuKntGWbpJ3bfUfU6Zm
  194. oJi+qRj1U+j83R38WIgMhC1AL7aTlFRiiybf1g+sF1hwR2ZaFN6N8IXCEQ==
  195. -----END PUBLIC KEY-----
  196. 可以看到,这里的内容与之前从证书中提取的公钥内容相同。
  197. 使用私钥对测试文件 origcont 进行签名
  198. echo TheContent > origcont
  199. openssl dgst -sha256 -hex -c -sign key.pem origcont
  200. 输出内容如下:
  201. EC-SHA256(origcont)= 30:44:02:20:15:71:15:71:63:d2:0f:15:83:09:86:67:bb:5d:b6:a9:14:8c:ef:02:c1:6e:52:0e:29:ea:f6:5f:d8:66:4f:62:02:20:17:31:ce:d7:ea:c3:f5:d6:11:37:eb:ed:cd:1d:64:4d:34:ed:da:7c:91:0a:bb:a0:89:da:f1:50:3c:8c:1f:d2
  202. 因为有随机数影响,当重复执行命令时,我们可以看到每次输出结果都是不同的。
  203. 使用私钥对文件 origcont 进行签名:
  204. openssl pkeyutl -sign -in origcont -inkey key.pem -out origcont.sig
  205. 使用公钥验证签名:
  206. openssl pkeyutl -verify -in origcont -sigfile origcont.sig -inkey pubkey.pem -pubin
  207. Orderer 节点管理员证书位于 crypto-config/ordererOrganizations/example.com/msp/admincerts。由 CA 颁发给 Admin@example.com
  208. 查看 Admin@example.com 证书:
  209. openssl x509 -in Admin@example.com-cert.pem -text -noout
  210. 显示证书内容如下:
  211. 清单 3. 管理员证书内容
  212. Certificate:
  213. Data:
  214. Version: 3 (0x2)
  215. Serial Number:
  216. 5e:ca:17:c3:99:28:45:2a:65:eb:07:1e:f7:e7:ea:d7
  217. Signature Algorithm: ecdsa-with-SHA256
  218. Issuer: C=US, ST=California, L=San Francisco, O=example.com, CN=ca.example.com
  219. Validity
  220. Not Before: Oct 7 13:15:00 2018 GMT
  221. Not After : Oct 4 13:15:00 2028 GMT
  222. Subject: C=US, ST=California, L=San Francisco, CN=Admin@example.com
  223. Subject Public Key Info:
  224. Public Key Algorithm: id-ecPublicKey
  225. Public-Key: (256 bit)
  226. pub:
  227. 04:0a:60:ba:17:9b:54:de:42:7b:82:7e:d5:0b:66:
  228. 6f:61:8e:de:8d:ab:d2:bc:3c:3f:2c:bb:49:f4:7a:
  229. ef:4b:59:e4:74:15:c3:4a:39:db:6c:04:f8:98:64:
  230. ef:dd:17:b7:68:9e:a1:f9:4d:a3:6b:66:5f:dc:44:
  231. a7:18:db:34:e9
  232. ASN1 OID: prime256v1
  233. NIST CURVE: P-256
  234. X509v3 extensions:
  235. X509v3 Key Usage: critical
  236. Digital Signature
  237. X509v3 Basic Constraints: critical
  238. CA:FALSE
  239. X509v3 Authority Key Identifier:
  240. keyid:4A:7D:8D:E2:9B:35:97:D4:25:49:42:54:60:58:33:72:1A:6F:12:1D:49:41:B1:CA:76:11:C1:36:4C:14:36:FF
  241. Signature Algorithm: ecdsa-with-SHA256
  242. 30:45:02:21:00:d6:de:4b:37:30:e6:be:b1:3f:b1:4b:11:0d:
  243. 50:21:dd:d8:b4:59:4c:e8:09:a7:65:f4:eb:1c:e6:66:d8:5f:
  244. d9:02:20:42:1e:18:f0:cf:b6:79:9b:07:9a:3c:77:55:84:8f:
  245. b2:c4:2e:8a:dd:c9:7e:e2:2d:0d:ea:89:71:eb:b4:81:3f
  246. 显示较少
  247. 用根证书验证 A dmin@example.com 证书:
  248. openssl verify -CAfile ../../ca/ca.example.com-cert.pem Admin@example.com-cert.pem
  249. TLS 证书
  250. TLS 证书是自签名证书,与之前的 CA 证书没有关系。位于 crypto-config/ordererOrganizations/example.com/msp/tlscacerts 查看 TLS 证书:
  251. openssl x509 -in tlsca.example.com-cert.pem -text
  252. 清单 4. TLS 证书内容
  253. Certificate:
  254. Data:
  255. Version: 3 (0x2)
  256. Serial Number:
  257. 26:46:ff:f7:80:6a:97:8c:77:b4:0d:e3:8e:b7:de:8f
  258. Signature Algorithm: ecdsa-with-SHA256
  259. Issuer: C=US, ST=California, L=San Francisco, O=example.com, CN=tlsca.example.com
  260. Validity
  261. Not Before: Oct 7 13:15:00 2018 GMT
  262. Not After : Oct 4 13:15:00 2028 GMT
  263. Subject: C=US, ST=California, L=San Francisco, O=example.com, CN=tlsca.example.com
  264. 显示更多
  265. TLS 客户端证书
  266. TLS 客户端证书是由 TLS CA 颁发给 Admin@example.com 的用于 TLS 连接的证书。位于 crypto-config/ordererOrganizations/example.com/users/Admin@example.com/tls 查看 TLS 客户端证书:
  267. openssl x509 -in client.crt -text -noout
  268. 显示内容如下(部分内容略):
  269. 清单 5. TLS 客户端证书内容
  270. Certificate:
  271. Data:
  272. Version: 3 (0x2)
  273. Serial Number:
  274. 91:e8:d1:66:9e:1a:73:d8:32:0e:b4:84:3c:1f:eb:7a
  275. Signature Algorithm: ecdsa-with-SHA256
  276. Issuer: C=US, ST=California, L=San Francisco, O=example.com, CN=tlsca.example.com
  277. Validity
  278. Not Before: Oct 7 13:15:00 2018 GMT
  279. Not After : Oct 4 13:15:00 2028 GMT
  280. Subject: C=US, ST=California, L=San Francisco, CN=Admin@example.com
  281. 显示更多
  282. 证书间的关系
  283. 如前文所述,cryptogen 命令一般情况下仅用作测试用途,在生产环境中应通过正式合法 CA 颁发证书。但 cryptogen 命令产生的示例证书及其间的关系仍然值得学习与研究。
  284. 下面试着通过图表的方式将 ordererOrganizations 目录下的证书及其部分关系展示出来。
  285. 颜色相同的线条表示文件内容相同。
  286. 红色箭头表示 CA 颁发证书给某个组织或个人。
  287. 3. 证书间关系
  288. 证书间关系
  289. 对于 peerOrganizations 目录下证书间的关系这里不再详述,读者可以自行按类似方法进行分析与理解。
  290. Channel 文件
  291. 配置文件
  292. 以下操作将使用配置文件 configtx.yaml,其中定义了 TwoOrgsOrdererGenesis profile TwoOrgsChannel profile。读者可以先行查看此文件内容,也可以留待生成 channel 文件后再对比分析。其中部分内容如下:
  293. 清单 6. configtx.yaml
  294. Profiles:
  295. TwoOrgsOrdererGenesis:
  296. <<: *ChannelDefaults
  297. Orderer:
  298. <<: *OrdererDefaults
  299. Organizations:
  300. - *OrdererOrg
  301. Capabilities:
  302. <<: *OrdererCapabilities
  303. Consortiums:
  304. SampleConsortium:
  305. Organizations:
  306. - *Org1
  307. - *Org2
  308. TwoOrgsChannel:
  309. Consortium: SampleConsortium
  310. Application:
  311. <<: *ApplicationDefaults
  312. Organizations:
  313. - *Org1
  314. - *Org2
  315. Capabilities:
  316. <<: *ApplicationCapabilities
  317. 显示较少
  318. 生成创世区块 Genesis Block
  319. configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block
  320. 显示更多
  321. 生成的文件位于目录 channel-artifacts 下,可以通过以下命令将 Block 详细内容导入到 json 文件方便查看:
  322. configtxgen -inspectBlock channel-artifacts/genesis.block > genesis.block.json
  323. 其结构大概如下:
  324. 4. genesis.block.json
  325. genesis.block.json
  326. genesis.block 中也包含了相关的证书内容,如下面这段内容:
  327. "values":
  328. { "MSP": {
  329. "mod_policy": "Admins",
  330. "value": {
  331. "config": {
  332. "admins": [
  333. "LS0tLS1CRUdJTi<此处省略>RJRklDQVRFLS0tLS0K"
  334. ],
  335. 显示较少
  336. admins 对应的字符串即为经过 base64 编码的 Admin@org1.example.com 证书。我们可以通过以下命令查看它:
  337. echo LS0tLS1CRUdJTi<此处省略>RJRklDQVRFLS0tLS0K| base64 -d > test.pem
  338. openssl x509 -in test.pem -text -noout
  339. 显示更多
  340. 生成其他 Channel 文件
  341. 生成 Channel 配置 Transaction
  342. configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME
  343. 生成锚节点配置 Transaction for Org1
  344. configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP
  345. 生成锚节点配置 Transaction for Org2
  346. configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP
  347. 可以通过以下命令将 transaction 导出到 JSON 文件进行查看:
  348. configtxgen -inspectChannelCreateTx channel.tx > channel.tx.json
  349. configtxgen -inspectChannelCreateTx Org1MSPanchors.tx > Org1MSPanchors.tx.json
  350. configtxgen -inspectChannelCreateTx Org2MSPanchors.tx > Org2MSPanchors.tx.json
  351. 显示较少
  352. 这三个文件的结构类似,但与 genesis.block 的结构很大不同。前者是交易,而后者是 block
  353. 部署示例区块链网络
  354. 启动网络将使用三个配置文件,且它们有继承、扩展关系如下:
  355. COMPOSE_FILE = docker-compose-cli.yaml
  356. base/docker-compose-base.yaml
  357. base/peer-base.yaml
  358. 显示较少
  359. peer-base.yaml
  360. 这个配置文件中定义了将要启动的 container 所使用的镜像 image,并且定义了 container 启动后自动执行的命令。
  361. docker-compose-base.yaml
  362. 这个配置文件里定义了 5 containerorderer.example.compeer0.org1.example.compeer1.org1.example.compeer0.org2.example.compeer1.org2.example.com。其中,4 peer node 的配置继承自 peer-base.yaml 如:
  363. peer0.org1.example.com:
  364. container_name: peer0.org1.example.com
  365. extends:
  366. file: peer-base.yaml
  367. service: peer-base
  368. 显示较少
  369. orderer.example.com 则是单独的定义,并会执行不同的命令 command: orderer
  370. docker-compose-cli
  371. 这个配置文件扩展了 docker-compose-base.yaml 中的内容,并指定了 docker container 所加入的网络 networks: byfn。而且又启动了一个 container cli, 这是一个 fabric 工具集 docker container。后续中,我们会经常登录这个 container 以与 fabric 进行交互、操作。
  372. 启动区块链网络
  373. docker-compose -f $COMPOSE_FILE up -d 2>&1
  374. 启动后,执行 docker ps 可以看到 6 docker container
  375. docker ps --format "{
  376. {.ID}}\t{
  377. {.Command}}\t {
  378. {.Image}}\t{
  379. {.Names}}"
  380. 显示结果类似:
  381. 109b538211e2 "/bin/bash" hyperledger/fabric-tools:latest cli
  382. d6ca0ef10248 "peer node start" hyperledger/fabric-peer:latest peer0.org2.example.com
  383. b5143e44f87d "orderer" hyperledger/fabric-orderer:latest orderer.example.com
  384. 4618ecb778cf "peer node start" hyperledger/fabric-peer:latest peer1.org1.example.com
  385. 563244de0109 "peer node start" hyperledger/fabric-peer:latest peer0.org1.example.com
  386. 23dc569f214e "peer node start" hyperledger/fabric-peer:latest peer1.org2.example.com
  387. 显示更多
  388. 登录 cli Container
  389. docker exec -it cli bash
  390. 登录成功后进入 cli container, 请注意之后的操作如无特别说明, 为于 container 内执行命令。
  391. 如果退出 container 次登入时,下面的”准备环境变量 操作必须再执行一次。
  392. 清单 7. 准备环境变量
  393. export CHANNEL_NAME="mychannel"
  394. export LANGUAGE=golang
  395. export ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
  396. export PEER0_ORG1_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
  397. export PEER0_ORG2_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
  398. export ORG1_MSP=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
  399. export ORG2_MSP=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
  400. export CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/"
  401. export CORE_PEER_LOCALMSPID="Org1MSP"
  402. export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG1_CA
  403. export CORE_PEER_MSPCONFIGPATH=$ORG1_MSP
  404. export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
  405. 显示较少
  406. 这些环境变量将在执行 peer 命令时被使用,这些值也可以以参数的形式直接传递给 peer command。具体请查看 Fabric Commands 文档。
  407. 创建 Channel
  408. peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f
  409. ./channel-artifacts/channel.tx --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA
  410. 显示较少
  411. 执行成功后后,会在当前目录增加文件 mychannel.block,即<$CHANNEL_NAME>.block,可以通过以下命令查看 block 文件内容:
  412. configtxgen -inspectBlock mychannel.block
  413. 加入 Channel
  414. 将之前在配置文件中定义的 4 个节点加入 channel
  415. 清单 8. 将节点加入 channel
  416. # joinChannelWithRetry 0 1
  417. export CORE_PEER_LOCALMSPID="Org1MSP"
  418. export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG1_CA
  419. export CORE_PEER_MSPCONFIGPATH=$ORG1_MSP
  420. export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
  421. peer channel join -b $CHANNEL_NAME.block
  422. # joinChannelWithRetry 1 1
  423. export CORE_PEER_LOCALMSPID="Org1MSP"
  424. export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG1_CA
  425. export CORE_PEER_MSPCONFIGPATH=$ORG1_MSP
  426. export CORE_PEER_ADDRESS=peer1.org1.example.com:7051
  427. peer channel join -b $CHANNEL_NAME.block
  428. # joinChannelWithRetry 0 2
  429. export CORE_PEER_LOCALMSPID="Org2MSP"
  430. export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG2_CA
  431. export CORE_PEER_MSPCONFIGPATH=$ORG2_MSP
  432. export CORE_PEER_ADDRESS=peer0.org2.example.com:7051
  433. peer channel join -b $CHANNEL_NAME.block
  434. # joinChannelWithRetry 1 2
  435. export CORE_PEER_LOCALMSPID="Org2MSP"
  436. export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG2_CA
  437. export CORE_PEER_MSPCONFIGPATH=$ORG2_MSP
  438. export CORE_PEER_ADDRESS=peer1.org2.example.com:7051
  439. peer channel join -b $CHANNEL_NAME.block
  440. 显示较少
  441. 更新 Anchor Peer
  442. 清单 9. 更新 Anchor Peer
  443. # updateAnchorPeers 0 1
  444. export CORE_PEER_LOCALMSPID="Org1MSP"
  445. export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG1_CA
  446. export CORE_PEER_MSPCONFIGPATH=$ORG1_MSP
  447. export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
  448. peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/${CORE_PEER_LOCALMSPID}anchors.tx --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA
  449. # updateAnchorPeers 0 2
  450. export CORE_PEER_LOCALMSPID="Org2MSP"
  451. export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG2_CA
  452. export CORE_PEER_MSPCONFIGPATH=$ORG2_MSP
  453. export CORE_PEER_ADDRESS=peer0.org2.example.com:7051
  454. peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/${CORE_PEER_LOCALMSPID}anchors.tx --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA
  455. 显示较少
  456. 安装 Chaincode
  457. 如果要通过某个 peer node 访问 chaincode,那么,这个节点必须事先安装这个 chaincode
  458. 我们将要安装的 chaincode 位于 container 中的目录 /opt/gopath/src/github.com/chaincode/chaincode_example02/go (环境变量${CC_SRC_PATH})。 在主机中的位置是 fabric/fabric-samples/chaincode/chaincode_example02/go。我们可以打开文件 chaincode_example02.go 查看代码。
  459. 它主要实现了 Init Invoke 接口,并通过 Invoke 接口实现了三种操作:invode, delete, query
  460. 清单 10. chaincode_example02.go
  461. func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
  462. ...
  463. }
  464. func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
  465. ...
  466. }
  467. // Transaction makes payment of X units from A to B
  468. func (t *SimpleChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) pb.Response {
  469. ...
  470. }
  471. // Deletes an entity from state
  472. func (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) pb.Response {
  473. ...
  474. }
  475. // query callback representing the query of a chaincode
  476. func (t *SimpleChaincode) query(stub shim.ChaincodeStubInterface, args []string) pb.Response {
  477. ...
  478. }
  479. 显示更多
  480. cli container 中安装 chaincode
  481. 清单 11. cli container 中安装 chaincode
  482. # installChaincode in peer 0 1
  483. export CORE_PEER_LOCALMSPID="Org1MSP"
  484. export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG1_CA
  485. export CORE_PEER_MSPCONFIGPATH=$ORG1_MSP
  486. export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
  487. export VERSION="1.0"
  488. peer chaincode install -n mycc -v ${VERSION} -l ${LANGUAGE} -p ${CC_SRC_PATH}
  489. # installChaincode in peer 0 2
  490. export CORE_PEER_LOCALMSPID="Org2MSP"
  491. export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG2_CA
  492. export CORE_PEER_MSPCONFIGPATH=$ORG2_MSP
  493. export CORE_PEER_ADDRESS=peer0.org2.example.com:7051
  494. export VERSION="1.0"
  495. peer chaincode install -n mycc -v ${VERSION} -l ${LANGUAGE} -p ${CC_SRC_PATH}
  496. 显示较少
  497. 实例化 Chaincode
  498. Chaincode 安装后需要实例化才能使用,在 channel 中,一个 chaincode 只需要进行一次 instantiate 操作即可。这个步骤需要比较长的时间(在当前测试环境里需要 10 秒左右)。
  499. export CORE_PEER_LOCALMSPID="Org2MSP"
  500. export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG2_CA
  501. export CORE_PEER_MSPCONFIGPATH=$ORG2_MSP
  502. export CORE_PEER_ADDRESS=peer0.org2.example.com:7051
  503. export VERSION="1.0"
  504. peer chaincode instantiate -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED
  505. --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -l ${LANGUAGE} -v ${VERSION} -c
  506. '{"Args":["init","a","100","b","200"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer')"
  507. 显示更多
  508. Chaincode Query
  509. peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
  510. 得到结果为 100,即为这个 channel ledger a 所对应的初始的值。
  511. peer chaincode query 命令会获得经背书的 chaincode 执行结果。但它不会产生 transaction
  512. Chaincode Invoke
  513. export PEER_CONN_PARMS="--peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles
  514. /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:7051 --tlsRootCertFiles
  515. /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt"
  516. peer chaincode invoke -o orderer.example.com:7050 --tls
  517. $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc
  518. $PEER_CONN_PARMS -c '{"Args":["invoke","a","b","10"]}'
  519. 显示较少
  520. 通过这个命令会产生一个 transaction,将 a 对应的值减 10,同时将 b 的值加 10
  521. 再次查询:
  522. peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
  523. 返回结果为 90
  524. Chaincode Query2
  525. 尝试连接 peer1.org1.example.com 进行查询:
  526. export CORE_PEER_LOCALMSPID="Org1MSP"
  527. export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG1_CA
  528. export CORE_PEER_MSPCONFIGPATH=$ORG1_MSP
  529. export CORE_PEER_ADDRESS=peer1.org1.example.com:7051
  530. export VERSION="1.0"
  531. peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
  532. 显示较少
  533. 返回错误结果如下:
  534. Error: endorsement failure during query. response: status:500 message:"cannot retrieve package for chaincode mycc/1.0, error open /var/hyperledger/production/chaincodes/mycc.1.0: no such file or directory"
  535. 因为我们之前并没有在 peer1.org1.example.com 节点上安装 chaincode。我们尝试安装:
  536. peer chaincode install -n mycc -v ${VERSION} -l ${LANGUAGE} -p ${CC_SRC_PATH}
  537. 再次进行查询:
  538. peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
  539. Chaincode Container
  540. 在节点的 Chaincode 第一次被实例化或使用激活时,会启动一个 container 以运行 chaincode。再次执行 docker ps 可以看到增加了 3 container
  541. d1a150be4270 dev-peer1.org1.example.com-mycc-1.0-cd123150154e6bf2df7ce682e0b1bcbea...
  542. 9506d7970113 dev-peer0.org1.example.com-mycc-1.0-384f11f484b9302df90b453200cfb2517...
  543. 3d710c8dc821 dev-peer0.org2.example.com-mycc-1.0-15b571b3ce849066b7ec74497da3b27e5...
  544. 显示较少
  545. 其他 ChannelChaincode 操作
  546. 仍然在 cli Container 中执行以下操作。
  547. 列出当前节点所有加入 C hannel
  548. peer channel list
  549. 列出当前节点所 有已经安装的 Chaincode
  550. peer chaincode list --installed
  551. 获取特 C hanne l 区块链信息:
  552. peer channel getinfo -c $CHANNEL_NAME
  553. 可得到返回结果类似如下:
  554. Blockchain info: {"height":7,"currentBlockHash":"OV8dnCVwKhfJlLUsIg+orqpdMnn6cEjWDxq+1njNBZM=","previousBlockHash":"6VjT1rtVhY6jSCz+e5pWQzw7eMOkOewcfT7JkRXkw0c="}
  555. 其中,block height 的值是 7
  556. 我们可以进一步获取特定的 Block 的详细内容:
  557. peer channel fetch 6 mychannel_6.block -o orderer.example.com:7050 -c $CHANNEL_NAME --tls
  558. --cafile $ORDERER_CA
  559. configtxgen --inspectBlock mychannel_6.block > mychannel_6.json
  560. 显示较少
  561. 结束语
  562. 我们准备了 Fabric 1.3 所需要的系统环境,下载了 Fabric 示例镜像、文件,部署了第一个 Fabric 区块链示例网络 first-network,并一步一步地分解执行了 byfn.sh 中的内容。在此过程中,对每一步骤的作用进行了讲解,也分析了所用的资源文件,与产生的结果。
  563. 希望通过这个初始的比较简单的示例,我们可以对 Fabric 建立起直观印象,了解到它的一些概念、结构与运行方式。
  564. 为方便读者,本文中”byfn 启动过程详解”中用到的命令被集中于文件 stepbystep.txt 中,可以下载并分步执行。
  565. 在本系列的下一篇文章中,我们将一起学习开发、部署 Chaincode,并学习如何与数据库结合,使用 Private data Fabric 特性,并探讨如何将一个新的节点加入区块链。
  566. 参考资源
  567. 参考 IBM Blockchain Dev Center ,查看 IBM 在区块链领域的最新信息。
  568. 参考 Hyperledger Projects ,了解开源项目 Hyperledger 的主要内容。
  569. 参考 Hyperledger Fabric Documentation ,了解开源项目 Fabric 的主要内容。
  570. 参考 PKI ,了解 PKI 相关内容。
  571. 参考 openssl ,了解证书上、签名、加密的相关操作。

发表评论

表情:
评论列表 (有 0 条评论,259人围观)

还没有评论,来说两句吧...

相关阅读