深度探索Hyperledger技术与应用之超级帐本初体验(附部署代码)

image

本章零基础地介绍了如何快速体验超级帐本搭建的区块链网络,咱们先绕过了比较复杂的初始化配置,用官方提供的fabric-samples提供的配置和链码示例,展现了如何调用和查询链码,对Hyperledger Fabric实现的功能有一个初步的认识。html

1

基础环境安装

Hyperledger Fabric 1.0依赖Docker执行智能合约,须要先安装Docker和Docker Compose的运行环境。java

一、Docker的安装和使用python

Docker支持Linux、Mac、Windows等多个平台,安装文档参考:https://docs.docker.com/engine/installation。git

在Linux环境下Docker的安装github

Ubuntu、Debian、CentOS等Linux系统,能够经过Docker官方提供的脚本进行安装:golang

curl -sSL https://get.docker.com | sh算法

而后把用户加入到docker组,非root用户USER能够执行docker命令(可能须要从新登陆生效):docker

sudo usermod -aG docker $USER编程

若是是Ubuntu或者Debian操做系统,修改Docker的配置文件/etc/default/docker,增长Docker的socket绑定,运行在Docker中的进程才能经过映射的socket调用Docker的API执行镜像编译和建立容器等操做。json

DOCKER_OPTS="-s=aufs -r=true --api-cors-header='*' -H tcp://0.0.0.0:2375 -H

unix:///var/run/docker.sock "

接着,重启Docker服务让配置生效:

sudo service docker start

CentOS系统采用Systemd进行系统和服务管理,配置文件的修改方法是不同的。CentOS系统下Docker的配置文件是/etc/sysconfig/docker,一样要修改DOCKER_OPTS选项。

还须要修改/usr/lib/systemd/system/docker.service文件,在[Service]的ExexStart=下面增长一行$DOCKER_OPTS,以下所示:

[Service]  

Type=notify  

NotifyAccess=all  

EnvironmentFile=-/etc/sysconfig/docker  

EnvironmentFile=-/etc/sysconfig/docker-storage  

EnvironmentFile=-/etc/sysconfig/docker-network  

Environment=GOTRACEBACK=crash  

Environment=DOCKER_HTTP_HOST_COMPAT=1  

Environment=PATH=/usr/libexec/docker:/usr/bin:/usr/sbin  

ExecStart=/usr/bin/dockerd-current \  

        --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current \  

        --default-runtime=docker-runc \  

        --exec-opt native.cgroupdriver=systemd \  

        --userland-proxy-path=/usr/libexec/docker/docker-proxy-current \  

        $DOCKER_OPTS \  

        $OPTIONS \  

        $DOCKER_STORAGE_OPTIONS \  

        $DOCKER_NETWORK_OPTIONS \  

        $ADD_REGISTRY \  

        $BLOCK_REGISTRY \  

        $INSECURE_REGISTRY  

重启服务让配置生效:

systemctl daemon-reload

systemctl restart docker.service

其余环境下Docker的安装

Windows和Mac都提供了安装包,直接下载便可安装:

Docker for Mac: https://download.docker.com/mac/stable/Docker.dmg

Docker for Windows: https://download.docker.com/win/stable/InstallDocker.msi

Docker国内镜像仓库

国外的镜像下载较慢,能够设置国内的镜像,阿里云和DaoCloud都提供镜像加速的服务,须要登陆注册才能使用。

阿里云:登陆容器Hub服务https://cr.console.aliyun.com的控制台,左侧的加速器帮助页面会显示为你独立分配的加速地址。

DaoCloud:在https://www.daocloud.io进行注册登陆,而后点击加速器,就能够获取加速器的相关配置。

修改Docker镜像仓库的办法是在DOCKER_OPTS里增长registry-mirror参数,好比:

DOCKER_OPTS="-s=aufs -r=true --api-cors-header='*' -H tcp://0.0.0.0:2375

-H unix:///var/run/docker.sock

--registry-mirror=http://069f616f.m.daocloud.io”

重启Docker服务就可使用镜像加速了。

Docker在Windows和Mac中的版本能够在图形界面添加镜像仓库。

Docker经常使用命令

Docker经常使用命令如图所示。

image

更多的命令请查看帮助文档和在线文档:https://docs.docker.com/engine/reference/commandline/docker。

二、Docker Compose的安装和使用

Docker Compose可以在一个主机上建立出相互隔离的网络,经过命令行管理多个Docker容器,快速启动、中止和更新容器。

Docker Compose的安装

Docker在Windows和Mac中都已经集成了Docker Compose工具,不须要单独安装。在Linux系统下有多种安装方法,以下所示:

  • 经过pip进行安装

sudo apt install python-pip

sudo pip install docker-compose

  • 直接下载文件

curl -L

https://github.com/docker/compose/releases/download/1.17.1/docker-compose-uname -s-uname -m -o /usr/local/bin/docker-composechmod +x /usr/local/bin/docker-compose

Docker Compose的配置文件

Compose采用YAML文件定义Docker容器之间的依赖,设置环境变量和文件的持久化。咱们看一个配置文件examples/e2e_cli/base/docker-compose-base.yaml的节选:

version: '2'

services:

    orderer.example.com:

        container_name: orderer.example.com

        image: hyperledger/fabric-orderer

        environment:

            - ORDERER_GENERAL_LOGLEVEL=debug

            - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0

            - ORDERER_GENERAL_GENESISMETHOD=file

        - ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block

        - ORDERER_GENERAL_LOCALMSPID=OrdererMSP

        - ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp

        # enabled TLS

        - ORDERER_GENERAL_TLS_ENABLED=true

        - ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key

        - ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt

        - ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]

        working_dir: /opt/gopath/src/github.com/hyperledger/fabric

    command: orderer

    volumes:

  • ../channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block

  • ../crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/

msp:/var/hyperledger/orderer/msp

  • ../crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/

tls/:/var/hyperledger/orderer/tls

    ports:

        - 7050:7050

peer0.org1.example.com:

    container_name: peer0.org1.example.com

    extends:

        file: peer-base.yaml

        service: peer-base

    environment:

        - CORE_PEER_ID=peer0.org1.example.com

        - CORE_PEER_ADDRESS=peer0.org1.example.com:7051

        - CORE_PEER_CHAINCODELISTENADDRESS=peer0.org1.example.com:7052

        - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051

        - CORE_PEER_LOCALMSPID=Org1MSP

    volumes:

        - /var/run/:/host/var/run/

  • ../crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.

com/msp:/etc/hyperledger/fabric/msp

  • ../crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.

com/tls:/etc/hyperledger/fabric/tls

    ports:

        - 7051:7051

        - 7052:7052

        - 7053:7053

在这个节选的配置文件中,一共定义了1个排序服务节点orderer.example.com和1个Peer节点peer0.org1.example.com。Docker Compose目前有3个版本,这个配置文件采用的version 2的语法,配置文件的解释如图所示。

image

更多不一样版本的配置文件说明请参考在线帮助文档:https://docs.docker.com/compose/compose-file。

Docker Compose的经常使用命令

Docker Compose的经常使用命令如图所示。

image

更多的命令查看帮助文档和在线文档:https://docs.docker.com/compose/reference。

三、下载超级帐本源代码

超级帐本的源代码都托管在https://gerrit.hyperledger.org/r/#/admin/projects/下面,并在https://github.com/hyperledger上提供只读代码。最好的方式是直接经过git下载:

git clone https://github.com/hyperledger/fabric.git

也能够打包下载文件后解压:https://github.com/hyperledger/fabric/archive/release.zip。

2

超级帐本部署调用

先最小化地体验一下超级帐本的环境,更详细的部署流程参考第11章。

一、下载Docker镜像文件

超级帐本源码scripts目录下有多个下载镜像的脚本,咱们能够修改权限之后直接运行:

进入fabric/scripts目录

chmod +x bootstrap-1.0.0.sh

MacOS系统执行以下命令(不下载二进制文件)

sed -i '' 's/curl/#curl/g' bootstrap-1.0.0.sh

#其余系统执行以下命令(不下载二进制文件)

sed -i 's/curl/#curl/g' bootstrap-1.0.0.sh

直接下载Docker镜像文件

./bootstrap-1.0.0.sh

根据网络状况,可能须要等待一段时间。下面是下载的Docker镜像文件:

localhost:dive-into-fabric clarity$ docker images

REPOSITORY                     TAG                 IMAGE ID            SIZE

hyperledger/fabric-tools       latest              0403fd1c72c7        1.32GB

hyperledger/fabric-tools       x86_64-1.0.0        0403fd1c72c7   1.32GB

hyperledger/fabric-couchdb     latest              2fbdbf3ab945      1.48GB

hyperledger/fabric-couchdb     x86_64-1.0.0      2fbdbf3ab945  1.48GB

hyperledger/fabric-kafka       latest              dbd3f94de4b5        1.3GB

hyperledger/fabric-kafka       x86_64-1.0.0        dbd3f94de4b5  1.3GB

hyperledger/fabric-zookeeper   latest             e545dbf1c6af    1.31GB

hyperledger/fabric-zookeeper   x86_64-1.0.0     e545dbf1c6af  1.31GB

hyperledger/fabric-orderer     latest              e317ca5638ba  179MB

hyperledger/fabric-orderer     x86_64-1.0.0        e317ca5638ba 179MB

hyperledger/fabric-peer        latest              6830dcd7b9b5        182MB

hyperledger/fabric-peer        x86_64-1.0.0        6830dcd7b9b5 182MB

hyperledger/fabric-javaenv     latest              8948126f0935  1.42GB

hyperledger/fabric-javaenv     x86_64-1.0.0        8948126f0935 1.42GB

hyperledger/fabric-ccenv       latest              7182c260a5ca  1.29GB

hyperledger/fabric-ccenv       x86_64-1.0.0        7182c260a5ca 1.29GB

hyperledger/fabric-ca          latest              a15c59ecda5b        238MB

hyperledger/fabric-ca          x86_64-1.0.0        a15c59ecda5b  238MB

REPOSITORY表明的是镜像的仓库名称,每一个仓库下面都有打了不一样TAG的标签名称,表明不一样的版本。一般最少有两个标签,一个是latest;另一个的命名规则是“主机CPU类型–超级帐本主版本号–snapshot–代码库版本号”,其中主机CPU类型为x86_64,说明是Intel的64位CPU,超级帐本的主版本为1.0.0,snapshot是固定名称,代码库版本号为58cde93,它是git代码库最近一次提交版本号的前7位。snapshot和代码库版本号只有经过本地编译的时候才会出现。每次make docker的时候都会检查是否有文件改动,若是有变化的文件,则会从新构建,生成新的镜像再标记成latest。镜像文件详细的解释请参考第11章的相关内容。

二、部署超级帐本网络

运行超级帐本须要设置较多的初始化配置,咱们先绕开初始化过程,用fabric-samples工程中已经生成的配置文件来体验部署安装的过程:

git clone https://github.com/hyperledger/fabric-samples.git

进入basic-network目录,利用docker-compose启动容器:

cd fabric-samples/basic-network

docker-compose -f docker-compose.yml up -d

查看已经启动的容器(输出进行了删减):

localhost:basic-network clarity$ docker ps

CONTAINER ID   IMAGE                                     NAMES

efddfbf4fc0a   hyperledger/fabric-peer:x86_64-1.0.0      peer0.org1.example.com

606d13c1e7a2   hyperledger/fabric-couchdb:x86_64-1.0.0   couchdb

d8c870db8634   hyperledger/fabric-ca:x86_64-1.0.0        ca.example.com

c6f25a5e6fd6   hyperledger/fabric-tools:x86_64-1.0.0     cli

a5f6331c5bc5   hyperledger/fabric-orderer:x86_64-1.0.0   orderer.example.com

切换到管理员用户再建立通道和加入通道:

切换环境到管理员用户的MSP,进入Peer节点容器peer0.org1.example.com

docker exec -it -e "CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/users/Admin@

org1.example.com/msp" peer0.org1.example.com bash

建立通道

peer channel create -o orderer.example.com:7050 -c mychannel -f /etc/hyperledger/

configtx/channel.tx

加入通道

peer channel join -b mychannel.block

退出Peer节点容器peer0.org1.example.com

exit

    #退出Peer节点容器peer0.org1.example.com,进入cli容器安装链码和实例化:

    # 进入cli容器

docker exec -it cli /bin/bash

给Peer节点peer0.org1.example.com安装链码

peer chaincode install -n mycc -v v0 -p github.com/chaincode_example02

实例化链码

peer chaincode instantiate -o orderer.example.com:7050 -C mychannel -n mycc -v

v0 -c '{"Args":["init","a","100","b","200"]}'

三、链码调用和查询

链码实例化之后,能够查询初始值,一样是在cli容器里执行下面的操做:

peer chaincode query -C mychannel -n mycc -v v0 -c '{"Args":["query","a"]}'

查询结果显示为Query Result: 100,详细信息以下:

2017-08-09 14:47:05.853 UTC [msp] GetLocalMSP -> DEBU 001 Returning existing

local MSP

2017-08-09 14:47:05.853 UTC [msp] GetDefaultSigningIdentity -> DEBU 002 Obtaining

default signing identity

2017-08-09 14:47:05.853 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 003

Using default escc

2017-08-09 14:47:05.854 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 004

Using default vscc

2017-08-09 14:47:05.854 UTC [msp/identity] Sign -> DEBU 005 Sign: plaintext: 0A9

1070A6708031A0C08A9A694D00510...6D7963631A0A0A0571756572790A0161

2017-08-09 14:47:05.854 UTC [msp/identity] Sign -> DEBU 006 Sign: digest: E18FC9

7C13D550C5E3349AAD49523A6D7C71B4E51C219CD9A8799DEF54FFFE66

Query Result: 100

2017-08-09 14:47:05.886 UTC [main] main -> INFO 007 Exiting.....

调用链码,从“a”转移10到“b”:

peer chaincode invoke -C mychannel -n mycc -v v0 -c '{"Args":["invoke","a",

"b","10"]}'

显示调用成功的结果:

2017-08-09 14:49:46.018 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 0cb

Chaincode invoke successful. result: status:200

再次查询“a”和“b”的值:

peer chaincode query -C mychannel -n mycc -v v0 -c '{"Args":["query","a"]}'

peer chaincode query -C mychannel -n mycc -v v0 -c '{"Args":["query","b"]}'

查询结果显示“a”的值为Query Result: 90,“b”的值为Query Result: 210。

四、常见错误

请求调用者权限不足

调用的时候设置了错误的MSP,好比须要管理员才能执行建立通道的操做,可是设置了普通的成员MSP,会出现Error: Got unexpected status: BAD_REQUEST的错误:

2017-08-09 14:49:04.652 UTC [msp] GetLocalMSP -> DEBU 001 Returning existing

local MSP

2017-08-09 14:49:04.652 UTC [msp] GetDefaultSigningIdentity -> DEBU 002 Obtaining

default signing identity

2017-08-09 14:49:04.654 UTC [channelCmd] InitCmdFactory -> INFO 003 Endorser and

orderer connections initialized

2017-08-09 14:49:04.656 UTC [msp] GetLocalMSP -> DEBU 004 Returning existing

local MSP

2017-08-09 14:49:04.656 UTC [msp] GetDefaultSigningIdentity -> DEBU 005 Obtaining

default signing identity

2017-08-09 14:49:04.657 UTC [msp] GetLocalMSP -> DEBU 006 Returning existing

local MSP

2017-08-09 14:49:04.657 UTC [msp] GetDefaultSigningIdentity -> DEBU 007 Obtaining

default signing identity

2017-08-09 14:49:04.657 UTC [msp/identity] Sign -> DEBU 008 Sign: plaintext: 0A8

8060A074F7267314D535012FC052D...53616D706C65436F6E736F727469756D

2017-08-09 14:49:04.657 UTC [msp/identity] Sign -> DEBU 009 Sign: digest: F77320

AE89B131CE75A858A4A450CF0F35301DA62FE1DE465CAEF4439F6FC520

2017-08-09 14:49:04.657 UTC [msp] GetLocalMSP -> DEBU 00a Returning existing

local MSP

2017-08-09 14:49:04.657 UTC [msp] GetDefaultSigningIdentity -> DEBU 00b Obtaining

default signing identity

2017-08-09 14:49:04.657 UTC [msp] GetLocalMSP -> DEBU 00c Returning existing

local MSP

2017-08-09 14:49:04.657 UTC [msp] GetDefaultSigningIdentity -> DEBU 00d Obtaining

default signing identity

2017-08-09 14:49:04.657 UTC [msp/identity] Sign -> DEBU 00e Sign: plaintext: 0AB

F060A1508021A0608E0D591D00522...A38A58EED7B94AC4CB800B86F0A5EF03

2017-08-09 14:49:04.658 UTC [msp/identity] Sign -> DEBU 00f Sign: digest: 475A33

426FA36D50F090AAF7C3AAAB2BF34339191BA74D4A60BF13460B241329

Error: Got unexpected status: BAD_REQUEST

Usage:

    peer channel create [flags]

Flags:

    -c, --channelID string   In case of a newChain command, the channel ID to

create.

    -f, --file string        Configuration transaction file generated by a tool

such as configtxgen for submitting to orderer

    -t, --timeout int        Channel creation timeout (default 5)

Global Flags:

        --cafile string              Path to file containing PEM-encoded trusted

certificate(s) for the ordering endpoint

        --logging-level string     Default logging level and overrides, see

core.yaml for full syntax

    -o, --orderer string            Ordering service endpoint

        --test.coverprofile string   Done (default "coverage.cov")

        --tls                Use TLS when communicating with the orderer endpoint

    -v, --version            Display current version of fabric peer server

传递错误的通道名称

好比通道名称是mychannel,传递参数的时候写成了错误的myc:

peer chaincode query -C myc -n mycc -v v0 -c '{"Args":["query","a"]}'

会出现以下错误:

2017-08-09 14:40:36.703 UTC [msp] GetLocalMSP -> DEBU 001 Returning existing

local MSP

2017-08-09 14:40:36.703 UTC [msp] GetDefaultSigningIdentity -> DEBU 002 Obtaining

default signing identity

2017-08-09 14:40:36.706 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 003

Using default escc

2017-08-09 14:40:36.706 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 004

Using default vscc

2017-08-09 14:40:36.707 UTC [msp/identity] Sign -> DEBU 005 Sign: plaintext: 0A9

1070A6708031A0C08A4A394D00510...30300A000A04657363630A0476736363

2017-08-09 14:40:36.707 UTC [msp/identity] Sign -> DEBU 006 Sign: digest: F085E1

89A0765713209DD8802DDF57B054EBCD294305A500F56BC34CB3D2E577

Error: Error endorsing chaincode: rpc error: code = Unknown desc = chaincode

error (status: 500, message: chaincode exists mycc)

Usage:

    peer chaincode instantiate [flags]

Flags:

    -C, --channelID string   The channel on which this command should be executed

(default "testchainid")

    -c, --ctor string      Constructor message for the chaincode in JSON format

(default "{}")

    -E, --escc string    The name of the endorsement system chaincode to be used

for this chaincode

    -l, --lang string     Language the chaincode is written in (default "golang")

    -n, --name string     Name of the chaincode

    -P, --policy string      The endorsement policy associated to this chaincode

    -v, --version string     Version of the chaincode specified in install/

instantiate/upgrade commands

    -V, --vscc string        The name of the verification system chaincode to be

used for this chaincode

Global Flags:

        --cafile string              Path to file containing PEM-encoded trusted

certificate(s) for the ordering endpoint

        --logging-level string    Default logging level and overrides, see core.

yaml for full syntax

    -o, --orderer string             Ordering service endpoint

        --test.coverprofile string   Done (default "coverage.cov")

        --tls                Use TLS when communicating with the orderer endpoint

3

节点的配置参数传递规则

在docker-compose.yml文件中,咱们能够看到有ORDERER_GENERAL_LEDGERTYPE= ram的设置,这是传递给节点的参数。给节点传递参数的方法有多种方式:环境变量、配置文件、动态环境变量、默认值。

程序在启动的时候会读取配置文件和环境变量的值,分别保存到不一样变量缓存起来,在程序须要获取某个变量值的时候,不一样传递方法的参数读取流程图如图所示。

从图中能够看到,若是配置了自动从环境变量获取参数的值,那么每次都实时地从环境变量中获取,不然依次读取程序启动时从环境变量、配置文件中读取后缓存到内存中的值,优先获取到的值做为返回值。若是都没有获取到,则返回空,交给程序进行处理,程序可能会以默认值运行,也可能会报错中止运行,这跟业务逻辑有关系。因此,只有在设置了自动从环境变量中获取参数的状况下,才能在运行时经过修改环境变量改变参数的值。

每一个环境变量的名称都有一个前缀,每一个模块都是单独设置的,好比ORDERER_GENERAL_

LEDGERTYPE的前缀是ORDERER,一般每一个模块的前缀是不同的。好比这里的ORDERER表明的是排序服务节点,Peer节点的变量名称前缀是CORE。环境变量名称是以“_”做为分隔符的,表明一种层级,是和配置文件一一对应的,好比ORDERER_GENERAL_LEDGERTYPE对应orderer.yaml配置文件的General.LedgerType。环境变量和配置文件的变量名称都是不区分大小写的,内部会统一转换成小写的变量名称进行处理。

配置文件路径优先读取环境变量设置的路径,排序服务节点和Peer节点都是相同的环境变量。若是没有设置环境变量,则默认是应用程序所在的目录,而后环境变量GOPATH路径对应到模块代码工程下的目录,好比排序服务节点的目录是$GOPATH/src/github.com/hyperledger/fabric/orderer,Peer节点的目录是$GOPATH/src/github.com/hyperledger/fabric/peer。

image

节点配置参数的传递规则

通常状况下,配置文件的名称设置成模块前缀的小写,好比排序服务节点的配置文件名称是orderer,Peer节点的配置文件名称是core。

配置文件名称的后缀支持:json、toml、yaml、properties、props、prop,它们分别对应JSON文件、TOML文件、YAML文件和Properties文件,程序设置配置文件的时候若是不指定后缀,则按支持的后缀顺序在配置文件路径下进行搜索,找到第一个匹配的文件做为最终的配置文件。文件路径和文件后缀按照广度优先的搜索顺序,即在同一路径下匹配完全部文件后缀再进入下一个文件路径。假设Peer节点没有设置配置文件路径,$GOPATH的路径是/opt/gopath,则有两个目录下的文件以下所示:

vagrant@hyperledger-devenv:v0.2.2-58cde93: /opt/gopath/bin$ tree .

.

├── core.yaml

└── peer

vagrant@hyperledger-devenv:v0.2.2-58cde93: /opt/gopath/bin$ tree /opt/gopath/

src/github.com/hyperledger/fabric/peer

.

├── core.json

└── peer

搜索路径顺序是:

./core.json

./core.toml

./core.yaml

./core.properties

./core.props

./core.prop

/opt/gopath/src/github.com/hyperledger/fabric/peer/core.json

/opt/gopath/src/github.com/hyperledger/fabric/peer/core.toml

/opt/gopath/src/github.com/hyperledger/fabric/peer/core.yaml

/opt/gopath/src/github.com/hyperledger/fabric/peer/core.properties

/opt/gopath/src/github.com/hyperledger/fabric/peer/core.props

/opt/gopath/src/github.com/hyperledger/fabric/peer/core.prop

因此最终获取到的配置文件是:./core.yaml。

而不是/opt/gopath/src/github.com/hyperledger/

fabric/peer/core.json。

image

深度探索区块链

Hyperledger技术与应用

区块链

张增骏,董宁,朱轩彤,陈剑雄  著

本书由超级帐本执行董事Brian Behlendorf领衔推荐,区块链一线落地实践团队、Hyperleger会员智链骨干团对撰写。深刻讲解Hyperledger Fabric 1.0的架构、执行逻辑、核心功能实现、从零部署,并以票据案例为例,讲解具体开发实践,穿插开发所需的最佳实践和遇到的问题解决。

机械工业

出版社

image

 华章科技是机械出版社的旗下品牌,出版了“计算机科学丛书”等近30个经典套系,在各个细分领域均处于领导地位,其中《Java编程思想》、《算法导论》、《编译原理》、《数据挖掘:概念与技术》、《深刻理解计算机系统》、《深刻理解Java虚拟机》等著做犹如计算机图书领域的璀璨明珠,长销不衰!

本文内容节选自《深度探索区块链:Hyperledger技术与应用》一书的第2章《超级帐本初体验》。

本书做者:张增骏,董宁,朱轩彤,陈剑雄

感谢机械工业出版社华章分社的支持和分享。

image

点击“阅读原文”便可购买

相关文章
相关标签/搜索