HyperLedger Fabric 简述&安装

Scroll Down

HyperLedger Fabric 简述

区块链概念

区块链demo:https://andersbrownworth.com/blockchain/block

什么是区块

区块由几部分组成:

  1. Previous Hash:前一个区块的hash值
  2. Timestamp:时间戳
  3. Data:区块中存储的数据
  4. Nonce(Prove):工作量证明
  5. Hash:本区块Hash

mine挖矿

找到一个数(Nonce),使它与此区块其他部分组成的Hash值满足一定的规则,如:Hash值前导为4个0,那么这个Hash值就算满足条件,这就是所谓的POW工作量证明(Proof of Work)。

区块链

因为有Previous Hash这个值,所以后面的区块都能向前溯源,找到前导的区块,因此组成了一个链式结构

区块链的安全性

在集群环境下,区块中所有的节点都有同样的区块数据

如果有人恶意攻击某一个节点,篡改这个节点的数据,这个修改是无效的,因为集群中其他节点的区块数据都是正常的,保证了数据的安全性

HyperLedger

架构

  1. 会员制

    因为这里面的东西区别于公有链,是不公开的,所以需要会员制来保证信息的安全性

  2. 区块链

  3. 链上代码(智能合约)

    只能合约是部署在区块链上的自动执行的脚本,是多方的一个共同约定

HyperLedger 术语

Anchor Peer 锚节点

用来确保在不同组织中的 Peer 节点能够知道彼此。锚节点能被通道中的所有对等节点探测,并能与之通信的一种对等节点。通道中的每个成员都有一个或多个锚节点,允许属于不同成员身份的节点来发现通道中存在的其他节点。

Chaincode 链码

链码是定义单项或多项资产的软件,和能修改资产的交易指令,也就是智能合约

ACL

ACL(Access Control List),或称访问控制列表,将特定节点资源(例如系统链码的 API 或事件服务)的访问与策略(指定需要多少和哪些类型的组织或角色)相关联。

Channel 通道

构建在“Fabric”网络中的私有区块链,实现了数据的隔离和保密。

Commitment 确认节点

一个通道中的每个对等节点都会验证交易的有序区块,然后将区块提交到通道上的各个副本。对等节点也会标记每个区块中的每笔交易的状态是有效或无效。

并发控制版本检查

并发控制版本检查(Concurrency Control Version Check,CCVC)是保持通道中各节点间状态同步的一种方法。

配置区块

包含为系统链(排序服务)或通道定义成员和策略的配置数据。对某个通道或整个网络的配置修改(比如,成员离开或加入)都将导致生成一个新的配置区块并追加到适当的链上。这个配置区块会包含创始区块的内容,再加上增量。

共识

贯串交易流程的一个广泛的概念,用于对区块中的交易生成一致的顺序和确保其正确性。

共识者集合

Raft 排序服务中,在一个通道的共识机制中会有多个活动的排序节点参与其中。如果其他排序节点存在于系统通道,但是没有加入通道,它就不属于这个通道的共识者集合

联盟

联盟是区块链网络上非定序的组织集合。这些是组建和加入通道及拥有节点的组织。虽然区块链网络可以有多个联盟,但大多数区块链网络都只有一个联盟。在通道创建时,添加到通道的所有组织都必须是联盟的一部分。但是,未在联盟中定义的组织可能会被添加到现有通道中。

Current State 当前状态

当前状态表示链交易日志中包含的所有键的最新值。链码针对当前状态数据执行交易提案,因为当前状态提供对这些密钥的最新值的直接访问,而不是通过遍历整个交易日志来计算它们。每当键的值发生变化时(例如,当汽车的所有权——“钥匙”——从一个所有者转移到另一个——“值”)或添加新键(创造汽车)时,当前状态就会改变。因此,当前状态对交易流程至关重要,因为键值对的当前状态必须先知道才能更改。对于处理过的区块中包含的每个有效事务,节点将

Endorsement 背书

Endorsement是指一个节点执行一个交易并返回YES-NO给客户端应用的过程。也就是对这次交易的一个担保。

背书策略

定义了通道上必须执行依赖于特定链码的交易的节点,和必要的组合响应(背书)。背书策略可指定特定链码应用交易背书的最小背书节点数、百分比或全部节点。

Fabric-ca 证书节点

Hyperledger Fabric CA 是默认的证书授权组件,用于向网络成员组织和他们的用户发行基于 PKI 的证书。CA 向每一个成员发行一个根证书(rootCert)并向每一个授权的用户发行一个注册证书(ECert)。

Invoke 调用

调用链码中的函数。

Proposal

一种通道中针对特定节点的背书请求。每个提案要么是链码的实例化,要么是链码的调用(读写)请求。

Leader Peer 主导节点

每一个Member在其订阅的Channel 上可以拥有多个节点,其中一个节点会作为Channel的leader peer代表该Member与order service进行通信。order service将block传递给leading peer,该peer再将此block分发给同一member下的其他peer。

Ledger 账本

账本是个通道中的每个成员共同维护的数据库。

Membership Service Provider

成员服务提供者(MSP)是指为客户端和节点加入超级账本Fabric网络,提供证书的系统抽象组件。客户端用证书来认证他们的交易;节点用证书认证交易处理结果(背书)。

Membership Service 成员服务

成员服务在许可区块链网络上用于认证、授权和身份管理。运行于节点和排序服务的成员服务代码均会参与认证和授权区块链操作。

Order Service 排序服务

预先定义好的一组将交易排序放入区块的节点。排序服务独立于节点流程之外,并以先到先处理的方式为网络上所有通道做交易排序。

Query 查询

查询是一个只读账本当前状态不写入账本的链码调用。

在CentOS 7中安装环境

安装Docker

根据此篇教程安装: https://www.runoob.com/docker/centos-docker-install.html

$ curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
$ docker --version #查看是否安装成功

安装docker-compose

参考博客:

  1. 添加企业版附加包

    $ yum -y install epel-release

  2. 安装 PIP

    $ yum -y install python-pip

  3. 更新 PIP

    $ pip install --upgrade pip

  4. 安装 Docker Compose

    $ pip install docker-compose

    不过这一步我用pip安装是失败的,使用官方下下来的二进制文件放到/usr/local/bin目录下,然后执行

    $ sudo chmod +x /usr/local/bin/docker-compose
    $ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
    $ docker-compose --version # 最后查看版本
    

安装git

git用于一会的bash脚本clone仓库使用

$ sudo yum install git

安装GO语言环境

Go 版本必须在1.12.x以上

Go 安装我先从官网下载的tar.gz包,然后进行解压缩,在linux虚拟机中下载太慢

$ sudo tar -C /usr/local/ -zxvf go1.15.2.linux-amd64.tar.gz 

添加到系统环境变量

$ sudo vim /etc/profile.d/go.sh
# 此步骤写入到vim中
$ export PATH=$PATH:/usr/local/go/bin
$ source /etc/profile.d/go.sh

设置GOPATH

$ mkdir /gopath
$ sudo chmod 777 /gopath
$ sudo vim /etc/profile.d/gopath.sh
$ #写入
$ export GOPATH=/gopath
$ #使之生效
$ source /etc/profile.d/gopath.sh

安装HyperLedger-Fabric

官方的方法对于我来说下载速度太慢了,我决定使用1.4.8版本

官方给出的版本是通过一个bootstrap.sh进行下载

但是根据里面的内容描述,需要下载三样东西,分别是:

  1. fabric-sample
  2. hyperledger-fabric 平台二进制文件
  3. 对应版本的docker镜像文件

其中hyperledger-fabric 平台二进制文件体积过大,下载速度过慢,所以使用手动下载,这次连同sample也一起手动下载了

下载对应文件

二进制文件下载地址: https://github.com/hyperledger/fabric/releases

samples下载地址: https://github.com/hyperledger/fabric/releases

找到相应版本的文件进行下载,解压到虚拟机/linux中

二进制文件也解压缩到samples中,就是二进制文件中有两个文件夹binconfig都解压到samples中

然后给文件授予权限(这一步很重要)

$ chmod -R 777 fabric-samples

脚本的获取和执行

#!/bin/bash
#
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

# if version not passed in, default to latest released version
VERSION=2.2.1
# if ca version not passed in, default to latest released version
CA_VERSION=1.4.9
ARCH=$(echo "$(uname -s|tr '[:upper:]' '[:lower:]'|sed 's/mingw64_nt.*/windows/')-$(uname -m | sed 's/x86_64/amd64/g')")
MARCH=$(uname -m)

printHelp() {
    echo "Usage: bootstrap.sh [version [ca_version]] [options]"
    echo
    echo "options:"
    echo "-h : this help"
    echo "-d : bypass docker image download"
    echo "-s : bypass fabric-samples repo clone"
    echo "-b : bypass download of platform-specific binaries"
    echo
    echo "e.g. bootstrap.sh 2.2.1 1.4.9 -s"
    echo "will download docker images and binaries for Fabric v2.2.1 and Fabric CA v1.4.9"
}

# dockerPull() pulls docker images from fabric and chaincode repositories
# note, if a docker image doesn't exist for a requested release, it will simply
# be skipped, since this script doesn't terminate upon errors.

dockerPull() {
    #three_digit_image_tag is passed in, e.g. "1.4.7"
    three_digit_image_tag=$1
    shift
    #two_digit_image_tag is derived, e.g. "1.4", especially useful as a local tag for two digit references to most recent baseos, ccenv, javaenv, nodeenv patch releases
    two_digit_image_tag=$(echo "$three_digit_image_tag" | cut -d'.' -f1,2)
    while [[ $# -gt 0 ]]
    do
        image_name="$1"
        echo "====> hyperledger/fabric-$image_name:$three_digit_image_tag"
        docker pull "hyperledger/fabric-$image_name:$three_digit_image_tag"
        docker tag "hyperledger/fabric-$image_name:$three_digit_image_tag" "hyperledger/fabric-$image_name"
        docker tag "hyperledger/fabric-$image_name:$three_digit_image_tag" "hyperledger/fabric-$image_name:$two_digit_image_tag"
        shift
    done
}

cloneSamplesRepo() {
    # clone (if needed) hyperledger/fabric-samples and checkout corresponding
    # version to the binaries and docker images to be downloaded
    if [ -d first-network ]; then
        # if we are in the fabric-samples repo, checkout corresponding version
        echo "===> Checking out v${VERSION} of hyperledger/fabric-samples"
        git checkout v${VERSION}
    elif [ -d fabric-samples ]; then
        # if fabric-samples repo already cloned and in current directory,
        # cd fabric-samples and checkout corresponding version
        echo "===> Checking out v${VERSION} of hyperledger/fabric-samples"
        cd fabric-samples && git checkout v${VERSION}
    else
        echo "===> Cloning hyperledger/fabric-samples repo and checkout v${VERSION}"
        git clone -b master https://github.com/hyperledger/fabric-samples.git && cd fabric-samples && git checkout v${VERSION}
    fi
}

# This will download the .tar.gz
download() {
    local BINARY_FILE=$1
    local URL=$2
    echo "===> Downloading: " "${URL}"
    curl -L --retry 5 --retry-delay 3 "${URL}" | tar xz || rc=$?
    if [ -n "$rc" ]; then
        echo "==> There was an error downloading the binary file."
        return 22
    else
        echo "==> Done."
    fi
}

pullBinaries() {
    echo "===> Downloading version ${FABRIC_TAG} platform specific fabric binaries"
    download "${BINARY_FILE}" "https://github.com/hyperledger/fabric/releases/download/v${VERSION}/${BINARY_FILE}"
    if [ $? -eq 22 ]; then
        echo
        echo "------> ${FABRIC_TAG} platform specific fabric binary is not available to download <----"
        echo
        exit
    fi

    echo "===> Downloading version ${CA_TAG} platform specific fabric-ca-client binary"
    download "${CA_BINARY_FILE}" "https://github.com/hyperledger/fabric-ca/releases/download/v${CA_VERSION}/${CA_BINARY_FILE}"
    if [ $? -eq 22 ]; then
        echo
        echo "------> ${CA_TAG} fabric-ca-client binary is not available to download  (Available from 1.1.0-rc1) <----"
        echo
        exit
    fi
}

pullDockerImages() {
    command -v docker >& /dev/null
    NODOCKER=$?
    if [ "${NODOCKER}" == 0 ]; then
        FABRIC_IMAGES=(peer orderer ccenv tools)
        case "$VERSION" in
        2.*)
            FABRIC_IMAGES+=(baseos)
            shift
            ;;
        esac
        echo "FABRIC_IMAGES:" "${FABRIC_IMAGES[@]}"
        echo "===> Pulling fabric Images"
        dockerPull "${FABRIC_TAG}" "${FABRIC_IMAGES[@]}"
        echo "===> Pulling fabric ca Image"
        CA_IMAGE=(ca)
        dockerPull "${CA_TAG}" "${CA_IMAGE[@]}"
        echo "===> List out hyperledger docker images"
        docker images | grep hyperledger
    else
        echo "========================================================="
        echo "Docker not installed, bypassing download of Fabric images"
        echo "========================================================="
    fi
}

DOCKER=true
SAMPLES=false
BINARIES=false

# Parse commandline args pull out
# version and/or ca-version strings first
if [ -n "$1" ] && [ "${1:0:1}" != "-" ]; then
    VERSION=$1;shift
    if [ -n "$1" ]  && [ "${1:0:1}" != "-" ]; then
        CA_VERSION=$1;shift
        if [ -n  "$1" ] && [ "${1:0:1}" != "-" ]; then
            THIRDPARTY_IMAGE_VERSION=$1;shift
        fi
    fi
fi

# prior to 1.2.0 architecture was determined by uname -m
if [[ $VERSION =~ ^1\.[0-1]\.* ]]; then
    export FABRIC_TAG=${MARCH}-${VERSION}
    export CA_TAG=${MARCH}-${CA_VERSION}
    export THIRDPARTY_TAG=${MARCH}-${THIRDPARTY_IMAGE_VERSION}
else
    # starting with 1.2.0, multi-arch images will be default
    : "${CA_TAG:="$CA_VERSION"}"
    : "${FABRIC_TAG:="$VERSION"}"
    : "${THIRDPARTY_TAG:="$THIRDPARTY_IMAGE_VERSION"}"
fi

BINARY_FILE=hyperledger-fabric-${ARCH}-${VERSION}.tar.gz
CA_BINARY_FILE=hyperledger-fabric-ca-${ARCH}-${CA_VERSION}.tar.gz

# then parse opts
while getopts "h?dsb" opt; do
    case "$opt" in
        h|\?)
            printHelp
            exit 0
            ;;
        d)  DOCKER=false
            ;;
        s)  SAMPLES=false
            ;;
        b)  BINARIES=false
            ;;
    esac
done

if [ "$SAMPLES" == "true" ]; then
    echo
    echo "Clone hyperledger/fabric-samples repo"
    echo
    cloneSamplesRepo
fi
if [ "$BINARIES" == "true" ]; then
    echo
    echo "Pull Hyperledger Fabric binaries"
    echo
    pullBinaries
fi
if [ "$DOCKER" == "true" ]; then
    echo
    echo "Pull Hyperledger Fabric docker images"
    echo
    pullDockerImages
fi

在vim中新建一个bootstrap.sh把脚本内容复制进去就行了

然后执行

$ sudo chmod 777 bootstrap.sh
$ sudo ./bootstrap.sh 1.4.8 1.4.8 0.4.21

等待命令执行完毕

测试这个程序

cd 到samples目录下的first-network文件夹下

$ sudo ./byfn.sh generate
$ sudo ./byfn.sh up

如果不报错就差不多可以了,如果报错建议去stackoverflow上搜索,国内大概率是找不到答案的

最后和成功的输出结果合影

image20201005175322136.png

ALL GOOD!

最后的最后,关闭这个测试网络

$ sudo ./byfn.sh down