Hyperledger Fabric入门1:快速上手_hyperledger fabric教程-程序员宅基地

技术标签: it  

 
参考视频教程:  
 
**学习Hyperledger Fabric 实战联盟链  **
Hyperledger Fabric入门1:快速上手

jasonruan 2018.11.17

  1. 前言

本文是自己学习超级账本Fabric的第一篇文章,主要是体验了下基本功能——快速搭建起网络环境,并利用自带sample,体会了一下链码的部署与调用,为后续逐步深入其内部原理和链码开发做一个铺垫。

  1. 名词解释

自己初学超级账本Fabric,其众多的术语确实弄得有些蒙圈,以下摘记部分术语。

术语 含义
Anchor Peer(锚节点) 通道中能被所有对等节点探测,并能与之进行通信的一种对等节点。 通道中的每个成员都有一个或多个锚节点,允许属于不同身份的节点来发现通道中存在的其他节点。
Block(区块) 区块是一组有序的交易集合,在通道中经过哈希加密后与前序区块连接。
Chaincode(链码) 区块链上的应用代码,扩展自"智能合约"概念。
Channel(通道) Fabric 网络上的私有隔离。通道中的链码和交易只有加入该通道的节点可见。
Consensus (共识) 共识是贯穿整个交易流程, 对包含块的一组交易的正确性的全面验证。
Endorser(背书节点) 负责检验某个交易是否合法,是否愿意为之担保、签名。
Fabric-CA(证书节点) 默认的证书管理组件,它向网络成员及其用户颁发基于PKI的证书。 CA为每个成员颁发一个根证书,为没有授权用户颁发一个注册证书,为每个注册证书颁发大量交易证书。
Genesis Block(创世区块) 是区块链上的第一个区块,是初始化区块链网络或通道的配置区块
Ledger(账本) 账本是由通道中每个peer维护的数据库。
MSP(Member Service Provider,成员服务提供者) 抽象的实现成员服务(身份验证,证书管理等)的组件,实现对不同类型的成员服务的可拔插支持。
Orderer Peer(排序节点) 负责排序看到的交易,提供全局确认的顺序。
Ordering Service(排序服务) 将交易排序放入block的节点的集合。排序服务独立与peer流程之外,并以先到先服务的方式为网络上所有的通道做交易排序。
State Database(状态数据库) 当前状态数据存储在状态数据库中,以便从chaincode进行有效读取和查询。这些数据库包括levelDB和couchDB。
Transaction(交易) 执行账本上的某个函数调用或者部署 chaincode。调用的具体函数在 chaincode 中实现。
Validating Peer(验证节点) 维护账本的核心节点,参与一致性维护、对交易的验证和执行。
World State(世界状态) 即最新的全局账本状态。Fabric 用它来存储历史交易发生后产生的最新的状态,可以用键值或文档数据库实现。
  1. 环境搭建

2.1 前置依赖

省略具体安装步骤

  • ubuntu 18.04

  • go 1.11.2

  • docker-ce 18.09

  • docker-compose 1.23.1

2.2 fabric下载

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


$ git clone https://github.com/hyperledger/fabric.git
Cloning into 'fabric'...
remote: Enumerating objects: 183, done.
remote: Counting objects: 100% (183/183), done.
remote: Compressing objects: 100% (164/164), done.
remote: Total 81151 (delta 64), reused 135 (delta 18), pack-reused 80968
Receiving objects: 100% (81151/81151), 77.50 MiB | 440.00 KiB/s, done.
Resolving deltas: 100% (51831/51831), done.

2.3 fabric安装

步骤:

  • 进入clone好的源码目录fabric/scripts

  • 执行bootstrap.sh脚本,该脚本将执行如下操作:

> 首先是安装fabric-samples

(1)下载hyperledger/fabric-samples


  Installing hyperledger/fabric-samples repo
  ===> Cloning hyperledger/fabric-samples repo and checkout v1.3.0
  

(2)下载当前平台的fabric二进制包


  ===> Downloading version 1.3.0 platform specific fabric binaries
  ===> Downloading:  https://nexus.hyperledger.org/content/repositories/releases/org/hyperledger/fabric/hyperledger-fabric/linux-amd64-1.3.0/hyperledger-fabric-linux-amd64-1.3.0.tar.gz
  

(3)下载当前平台的CA客户端


  ===> Downloading version 1.3.0 platform specific fabric-ca-client binary
  ===> Downloading:  https://nexus.hyperledger.org/content/repositories/releases/org/hyperledger/fabric-ca/hyperledger-fabric-ca/linux-amd64-1.3.0/hyperledger-fabric-ca-linux-amd64-1.3.0.tar.gz
  

> 接下来拉取fabric镜像

(4)peer节点镜像


  ==> FABRIC IMAGE: peer
  1.3.0: Pulling from hyperledger/fabric-peer
  Digest: sha256:6756c7c48234ae6b0a8822a378681017cf6dbfeadfbf1f8a528ee6c4db343621
  Status: Image is up to date for hyperledger/fabric-peer:1.3.0
  

(5)排序节点镜像


  ==> FABRIC IMAGE: orderer
  1.3.0: Pulling from hyperledger/fabric-orderer
  Digest: sha256:6ee1abcfd84031765d67544e5d6b4f3af08c3f064312c65715587d392fe7c3eb
  Status: Image is up to date for hyperledger/fabric-orderer:1.3.0
  

(6)CC环境镜像


  ==> FABRIC IMAGE: ccenv
  1.3.0: Pulling from hyperledger/fabric-ccenv
  Digest: sha256:05fce5513fcae3110ac041469ed9e0e4c9661f44782f52ef5d8930eb416c2197
  Status: Image is up to date for hyperledger/fabric-ccenv:1.3.0
  

(7)工具镜像


  ==> FABRIC IMAGE: tools
  1.3.0: Pulling from hyperledger/fabric-tools
  Digest: sha256:058cff3b378c1f3ebe35d56deb7bf33171bf19b327d91b452991509b8e9c7870
  Status: Image is up to date for hyperledger/fabric-tools:1.3.0
  

> 下面拉取fabric CA镜像

(8)CA镜像


  ==> FABRIC CA IMAGE
  1.3.0: Pulling from hyperledger/fabric-ca
  Digest: sha256:83abc367c5273a12d59ef9777637eb6c1abf04a5d00d66a0bffc55c40075850e
  Status: Image is up to date for hyperledger/fabric-ca:1.3.0
  

> 最后拉取第三方docker镜像

(9)couchdb镜像


  ==> THIRDPARTY DOCKER IMAGE: couchdb
  0.4.13: Pulling from hyperledger/fabric-couchdb
  Digest: sha256:b26dfcf9abb466ffb60d0734d0c5c3bf1d4816c96e944ba69584d94681028cfd
  Status: Image is up to date for hyperledger/fabric-couchdb:0.4.13
  

(10)kafka镜像


  ==> THIRDPARTY DOCKER IMAGE: kafka
  0.4.13: Pulling from hyperledger/fabric-kafka
  Digest: sha256:7caa31210504bc99ae45d19d528671f238d25418d9433c42f8c582ba415703b4
  Status: Image is up to date for hyperledger/fabric-kafka:0.4.13
  

(11)zookeeper镜像


  ==> THIRDPARTY DOCKER IMAGE: zookeeper
  0.4.13: Pulling from hyperledger/fabric-zookeeper
  Digest: sha256:9fdff6aa2c086816ad693339c25f1e49ea4a0b6b7102c7342aff4137991a15a1
  Status: Image is up to date for hyperledger/fabric-zookeeper:0.4.13
  

镜像拉取完毕后,列出镜像清单


  ===> List out hyperledger docker images                                       
  hyperledger/fabric-ca         1.3.0         5c6b20ba944f    4 weeks ago   244MB  
  hyperledger/fabric-ca         latest        5c6b20ba944f    4 weeks ago   244MB
  hyperledger/fabric-tools      1.3.0         c056cd9890e7    4 weeks ago   1.5GB
  hyperledger/fabric-tools      latest        c056cd9890e7    4 weeks ago   1.5GB
  hyperledger/fabric-ccenv      1.3.0         953124d80237    4 weeks ago   1.38GB
  hyperledger/fabric-ccenv      latest        953124d80237    4 weeks ago   1.38GB
  hyperledger/fabric-orderer    1.3.0         f430f581b46b    4 weeks ago   145MB
  hyperledger/fabric-orderer    latest        f430f581b46b    4 weeks ago   145MB
  hyperledger/fabric-peer       1.3.0         f3ea63abddaa    4 weeks ago   151MB
  hyperledger/fabric-peer       latest        f3ea63abddaa    4 weeks ago   151MB
  hyperledger/fabric-zookeeper  0.4.13        e62e0af39193    4 weeks ago   1.39GB
  hyperledger/fabric-zookeeper  latest        e62e0af39193    4 weeks ago   1.39GB
  hyperledger/fabric-kafka      0.4.13        4121ea662c47    4 weeks ago   1.4GB
  hyperledger/fabric-kafka      latest        4121ea662c47    4 weeks ago   1.4GB
  hyperledger/fabric-couchdb    0.4.13        1d3266e01e64    4 weeks ago   1.45GB
  hyperledger/fabric-couchdb    latest        1d3266e01e64    4 weeks ago   1.45GB
  hyperledger/fabric-baseos     amd64-0.4.13  f0fe49196c40    4 weeks ago   124MB
  
  1. 构建网络

下面基于fabric-samples提供的BYFN(build your first network),来快速的构建我们第一个超级账本fabric网络,以此来熟悉整个运行过程。

3.1 生成配置

3.1.1 执行命令

进入到:fabric/scripts/fabric-samples/first-network/,执行命令:


$ sudo ./byfn.sh -m generate -c jschannel

3.1.2 命令说明
  • 这条命令也可以不用执行,在使用up命令启动网络时,若发现未生成所需配置,会自动进行执行。

  • 该条命令将根据配置文件(crypto-config.yaml)生成初始化配置,包含Peer节点、排序服务节点的MSP证书


  # crypto-config.yaml
  OrdererOrgs:
    - Name: Orderer
      Domain: example.com
      Specs:
        - Hostname: orderer
  PeerOrgs:
    - Name: Org1
      Domain: org1.example.com
      EnableNodeOUs: true
      Template:
        Count: 2
      Users:
        Count: 1
    - Name: Org2
      Domain: org2.example.com
      EnableNodeOUs: true
      Template:
        Count: 2
      Users:
        Count: 1
  
  • 根据配置文件configtx.yaml生成创世区块等

  # configtx.yaml
  Organizations:
      - &OrdererOrg
          Name: OrdererOrg
          ID: OrdererMSP
          MSPDir: crypto-config/ordererOrganizations/example.com/msp
          Policies:
            ......
      - &Org1
          Name: Org1MSP
          ID: Org1MSP
          MSPDir: crypto-config/peerOrganizations/org1.example.com/msp
          Policies:
              Readers:
                  ......
          AnchorPeers:
              - Host: peer0.org1.example.com
                Port: 7051
      - &Org2
            ......
  Capabilities:
      ......
  Application: &ApplicationDefaults
      Organizations:
      Policies:
          ......
  Orderer: &OrdererDefaults
      OrdererType: solo
      Addresses:
          - orderer.example.com:7050
      BatchTimeout: 2s
      BatchSize:
          ......
      Kafka:
          Brokers:
              - 127.0.0.1:9092
      Organizations:
      Policies:
          ......
  Channel: &ChannelDefaults
      ......
      Capabilities:
          <<: *ChannelCapabilities
  Profiles:
      ......
  
3.1.3 步骤说明
(1)生成证书

使用cryptogen工具为组织org1和org2生成MSP证书,MSP证书是超级账本网络实体的身份标识,实体在通信和交易时,使用证书进行签名和验证。成功执行后,证书文件将会放到crypto-config目录中。


##########################################################
##### Generate certificates using cryptogen tool #########
##########################################################
+ cryptogen generate --config=./crypto-config.yaml
org1.example.com
org2.example.com

(2)创建创世块

为排序服务生成创世区块,成功执行后,会在channel-artifacts目录下生成创世区块文件:genesis.block


##########################################################
#########  Generating Orderer Genesis block ##############
##########################################################
+ configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block

(3)创建通道

生成通道配置文件channel.tx,成功执行后,会在channel-artifacts目录下生成通道配置channel.tx


#################################################################
### Generating channel configuration transaction 'channel.tx' ###
#################################################################
+ configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID jschannel

(4)生成锚节点配置

生成Org1MSPOrg2MSP的锚节点配置,成功执行后,生成的锚点配置文件Org1MSPanchors.txOrg2MSPanchors.tx同样位于目录channel-artifacts中。


#################################################################
#######    Generating anchor peer update for Org1MSP   ##########
#################################################################
+ configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID jschannel -asOrg Org1MSP

#################################################################
#######    Generating anchor peer update for Org2MSP   ##########
#################################################################
+ configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID jschannel -asOrg Org2MSP

3.1.4 配置输出

综上,命令执行完后,将会在当前目录生成两个文件夹,内容分别如下:

  • 创世区块目录(channel-artifacts

$ tree channel-artifacts/
channel-artifacts/
├── channel.tx                          # 通道配置创世区块
├── genesis.block                       # 排序服务创世区块
├── Org1MSPanchors.tx                   # Org1锚节点配置
└── Org2MSPanchors.tx                   # Org2锚节点配置

  • 证书目录(crypto-config

> 该目录存放生成排序服务节点和Peer节点的MSP证书文件


$ tree crypto-config
crypto-config
├── ordererOrganizations
│   └── example.com
│       ├── ca
│       │   ├── 2b749470c3d6cae6d63caa7b69ee9ebbc310ca68526521e444012f186e97bd92_sk
│       │   └── ca.example.com-cert.pem
│       ├── msp
│       │   ├── admincerts
│       │   │   └── [email protected]
│       │   ├── cacerts
│       │   │   └── ca.example.com-cert.pem
│       │   └── tlscacerts
│       │       └── tlsca.example.com-cert.pem
│       ├── orderers
│       │   └── orderer.example.com
│       │       ├── msp
│       │       └── tls
│       │           ├── ca.crt
│       │           ├── server.crt
│       │           └── server.key
│       ├── tlsca
│       │   ├── c79b35c1154c5377923a77dfa6036707652715671e2b1450e6313b64a65f238e_sk
│       │   └── tlsca.example.com-cert.pem
│       └── users
│           └── [email protected]
│               ├── msp
└── peerOrganizations
    ├── org1.example.com
    │   ├── ca
    │   ├── msp
    │   ├── peers
    │   ├── tlsca
    │   └── users
    └── org2.example.com

3.2 启动网络

3.2.1 执行命令

$ sudo ./byfn.sh -m up -c jschannel

3.2.2 命令说明
  • 执行该命令后,首先会根据docker-compose-cli.yaml配置文件启动超级账本fabric网络

  • 其中包含了1个排序服务节点、4个Peer节点,以及1个命令行容器cli


  # docker-compose-cli.yaml 
  services:
    orderer.example.com:
      extends:
        file:   base/docker-compose-base.yaml
        service: orderer.example.com
      container_name: orderer.example.com
      networks:
        - byfn

    peer0.org1.example.com:
      container_name: peer0.org1.example.com
      extends:
        file:  base/docker-compose-base.yaml
        service: peer0.org1.example.com
      networks:
        - byfn

    peer1.org1.example.com:
    ......

    peer0.org2.example.com:
      container_name: peer0.org2.example.com
      extends:
        file:  base/docker-compose-base.yaml
        service: peer0.org2.example.com
      networks:
        - byfn

    peer1.org2.example.com:
    ......

    cli:
      container_name: cli
      image: hyperledger/fabric-tools:$IMAGE_TAG
      tty: true
      stdin_open: true
      environment:
        ......
      working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
      command: /bin/bash
      volumes:
          - ./../chaincode/:/opt/gopath/src/github.com/chaincode
          - ./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/
        ......
      depends_on:
        - orderer.example.com
        - peer0.org1.example.com
        - peer1.org1.example.com
        - peer0.org2.example.com
        - peer1.org2.example.com
      networks:
        - byfn
  
3.2.3 命令输出

看到下面信息,表明超级账本Fabric网络已经启动完毕。


  Creating network "net_byfn" with the default driver
  Creating volume "net_orderer.example.com" with default driver
  Creating volume "net_peer0.org1.example.com" with default driver
  Creating volume "net_peer1.org1.example.com" with default driver
  Creating volume "net_peer0.org2.example.com" with default driver
  Creating volume "net_peer1.org2.example.com" with default driver
  Creating peer1.org2.example.com ... done
  Creating orderer.example.com    ... done
  Creating peer1.org1.example.com ... done
  Creating peer0.org2.example.com ... done
  Creating peer0.org1.example.com ... done
  Creating cli                    ... done

3.2.4 查看容器

使用docker ps命令查看容器启动情况


$ sudo docker ps                                                      
CONTAINER ID IMAGE                             COMMAND            PORTS                                              NAMES
c32c37c5742f hyperledger/fabric-tools:latest   "/bin/bash"                                                           cli                         
dadda8aff9ae hyperledger/fabric-peer:latest    "peer node start"  0.0.0.0:8051->7051/tcp, 0.0.0.0:8053->7053/tcp     peer1.org1.example.com
f35e303b931d hyperledger/fabric-peer:latest    "peer node start"  0.0.0.0:7051->7051/tcp, 0.0.0.0:7053->7053/tcp     peer0.org1.example.com
5bf8fdf0f804 hyperledger/fabric-peer:latest    "peer node start"  0.0.0.0:9051->7051/tcp, 0.0.0.0:9053->7053/tcp     peer0.org2.example.com
48c9b04f48db hyperledger/fabric-peer:latest    "peer node start"  0.0.0.0:10051->7051/tcp, 0.0.0.0:10053->7053/tcp   peer1.org2.example.com
023b2fed2737 hyperledger/fabric-orderer:latest "orderer"          0.0.0.0:7050->7050/tcp                             orderer.example.com

3.3 链码调用

3.3.1 执行命令

启动网络 使用的$ sudo ./byfn.sh -m up -c jschannel中,启动的cli容器会调用scripts/script.sh脚本,该脚本会进行通道创建、Peer节点加入通道、安装和实例化链码等,并进行链码的调用和查询。下面我们对命令进行进一步的说明。

3.3.2 命令说明

scripts/script.sh中执行的具体命令如下,每个命令都对应一个shell脚本函数


## Create channel                                     
createChannel
 
## Join all the peers to the channel
joinChannel
 
## Set the anchor peers for each org in the channel
updateAnchorPeers 0 1 
updateAnchorPeers 0 2 
 
## Install chaincode on peer0.org1 and peer0.org2
installChaincode 0 1 
installChaincode 0 2 
 
# Instantiate chaincode on peer0.org2
instantiateChaincode 0 2 
 
# Query chaincode on peer0.org1
chaincodeQuery 0 1 100 
 
# Invoke chaincode on peer0.org1 and peer0.org2
chaincodeInvoke 0 1 0 2 
 
## Install chaincode on peer1.org2
installChaincode 1 2 
 
# Query on chaincode on peer1.org2, check if the result is 90
chaincodeQuery 1 2 90

3.3.3 步骤说明
(1)创建通道

进入cli容器,执行创建通道命令。成功执行后,将在cli容器的当前路径下生成通道配置jschannel.block,加入通道操作时需要使用。


Channel name : jschannel
Creating channel...
+ peer channel create -o orderer.example.com:7050 -c jschannel -f ./channel-artifacts/channel.tx --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
===================== Channel 'mychannel' created =====================

(2)4个peer节点依次加入通道

通过在cli容器中设置不同的环境变量,设置连接的Peer节点和MSP等,依次将4个Peer节点加入通道


+ peer channel join -b jschannel.block
Having all peers join the channel...
===================== peer0.org1 joined channel 'jschannel' ===================== 
+ peer channel join -b jschannel.block
===================== peer1.org1 joined channel 'jschannel' ===================== 
+ peer channel join -b jschannel.block
===================== peer0.org2 joined channel 'jschannel' ===================== 
+ peer channel join -b jschannel.block
===================== peer1.org2 joined channel 'jschannel' ===================== 

(3)更新组织的锚节点

Updating anchor peers for org1...
+ peer channel update -o orderer.example.com:7050 -c jschannel -f ./channel-artifacts/Org1MSPanchors.tx --tls true --cafile 
========= Anchor peers updated for org 'Org1MSP' on channel 'jschannel' ========= 

Updating anchor peers for org2...
+ peer channel update -o orderer.example.com:7050 -c jschannel -f ./channel-artifacts/Org2MSPanchors.tx --tls true --cafile 
========== Anchor peers updated for org 'Org2MSP' on channel 'jschannel' ========== 

(4)在Peer节点(peer0.org1peer0.org2)上安装链码

应用程序通过链码执行智能合约的功能,需要先在Peer节点上安装链码,然后在通道上实例化链码


Installing chaincode on peer0.org1...
+ peer chaincode install -n mycc -v 1.0 -l golang -p github.com/chaincode/chaincode_example02/go/
===================== Chaincode is installed on peer0.org1 ===================== 

Install chaincode on peer0.org2...
+ peer chaincode install -n mycc -v 1.0 -l golang -p github.com/chaincode/chaincode_example02/go/
===================== Chaincode is installed on peer0.org2 ===================== 

(5)在Peer节点(peer0.org2)上实例化链码

实例化链码只需要执行一次,这条命令比较复杂,-c:指定初始化参数;-P:指定了背书策略,链码的每个交易需要由Org1MSPOrg2MSP两个组织都进行背书签名,才能通过背书策略,继续进入后续交易流程。成功执行后,会启动链码容器mycc


Instantiating chaincode on peer0.org2...
+ peer chaincode instantiate -o orderer.example.com:7050 --tls true --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 jschannel -n mycc -l golang -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P 'AND ('\''Org1MSP.peer'\'','\''Org2MSP.peer'\'')'
========= Chaincode is instantiated on peer0.org2 on channel 'jschannel' ========= 

(6)在Peer节点(peer0.org1)上执行链码查询a的值

Querying chaincode on peer0.org1...
========== Querying on peer0.org1 on channel 'jschannel'... ========== 
+ peer chaincode query -C jschannel -n mycc -c '{"Args":["query","a"]}'

100
========== Query successful on peer0.org1 on channel 'jschannel' ==========

(7)在Peer节点(peer0.org1)调用链码,从a转10到b

Sending invoke transaction on peer0.org1 peer0.org2...
+ peer chaincode invoke -o orderer.example.com:7050 --tls true --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 jschannel -n mycc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["invoke","a","b","10"]}'

==== Invoke transaction successful on peer0.org1 peer0.org2 on channel 'jschannel' ====

(8)在Peer节点(peer1.org2)安装链码

Installing chaincode on peer1.org2...
+ peer chaincode install -n mycc -v 1.0 -l golang -p github.com/chaincode/chaincode_example02/go/
===================== Chaincode is installed on peer1.org2 ===================== 

(9)在Peer节点(peer1.org2)执行链码查询a的值

Querying chaincode on peer1.org2...
========== Querying on peer1.org2 on channel 'jschannel'... ========== 
+ peer chaincode query -C jschannel -n mycc -c '{"Args":["query","a"]}'

90
========= Query successful on peer1.org2 on channel 'jschannel' ========= 
========= All GOOD, BYFN execution completed =========== 

3.4 关闭网络

3.4.1 执行命令

测试完成后,使用如下命令,关闭网络


$ sudo ./byfn.sh -m down

  1. 总结

本文通过分解的方式,逐步介绍了搭建超级账本Fabric网络的基本过程以及链码部署和调用的方法,在理解和掌握了最基本的步骤后,也为后续自己深入学习超级账本的原理和开发更为复杂的链码应用打下基础。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u013328649/article/details/120679634

智能推荐

第三十六篇、基于Arduino uno,获取红外寻迹传感器的原始值——结果导向_怎么检测红外寻迹模块返回值-程序员宅基地

文章浏览阅读385次。基于Arduino uno,获取红外寻迹传感器的原始值_怎么检测红外寻迹模块返回值

基于单片机的无线投票显示系统设计-程序员宅基地

文章浏览阅读494次,点赞5次,收藏9次。单片机(Microcontroller)是一种集成了微处理器核心、存储器、输入/输出接口和定时器等功能模块的集成电路芯片,具有体积小、功耗低、性价比高等特点,被广泛应用于各个领域。单片机的发展历史可以追溯到20世纪70年代,当时的单片机功能有限,主要用于简单的控制任务。

生成对抗网络GAN_生成对抗网络 python代码-程序员宅基地

文章浏览阅读412次。https://zhuanlan.zhihu.com/p/54096381_生成对抗网络 python代码

html——网页上添加表格_怎样在网站中添加表格别人可以下载-程序员宅基地

文章浏览阅读5.2k次,点赞7次,收藏18次。有时候我们需要在网页上展示一些数据,如某公司想在网页上展示公司的库存清单。如下表:想在网页上展示上述表格效果可以使用以下代码:创建表格的四个元素:table、tbody、tr、th、td1、…:整个表格以标记开始、标记结束。2、…:当表格内容非常多时,表格会下载一点显示一点,但如果加上标签后,这个表格就要等表格内容全部下载完才会显示。如右侧代码编辑器中的代码。3、…_怎样在网站中添加表格别人可以下载

《Qt MOOC系列教程》第五章第三节:创建新的QML类型_qmlregisteruncreatabletype-程序员宅基地

文章浏览阅读770次。到目前为止,我们已经讨论了如何将对象实例公开给QML上下文。有时我们还希望在QML中可以使用注册类本身。注册允许将类当作QML中的数据类型来使用。此外,注册还可以提供其他功能,比如允许在QML中将类用作可实例化的QML对象类型,或者允许在QML中导入和使用类的单例实例。通常我们使用Q_OBJECT宏注册从QObject派生的类,也可以用Q_GADGET宏声明一个比QObject“更轻”的版本。在这些更轻的类中,我们可以访问它们的属性、枚举和可调用的方法,但不能使用信号槽系统,我们稍后会进行介绍。1. 注_qmlregisteruncreatabletype

头文件与命名空间的关系_c#中命名空间和c语言中头文件之间的关系-程序员宅基地

文章浏览阅读2.1k次,点赞7次,收藏15次。头文件与命名空间的关系 Q:有些书说有些头文件不在std里是什么意思?std里包含些什么?为什么不用std就不能使用cout?头文件中声明的东西为什么在使用的时候需要先using namespace std;一下?如果我不用#include和其他头文件。只用using namespace std 的话,是不能用cout的。这说明cout是在iostream里声明_c#中命名空间和c语言中头文件之间的关系

随便推点

python实现矩阵乘法(实现文件读写操作)_python 读取csv矩阵乘法-程序员宅基地

文章浏览阅读1.2k次,点赞2次,收藏8次。注释dtype=np.int代表导入数据的格式为整数delimiter=’,'代表原始数据的存储格式为以‘,’为间隔原始文件中以‘#’开头的行代表被注释,不会被np.loadtxt读取通过[[0] * b for i in range(a)]的方式初始化一个x[a][b]的二维数组np.savetxt()函数可以用来保存数据,第一个参数为保存数据的路径,其中C是自定义的文件名,如果该文..._python 读取csv矩阵乘法

《军团要塞2》绘画渲染_军团要塞画师-程序员宅基地

文章浏览阅读1.4k次。军团要塞2绘画渲染(a)美术概念 (b)游戏内玩家看到的角色摘要在《军团要塞2》中我们提出了一整套美术方案和新的实时渲染技术,这种技术能实现出一种独一无二的渲染风格。《军团要塞2》由美术和程序基于20世纪初时商业插画中的传统风格合作完成。在这篇论文中,我们会结合美术方向与技术选择,来讨论如何支持美术目标和玩法限制。除了实现一种有冲击力的风格外,我们也设计了边缘光照和亮度与色调变化的着色器技..._军团要塞画师

【数字图像处理实验二】:RGB图3个通道的提取、RGB图转灰度图、图片反转、图片亮度调整、直方图显示_jupter rgb灰度直方图提取-程序员宅基地

文章浏览阅读9.6k次,点赞8次,收藏65次。这里介绍:RGB图3个通道的提取、RGB图转灰度图、图片反转、图片亮度调整具体操作,需导入的库如下:原图如下:结果如下,从左到右分别是:Red,Green,Blue这里借助skimage库中的exposure函数来进行图像亮度的调整结果如下:........._jupter rgb灰度直方图提取

2023年地级、省级、县级、国界、九段线的shp数据_九段线shp数据-程序员宅基地

文章浏览阅读931次。2023年地级、省级、县级、国界、九段线的shp数据_九段线shp数据

python高校本科生学习成长记录系统的设计与实现flask-django-php-nodejs-程序员宅基地

文章浏览阅读797次,点赞16次,收藏19次。二十一世纪我们的社会进入了信息时代,信息管理系统的建立,大大提高了人们信息化水平。传统的管理方式对时间、地点的限制太多,而在线管理系统刚好能满足这些需求,在线管理系统突破了传统管理方式的局限性。于是本文针对这一需求设计并实现了一个基于django高校本科生学习成长记录系统,为了简捷并有效的解决学习各方面的问题。

redis实现分布式session共享_redis分布式session共享-程序员宅基地

文章浏览阅读7.7k次。为什么要共享session?我们使用单台Tomcat的时候不会有共享sesssion的疑虑,只要使用Tomcat的默认配置即可,session即可存储在Tomcat上。但是随着业务的扩大,增加Tomcat节点构成Tomcat集群大势所趋,分布式带来了增加更大规模并发请求的优势,但是也随之到来了一个问题,每个Tomcat只存储来访问自己的请求产生的session,如果Tomcat-A已经为客..._redis分布式session共享

推荐文章

热门文章

相关标签