HyperLedger Fabric 单机多节点示例

目标


实践一个简化版本的 fabric 1.1 网络,在一台服务器中部署完成,并执行 chaincode。

包括:

  • 1个orderer 节点
  • 2个组织,每个组织1个peer节点
  • chaincode 使用 fabric-release-1.1 中的 examples/chaincode/go/chaincode_example02

实践本示例最好先把 fabric 基础跑通,可以参考之前的文章:
HyperLedger Fabric 1.1 End-2-End 示例

思路


  • 生成基础文件,如权限、创始块相关文件
  • 部署 orderer 服务
  • 部署一个 peer 服务,在这个 peer 上安装 chaincode,执行测试操作,这时,一个最小化的 fabric 网络就完成了
  • 部署其他 peer 服务,加入到现有网络中,并在其中执行 chaincode 进行测试

步骤说明


  1. 写配置文件 生成权限文件、创始块
  2. 写orderer配置文件 启动
  3. 写org1的peer配置文件 启动
  4. 安装执行 chaincode
  5. 写org2的peer配置文件 启动 执行chaincode
  6. org2的peer中执行chaincode

详细步骤


(1)写配置文件 生成权限文件、创始块

创建测试项目目录 fabrictest,并把 chaincode_example02 拷贝到 fabrictest/chaincode/go 目录下。

写配置文件 fabrictest/crypto-config.yaml,内容:

OrdererOrgs:
  - Name: Orderer
    Domain: example.com
    Specs:
      - Hostname: orderer
PeerOrgs:
  - Name: Org1
    Domain: org1.example.com
    Template:
      Count: 1
    Users:
      Count: 1
  - Name: Org2
    Domain: org2.example.com
    Template:
      Count: 1
    Users:
      Count: 1

执行命令生成安全文件:

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

# 返回信息
org1.example.com
org2.example.com

会自动生成一个文件夹 crypto-config,里面是各个组织的安全文件,现在项目的目录结构如下:

├── chaincode
│   └── go
│       └── chaincode_example02
│           ├── chaincode_example02.go
│           └── chaincode_example02_test.go
├── crypto-config.yaml
├── crypto-config
│   ├── ordererOrganizations
│   │   └── example.com
│   │       ├── ca
│   │       ├── msp
│   │       ├── orderers
│   │       ├── tlsca
│   │       └── users
│   └── peerOrganizations
│       ├── org1.example.com
│       │   ├── ca
│       │   ├── msp
│       │   ├── peers
│       │   ├── tlsca
│       │   └── users
│       └── org2.example.com
│           ├── ca
│           ├── msp
│           ├── peers
│           ├── tlsca
│           └── users

编写文件 fabrictest/configtx.yaml,内容:

Profiles:
    TwoOrgsOrdererGenesis:
        Orderer:
            <<: *OrdererDefaults
            Organizations:
                - *OrdererOrg
        Consortiums:
            SampleConsortium:
                Organizations:
                    - *Org1
                    - *Org2
    TwoOrgsChannel:
        Consortium: SampleConsortium
        Application:
            <<: *ApplicationDefaults
            Organizations:
                - *Org1
                - *Org2
Organizations:
    - &OrdererOrg
        Name: OrdererOrg
        ID: OrdererMSP
        MSPDir: crypto-config/ordererOrganizations/example.com/msp
    - &Org1
        Name: Org1MSP
        ID: Org1MSP
        MSPDir: crypto-config/peerOrganizations/org1.example.com/msp
        AnchorPeers:
            - Host: peer0.org1.example.com
              Port: 7051
    - &Org2
        Name: Org2MSP
        ID: Org2MSP
        MSPDir: crypto-config/peerOrganizations/org2.example.com/msp
        AnchorPeers:
            - Host: peer0.org2.example.com
              Port: 7051
Orderer: &OrdererDefaults
    OrdererType: solo
    Addresses:
        - orderer.example.com:7050
    BatchTimeout: 2s
    BatchSize:
        MaxMessageCount: 10
        AbsoluteMaxBytes: 98 MB
        PreferredMaxBytes: 512 KB
    Kafka:
        Brokers:
            - 127.0.0.1:9092
    Organizations:
Application: &ApplicationDefaults
    Organizations:

执行命令,生成创始块和频道认证文件:

mkdir channel-artifacts

configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block

configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/mychannel.tx -channelID mychannel

目录结构:

├── chaincode
│   └── go
├── channel-artifacts
│   ├── genesis.block
│   └── mychannel.tx
├── configtx.yaml
├── crypto-config
│   ├── ordererOrganizations
│   └── peerOrganizations
└── crypto-config.yaml

(2)写orderer配置文件 启动

编写 docker-orderer.yaml,内容:

version: '2'
services:
  orderer.example.com:
    container_name: orderer.example.com
    image: hyperledger/fabric-orderer
    environment:
      - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fabrictest_default
      - ORDERER_GENERAL_LOGLEVEL=debug
      - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
      - ORDERER_GENERAL_LISTENPORT=7050
      - ORDERER_GENERAL_GENESISMETHOD=file
      - ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
      - ORDERER_GENERAL_LOCALMSPID=OrdererMSP
      - ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
      - ORDERER_GENERAL_TLS_ENABLED=false
      - 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
    networks:
      default:
        aliases:
          - aberic
    ports:
      - 7050:7050

启动:

docker-compose -f docker-orderer.yaml up -d

检查:

docker ps --format 'table {{.Names}}\t{{.Ports}}\t{{.Status}}'
NAMES                 PORTS                    STATUS
orderer.example.com   0.0.0.0:7050->7050/tcp   Up 57 seconds

(3)写org1的peer配置文件 启动

编写 docker-peer01.yaml,内容:

version: '2'
services:
  couchdb:
    container_name: couchdb
    image: hyperledger/fabric-couchdb
    ports:
      - "5984:5984"
  ca:
    container_name: ca
    image: hyperledger/fabric-ca
    environment:
      - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
      - FABRIC_CA_SERVER_CA_NAME=ca
      - FABRIC_CA_SERVER_TLS_ENABLED=false
      - FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem
      - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/ab7dca5e5f6b1cc24c2023764c5b34d1f78d8614d2a11e74178d2d5509bd3be8_sk
    ports:
      - "7054:7054"
    command: sh -c 'fabric-ca-server start --ca.certfile /etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem --ca.keyfile /etc/hyperledger/fabric-ca-server-config/ab7dca5e5f6b1cc24c2023764c5b34d1f78d8614d2a11e74178d2d5509bd3be8_sk -b admin:adminpw -d'
    volumes:
      - ./crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config

  peer0.org1.example.com:
    container_name: peer0.org1.example.com
    image: hyperledger/fabric-peer
    environment:
      - CORE_LEDGER_STATE_STATEDATABASE=CouchDB
      - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb:5984

      - CORE_PEER_ID=peer0.org1.example.com
      - CORE_PEER_NETWORKID=fabrictest
      - 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

      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fabrictest
      - CORE_LOGGING_LEVEL=DEBUG
      - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fabrictest_default
      - CORE_PEER_GOSSIP_SKIPHANDSHAKE=true
      - CORE_PEER_GOSSIP_USELEADERELECTION=true
      - CORE_PEER_GOSSIP_ORGLEADER=false
      - CORE_PEER_PROFILE_ENABLED=false
      - CORE_PEER_TLS_ENABLED=false
      - CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
      - CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
      - CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
    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
    working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
    command: peer node start
    ports:
      - 7051:7051
      - 7052:7052
      - 7053:7053
    depends_on:
      - couchdb
    networks:
      default:
        aliases:
          - fabrictest

  cli:
    container_name: cli
    image: hyperledger/fabric-tools
    tty: true
    environment:
      - GOPATH=/opt/gopath
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      - CORE_LOGGING_LEVEL=DEBUG
      - CORE_PEER_ID=cli
      - CORE_PEER_ADDRESS=peer0.org1.example.com:7051
      - CORE_PEER_LOCALMSPID=Org1MSP
      - CORE_PEER_TLS_ENABLED=false
      - CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt
      - CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key
      - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
      - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
    working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
    volumes:
        - /var/run/:/host/var/run/
        - ./chaincode/go/:/opt/gopath/src/github.com/hyperledger/fabric/fabrictest/chaincode/go
        - ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
        - ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
    depends_on:
      - peer0.org1.example.com

注意,ca 服务中在 fabric-ca-server-config 后面有一个很长的文件名,以 _sk 结尾,这个需要根据自己的情况修改,到自己的 crypto-config/peerOrganizations/org1.example.com/ca/ 文件夹下查看实际的文件名,修改上面的配置文件,共有两处。

启动:

docker-compose -f docker-peer01.yaml up -d

检查:

docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}'
NAMES                    IMAGE                        STATUS
cli                      hyperledger/fabric-tools     Up About a minute
peer0.org1.example.com   hyperledger/fabric-peer      Up About a minute
couchdb                  hyperledger/fabric-couchdb   Up About a minute
ca                       hyperledger/fabric-ca        Up About a minute
orderer.example.com      hyperledger/fabric-orderer   Up 12 minutes

(4)安装执行 chaincode

进入 cli 容器:

docker exec -it cli bash

容器内执行命令:

# 创建channel
peer channel create -o orderer.example.com:7050 -c mychannel -t 50 -f ./channel-artifacts/mychannel.tx
# 加入channel
peer channel join -b mychannel.block
# 安装 chaincode
peer chaincode install -n mychannel -p github.com/hyperledger/fabric/fabrictest/chaincode/go/chaincode_example02 -v 1.0
# 实例化
peer chaincode instantiate -o orderer.example.com:7050 -C mychannel -n mychannel -c '{"Args":["init","A","10","B","10"]}' -P "OR ('Org1MSP.member','Org2MSP.member')" -v 1.0
# 查询
peer chaincode query -C mychannel -n mychannel -c '{"Args":["query", "A"]}'
# 结果为 Query Result: 10

peer chaincode query -C mychannel -n mychannel -c '{"Args":["query", "B"]}'
# 转移资产
peer chaincode invoke -C mychannel -n mychannel -c '{"Args":["invoke", "A", "B", "1"]}'

# 查询验证
peer chaincode query -C mychannel -n mychannel -c '{"Args":["query", "A"]}'
# 结果为 Query Result: 9

(5)写org2的peer配置文件 启动 执行chaincode

编写 docker-peer02.yaml,内容:

version: '2'
services:
  peer0.org2.example.com:
    container_name: peer0.org2.example.com
    image: hyperledger/fabric-peer
    environment:
      - CORE_PEER_ID=peer0.org2.example.com
      - CORE_PEER_NETWORKID=fabrictest
      - CORE_PEER_ADDRESS=peer0.org2.example.com:7051
      - CORE_PEER_CHAINCODELISTENADDRESS=peer0.org2.example.com:7052
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:7051
      - CORE_PEER_LOCALMSPID=Org2MSP

      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fabrictest
      - CORE_LOGGING_LEVEL=DEBUG
      - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fabrictest_default
      - CORE_PEER_GOSSIP_SKIPHANDSHAKE=true
      - CORE_PEER_GOSSIP_USELEADERELECTION=true
      - CORE_PEER_GOSSIP_ORGLEADER=false
      - CORE_PEER_PROFILE_ENABLED=false
      - CORE_PEER_TLS_ENABLED=false
      - CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
      - CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
      - CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
    volumes:
        - /var/run/:/host/var/run/
        - ./crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/msp:/etc/hyperledger/fabric/msp
        - ./crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls:/etc/hyperledger/fabric/tls
    working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
    command: peer node start
    ports:
      - 8051:7051
      - 8052:7052
      - 8053:7053
    networks:
      default:
        aliases:
          - fabrictest

启动:

docker-compose -f docker-peer02.yaml up -d

检查:

docker ps --format 'table {{.Names}}\t{{.Ports}}'
NAMES                                             PORTS
peer0.org2.example.com                            0.0.0.0:8051->7051/tcp, 0.0.0.0:8052->7052/tcp, 0.0.0.0:8053->7053/tcp
fabrictest-peer0.org1.example.com-mychannel-1.0
cli
peer0.org1.example.com                            0.0.0.0:7051-7053->7051-7053/tcp
couchdb                                           4369/tcp, 9100/tcp, 0.0.0.0:5984->5984/tcp
ca                                                0.0.0.0:7054->7054/tcp
orderer.example.com                               0.0.0.0:7050->7050/tcp

加入 channel :

docker exec \
-e "CORE_PEER_ID=peer0.org2.example.com" \
-e "CORE_PEER_ADDRESS=peer0.org2.example.com:7051" \
-e "CORE_PEER_CHAINCODELISTENADDRESS=peer0.org2.example.com:7052" \
-e "CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:7051" \
-e "CORE_PEER_LOCALMSPID=Org2MSP" \
-e "CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" \
-e "CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp" \
cli \
peer channel join -b mychannel.block

此命令中设置了多个环境变量,这是因为 cli 容器是属于 peer01 的,为了让其变为 peer02 就需要通过修改环境变量来实现。

安装chain code:

docker exec \
-e "CORE_PEER_ID=peer0.org2.example.com" \
-e "CORE_PEER_ADDRESS=peer0.org2.example.com:7051" \
-e "CORE_PEER_CHAINCODELISTENADDRESS=peer0.org2.example.com:7052" \
-e "CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:7051" \
-e "CORE_PEER_LOCALMSPID=Org2MSP" \
-e "CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" \
-e "CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp" \
cli \
peer chaincode install -n mychannel -p github.com/hyperledger/fabric/fabrictest/chaincode/go/chaincode_example02 -v 1.0

查询测试:

docker exec \
-e "CORE_PEER_ID=peer0.org2.example.com" \
-e "CORE_PEER_ADDRESS=peer0.org2.example.com:7051" \
-e "CORE_PEER_CHAINCODELISTENADDRESS=peer0.org2.example.com:7052" \
-e "CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:7051" \
-e "CORE_PEER_LOCALMSPID=Org2MSP" \
-e "CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" \
-e "CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp" \
cli \
peer chaincode query -C mychannel -n mychannel -c '{"Args":["query", "A"]}'

查询结果:

Query Result: 9

和第一个peer中一致。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,558评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,002评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,024评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,144评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,255评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,295评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,068评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,478评论 1 305
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,789评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,965评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,649评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,267评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,982评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,800评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,847评论 2 351