好久不见,看了下,距离上次更文 1 个多月过去了,卷不动。

大概 2 年前,碰巧学习区块链(Hyperledger Fabric),便写了一个入门级的项目放在 GitHub 上,公众号有不少读者是通过这个项目关注到我的,也经常问我,有没有区块链这方面的学习资料,有没有这个项目的详细讲解,如何搭建一个区块链网络,林林总总。

对于这些问题,我每次的回复都一样,学习资料我倒是没有,但是 官方文档[1] 就是最好的资料了。

不过今天,我想还是通过这篇文章来记录一下我对之前区块链学习的一次总结吧。




预警:为了照顾到更多读者,本篇尽量从新手的视角出发,可能会有很多特别基础的内容,对于已经懂的部分,选择跳过即可。

再次预警:文章内容有点长,请耐心看,最好跟着一起动手实践,如果中途发现了错误之处,欢迎告知我。

技术栈

首先,以下这些我提到的技术要求你事先稍微学习掌握一下:

1、yaml 文件的编写

需要注意一下几个规则:

#&<<*

2、Docker 和 Docker Compose

  • Docker 是一个开源的应用容器引擎,可以将应用以及所需要的环境一起打包到一个轻量级、可移植的容器中,从而可以快速交付软件。
  • Docker Compose 是用来定义和运行多容器的工具。可以通过 yaml 文件来配置应用程序需要的所有服务。说白了,就是批量管理 Docker 容器。

后续区块链的节点以及应用程序的部署我们都会使用 Docker Compose 来管理。

3、 go 语言

我的项目包括本篇文章的示例都是使用 go 语言开发的,虽然 fabric 也提供了 Java,nodejs,python 等语言的 SDK ,但个人还是比较推荐 go 语言,毕竟 fabric 自身也是 go 实现的。

题外话:以上这些技能除了在 fabric 区块链体系中需掌握,在如今火热的云原生技术下也一样是基础。

区块链基础知识

1、什么是区块

Blockhashhashhash

2、什么是区块链

Blockchain

区块链本质上就是一个多方共享的分布式账本技术,用来记录网络上发生的所有交易。

而其中去中心化的概念,是因为账本信息会被复制到许多网络参与者中,每个参与者都在协作维护账本,不像传统应用的数据被中心管理着。

另外信息只能以附加的方式记录到账本上,并使用加密技术保证一旦将交易添加到账本就无法修改。这种不可修改的属性简化了信息的溯源,因为参与者可以确定信息在记录后没有改变过。所以区块链有时也被称为证明系统

3、什么是公链、联盟链和私链

区块链分为公有链、联盟链、私有链三种基本类型。其中:

  • 完全去中心化:公链,人人都可以参与,就像比特币(挖矿相当于在记账)。主要采取工作量证明机制(POW)、权益证明机制(POS)、股份授权证明机制(DPOS)等方式。
  • 部分去中心化:联盟链,参与者是指定的。联盟链可以是几家公司共同拥有的链,也可能是几个国家共同承认的链。这是后续发展的趋势。
  • 中心化:私链,写入权限仅在一个组织手里的区块链,仅对特定的团队、组织或者个人开放。

4、什么是交易

Transaction

5、什么是智能合约

Smart contract

智能合约不仅是在网络中封装和简化信息的关键机制,它还可以被编写成自动执行参与者的特定交易的合约。

例如,可以编写智能合约以规定运输物品的成本,其中运费根据物品到达的速度而变化。根据双方同意并写入账本的条款,当收到物品时,相应的资金会自动转手。

通俗易懂点,智能合约就是按照大家约定好的规则编写的业务逻辑代码实现,然后只能通过这些合约来操作区块链网络这个账本。

6、什么是共识

保持账本在整个网络中同步的过程称为共识。该过程确保账本仅在交易被相应参与者批准时才会更新,并且当账本更新时,它们以相同的顺序更新相同的交易。

Hyperledger Fabric 基础知识

1、什么是 Hyperledger Fabric

Linux 基金会于 2015 年创建了 Hyperledger(超级账本)项目,而 Hyperledger Fabric 是其中一个用 Go 语言实现的版本。

Hyperledger Fabric 网络的成员只能从可信赖的成员服务提供者(MSP) 注册,也就是说 Hyperledger Fabric 搭建的区块链是一种联盟链。

Hyperledger Fabric 的账本包括两个组件: 世界状态和交易日志。并且每个参与者都拥有他们所属的每个 Hyperledger Fabric 网络的账本的副本。

  • 世界状态:描述了在给定时间点的账本的状态。它是账本的数据库。默认情况下,使用 LevelDB 键值存储数据库,可插拔,可替换为 CouchDB 。
  • 交易日志:记录产生世界状态中当前值的所有交易。这是世界状态的更新历史。它只记录区块链网络使用账本数据库前后的值。

总结:Hyperledger Fabric 是一种账本技术,其账本包括世界状态数据库和交易日志历史记录。

2、什么是联盟

联盟指参与一个基于区块链的业务协作或业务交易网络的所有组织的集合,一个联盟一般包含多个组织。

Orderer

3、什么是组织

组织代表的是参与区块链网络的企业、政府机构、团体等实体。

一个组织实例主要包含如下节点:

CAregisterenrollPeer

4、什么是节点

节点(Peers)是区块链的通信实体。它只是一个逻辑功能,只要能在“信任域”中分组并与控制它们的逻辑实体相关联,就可以将不同类型的多个节点运行在同一个物理服务器上,比如用 Docker 部署。

OrdererPeerCommitting PeerEndorsing PeerAnchorPeerAnchorPeerOrderer

5、什么是通道

Channel

可以理解为组织间拉了个群聊,这个群聊就是通道,在里面聊天交易,一个联盟链中可以有多个群聊(通道),一个组织可以加入多个群聊,每个群聊可以代表一项具体的业务,有自身对应的一套账本,群聊间互不干扰,互相隔离。

6、什么是链码

Chaincode

链码可以用多种编程语言实现。有 Go、Node.js 和 Java 链码等。

搭建区块链网络

基础知识过完,接下来就到了本篇核心的项目实战环节。首先是搭建一个区块链网络,只需按照下面几个顺序,一步步来就行(推荐在 Linux 或 MacOS 下操作):

1、下载 fabric 二进制工具

v1.4.12

自行根据你的系统环境下载对应的包。

其中几个主要的工具说明:

cryptogencryptogencrypto-config.yamlcryptogenconfigtxgenconfigtxgenconfigtx.yamlconfigtxlatorProtobufJSONProtobufpeerpeer channelpeer chaincode

2、将 fabric 二进制工具添加到环境变量

为了后续方便使用命令,可以将第 1 步下载的工具添加到系统环境变量中:

3、生成证书和秘钥

cryptogen
crypto-config.yaml
cryptogen generatecrypto-config
crypto-config
QQorderer.qq.comTaobaoJDpeer0.xx.compeer1.xx.comAdminUser1crypto-config.yamlcryptogen

4、创建排序通道创世区块

configtx.yamlconfigtxgenconfigtx.yamlyamlconfigtxgenconfigtx.yamlprotobuf
configtx.yaml
configtxgenTwoOrgsOrdererGenesis
protobuf./config/genesis.block

5、创建通道配置交易

configtxgenTwoOrgsChannel
./config/appchannel.tx
Taobao./config/TaobaoAnchor.tx
JD./config/JDAnchor.tx

当然,这一步也是为后续使用做准备的。不过至此,需要准备的配置都齐了。

config

6、创建并启动各组织的节点

QQorderer.qq.comTaobaoJDpeer0.xx.compeer1.xx.com

现在这些组织及其节点所需要的配置已经准备好了。我们接下来就可以使用 Docker Compose 来模拟启动这些节点服务。

fabric_network
docker-compose.yaml
docker-compose-base.yaml
volumesconfigcrypto-config/var/run/docker.sock

现在继续将这些节点服务启动起来:

clihyperledger/fabric-tools
cli
clipeerTaobaoPeer0CliTaobaoPeer1CliJDPeer0CliJDPeer1Clicli

8、开始创建通道

通道主要用于实现区块链网络中业务的隔离。一个联盟中可以有多个通道,每个通道可代表一项业务,并且对应一套账本。通道内的成员为业务参与方(即联盟内的组织),一个组织可以加入多个通道。

Taobaopeer0appchannel
Taobaopeer0appchannel

9、将所有节点加入通道

appchannel
appchannel

10、更新锚节点

锚节点是必需的。普通节点只能发现本组织下的其它节点,而锚节点可以跨组织服务发现到其它组织下的节点,建议每个组织都选择至少一个锚节点。

利用之前准备好的配置文件,向通道更新锚节点:

TaobaoJD

到这里,我们的区块链网络基本已经搭建好了,但是还差最关键的智能合约。一个没有智能合约的通道是没有灵魂的,啥事都做不了。

编写智能合约

fabric 的智能合约称为链码,编写智能合约也就是编写链码。

链码其实很简单,可以由 Go 、 node.js 、或者 Java 编写,其实只是实现一些预定义的接口。

main.go
MyChaincodeshim.Chaincode
mainshim.Start(new(MyChaincode))
TaobaoJD
Invoke

一个简易的示例如下:

AB1000InvokequerytransferqueryABtransfer{"Args":["transfer","A","B","100.0"]}AB100

部署链码

cliTaobaopeer0JDpeer0
-n-v-pcli/opt/gopath/src/
Taobaopeer0
{"Args":["init"]}func (c *MyChaincode) Init-PAND ('TaobaoMSP.member','JDMSP.member')TaobaoJDANDOR
/var/run/docker.sock

查看启动的链码容器:

Taobaopeer0
cli
JD
JDpeer0

现在,我们的智能合约就成功部署到区块链网络的通道中了。

编写应用程序

cliSDK
github.com/hyperledger/fabric-sdk-go

这个 SDK 使用起来也很简单。

NewFabricSDK
configProviderReaderio.ReaderFileRaw[]byte
config.yaml
JDJD
{username}
sdk.go
Adminpeer0.jd.compeer0.taobao.comAND ('TaobaoMSP.member','JDMSP.member')TaobaoJD
main.gogin
mainGET /queryPOST /transfer/queryquery/transfertransfer
config.yamlDockerfile
docker-compose.yml
crypto-config

编译部署应用程序:

调用应用程序的接口:

到这里,我们就已经完整地实现了一个区块链应用了。你也可以继续为这个区块链应用实现前端页面。流程呢,和传统前后端分离架构也没什么区别。