本文水份很严重,如果你正处于配置fabric的环境而翻了一遍又一遍的网文的过程, 那么本文可能并不会帮你解决你当前的紧要问题。

一、准备二进制文件

在我们准备开始之前,我们需要获得以下二进制文件:

configtxgen
cryptogen
orderer
peer
configtxlator(非必须)
discover(非必须)
idemixgen(非必须)
fabric-ca-client(非必须)

二进制文件,我们可以通过官方的源码自己编译得到https://github.com/hyperledger/fabric, 但是这个过程显得比较麻烦,你可能需要一个一个工具去编译。

当然,繁锁的工序并不是主要原因,让我编译不下去的主要原因是因为编译过程 需要从golang.orggoogle.golang.org获取大量的依赖包, 而不巧这两个网站正好被墙了,作为深知党的良苦用心以及没钱买梯子的我,就此放弃了此条道路。

除了自己手动编译,从Fabric的官方文档找到了另一种方法Install Samples, Binaries and Docker Images,如果你和我一样,一直饱受E文的折磨,那你可以略过大部分的内容,但应该可以找到以下链接:

https://raw.githubusercontent.com/hyperledger/fabric/master/scripts/bootstrap.sh

当然,你可能会遇到和我一样的情况,那就是raw.githubusercontent.com也被墙了,怎么办?

我试着修改hosts文件,于是通过以下链接查询了一下该域名的原始IP地址,修改完成后,竟然可以访问

http://ip.webmasterhome.cn/?ip=raw.githubusercontent.com
# 得到的IP地址为:151.101.108.133

PS:golang.org也试过,但修改后也访问不了.

那么终于顺序的得到了bootstrap.sh文件,我在这个文件找到了heyperledger fabric的二进制文件下载地址:hyperledger-fabric-linux-amd64-1.4.3.tar.gz,如果文件地址已经访问不了,可以试试把文件名去掉, 访问目录,可能会显示可下载的文件列表。 >PS:nexus.hyperledger.org没有被墙,应该可以正常下载hyperledger-fabric-linux-amd64-1.4.3.tar.gz文件。
不过速度可能不敢恭维,为了备用,我把它放了在百度网盘: https://pan.baidu.com/s/13X49PZdIdiPTgQXuud3MfA 提取码: e592
(别再抱怨了,虽然我很厌恶为了下载一个文件,还必须得下载一个百度网盘。)

最后终于得到我们所需求的二进制文件。

fabric/
├── bin
│   ├── configtxgen
│   ├── configtxlator
│   ├── cryptogen
│   ├── discover
│   ├── idemixgen
│   ├── orderer
│   └── peer
└── config
    ├── configtx.yaml
    ├── core.yaml
    └── orderer.yaml

记得将bin目录下的文件修改为可执行。同时设置环境变量export FABRIC_CFG_PATH=/var/fabric/config

二、整体流程

  1. 通过cryptogen生成证书文件。
  2. 通过configtxgen生成创世块、channel管道配置文件、anchor锚点配置文件。
  3. 启动orderer节点。
  4. 通过peer节点创建channel管道。
  5. 通过peer节点加入channel管道。
  6. 通过peer节点更新锚点信息。
  7. 通过peer节点安装链码。
  8. 通过peer节点实例化链码。
  9. 通过客户端操作交易。

三、生成证书文件

证书的作用在于节点在参与区块链网络工作时,为节点提供身份证明、签名等。它可以通过cryptogenFabirc CA来生成, 本文以cryptogen做为示例。

生成证书前,首先需要准备一个配置文件,从刚下载的二进制文件包,并没有该配置文件,因为cryptogen已经提供了一个模板。

./bin/cryptogen showtemplate>>config/crypto-config.yaml

通过以上命令,我们得到了一个配置文件模板。

OrdererOrgs:
  - Name: Orderer              # 组织名
    Domain: example.com        # 组织域名
    EnableNodeOUs: true        # 设置为true时,会在证书目录生成config.yaml
    Specs:
      - Hostname: orderer      # 域名前缀,此处节点将生成`orderer.example.com`,设置多个Hostname时,生成多个节点。

PeerOrgs:
  - Name: Org1                 # 组织名
    Domain: org1.example.com   # 组织域名
    EnableNodeOUs: true        # 设置为true时,会在证书目录生成config.yaml
    Template:
      Count: 1                 # 生成的节点数
    Users:
      Count: 1                 # 生成的用户数

配置完成后,接下来可以生成对应的证书文件了

./bin/cryptogen generate --config=config/crypto-config.yaml

如果未指定--config,会对showtemplate中的内容生成。

默认生成的文件会在crypto-config目录下

crypto-config
├── ordererOrganizations
│   └── example.com
│       ├── ca         # 存放组织的根证书
│       ├── msp        # 存放组织的MSP文件
│       ├── orderers   # 该组织下的节点所拥有的证书及key文件
│       ├── tlsca      # 组织内部的tlsca证书
│       └── users      # 该组织下的用户所拥有的证书及key文件  
└── peerOrganizations
    └── org1.example.com
        ├── ca
        ├── msp
        ├── peers
        ├── tlsca
        └── users
  1. 通过配置文件,首先生成orderer或peer节点的ca证书与tls证书(*.pem结尾),分别存放在 /ca 与 /tlsca 目录。
  2. 将上面的ca、tls证书分别复制到/msp下面对应的ca/与tlsca目录。
  3. 创建子节点,并把ca、tls证书分别复制到子节点的msp下面对应的ca/与tlsca目录。
  4. 创建用户,并把ca、tls证书分别复制到用户的msp下面对应的ca/与tlsca目录。 > 证书文件有点凌乱,实际的引用可以围绕组织、节点、用户三个方面相对应的msp文件。此处没有必须 过多纠结,后续会介绍相关的证书文件用处。

四、配置区块链网络

该过程主要是生成后续区块链运行的必备文件,我们需要完成以下三件事: * 生成创世块 * 生成channel管道配置文件 * 生成anchor锚点配置文件

我们需要通过configtxgen工具来完成工作,在进行我们的工作之前,需要调整配置文件config/configtx.yaml, 在配置文件中,需要配置orderer节点的共享方式,Fabirc支持Solo、Kafka、Raft三种类型, 本着反正不是我用,调通万岁的复杂心理,我决定采用Solo类型(听说它最简单) > Solo类型见其名就知道是指单节点通信,只有一个orderer节点进行排序服务, 所有peer节点发送来的消息由一个orderer进行排序和产生区块,实现绝对的独裁。
Solo模式有背区块链的理念,它没有没有高可用性和可扩展性,更为关键的是共识类型一旦使用在中途是不能切换;
也就是,如果你要生产使用了Solo模式,你要么继续用,要么推倒重来,所以它不适合用于生产环境, 但对于我们快速搭建开发和测试环境还是能节省不少时间。

config/configtx.yaml:

# 组织信息
Organizations:
    - &SampleOrg
        Name: SampleOrg                         # 组织名称,这里的NAME并一定要求与前面证书中的组织NAME一致
        ID: SampleOrg                           # 组织ID,记住这里,后面要考的
        # 这里的MSP是指组织的MSP,如果该组织是在orderer中引用,
        # 那么调用ordererOrganizations下对应组织的MSP.
        MSPDir: /var/fabric/crypto-config/ordererOrganizations/example.com/msp
        # 策略类型
        # UNKNOWN:保留值,用于初始化;
        # SIGNATURE:通过匹配基于签名的组合,如某个 MSP 中至少三个签名;
        # MSP:代表策略必须要匹配某 MSP 下的指定身份身份,如 MSP 的管理员身份;
        # IMPLICIT_META:隐式类型,包括若干子策略,并通过 Rule 来指定具体的规则,包括 ANY、ALL、MAJORITY 三种。
        #           ANY:满足任意子组的对应策略。
        #           ALL:满足所有子组的对应策略。
        #      MAJORITY:满足大多数(过半)子组的对应策略。
        Policies: &SampleOrgPolicies
            Readers:
                Type: Signature
                Rule: "OR('SampleOrg.member')"
            Writers:
                Type: Signature
                Rule: "OR('SampleOrg.member')"
            Admins:
                Type: Signature
                Rule: "OR('SampleOrg.admin')"
        # Orderer节点
        OrdererEndpoints:
            - "127.0.0.1:7050"
        # Peer节点
        AnchorPeers:
            - Host: 127.0.0.1
              Port: 7051

# Capabilities是用于处理兼容,官方举了一个栗子,他们说如果有一个新MSP类型被引来了,一些高
# 版本的节点呢可能可以识别出来,而一些低版本的节点,可能就识别不出来了,如果高版本的拿着
# 新的MSP类型,而低版本的节点由于识别不了只能继续拿着旧的MSP类型,这样可能会乱成一锅粥。
# 于是他们便设置`Capabilities`,由它来掌管哪些满足版本要求节点可以参与区块链网络,
# 而那些不能满足版本要求的,那升级完成后再来.
Capabilities:
    Channel: &ChannelCapabilities
        V1_4_3: true
        V1_3: false
        V1_1: false
    Orderer: &OrdererCapabilities
        V1_4_2: true
        V1_1: false
    Application: &ApplicationCapabilities
        V1_4_2: true
        V1_3: false
        V1_2: false
        V1_1: false
Application: &ApplicationDefaults
    ACLs: &ACLsDefault
        lscc/ChaincodeExists: /Channel/Application/Readers
        lscc/GetDeploymentSpec: /Channel/Application/Readers
        lscc/GetChaincodeData: /Channel/Application/Readers
        lscc/GetInstantiatedChaincodes: /Channel/Application/Readers
        qscc/GetChainInfo: /Channel/Application/Readers
        qscc/GetBlockByNumber: /Channel/Application/Readers
        qscc/GetBlockByHash: /Channel/Application/Readers
        qscc/GetTransactionByID: /Channel/Application/Readers
        qscc/GetBlockByTxID: /Channel/Application/Readers
        cscc/GetConfigBlock: /Channel/Application/Readers
        cscc/GetConfigTree: /Channel/Application/Readers
        cscc/SimulateConfigTreeUpdate: /Channel/Application/Readers
        peer/Propose: /Channel/Application/Writers
        peer/ChaincodeToChaincode: /Channel/Application/Readers
        event/Block: /Channel/Application/Readers
        event/FilteredBlock: /Channel/Application/Readers
    Organizations:
    Policies: &ApplicationDefaultPolicies
        Readers:
            Type: ImplicitMeta
            Rule: "ANY Readers"
        Writers:
            Type: ImplicitMeta
            Rule: "ANY Writers"
        Admins:
            Type: ImplicitMeta
            Rule: "MAJORITY Admins"
    Capabilities:
        <<: *ApplicationCapabilities
Orderer: &OrdererDefaults
    # 共识排序支持三种模式,solo、kafka、etcdraft
    # solo 用于测试环境,它不支持扩展高可用性
    # kafka和etcdraft均可用作生产
    # 警告:生产环境请谨慎选择OrdererType,一量选择投入使用,后续不可更改。
    OrdererType: solo
    Addresses:
        # - 127.0.0.1:7050
    BatchTimeout: 2s
    BatchSize:
        MaxMessageCount: 500
        AbsoluteMaxBytes: 10 MB
        PreferredMaxBytes: 2 MB
    MaxChannels: 0
    Organizations:
    Policies:
        Readers:
            Type: ImplicitMeta
            Rule: "ANY Readers"
        Writers:
            Type: ImplicitMeta
            Rule: "ANY Writers"
        Admins:
            Type: ImplicitMeta
            Rule: "MAJORITY Admins"
        BlockValidation:
            Type: ImplicitMeta
            Rule: "ANY Writers"
    Capabilities:
        <<: *OrdererCapabilities
Channel: &ChannelDefaults
    Policies:
        Readers:
            Type: ImplicitMeta
            Rule: "ANY Readers"
        Writers:
            Type: ImplicitMeta
            Rule: "ANY Writers"
        Admins:
            Type: ImplicitMeta
            Rule: "MAJORITY Admins"
    Capabilities:
        <<: *ChannelCapabilities
  # 以下部分定义了整个系统的配置信息,指定configtxgen工具的参数
  Profiles:
      # 组织定义标识符,可以自定义,命令中的-profile参数对应该标识符
      # 命令示例:./bin/configtxgen -profile OneOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block
      OneOrgsOrdererGenesis:
          <<: *ChannelDefaults

          # Orderer属性配置,系统关键字不得更改
          Orderer:
              <<: *OrdererDefaults
              Organizations:
                  # OrdererOrg是官方样板给出的名称,实际生产环境中可自定义
                  - *OrdererOrg
              Capabilities:
                  <<: *OrdererCapabilities
          # 定义了系统中包含的组织
          Consortiums:
              SampleConsortium:
                  # 系统中包含的组织
                  Organizations:
                      - *Org1

      # 以下是channel的配置信息
      # 通道定义标识符,可自定义
      OneOrgsChannel:
          Consortium: SampleConsortium
          <<: *ChannelDefaults
          Application:
              <<: *ApplicationDefaults
              Organizations:
                  - *Org1
              Capabilities:
                  <<: *ApplicationCapabilities
  1. 生成创世块 ./bin/configtxgen -channelID testc -profile OneOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block
  2. 生成anchor锚点配置文件 ./bin/configtxgen -profile OneOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID testc
  3. 生成anchor锚点配置 ./bin/configtxgen -profile OneOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/anchors.tx -channelID testc -asOrg Org1MSP

五、启动orderer节点

在启动orderer节点前,必须完成orderder节点的相关配置,配置形式有两种,一种是通过配置yaml文件,另一种是通过环境变量的形式配置。 首先通过yaml文件配置,我们创建文件config/orderer.yaml:

General:
    # 账本类型,提供了两种用于测试环境的类型,一种用于生产环境:
    # ram: 基于内存的账本类型,在orderer重启后将被清空。
    # json: 以json模式存储在磁盘中,但保密性不好,不适用生产环境。
    # file: 生产环境建议使用file类型。
    LedgerType: file
    ListenAddress: 127.0.0.1
    ListenPort: 7050
    TLS:
        # 是否开户TLS,开启后,凡是peer节点操作channel时,需要带上orderer节点的证文件证文件:
        # `--tls --cafile=ordererOrganizations/36sn.com/orderers/orderer.36sn.com/msp/tlscacerts/tlsca.36sn.com-cert.pem`
        Enabled: true
        PrivateKey: /home/vagrant/fabric/crypto-config/ordererOrganizations/36sn.com/orderers/orderer.36sn.com/tls/server.key
        Certificate: /home/vagrant/fabric/crypto-config/ordererOrganizations/36sn.com/orderers/orderer.36sn.com/tls/server.crt
        RootCAs:
          - /home/vagrant/fabric/crypto-config/ordererOrganizations/36sn.com/orderers/orderer.36sn.com/tls/ca.crt
        ClientAuthRequired: false
        ClientRootCAs:
    Keepalive:
        ServerMinInterval: 60s
        ServerInterval: 7200s
        ServerTimeout: 20s
    Cluster:
        SendBufferSize: 10
        ClientCertificate: /home/vagrant/fabric/crypto-config/ordererOrganizations/36sn.com/orderers/orderer.36sn.com/tls/server.key
        ClientPrivateKey: /home/vagrant/fabric/crypto-config/ordererOrganizations/36sn.com/orderers/orderer.36sn.com/tls/server.crt
        ListenPort:
        ListenAddress:
        ServerCertificate:
        ServerPrivateKey:
    # 创世块的提供方式,有两种方式
    # provisional 该方式提供一种临时的方法,即在order节点启用时根据`GenesisProfile`的值生成一个临时创世块。
    # file        该方式通过读取本地已存在的创世块来启动节点。
    GenesisMethod: provisional
    GenesisProfile: OneOrgsOrdererGenesis
    GenesisFile: /home/vagrant/fabric/channel-artifacts/genesis.block
    # ordere节点的MSP目录
    LocalMSPDir: /home/vagrant/fabric/crypto-config/ordererOrganizations/36sn.com/orderers/orderer.36sn.com/msp
    # orderer节点的MSPID
    LocalMSPID: OrdererMSP
    Profile:
        Enabled: false
        Address: 0.0.0.0:6060
    BCCSP:
        Default: SW
        SW:
            Hash: SHA2
            Security: 256
            FileKeyStore:
                KeyStore:
    Authentication:
        TimeWindow: 15m
FileLedger:
    Location: /var/hyperledger/production/orderer
    Prefix: hyperledger-fabric-ordererledger
RAMLedger:
    HistorySize: 1000
Kafka:
    Retry:
        ShortInterval: 5s
        ShortTotal: 10m
        LongInterval: 5m
        LongTotal: 12h
        NetworkTimeouts:
            DialTimeout: 10s
            ReadTimeout: 10s
            WriteTimeout: 10s
        Metadata:
            RetryBackoff: 250ms
            RetryMax: 3
        Producer:
            RetryBackoff: 100ms
            RetryMax: 3
        Consumer:
            RetryBackoff: 2s
    Topic:
        ReplicationFactor: 1
    Verbose: true
    TLS:
      Enabled: false
      PrivateKey:
      Certificate:
      RootCAs:
    SASLPlain:
      Enabled: false
      User:
      Password:
    Version:
Debug:
    BroadcastTraceDir:
    DeliverTraceDir:
Operations:
    ListenAddress: 127.0.0.1:8443
    TLS:
        Enabled: false
        Certificate:
        PrivateKey:
        ClientAuthRequired: false
        ClientRootCAs: []
Metrics:
    Provider: disabled
    Statsd:
      Network: udp
      Address: 127.0.0.1:8125
      WriteInterval: 30s
      Prefix:
Consensus:
    WALDir: /var/hyperledger/production/orderer/etcdraft/wal
    SnapDir: /var/hyperledger/production/orderer/etcdraft/snapshot

orderer节点需要设置FABRIC_CFG_PATH环境变量,orderer启动时会从该路径下寻找orderer配置文件, 如果不存在该路径,则会在当前目录寻找,当前目录不存时,会从/etc/hyperledger/fabric/路径寻找。

通过环境变量的形式配置:

export ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
export ORDERER_GENERAL_GENESISMETHOD=file
export ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
export ORDERER_GENERAL_LOCALMSPID=OrdererMSP
export ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
export ORDERER_GENERAL_TLS_ENABLED=true
export ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key
export ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt
export ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]

配置完成后,启动orderer节点

./bin/orderer start

六、启动 peer 节点

peer 与 orderer 节点类似,必须完成peer节点的相关配置才能启动, 配置形式一种是通过配置yaml文件,另一种是通过环境变量的形式配置。 首先通过yaml文件配置,我们创建文件config/core.yaml:

peer:
    # 节点ID
    id: peer0.org1.36sn.com
    networkId: dev
    listenAddress: 0.0.0.0:7051
    address: peer0.org1.36sn.com:7051
    addressAutoDetect: false
    gomaxprocs: -1
    keepalive:
        minInterval: 60s
        client:
            interval: 60s
            timeout: 20s
        deliveryClient:
            interval: 60s
            timeout: 20s
    gossip:
        bootstrap: 127.0.0.1:7051
        useLeaderElection: true
        orgLeader: false
        membershipTrackerInterval: 5s
        endpoint:
        maxBlockCountToStore: 100
        maxPropagationBurstLatency: 10ms
        maxPropagationBurstSize: 10
        propagateIterations: 1
        propagatePeerNum: 3
        pullInterval: 4s
        pullPeerNum: 3
        requestStateInfoInterval: 4s
        publishStateInfoInterval: 4s
        stateInfoRetentionInterval:
        publishCertPeriod: 10s
        skipBlockVerification: false
        dialTimeout: 3s
        connTimeout: 2s
        recvBuffSize: 20
        sendBuffSize: 200
        digestWaitTime: 1s
        requestWaitTime: 1500ms
        responseWaitTime: 2s
        aliveTimeInterval: 5s
        aliveExpirationTimeout: 25s
        reconnectInterval: 25s
        externalEndpoint:
        election:
            startupGracePeriod: 15s
            membershipSampleInterval: 1s
            leaderAliveThreshold: 10s
            leaderElectionDuration: 5s
        pvtData:
            pullRetryThreshold: 60s
            transientstoreMaxBlockRetention: 1000
            pushAckTimeout: 3s
            btlPullMargin: 10
            reconcileBatchSize: 10
            reconcileSleepInterval: 1m
            reconciliationEnabled: true
            skipPullingInvalidTransactionsDuringCommit: false
        state:
            enabled: true
            checkInterval: 10s
            responseTimeout: 3s
            batchSize: 10
            blockBufferSize: 100
            maxRetries: 3
    # 是否启动tls
    tls:
        enabled:  true
        clientAuthRequired: false
        cert:
            file: /home/vagrant/fabric/crypto-config/peerOrganizations/org1.36sn.com/peers/peer0.org1.36sn.com/tls/server.crt
        key:
            file: /home/vagrant/fabric/crypto-config/peerOrganizations/org1.36sn.com/peers/peer0.org1.36sn.com/tls/server.key
        rootcert:
            file: /home/vagrant/fabric/crypto-config/peerOrganizations/org1.36sn.com/peers/peer0.org1.36sn.com/tls/ca.crt
        clientRootCAs:
            files:
              - /home/vagrant/fabric/crypto-config/peerOrganizations/org1.36sn.com/peers/peer0.org1.36sn.com/tls/ca.crt
        clientKey:
            file:
        clientCert:
            file:
    authentication:
        timewindow: 15m
    fileSystemPath: /var/hyperledger/production
    BCCSP:
        Default: SW
        SW:
            Hash: SHA2
            Security: 256
            FileKeyStore:
                KeyStore:
        PKCS11:
            Library:
            Label:
            Pin:
            Hash:
            Security:
            FileKeyStore:
                KeyStore:
    # 节点的MSP路径
    mspConfigPath: /home/vagrant/fabric/crypto-config/peerOrganizations/org1.36sn.com/peers/peer0.org1.36sn.com/msp
    # 节点MSPID
    localMspId: Org1MSP
    client:
        connTimeout: 3s
    deliveryclient:
        reconnectTotalTimeThreshold: 3600s
        connTimeout: 3s
        reConnectBackoffThreshold: 3600s
    localMspType: bccsp
    profile:
        enabled:     false
        listenAddress: 0.0.0.0:6060
    adminService:
    handlers:
        authFilters:
          -
            name: DefaultAuth
          -
            name: ExpirationCheck    # This filter checks identity x509 certificate expiration
        decorators:
          -
            name: DefaultDecorator
        endorsers:
          escc:
            name: DefaultEndorsement
            library:
        validators:
          vscc:
            name: DefaultValidation
            library:
    validatorPoolSize:
    discovery:
        enabled: true
        authCacheEnabled: true
        authCacheMaxSize: 1000
        authCachePurgeRetentionRatio: 0.75
        orgMembersAllowedAccess: false
vm:
    endpoint: unix:///var/run/docker.sock
    docker:
        tls:
            enabled: false
            ca:
                file: docker/ca.crt
            cert:
                file: docker/tls.crt
            key:
                file: docker/tls.key
        attachStdout: false
        hostConfig:
            NetworkMode: host
            Dns:
            LogConfig:
                Type: json-file
                Config:
                    max-size: "50m"
                    max-file: "5"
            Memory: 2147483648
chaincode:
    id:
        path:
        name:
    builder: $(DOCKER_NS)/fabric-ccenv:latest
    pull: false
    golang:
        runtime: $(BASE_DOCKER_NS)/fabric-baseos:$(ARCH)-$(BASE_VERSION)
        dynamicLink: false
    car:
        runtime: $(BASE_DOCKER_NS)/fabric-baseos:$(ARCH)-$(BASE_VERSION)
    java:
        runtime: $(DOCKER_NS)/fabric-javaenv:$(ARCH)-$(PROJECT_VERSION)
    node:
        runtime: $(BASE_DOCKER_NS)/fabric-baseimage:$(ARCH)-$(BASE_VERSION)
    startuptimeout: 300s
    executetimeout: 30s
    mode: net
    keepalive: 0
    system:
        cscc: enable
        lscc: enable
        escc: enable
        vscc: enable
        qscc: enable
    systemPlugins:
    logging:
      level:  info
      shim:   warning
      format: '%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}'
ledger:
  blockchain:
  state:
    stateDatabase: goleveldb
    totalQueryLimit: 100000
    couchDBConfig:
       couchDBAddress: 127.0.0.1:5984
       username:
       password:
       maxRetries: 3
       maxRetriesOnStartup: 12
       requestTimeout: 35s
       internalQueryLimit: 1000
       maxBatchUpdateSize: 1000
       warmIndexesAfterNBlocks: 1
       createGlobalChangesDB: false
  history:
    enableHistoryDatabase: true
operations:
    listenAddress: 127.0.0.1:9443
    tls:
        enabled: false
        cert:
            file:
        key:
            file:
        clientAuthRequired: false
        clientRootCAs:
            files: []

metrics:
    provider: disabled
    statsd:
        network: udp
        address: 127.0.0.1:8125
        writeInterval: 10s
        prefix:

peer 节点需要配置的内容不多,同样它也支持通过环境变量的形式进行配置:

export CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
export CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=test_byfn
export FABRIC_LOGGING_SPEC=INFO
export FABRIC_LOGGING_SPEC=DEBUG
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_GOSSIP_USELEADERELECTION=true
export CORE_PEER_GOSSIP_ORGLEADER=false
export CORE_PEER_PROFILE_ENABLED=true
export CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
export CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
export CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt

peer节点需要配置 docker 信息,因为安装好的链码需要在 docker 容器中执行。

配置完成后,启动 peer 节点

./bin/peer node start

七、管理管道channel

在本小节,我们将完成以下三项操作: * 通过 peer 节点创建 channel 管道。 * 通过 peer 节点加入 channel 管道。 * 通过 peer 节点更新锚点信息。

在完成操作前,我们需要做一些准备工作,因为需要操作管道,我们需要拥有节点的管理员权限, 我将三个操作合并成了一个 shell 文件:

#!/bin/bash

CHANNEL_NAME="zsjr"
APP_PATH=/home/vagrant/fabric
BLOCK_PATH=${APP_PATH}/channel-artifacts/${CHANNEL_NAME}.block
CHANNEL_PATH=${APP_PATH}/channel-artifacts/channel.tx
ANCHORS_PATH=${APP_PATH}/channel-artifacts/anchors.tx
ORDERER_ADDR=orderer.36sn.com:7050
CAFILE=/home/vagrant/fabric/crypto-config/ordererOrganizations/36sn.com/orderers/orderer.36sn.com/msp/tlscacerts/tlsca.36sn.com-cert.pem

export CORE_PEER_LOCALMSPID=Org1MSP
export CORE_PEER_MSPCONFIGPATH=/home/vagrant/fabric/crypto-config/peerOrganizations/org1.36sn.com/users/Admin@org1.36sn.com/msp
export FABRIC_CFG_PATH=/home/vagrant/fabric/config

env|grep PEER
echo "=======================Start ...========================"
set -x
${APP_PATH}/bin/peer channel create -o ${ORDERER_ADDR} -c ${CHANNEL_NAME} -f ${CHANNEL_PATH}  --outputBlock=${BLOCK_PATH} --tls --cafile=${CAFILE}
res=$?
set +x
if [ $res -ne 0 ]; then
    echo "Failed to create channel..."
    exit 1
fi
set -x
${APP_PATH}/bin/peer channel join -b ${BLOCK_PATH} --tls --cafile=${CAFILE}
res=$?
set +x
if [ $res -ne 0 ]; then
    echo "Failed to join channel..."
    exit 1
fi
set -x
${APP_PATH}/bin/peer channel update -o ${ORDERER_ADDR} -c ${CHANNEL_NAME} -f ${ANCHORS_PATH} --tls --cafile=${CAFILE}
res=$?
set +x
if [ $res -ne 0 ]; then
    echo "Failed to update channel..."
    exit 1
fi

八、链码安装

安装完成后,进行链码安装,同样,我把这三步进行了合并:

#!/bin/bash

CHANNEL_NAME="zsjr"
APP_PATH=/home/vagrant/fabric

CAFILE=/home/vagrant/fabric/crypto-config/ordererOrganizations/36sn.com/orderers/orderer.36sn.com/msp/tlscacerts/tlsca.36sn.com-cert.pem

export CORE_PEER_MSPCONFIGPATH=/home/vagrant/fabric/crypto-config/peerOrganizations/org1.36sn.com/users/Admin@org1.36sn.com/msp
export FABRIC_CFG_PATH=/home/vagrant/fabric/config
export GOPATH=/home/vagrant/go

${APP_PATH}/bin/peer chaincode install -n example -v 0.0.2 -p github.com/hyperledger/fabric-demo/chaincode/chaincode_example02/go/ --tls --cafile=${CAFILE}
${APP_PATH}/bin/peer chaincode instantiate -o orderer.36sn.com:7050 -C zsjr -n example -v 0.0.2 -c '{"Args":["init","a","100","b","200"]}' -P 'OR ('\''Org1MSP.member'\'')' --tls --cafile=${CAFILE}

安装完成后,如果想进行安装后的链码查询:

#查询链码情况前,需要设置MSP路径的环境变量
export CORE_PEER_MSPCONFIGPATH=/home/vagrant/fabric/crypto-config/peerOrganizations/org1.36sn.com/users/Admin@org1.36sn.com/msp
# 查询已安装的链码
./peer chaincode list --installed
# 查询已实列化的链码
./peer chaincode -C zsjr list --instantiated
# 查询账户a的全额
 ./peer chaincode query -C zsjr -n example -c '{"Args":["query","a"]}'

九、结尾

我以将以上代码上传到了github:

https://github.com/yiuked/myfabric.git

参考资料