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: ''

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:
- 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  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..." hours ago Up hours dev-peer0.org1.example.com-mycc-1.0
4a29b3322e06 dev-peer0.org2.example.com-mycc-1.0-15b571b3ce849066b7ec74497da3b27e54e0df1345daff3951b94245ce09c42b "chaincode -peer.a..." hours ago Up hours dev-peer0.org2.example.com-mycc-1.0
380421da2c99 hyperledger/fabric-tools "/bin/bash -c './s..." hours ago Up hours cli
98e1cb275d00 hyperledger/fabric-peer "peer node start" hours ago Up hours 0.0.0.0:->/tcp, 0.0.0.0:->/tcp, 0.0.0.0:->/tcp peer0.org2.example.com
f17f8c1dfd7d hyperledger/fabric-peer "peer node start" hours ago Up hours 0.0.0.0:->/tcp, 0.0.0.0:->/tcp, 0.0.0.0:->/tcp peer1.org2.example.com
7f1fbc2539f1 hyperledger/fabric-peer "peer node start" hours ago Up hours 0.0.0.0:->/tcp, 0.0.0.0:->/tcp, 0.0.0.0:->/tcp peer1.org1.example.com
44edc4b5557b hyperledger/fabric-peer "peer node start" hours ago Up hours 0.0.0.0:-->-/tcp peer0.org1.example.com
f0f688da1e7e hyperledger/fabric-couchdb "tini -- /docker-e..." hours ago Up hours /tcp, /tcp, 0.0.0.0:->/tcp couchdb1
48030f9de76c hyperledger/fabric-couchdb "tini -- /docker-e..." hours ago Up hours /tcp, /tcp, 0.0.0.0:->/tcp couchdb0
46acc883badc hyperledger/fabric-ca "sh -c 'fabric-ca-..." hours ago Up hours 0.0.0.0:->/tcp ca_peerOrg2
e67e62547da0 hyperledger/fabric-ca "sh -c 'fabric-ca-..." hours ago Up hours 0.0.0.0:->/tcp ca_peerOrg1
92b9a19e7a4b hyperledger/fabric-orderer "orderer" hours ago Up hours 0.0.0.0:->/tcp orderer.example.com
005c18e53da3 hyperledger/fabric-couchdb "tini -- /docker-e..." hours ago Up hours /tcp, /tcp, 0.0.0.0:->/tcp couchdb2
ecb4de206d3e hyperledger/fabric-couchdb "tini -- /docker-e..." hours ago Up hours /tcp, /tcp, 0.0.0.0:->/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:  --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 == - {
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

hyperledger fabric 1.0.5 分布式部署 (七)的更多相关文章

  1. hyperledger fabric 1.0.5 分布式部署 (八)

    gdb debug peer 程序 在开始我们从 github 上download 下来的源码包,实际上已经包含了可执行的 peer 程序,但是该程序是使用 release 方式编译的,并不支持gdb ...

  2. hyperledger fabric 1.0.5 分布式部署 (六)

    如何在相同的peer 节点上创建多个 channel 作者在hyperledger fabric 1.0.5 分布式部署 (五)已经向读者们介绍了一个简单的fabric 的部署流程,那么根据上一篇博客 ...

  3. hyperledger fabric 1.0.5 分布式部署 (五)

    梳理fabric e2e_cli 测试程序的具体步骤 作者在 hyperledger fabric 1.0.5 分布式部署 (一)中给读者们介绍了如何从零开始部署一个测试的 demo 环境,如果细心的 ...

  4. hyperledger fabric 1.0.5 分布式部署 (四)

    chaincode 的开发 作者在hyperledger fabric 1.0.5 分布式部署 (三)中向读者介绍了如何开发fabric 的chaincode,那么实际上chaincode 还有其他的 ...

  5. hyperledger fabric 1.0.5 分布式部署 (二)

    环境:2台 ubuntu 16.04 角色列表 角色 IP地址 宿主端口 docker端口  peer0.org1.example.com  47.93.249.250  7051  7051  pe ...

  6. hyperledger fabric 1.0.5 分布式部署 (三)

    本篇博客主要是向读者介绍 fabric 在部署时的一些细节,还有作者自己学习过程中的心得. 初始化相关密钥的程序,实际上是一个shell脚本,并且结构特别简单 generateArtifacts.sh ...

  7. hyperledger fabric 1.0.5 分布式部署 (一)

    环境是个人虚拟机ubuntu 16.04 64 位版本 前期用户需要先安装好:gcc.g++.git 软件 安装 golang 首先给环境安装一个 go 语言环境,版本最好在1.8 以上 golang ...

  8. hyperledger fabric 1.0.5 分布式部署 (九)

    linux 使用vim.ctags 配置fabric 源码阅读环境 首先需要安装 ctags,作者使用apt-get 来安装的,安装的版本是5.9 apt-get install ctags 5.9 ...

  9. Hyperledger Fabric 1.0 从零开始(十三)——orderer分布式方案

    简述 在搭建HyperLedger Fabric环境的过程中,我们会用到一个configtx.yaml文件(可参考Hyperledger Fabric 1.0 从零开始(八)——Fabric多节点集群 ...

随机推荐

  1. EasyDarwin开源平台直播架构

    Created with Raphaël 2.1.0ClientClientEasyCMSEasyCMSEasyCameraEasyCameraEasyDarwinEasyDarwin请求设备列表设备 ...

  2. java关于数组之间的相互赋值

    java中数组是被当作对象看待,假设a,b为两个已经初始化的数组,那么语句a=b就表示把b数组对象的引用赋值给a,那么a和b就指向了同一个数组,无论用哪个来操作都影响其指向的数组.原来a指向的数组现在 ...

  3. java内部类和静态内部类的区别

    1 相同点 使用的时候,import的时候,除了包名,还要带外部类. 2 不同点 2.1 对象创建的方式不同 静态内部类创建对象的时候,独立于外部类及其对象,就好像它是一个独立的类,可以和外部类一样使 ...

  4. Embed image in a <button> element 微信小程序 客服按钮

    html - Embed image in a <button> element - Stack Overflow https://stackoverflow.com/questions/ ...

  5. 在VC++空工程中使用MFC类,采用Unicode字符集后,运行工程程序报错的解决方案

    创建一个VC++空工程,将Project Properties->General->Use of MFC改为Use MFC in a Shared DLL 新建一个源文件,内容如下 #in ...

  6. Understand .sync in Vue

    Preface The first time I met .sync modifier, I didn't know it very well. So, I seldom use that. Toda ...

  7. jzyz集训 0228

    早上考了一波. 出题人是wangyurzee王队长,题目亲民,数据很水(除了第二题).用来做比赛很不错.(尽管我只有第一题A了). 第一题大意是给你n个操作,每个操作是将你手上的数字区间集合与给出的区 ...

  8. 在 Linux 上如何清除内存的 Cache、Buffer 和交换空间

    原文链接:http://www.linuxidc.com/Linux/2015-06/118856.htm 像任何其他的操作系统一样,GNU/Linux 已经实现的内存管理不仅有效,而且更好.但是,如 ...

  9. Good Bye 2015 B. New Year and Old Property —— dfs 数学

    题目链接:http://codeforces.com/problemset/problem/611/B B. New Year and Old Property time limit per test ...

  10. 关于Linux启动文件rc.local的解惑

    背景 首先,rc.local是Linux启动程序在login程序前执行的最后一个脚本,有的服务器中在rc.local中可能会有一句touch /var/lock/subsys/local,这是干什么的 ...