hyperledger fabric 1.0.5 分布式部署 (七)


fabric 使用 fabric-ca 服務

 

  • 准備部分

首先需要用戶從github上download fabric-ca 的工程代碼

cd $GOPATH/src/github.com/hyperledger
git clone https://github.com/hyperledger/fabric-ca.git

然后對它進行編譯,在編譯時,會需要安裝 goimports 命令,貌似目前關於golang的相關內容都被“東方神秘力量”所限制,請讀者們自行科學上網。

cd fabric-ca
make

在編譯過程中,可能會在test 部分遇到錯誤,但是沒有關系,因為用不到,我們只需要將 fabric-ca-client 編譯出來即可。

  • 部署環境

讓我們還是以e2e_cli 做例子給大家介紹如何部署ca以及使用它來創建用戶。

在啟動fabric 服務的 network_setup.sh 腳本中,默認是使用 docker-compose-cli.yaml 配置文件啟動 docker 鏡像的,將 COMPOSE_FILE 變量修改為使用 docker-compose-e2e.yaml 配置文件啟動docker 鏡像

#COMPOSE_FILE=docker-compose-cli.yaml
COMPOSE_FILE_COUCH=docker-compose-couch.yaml
COMPOSE_FILE=docker-compose-e2e.yaml

在 hyperledger fabric 1.0.5 分布式部署 (五)介紹的 generateArtifacts.sh 腳本,在其 replacePrivateKey 函數中,會將 docker-compose-e2e-template.yaml 配置文件拷貝一個名叫 docker-compose-e2e.yaml 的文件,並且將 cryptogen 生成的相關私鑰和證書信息替換 docker-compose-e2e.yaml 其中的內容。

所以我們還需要將 docker-compose-e2e-template.yaml 配置進行修改,修改后內容如下

version: '2'

services:
  ca0:
    image: hyperledger/fabric-ca
    environment:
      - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
      - FABRIC_CA_SERVER_CA_NAME=ca-org1
      - 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/CA1_PRIVATE_KEY
    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/CA1_PRIVATE_KEY -b admin:adminpw -d'
    volumes:
      - ./crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config
    container_name: ca_peerOrg1

  ca1:
    image: hyperledger/fabric-ca
    environment:
      - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
      - FABRIC_CA_SERVER_CA_NAME=ca-org2
      - FABRIC_CA_SERVER_TLS_ENABLED=false
      - FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org2.example.com-cert.pem
      - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/CA2_PRIVATE_KEY
    ports:
      - "8054:7054"
    command: sh -c 'fabric-ca-server start --ca.certfile /etc/hyperledger/fabric-ca-server-config/ca.org2.example.com-cert.pem --ca.keyfile /etc/hyperledger/fabric-ca-server-config/CA2_PRIVATE_KEY -b admin:adminpw -d'
    volumes:
      - ./crypto-config/peerOrganizations/org2.example.com/ca/:/etc/hyperledger/fabric-ca-server-config
    container_name: ca_peerOrg2

  orderer.example.com:
    extends:
      file:   base/docker-compose-base.yaml
      service: orderer.example.com
    container_name: orderer.example.com

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

  peer1.org1.example.com:
    container_name: peer1.org1.example.com
    extends:
      file:  base/docker-compose-base.yaml
      service: 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

  peer1.org2.example.com:
    container_name: peer1.org2.example.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer1.org2.example.com

  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=true
      - 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
    command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME}; sleep $TIMEOUT'
    volumes:
        - /var/run/:/host/var/run/
        - ../chaincode/go/:/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go
        - ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
        - ./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/
        - ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
    depends_on:
      - orderer.example.com
      - peer0.org1.example.com
      - peer1.org1.example.com
      - peer0.org2.example.com
      - peer1.org2.example.com

 ca0 和 ca1 兩個鏡像的環境變量 FABRIC_CA_SERVER_TLS_ENABLED 必須要設置為 false ,否則后續連接ca server 時會報錯以下錯誤

Error: POST failure [Post http://localhost:7054/enroll: malformed HTTP response "\x15\x03\x01\x00\x02\x02\x16"]; not sending
POST http://localhost:7054/enroll

用戶可以像以前沒有ca 服務一樣,通過 network_setup.sh 腳本啟動整個 fabric 服務

./network_setup.sh up mychannel 10000 couchdb ;

然后查看一下docker 鏡像起來了哪些 docker ps

CONTAINER ID        IMAGE                                                                                                  COMMAND                  CREATED             STATUS              PORTS                                                                       NAMES
7da99a56c176        dev-peer0.org1.example.com-mycc-1.0-384f11f484b9302df90b453200cfb25174305fce8f53f4e94d45ee3b6cab0ce9   "chaincode -peer.a..."   2 hours ago         Up 2 hours                                                                                      dev-peer0.org1.example.com-mycc-1.0
4a29b3322e06        dev-peer0.org2.example.com-mycc-1.0-15b571b3ce849066b7ec74497da3b27e54e0df1345daff3951b94245ce09c42b   "chaincode -peer.a..."   2 hours ago         Up 2 hours                                                                                      dev-peer0.org2.example.com-mycc-1.0
380421da2c99        hyperledger/fabric-tools                                                                               "/bin/bash -c './s..."   2 hours ago         Up 2 hours                                                                                      cli
98e1cb275d00        hyperledger/fabric-peer                                                                                "peer node start"        2 hours ago         Up 2 hours          0.0.0.0:9051->7051/tcp, 0.0.0.0:9052->7052/tcp, 0.0.0.0:9053->7053/tcp      peer0.org2.example.com
f17f8c1dfd7d        hyperledger/fabric-peer                                                                                "peer node start"        2 hours ago         Up 2 hours          0.0.0.0:10051->7051/tcp, 0.0.0.0:10052->7052/tcp, 0.0.0.0:10053->7053/tcp   peer1.org2.example.com
7f1fbc2539f1        hyperledger/fabric-peer                                                                                "peer node start"        2 hours ago         Up 2 hours          0.0.0.0:8051->7051/tcp, 0.0.0.0:8052->7052/tcp, 0.0.0.0:8053->7053/tcp      peer1.org1.example.com
44edc4b5557b        hyperledger/fabric-peer                                                                                "peer node start"        2 hours ago         Up 2 hours          0.0.0.0:7051-7053->7051-7053/tcp                                            peer0.org1.example.com
f0f688da1e7e        hyperledger/fabric-couchdb                                                                             "tini -- /docker-e..."   2 hours ago         Up 2 hours          4369/tcp, 9100/tcp, 0.0.0.0:6984->5984/tcp                                  couchdb1
48030f9de76c        hyperledger/fabric-couchdb                                                                             "tini -- /docker-e..."   2 hours ago         Up 2 hours          4369/tcp, 9100/tcp, 0.0.0.0:5984->5984/tcp                                  couchdb0
46acc883badc        hyperledger/fabric-ca                                                                                  "sh -c 'fabric-ca-..."   2 hours ago         Up 2 hours          0.0.0.0:8054->7054/tcp                                                      ca_peerOrg2
e67e62547da0        hyperledger/fabric-ca                                                                                  "sh -c 'fabric-ca-..."   2 hours ago         Up 2 hours          0.0.0.0:7054->7054/tcp                                                      ca_peerOrg1
92b9a19e7a4b        hyperledger/fabric-orderer                                                                             "orderer"                2 hours ago         Up 2 hours          0.0.0.0:7050->7050/tcp                                                      orderer.example.com
005c18e53da3        hyperledger/fabric-couchdb                                                                             "tini -- /docker-e..."   2 hours ago         Up 2 hours          4369/tcp, 9100/tcp, 0.0.0.0:7984->5984/tcp                                  couchdb2
ecb4de206d3e        hyperledger/fabric-couchdb                                                                             "tini -- /docker-e..."   2 hours ago         Up 2 hours          4369/tcp, 9100/tcp, 0.0.0.0:8984->5984/tcp                                  couchdb3

用戶可以看到分別啟動了兩個 ca server 服務,並且分別對應 Org1MSP 、 Org2MSP 兩個機構。

讓我們重寫切換一下路徑,並且設置一下環境變量,讓后續生成的相關文件落在該目錄

cd /opt/gopath/src/github.com/hyperledger/fabric-ca/bin
mkdir -p /root/ca
export FABRIC_CA_CLIENT_HOME=/root/ca

然后使用 fabric-ca-client 去連接 ca server。

注意 admin:adminpw 代表的是ca server 的管理員用戶名和密碼,7054 端口對應的是配置了 Org1MSP 的ca server,8054 端口則是配置了 Org2MSP 的ca server。

執行以下命令后,將會在 /root/ca 目錄上主動創建 fabric-ca-client-config.yaml 文件和 msp 目錄

./fabric-ca-client enroll -u http://admin:adminpw@localhost:7054

向ca server 注冊一個新的用戶,名字叫 test, 密碼為 test123

./fabric-ca-client register --id.name test --id.type user --id.affiliation org1.department1 --id.attrs 'hf.Revoker=true,foo=bar' --id.secret 'test123'

然后生成 test 用戶的相關私鑰和證書

./fabric-ca-client enroll -u http://test:test123@localhost:7054 -M $FABRIC_CA_CLIENT_HOME/testmsp --tls.certfiles "/opt/gopath/src/github.com/hyperledger/fabric/examples/e2e_cli/crypto-config/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem"

為了后續使用,我們還要再做一些輔助動作

mkdir /root/ca/testmsp/admincerts
cp /root/ca/testmsp/signcerts/cert.pem /root/ca/testmsp/admincerts/

 

  • 是原生的用戶查詢數據

在之前的博客中,作者向讀者演示如何查詢fabric 中的數據,都是通過docker-compose 啟動一個臨時的cli 鏡像來執行peer 命令,那么按照客戶端和服務端的連接關系,peer 命令應該在任何機器上執行都是可行的。

在作者查閱了相關的配置文件和腳本后,整理出以下關鍵環境變量,主要是設計該客戶端在連接 peer 節點時,應該采用哪些證書和私鑰進行加密通訊。

以下命令將設置client 連接 peer0.org1.example.com:7051 服務,並且使用 peer0.org1.example.com 節點的私鑰和證書。

export CORE_PEER_TLS_ROOTCERT_FILE="/opt/gopath/src/github.com/hyperledger/fabric/examples/e2e_cli/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" ; \
export CORE_PEER_LOCALMSPID="Org1MSP" ; \
export CORE_PEER_TLS_ENABLED=true ; \
export CORE_PEER_MSPCONFIGPATH="/opt/gopath/src/github.com/hyperledger/fabric/examples/e2e_cli/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp" ; \
export CORE_PEER_ADDRESS="peer0.org1.example.com:7051" ;
# CORE_PEER_TLS_KEY_FILE 變量貌似用不上
# export CORE_PEER_TLS_KEY_FILE="/opt/gopath/src/github.com/hyperledger/fabric/examples/e2e_cli/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key" ; \

 

 

宿主的peer 可執行程序在 /opt/gopath/src/github.com/hyperledger/fabric/release/linux-amd64/bin 目錄,切換到該目錄后執行

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

 

  • 使用新創建的test 用戶進行測試

 如果用戶希望使用剛才 fabric-ca-client 命令創建的test 用戶,則只需要修改 CORE_PEER_MSPCONFIGPATH 環境變量即可

export CORE_PEER_MSPCONFIGPATH="/root/ca/testmsp" ;

再次使用peer 執行查詢命令,查詢正常。

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

 同理,如果需要peer 執行 invoke 命令,則像過去一樣執行就ok 了

./peer chaincode invoke -o orderer.example.com:7050  --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/examples/e2e_cli/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem  -C mychannel -n mycc -c '{"Args":["invoke","a","b","20"]}'
  • 權限思考

不知道讀者在看到這里時,是否有反思過,fabric 區塊鏈是如何做到讀、寫權限分開的。

在環境變量設置上,是使用了peer 節點的私鑰和證書,此時peer 的命令可以直接從區塊鏈中讀取數據。

而在執行 invoke 命令時,則需要加上 --tls 和 --cafile 參數,並且還需要指定 orderer 的私鑰。

所以按照作者的理解,fabric 區塊鏈的數據寫入,必須要同時擁有 orderer 的私鑰和 peer 節點的私鑰、證書,而讀取,則只要擁有peer 節點的私鑰和證書即可。

  •  在chaincode 中獲取用戶的名字

根據 http://www.cnblogs.com/studyzy/p/7482451.html 博客的介紹,我們可以編寫一段測試的chaincode 來獲得執行peer 命令的用戶名

chaincode 代碼

package main

import (
   "github.com/hyperledger/fabric/core/chaincode/shim"
   pb "github.com/hyperledger/fabric/protos/peer"
   "fmt"
   "encoding/pem"
   "crypto/x509"
   "bytes"
)

type SimpleChaincode struct {
}

func main() {
   err := shim.Start(new(SimpleChaincode))
   if err != nil {
      fmt.Printf("Error starting Simple chaincode: %s", err)
   }
}
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
   return shim.Success(nil)
}


func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
   function, args := stub.GetFunctionAndParameters()
   fmt.Println("invoke is running " + function)
   if function == "cert" {//自定義函數名稱
      return t.testCertificate(stub, args)//定義調用的函數
   }
   return shim.Error("Received unknown function invocation")
}
func (t *SimpleChaincode) testCertificate(stub shim.ChaincodeStubInterface, args []string) pb.Response{
   creatorByte,_:= stub.GetCreator()
   certStart := bytes.IndexAny(creatorByte, "-----")// Devin:I don't know why sometimes -----BEGIN is invalid, so I use -----
   if certStart == -1 {
      fmt.Errorf("No certificate found")
   }
   certText := creatorByte[certStart:]
   bl, _ := pem.Decode(certText)
   if bl == nil {
      fmt.Errorf("Could not decode the PEM structure")
   }
   fmt.Println(string(certText))
   cert, err := x509.ParseCertificate(bl.Bytes)
   if err != nil {
      fmt.Errorf("ParseCertificate failed")
   }
   fmt.Println(cert)
   uname:=cert.Subject.CommonName
   fmt.Println("Name:"+uname)
   return shim.Success([]byte("Called testCertificate "+uname))
}

如果使用原生的配置執行

./peer chaincode query -C mychannel -n mycc --logging-level CRITICAL -c '{"Args":["cert"]}'

輸出

Query Result: Called testCertificate Admin@org1.example.com

如果使用test 用戶執行,則會輸出

Query Result: Called testCertificate test

 

 

參考博客:

http://www.cnblogs.com/studyzy/p/7482451.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM