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. java关于数组之间的相互赋值

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

  2. 九度OJ 1091:棋盘游戏 (DP、BFS、DFS、剪枝)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1497 解决:406 题目描述: 有一个6*6的棋盘,每个棋盘上都有一个数值,现在又一个起始位置和终止位置,请找出一个从起始位置到终止位置代 ...

  3. mybatis入门(八)

    mybatis入门---更新和删除 <!-- 删除用户 --> <delete id="deleteUser" parameterType="java. ...

  4. php date之间的相互转换

    字符串转成date $str =date("Y-m-d H:i:s",strtotime("2011-12-12 14:23:01")); echo $str; ...

  5. 【Effective C++】设计与声明

    条款18:让接口容易被正确使用,不易被误用 1,好的接口很容易被正确使用,不容易被误用.你应该在你的所有接口中努力达成这些性质. 2,“促进正使用”的办法包括接口的一致性,以及与内置类型的行为兼容. ...

  6. GCD 开启一个定时器实现倒计时功能

    UIAlertView * alt = [[UIAlertView alloc] initWithTitle:@"提示" message:@"操作成功,马上返回继续体验吧 ...

  7. Android Weekly Notes Issue #240

    Android Weekly Issue #240 January 15th, 2017 Android Weekly Issue #240 Hello, 各位亲, 从本篇笔记开始, 以后并不包含An ...

  8. Educational Codeforces Round 2 C. Make Palindrome —— 贪心 + 回文串

    题目链接:http://codeforces.com/contest/600/problem/C C. Make Palindrome time limit per test 2 seconds me ...

  9. springmvc junit测试

    import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.ann ...

  10. linux下mycat读写分离的配置

    为什么要配置读写分离,我想我就不需要再赘述了,那么在mycat下如何进行读写分离的配置,配置之后的实际效率又如何呢?我上午根据文档捣鼓和测试了一下,这里做一下记录: 最开始,我们还是要配置mysql本 ...