本文旨在给对区块链技术感兴趣的同学一个快速的技术演示,如果你对Docker, Linux命令和Go语言比较了解,那这篇文章对你将是轻车熟路。区块链技术到底是什么,我想大家从各种信息渠道都了解过,本文就不讲那些原理了。本次演示选择的区块链平台是Hyperledger Fabric, Hyperledger Fabric是企业级区块链技术,属于联盟链的一种。 目前作为Linux基金会的开源项目来发行和维护。目前的最新版本是v1.4, 这是官方的文档地址: https://hyperledger-fabric.readthedocs.io/en/release-1.4/。
接下来我们将利用Hyperledger Fabric搭建一个小型的区块链网络。然后在这个网络中部署智能合约代码, 在Hyperledger Fabric中我们称作Chaincode, 智能合约在以太坊那边则称作DApp。
一,准备环境
首先我们需要准备一部装有Linux的电脑, 本文选择使用公有云的虚拟主机来搭建环境,因为创建和销毁都比较方便,配置非常灵活。 配置方面建议选择2核4G以上的配置,因为CPU和内存配置过低会出现性能问题导致运行出错。操作系统本文选择的是Ubuntu 18.04的版本,当然你可以选择CentOS, 只不过命令会稍微有些不同。另外该主机一定要支持科(Fan)学(Qiang)上网,否则会比较麻烦。
1. 登录主机
目前公有云上的主机都支持SSH的连接方式,同时配合使用密钥进行登录。因为我使用的是Windows 10操作系统,所以我选择Putty作为连接的客户端, 但是一般公有云导出的密钥格式为RSA的私钥,所以你还需要把RSA的私钥转成Putty用的PPK格式。 好在Putty的软件还自带一个转换工具叫做Puttygen, 全称叫PuTTY Key Generator, 在菜单中选择Conversions -> Import Key, 选择你在公有云控制台下载的密钥文件。
然后输入Key passphrase, 也就是登录用的密码,然后选择 Save private Key。就生成了ppk后缀的密钥文件。
然后我们就可以使用Putty去登录主机了,在这个界面填写你主机的IP地址,端口就用默认的22
然后在左侧菜单中选择SSH-Auth, 然后右侧选择你刚才生成的ppk密钥。
2. 安装软件包
我们下面来逐一安装所需要的软件包,首先我们安装Docker。
2.1 首先卸载旧版本的Docker, 如果你是全新环境则无需此步。
$ sudo apt-get remove docker docker-engine docker.io
2.2 更新系统软件
$ sudo apt-get update
2.3 安装依赖包
$ sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
2.4 添加官方密钥
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
显示OK表示添加成功
2.5 添加仓库
$ sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
2.6 再次更新系统软件
注意这步不要少。
$ sudo apt-get update
2.7 安装Docker
$ sudo apt-get install docker-ce
安装完毕后,输入以下命令查看Docker版本号
$ docker -v
2.8 安装docker-compose
我们还需要继续安装docker-compose, 通过以下命令下载docker-compose。
$ sudo curl -L https://github.com/docker/compose/releases/download/1.17.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
2.9 授权
$ sudo chmod +x /usr/local/bin/docker-compose
2.10 查看版本
$ docker-compose --version
2.11 把当前用户添加到docker用户组
docker和docker-compose安装完毕后,还需要把当前用户加入到docker组中。
如果没有docker组就用下面命令创建
$ sudo groupadd docker
然后添加到docker组, 当前用户为ubuntu
$ sudo gpasswd -a ubuntu docker
我们把当前用户加入到docker组后,还要logout一下,再进入就会生效,当然也可以用命令直接生效。
2.22 安装Golang
安装完docker后,我们还要继续安装Golang的语言环境,用下面命令
$ sudo apt-get install golang
一般情况下不用单独设置golang的环境变量,默认会安装到 /usr/bin/ 下面, 可以通过whereis命令查看一下。
然后我们查看一下go的版本
$ go version
本文中的程序只使用Go语言作为开发语言,所以就不需要再安装Nodejs环境了。至此为止操作系统和软件环境基本安装完毕。下面我们来搭建Hyperledger Fabric的环境。
3. 安装Hyperledger Fabric
首先,我们直接在/home/ubuntu/下面来执行下面的命令。
$ curl -sSL http://bit.ly/2ysbOFE | bash -s
注意,这个链接需要科学上网才能打开, 这个链接实际上是下载了一个脚本文件,然后脚本中会执行拉取Hyperledger Fabric各种演示代码的安装包合集,包括所用到的Docker的镜像。这个过程取决于网速。
安装完毕后,会在当前执行的目录出现一个叫做fabric-samples的文件夹,我们所需要的一切都在这里面。 下面就是它的目录结构。
二, 配置环境
接下来, 我们正式进入的Hyperledger Fabric的实践阶段, 由于Hyperledger Fabric定位是作为联盟链的一种,允许多个组织加入到区块链的网络中,每个组织中有多个节点, 所以配置文件中会出现类似org或peer的字样。由于篇幅有限,我们此次也不过多讲解Hyperledger Fabric的原理,我们就直接一点让大家把一个简单的网络结构运行起来。从fabric-samples的目录中进入basci-network, 这里面有我们想要的一个最基本的网络配置。如下图。
这里面有几个重要的文件我们需要修改一下才能安装chaincode,首先我们vi打开docker-compose.yml文件,这个文件是用来配置docker容器的,我们在cli这个容器配置的volumes配置项中加入下面一行, 用来映射本地文件路径到容器中。
- ./config:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
写好后就像下面这样, 然后:wq存储退出。
然后我们还要修改一下start.sh, 默认启动的容器中没有cli这个容器,我们把它加到这个行的最后
docker-compose -f docker-compose.yml up -d ca.example.com orderer.example.com peer0.org1.example.com couchdb cli
似乎网络配置这块就改这么多就行了, 我们尽量保持它原来的样子, 由于在docker-compose.yml中配置的chaincode映射路径已经写好了,所以我们接下来编写Go的代码,就直接在本地的fabric-samples/chaincode/下面写就行了,这样最简单。
我们直接在chaincode里面新建一个文件夹叫做chaincode_helloworld, 然后进入chaincode_helloworld中再建一个文件夹main, 这个main实际上是Go程序的一个包结构, 然后在这个main里面,我们就可以写我们的go程序了。我们直接输入vi helloworld.go, 就可以开始编辑了,当然你可以用更熟悉的IDE工具去编辑。我们就直接输入下面的代码就好了。
package main
import (
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
"github.com/hyperledger/fabric/protos/peer"
)
type SimpleAsset struct {
}
func (t *SimpleAsset) Init(stub shim.ChaincodeStubInterface) peer.Response {
return shim.Success(nil)
}
func (t *SimpleAsset) Invoke(stub shim.ChaincodeStubInterface) peer.Response {
return shim.Success([]byte("^^^^^^^^^HELLO WORLD^^^^^^^^^^^^^^^^^"))
}
// main function starts up the chaincode in the container during instantiate
func main() {
if err := shim.Start(new(SimpleAsset)); err != nil {
fmt.Printf("Error starting SimpleAsset chaincode: %s", err)
}
}
写好代码后, 我们还要通过下面两条语句进行编译。
$ go get -u github.com/hyperledger/fabric/core/chaincode/shim
$ go build
我们这个go代码非常非常简单,并没有什么逻辑,只是在调用后打印出hello world这句话。 下面我们进入到最关键的步骤,启动,部署和调用。
三, 启动和部署
1. 启动区块链网络
首先我们还是要切换到basci-network, 然后执行 sudo ./generate.sh, 如下图
执行这个脚本的目的是生成org1用到的配置文件,因为默认的配置中并没有包含, 执行完毕后,在config文件夹中会多出一个Org1MSPanchors.tx的文件。
然后我们就可以启动这个网络了,执行 sudo ./start.sh, 稍等片刻后, 我们可以通过docker ps命令来看一下这个网络的启动情况,这个命令会列出已经启动的容器。
2. 部署程序
我们可以看到一个cli的容器,也就是我们之前修改start.sh后加入的那个容器。 然后我们通过下面的命令,进入容器内部。
$ docker exec -it cli bash
进入容器后, 命令行会变成下面的样子,表示已经登录到了cli容器中。
这是我们执行下面的命令,对helloworld进行安装。
$ peer chaincode install -n helloworld -v 1.0 -l golang -p github.com/chaincode_helloworld/main/
chaincode安装成功后,如下图这样。
接着,我们继续执行初始化操作, 用下面的命令。
$ peer chaincode instantiate -o orderer.example.com:7050 --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 mychannel -n helloworld -l golang -v 1.0 -c '{"Args":[]}' -P 'AND ('\''Org1MSP.peer'\'')'
3. 运行程序
最后,我们就可以通过下面的命令,来查看我们的helloworld程序输出了。
$ peer chaincode invoke -o orderer.example.com:7050 --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 mychannel -n helloworld --peerAddresses peer0.org1.example.com:7051 -c '{"Args":[]}'
结果如下图所示:
到此为止,我们的演示就结束了, 最后别忘了用exit命令退出cli容器,然后在basic-network中继续执行sudo ./stop.sh和sudo ./teardown.sh来终止和销毁所运行的容器。
三, 总结
Okay, 是不是很有成就感。 虽然看上去我们为了运行这个hello world做了很多准备工作,但实际都是值得的,因为我们这个区块链网络可谓是麻雀虽小五脏俱全,我们基于目前的这个结构可以做很多事情,比如写区块,存储数据到couch DB中。如果你理解了这个最简单的Hyperledger Fabric例子,你再学习fabric-samples下面的commerical-paper以及first-network就会比较轻松,但是Hyperledger Fabric的官方例子都大量使用各种bash命令和环境变量来简化重复的命令行操作,所以一开始理解它们调用的逻辑还是有些难度的。