Hyperledger Fabric 超级账本 Java 开发环境搭建
面向 Java 开发人员的链代码简介
您或许听说过区块链,但可能不确定它对 Java™ 开发人员有何用。本教程将帮助大家解惑。我将分步展示如何使用 Hyperledger Fabric v0.6 来构建、运行和执行使用 Java 语言编写的智能合约或链代码。您将安装一些工具,定义本地区块链网络,构建并运行一个链代码智能合约。
有关区块链的概述,请参阅 developerWorks 博客中的 “区块链是什么?分布式账本技术入门”。
前提条件
本教程假设您满足以下前提条件:
- 听说过区块链或 Hyperledger Fabric 框架
- 拥有中等水平的 Java 编程知识,以及使用该语言和平台的经验
- 熟悉或(最好)精通使用:
- Eclipse IDE
- Docker 和 Docker Compose
- Gradle
- Linux 命令行
- SoapUI 或另一种 HTTP 客户端软件,比如 Postman
您还应该能够在最少的指导下在计算机上安装软件。由于篇幅所限,我不会介绍所有必要软件的详细安装说明;为您提供软件的网站应该提供了安装说明。
深入介绍本教程之前,我想简单说说区块链。
区块链基础
尽管关于区块链存在大量炒作,但它确实物有所值。该技术不仅本身很有趣,而且它是颠覆性的,有潜力彻底变革互联网上的业务执行方式。
如何变革?让我们来想想一次成功的业务交易的基本属性:
- 信任:我们达成了协议,但我能够真的相信您会遵守它(或尊重我)吗?
- 透明性:允许查看 “幕后情况”(这既能建立信任,又能减少对信任的需求)。
- 责任性:用来定义确定所有各方是否都认为该协议得以遵守的条件。
两方或多方之间的任何业务关系的健康程度对应于上述 3 种属性的不同级别(例如,更信任意味着需要的透明度更少,反之亦然),但其中一些属性必须存在,否则就会出现问题。
“区块链技术正被快速应用到您身边的软件开发项目中。您准备好了吗?”
区块链有何帮助?首先,通过使用通用框架,业务合作伙伴可以提前建立一个信任网络。然后,通过使用对所有交易方可见的账本,区块链提供了透明性。最后,通过采用所有各方的一致意见(使用智能合约或链代码的形式),建立了责任制。
这对 Java 开发人员有何意义?
Hyperledger 社区和 Hyperledger Fabric 的快速发展,意味着区块链技术正快速被应用到您身边的软件开发项目中。您准备好了吗?
区块链技术发展形势
有时,开发技术可能会妨碍业务问题的解决。本教程的主要目的是展示如何编写 Java 链代码,所以我选择了最简单的开发技术组合来实现此目的。
也就是说,该组合中的组件还有其他选择。在本教程中,我将使用 Docker 作为网络容器环境,而另一个选择是带 VirtualBox 的 Vagrant。如果从未使用过 Vagrant,您至少应该尝试一下。
Docker 是一个容器环境,而 Vagrant 使用了虚拟化。在与 VirtualBox 结合使用时,虚拟化环境对计算环境进行了不同程度的控制,这一点备受一些开发人员的青睐(使其成为 fabric 开发人员的理想选择)。
如果想进一步了解容器化与虚拟化孰优孰劣,请参阅 developerWorks 博客上的 “Docker 是什么?容器对应用程序有哪些好处的简介”。
如果开发人员只想编写代码,而不必担心容器、虚拟化或任何基础架构,那么可以选择 IBM® Bluemix®。尽管 Bluemix 支持运行完整的 IBM 区块链网络,但它目前还不支持使用 Java 语言开发链代码。预计此情况很快就会发生变化,所以请时刻关注。
如果在您的印象中,区块链技术当时的发展情况非常不稳定,您是对的。但是,这意味着您在恰当的时机(从一开始)就开始接触区块链和链代码。随着该技术发展成熟,您早期阶段学习该技术的投资将会不断得到丰厚的回报。
区块链是能够彻底改变每个人的业务执行方式的颠覆式技术之一。这类技术不仅包括 B2B,还包括 B2C,甚至还有 C2C。这的确是一个非常激动人心的时刻。
让我们开始吧!
设置开发环境
要运行链代码,首先需要设置开发环境。
完成本节后,您就可以运行一个 Hyperledger Java 链代码示例了,在该示例中,您将在真实链代码上部署和调用交易。然后,我将展示如何(几乎)从头编写一个新链代码程序。
在本节中,您将:
- 设置网络环境 — 用于运行您的本地区块链网络。
- 安装构建软件 — 用于构建您的链代码。
- 安装一个 HTTP 客户端 — 用于在您的链代码上调用交易。
- 启动区块链网络。
- 构建 Java shim 客户端 JAR。
实话说,要编写链代码,有许多设置工作要做。但是,如果您按照这些说明进行操作并稍微勤奋一点,您的付出将是值得的。
1.设置网络环境
本教程将使用 Docker 以及来自 Docker Hub 的预构建区块链网络组件镜像来运行本地区块链网络。如果愿意的话,可以从头构建 fabric(毕竟它是开源的),但在此阶段,使用 Docker Hub 中提供的预构建的 Hyperledger Fabric 镜像更容易一些。
我在介绍中已经提到过,另一个选择(您可能在 Hyperledger 文档中看到过)是使用 Vagrant 和 VirtualBox。Vagrant 是 fabric 开发人员的一个不错选择,但作为链代码开发人员,与处理 fabric 本身相比,我们更关心链代码的构建、运行和测试。
如果已经安装 Docker 1.12 版或更高版本,可以跳到下一节(“安装构建软件”)。在下面的操作说明中,假设您尚未安装 Docker(也就是说,您不是从以前的 Docker 版本进行升级)。安装 Docker 的过程中也会安装 Docker Compose,该工具用于定义和运行需要多个容器的应用程序,比如本教程中将运行的本地 Hyperledger 区块链网络。
安装 Docker
可在这里找到针对 Mac、Windows 和 Linux 的安装说明:
将 Docker 安装在 Mac、Windows 和 Linux 上
验证 Docker 安装
要测试 Docker 安装,可打开一个终端窗口(或 Windows 上的命令提示符)并键入以下命令:
docker -v
docker-compose -v
您会获得以下输出:
$ docker -v
Docker version 1.13.1, build 092cba3
$ docker-compose -v
docker-compose version 1.11.1, build 7c5d5e4
如果想查看 Docker 的实际运行效果,您可运行 hello-world 镜像,如下所示:
$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
78445dd45222: Pull complete
Digest: sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7
Status: Downloaded newer image for hello-world:latest
Hello from Docker! This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://cloud.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/engine/userguide/
2.安装构建软件
对于构建系统,Hyperledger Fabric 使用了 Gradle,本教程也将使用它。Gradle 是一个构建自动化系统,它结合使用了指定构建组件的简单语法与 Apache Ant 和 Apache Maven 的最佳特性,创建了一个容易使用的强大构建系统。如此多开发人员正将他们的项目切换到 Gradle,这不足为奇。请注意,本文使用的是 Gradle 3.3 版本。使用其他版本的 Gradle 可能会导致项目搭建失败。
可以在 Gradle 主页 上进一步了解 Gradle(和它的一些知名度高的用户)。
安装 Gradle
要安装 Gradle,请按照下面的说明进行操作:
将 Gradle 安装在 Mac、Windows 和 Linux 上
验证 Gradle 安装
要验证 Gradle 安装,可打开一个终端窗口并执行此命令:
gradle -v
您会看到以下输出:
$ gradle -v
------------------------------------------------------------
Gradle 3.3
------------------------------------------------------------
Build time: 2017-01-03 15:31:04 UTC
Revision: 075893a3d0798c0c1f322899b41ceca82e4e134b
Groovy: 2.4.7
Ant: Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM: 1.8.0_102 (Oracle Corporation 25.102-b14)
OS: Mac OS X 10.12.3 x86_64
3.安装 HTTP 客户端
接下来安装 HTTP 客户端软件,它允许链代码与 Hyperledger 区块链结构的 REST 接口进行通信。您的浏览器可以发出 HTTP GET,但要与 fabric 进行交互,您需要能够通过 POST 发出消息。这意味着您需要一个 HTTP 客户端。
我为本教程选择的 HTTP 客户端是 SoapUI,它提供了一个强大的、容易使用的、包含许多功能的免费社区版本。
安装 SoapUI
要安装 SoapUI,请按照下面的说明进行操作:
为 Mac OS、Windows 和 Linux 安装 SoapUI
验证 SoapUI 安装
要确认 SoapUI 已安装,可在计算机上启动该应用程序。在 Mac OS 上,打开 SoapUI 后会显示 SoapUI Starter Page,如图 1 所示。
Mac OS X 上的 SoapUI
4.启动区块链网络
现在您已安装开发和测试链代码所需的软件,是时候启动本地区块链网络了。第一步是定义网络的配置。
首先,创建一个目录,用它作为链代码开发过程中使用的所有源代码的 root 目录。在本教程中,我将使用 ~/home/mychaincode(或 Windows 上的 C:\home\chaincode)。
接下来,将 GOPATH 环境变量设置为此路径。我们不会编译任何 Go 代码,也不会构建 Golang 包或其他二进制文件,但 Golang 术语已融合到 Hyperledger 中,所以熟悉按 Go 语言和 GOPATH 的方式进行思考是一个不错的主意。
在 Linux 上,执行以下命令:
export GOPATH=~/home/mychaincode
或者在 Windows 上,可以使用以下命令:
SET GOPATH=C:\home\mychaincode
接下来,必须告诉 Docker Compose 如何创建和运行区块链对等网络。该网络是使用 YAML 定义的,应该将它命名为 docker-compose.yml。可以将文件命名为其他名称,但在启动 Docker Compose 时,必须指定 -f 标志。建议坚持使用默认名称,也就是 docker-compose.yml。
在 GOPATH 的 root 目录中创建 docker-compose.yml 文件。粘贴以下内容:
membersrvc:
image: hyperledger/fabric-membersrvc
ports:
- "7054:7054"
command: membersrvc
vp0:
image: hyperledger/fabric-peer:x86_64-0.6.0-preview
ports:
- "7050:7050"
- "7051:7051"
- "7053:7053"
environment:
- CORE_PEER_ADDRESSAUTODETECT=true
- CORE_VM_ENDPOINT=unix:///var/run/docker.sock
- CORE_LOGGING_LEVEL=DEBUG
- CORE_PEER_ID=vp0
- CORE_PEER_PKI_ECA_PADDR=membersrvc:7054
- CORE_PEER_PKI_TCA_PADDR=membersrvc:7054
- CORE_PEER_PKI_TLSCA_PADDR=membersrvc:7054
- CORE_SECURITY_ENABLED=false
- CORE_SECURITY_ENROLLID=test_vp0
- CORE_SECURITY_ENROLLSECRET=MwYpmSRjupbT
links:
- membersrvc
command: sh -c "sleep 5; peer node start --peer-chaincodedev"
这里涉及许多内容,其中大部分内容都不属于本教程的讨论范围,但我想稍微解释一下。
- 此文件告诉 Docker Compose 定义两个服务:
- membersrvc:提供成员服务的成员服务节点,具体来讲,它是一个证书签发机构 (CA),负责处理所有加密解密工作(比如颁发和撤销证书)。将用于此目的的预构建 Docker 镜像命名为 hyperledger/fabric-membersrvc。
- vp0:网络中的单独验证对等节点。对于开发目的,我们不需要奢侈地执行对等网络验证,只需要一个对等节点即可。将用于此目的的预构建 Docker 镜像命名为 hyperledger/fabric-peer: x86_64-0.6.0-preview。请注意,由于 Fabric 版本升级,如果省略掉冒号及之后的字符,会导致构建错误。此处指定使用 Fabric 0.6 版本。hyperledger/fabric-peer 等同于 hyperledger/fabric-peer:latest。
- 一些环境变量由 vp0 对等节点设置。请注意,CORE_LOGGING_LEVEL 变量被设置为 DEBUG。这会生成大量输出,这些输出有时很方便。但是,如果想要更少的输出,可将该级别更改为 INFO。请参阅 Hyperledger 设置文档中的 “日志控制” 了解日志级别的更多信息。
可以在 Docker 网站 上找到有关 Docker Compose YML 文件定义的更多信息。
接下来请注意,CORE_SECURITY_ENABLED 的值为 false。这意味着 fabric 不需要您发送任何类型的最终用户凭证。安全性不属于本教程的讨论范围,但是如果您有兴趣了解更多信息,可以根据您的链代码请求来查阅这篇安全功能说明。
最后提醒一句:对任何这些值的默认设置(尤其是端口值)的任何改动都有可能导致本教程中的示例无法运行。区块链网络是一组分布式软件组件,它们需要经过精确协调的通信。强烈建议在理解 fabric 的所有组件如何相互作用之前,不要更改端口值的默认值。
完成区块链的定义后,就可以启动本地区块链网络了。为此,请运行 Docker Compose。导航到您的 $GOPATH 并执行此命令:
docker-compose up
您会在终端窗口中获得以下输出:
$ docker-compose up
.
.
Pulling membersrvc (hyperledger/fabric-membersrvc:latest)...
latest: Pulling from hyperledger/fabric-membersrvc
.
.
Status: Downloaded newer image for hyperledger/fabric-membersrvc:latest
Pulling vp0 (hyperledger/fabric-peer:latest)...
latest: Pulling from hyperledger/fabric-peer
.
.
Status: Downloaded newer image for hyperledger/fabric-peer:latest
Creating mychaincode_membersrvc_1
Creating mychaincode_vp0_1
Attaching to mychaincode_membersrvc_1, mychaincode_vp0_1
vp0_1 | 19:30:03.773 [logging] LoggingInit -> DEBU 001 Setting default logging level to DEBUG for command 'node'
vp0_1 | 19:30:03.773 [nodeCmd] serve -> INFO 002 Running in chaincode development mode
.
.
.
vp0_1 | 19:30:04.146 [peer] chatWithSomePeers -> DEBU 07c Starting up the first peer of a new network
vp0_1 | 19:30:04.146 [consensus/statetransfer] verifyAndRecoverBlockchain -> DEBU 07d Validating existing blockchain, highest validated block is 0, valid through 0
vp0_1 | 19:30:04.146 [consensus/statetransfer] blockThread -> INFO 07e Validated blockchain to the genesis block
vp0_1 | 19:30:04.146 [consensus/handler] 1 -> DEBU 07f Starting up message thread for consenter
vp0_1 | 19:30:04.146 [nodeCmd] serve -> INFO 080 Starting peer with ID=name:"vp0" , network ID=dev, address=172.17.0.3:7051, rootnodes=, validator=true
vp0_1 | 19:30:04.146 [rest] StartOpenchainRESTServer -> INFO 081 Initializing the REST service on 0.0.0.0:7050, TLS is disabled.
vp0_1 | 19:30:04.147 [peer] ensureConnected -> DEBU 082 Starting Peer reconnect service (touch service), with period = 6s
.
.
此输出告诉您该网络在正常运行,已准备好接受链代码注册请求。
备注:突出显示的行应该仅在第一次运行区块链网络时出现,因为 Docker 需要从 Docker Hub 下载镜像。镜像下载到计算机后,仅在来自 Docker Hub 的镜像比您计算机上的镜像更新时,Docker 才会拉入它们。
现在已准备好构建 Java shim 客户端 JAR,它允许 Java 语言链代码与 Hyperledger Fabric 框架进行通信。
5.构建 Java shim 客户端 JAR
在运行链代码示例前,需要从 Hyperledger 的 GitHub 存储库获取最新的源代码。
首先,需要将 Hyperledger Fabric 克隆到本地机器上,以便构建链代码(备注:这是一项临时措施;在以后某个时刻,应该能从主要的 Maven 存储库访问 Java shim 客户端 JAR)。
备注:回想一下,您之前已将 GOPATH 设置为 Linux(或 Mac)上的 ~/home/mychaincode 或 Windows 上的 C:\home\mychaincode。
执行此命令来创建结构构建脚本所期望的目录结构:
mkdir -p $GOPATH/src/github.com/hyperledger
接下来,导航到已创建的新目录结构的底部:
cd $GOPATH/src/github.com/hyperledger
您需要从这里获取 Hyperledger 源代码,以便构建 Java shim 客户端 JAR。
可通过两种方式获得 Hyperledger 源代码。
-
不使用 git:
导航到 Hyperledger GitHub 镜像,选择v0.6分支,并单击 Clone or download 按钮,然后单击 Download ZIP(参见图 2)。一个名为 fabric-master.zip 的 ZIP 文件被下载到您的计算机,您可以将它解压到 $GOPATH/src/github.com/hyperledger。备注:请确保在解压该文件时,将 root 目录的名称从 fabric-master 更改为 fabric。 -
使用 git:
导航到 $GOPATH/src/github.com/hyperledger,将文本字段中的 URL 复制到 “Clone with HTTPS” 框中(参见图 2 中的箭头),然后使用复制的 URL 执行此命令:
git clone https://github.com/hyperledger/fabric.git
或
git clone –b v0.6
https://gerrit.hyperledger.org/r/fabric
您会看到 git 命令返回了以下终端窗口输出:
$ git clone https://github.com/hyperledger/fabric.git
Cloning into 'fabric'...
remote: Counting objects: 26976, done.
remote: Compressing objects: 100% (406/406), done.
remote: Total 26976 (delta 172), reused 0 (delta 0), pack-reused 26558
Receiving objects: 100% (26976/26976), 43.68 MiB | 4.85 MiB/s, done.
Resolving deltas: 100% (15114/15114), done.
现在您已准备好构建 Java 链代码 shim 客户端 JAR。导航到 $GOPATH/src/github.com/hyperledger/fabric/core/chaincode/shim/java 并运行以下两个命令:
gradle -b build.gradle clean
gradle -b build.gradle build
Gradle 构建输出应如下所示:
$ cd $GOPATH/src/github.com/hyperledger/fabric/core/chaincode/shim/java
$ gradle -b build.gradle clean
Starting a Gradle Daemon (subsequent builds will be faster)
:core:chaincode:shim:java:clean
BUILD SUCCESSFUL
Total time: 5.422 secs
$ gradle -b build.gradle build
:core:chaincode:shim:java:copyProtos UP-TO-DATE
:core:chaincode:shim:java:extractIncludeProto
:core:chaincode:shim:java:extractProto UP-TO-DATE
:core:chaincode:shim:java:generateProto UP-TO-DATE
:core:chaincode:shim:java:compileJava
:core:chaincode:shim:java:processResources
:core:chaincode:shim:java:classes
:core:chaincode:shim:java:jar
:core:chaincode:shim:java:assemble
:core:chaincode:shim:java:extractIncludeTestProto
:core:chaincode:shim:java:extractTestProto UP-TO-DATE
:core:chaincode:shim:java:generateTestProto UP-TO-DATE
:core:chaincode:shim:java:compileTestJava UP-TO-DATE
:core:chaincode:shim:java:processTestResources UP-TO-DATE
:core:chaincode:shim:java:testClasses UP-TO-DATE
:core:chaincode:shim:java:test UP-TO-DATE
:core:chaincode:shim:java:check UP-TO-DATE
:core:chaincode:shim:java:build
:core:chaincode:shim:java:copyToLib
:core:chaincode:shim:java:generatePomFileForMavenJavaPublication
:core:chaincode:shim:java:publishMavenJavaPublicationToMavenLocal
:core:chaincode:shim:java:publishToMavenLocal
BUILD SUCCESSFUL
Total time: 4.521 secs
构建过程中执行的最后一件事是,将 shim 客户端 JAR 添加到本地 Maven 存储库。现在您已准备好构建链代码。除非在未来某个时刻要更新结构源代码,或者出于某种原因想要再次重新构建 shim 客户端 JAR,否则不需要再次运行 Java shim 客户端 JAR。
推荐两个区块链、以太坊开发DApp的实战教程:
1. 适合区块链新手的以太坊DApp开发:
http://xc.hubwiz.com/course/5a952991adb3847553d205d1
2. 用区块链、星际文件系统(IPFS)、Node.js和MongoDB来构建电商平台:
http://xc.hubwiz.com/course/5abbb7acc02e6b6a59171dd6
下一篇: java线程池的使用