曲冰的网络启动脚本详解
环境准备
工具包
sudo apt-get install -y apt-transport-https ca-certificates software-properties-common
sudo apt-get install -y unzip git curl wget vim tree jq
gradle
cd /tmp && wget https://services.gradle.org/distributions/gradle-6.4-bin.zip
unzip gradle-6.4-bin.zip
sudo mv gradle-6.4 /usr/local/gradle
sudo cat >> ~/.bashrc <<EOF
# setup gradle environments
# =====================
export PATH=$PATH:/usr/local/gradle/bin
# =====================
EOF
source ~/.bashrc
docker
# import docker repository
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable"
# update repository index & install docker-ce
sudo apt-get update & sudo apt-get install -y docker-ce
# check docker version
docker -v
# check docker image list (only root can use docker by default)
docker images
# enable current user to use docker (!!! need to re-login via terminal !!!)
sudo gpasswd -a ${USER} docker
# check docker image list
docker images
# 这里添加的镜像需要去 docker_practice 项目中看看镜像的可用性
sudo cat >> /etc/docker/daemon.json <<EOF
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
下载 Fabric 的相关镜像
# image of ca
docker pull hyperledger/fabric-ca:1.4.6
# image of peer
docker pull hyperledger/fabric-peer:2.1.0
# image of orderer
docker pull hyperledger/fabric-orderer:2.1.0
# image of tools & utilities
docker pull hyperledger/fabric-tools:2.1.0
# image of Chaincode deployment for Programming Languages (Go | Java | Node.JS)
docker pull hyperledger/fabric-ccenv:2.1.0
docker pull hyperledger/fabric-javaenv:2.1.0
docker pull hyperledger/fabric-nodeenv:2.1.0
# image of Base-OS of Chaincode runtime
docker pull hyperledger/fabric-baseos:0.4.20
# image of coucddb (one NOSQL DB for ledger state)
docker pull hyperledger/fabric-couchdb:0.4.20
# check image list to validate downloading
docker images
docker-compose
# download
#wget https://github.com/docker/compose/releases/download/1.25.3/docker-compose-`uname -s`-`uname -m`
#wget https://get.daocloud.io/docker/compose/releases/download/1.25.3/docker-compose-`uname -s`-`uname -m`
# 自己选择来源,那个快选哪个
wget https://blockchain-files.s3.cn-northwest-1.amazonaws.com.cn/docker-compose-`uname -s`-`uname -m`
# copy to ` /usr/local/bin/ ` and rename
sudo mv docker-compose-`uname -s`-`uname -m` /usr/local/bin/docker-compose
# make executable
sudo chmod +x /usr/local/bin/docker-compose
# validate installation
docker-compose -v
编程语言 SDK
- GO
cd /tmp && wget https://dl.google.com/go/go1.13.4.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.13.4.linux-amd64.tar.gz
sudo cat >> ~/.bashrc <<EOF
# setup go environments
# =====================
export PATH=$PATH:/usr/local/go/bin
export GOPATH=$HOME/gopath
export GO111MODULE=on
export GOPROXY=https://goproxy.cn
# =====================
EOF
source ~/.bashrc
go version
- Java
# install Java
sudo apt-get update
sudo apt-get install -y openjdk-8-jdk
java -version
- node.js
# install `nvm`
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
# validate installation of `nvm`
nvm --version
# install Node.JS version 10
nvm install 10
# check the version of Node.JS and NPM
node -v
npm -v
下载曲冰脚本的工作环境
git clone https://gitlab.com/qubing/blockchain_lab_v2.git ~/workspace
搭建网络
这部执行了四个脚本:
./setup.sh:用于下载 Fabric 和 Fabric CA 二进制文件以及网络相关的组件镜像,比如 Peer , Orderer , baseos 等等. ./init.sh:这个脚本用于初始化网络;- 把三个 CA 服务的的目标挂载路径先配置好,把 CA 的配置文件先放到对应的位置;
- 注册 Peer 和 Orderer 节点到 CA 上;
- 创建创世区块;
- 启动 Peer 和 Orderer 节点;
- 创建并将节点加入到通道中;
- 生成连接的配置文件;
. script/deploy_chaincode.sh:通过链码的生命周期管理机制,将链码安装到链上;. scripts/test_example.sh:通过 CLI 调用链码,测试链码返回结果;
. ./setup.sh
#!/bin/bash
WORK_PATH=$PWD
export FABRIC_VERSION=2.3.0
export CA_VERSION=1.4.9
export DB_VERSION=3.1.1
DOCKER_NS=hyperledger
if [[ "$1" == "docker" ]]; then
echo "Pulling Docker Images"
# Fabric-CA image
echo "Pulling ${DOCKER_NS}/fabric-ca:${CA_VERSION}"
docker pull ${DOCKER_NS}/fabric-ca:${CA_VERSION}
# Fabric images
# peer
# orderer
# tools
# ccenv, javaenv, nodeenv (可选)
# baseos
FABRIC_IMAGES=(fabric-peer fabric-orderer fabric-tools fabric-ccenv fabric-javaenv fabric-nodeenv fabric-baseos)
for image in ${FABRIC_IMAGES[@]}; do
echo "Pulling ${DOCKER_NS}/$image:${FABRIC_VERSION}"
docker pull ${DOCKER_NS}/$image:${FABRIC_VERSION}
done
# Other images
# couchdb image
docker pull couchdb:${DB_VERSION}
else
echo "ignored."
fi
# 所在系统的架构
ARCH=$(echo "$(uname -s|tr '[:upper:]' '[:lower:]'|sed 's/mingw64_nt.*/windows/')-$(uname -m | sed 's/x86_64/amd64/g')")
# Fabric Source Code
echo "Download Fabric Bianries"
cd ${WORK_PATH}/fabric-bin
FILE_NAME=hyperledger-fabric-${ARCH}-${FABRIC_VERSION}.tar.gz
if [ ! -f "${FILE_NAME}" ]; then
echo "downloading fabric binaries (${FILE_NAME})..."
wget https://github.com/hyperledger/fabric/releases/download/v${FABRIC_VERSION}/${FILE_NAME}
else
echo "fabric binaries existing (${FABRIC_VERSION}), ignored"
fi
# Fabric CA Source Code
CA_FILE_NAME=hyperledger-fabric-ca-${ARCH}-${CA_VERSION}.tar.gz
if [ ! -f $CA_FILE_NAME ]; then
echo "downloading fabric-ca binaries (${CA_FILE_NAME})..."
wget https://github.com/hyperledger/fabric-ca/releases/download/v${CA_VERSION}/${CA_FILE_NAME}
else
echo "fabric-ca binaries existing (${CA_VERSION}), ignored"
fi
# 移除旧的目录
if [ -d "${FABRIC_VERSION}" ]; then
rm -rf ./${FABRIC_VERSION}
fi
# 新建新的目录
mkdir -p ./${FABRIC_VERSION}
cd ./${FABRIC_VERSION}
# 解压下载的源码放到对应的目录下
tar zxf ../${FILE_NAME}
tar zxf ../${CA_FILE_NAME}
# 把 fabric 的组件命令放到 /usr/local/bin/
sudo cp ${WORK_PATH}/fabric-bin/${FABRIC_VERSION}/bin/* /usr/local/bin/
cd $WORK_PATH
echo
. ./init.sh
初始化目录结构
原本 ~/workspace/organizations/ 目录结构如下:
workspace/organizations/
├── ccp-generate.sh
├── ccp-template.json
├── ccp-template.yaml
└── fabric-ca
├── ca.orderer.example.com.yaml
├── ca.org1.example.com.yaml
├── ca.org2.example.com.yaml
└── registerEnroll.sh
要转换成:
workspace/organizations/
├── ccp-generate.sh
├── ccp-template.json
├── ccp-template.yaml
└── fabric-ca
├── ca.orderer.example.com.yaml
├── ca.org1.example.com.yaml
├── ca.org2.example.com.yaml
├── ordererOrg
│ └── fabric-ca-server-config.yaml
├── org1
│ └── fabric-ca-server-config.yaml
├── org2
│ └── fabric-ca-server-config.yaml
└── registerEnroll.sh
其中的 ordererOrg/fabric-ca-server-config.yaml 来自于 ~/workspace/organizations/fabric-ca/ca.order.example.com.yaml ,其他目录下的 fabric-ca-server-config.yaml 文件也来自于对应的文件。
新建起来的目录将作为下一步,要启动的 CA 服务容器所挂载的数据卷,其中的配置文件也是容器启动所需要的配置文件。
启动 CA 容器
CA_IMAGE_TAG=${CA_VERSION} docker-compose -f docker/docker-compose-ca.yaml up -d
docker-compose-ca.yaml 文件部分内容如下:
# docker-compose 版本
version: "2"
# 定义服务用到的网桥
networks:
ABC:
ORDERER:
ORG1:
ORG2:
# 一个服务就是一个容器
services:
# 服务名 ca_org1 ,也就是一个容器
ca_org1:
# 容器使用的镜像
image: hyperledger/fabric-ca:$CA_IMAGE_TAG
# 容器内的环境变量
environment:
- FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
- FABRIC_CA_SERVER_CA_NAME=ca-org1
- FABRIC_CA_SERVER_TLS_ENABLED=true
- FABRIC_CA_SERVER_PORT=7054
# 宿主机和容器的端口映射
ports:
- "7054:7054"
# 用于覆盖容器启动后默认执行的命令
# 这条命令做的是启动 CA Server
# -b 参数,如果 LDAP 的配置没有开启,那么就需要加上这个参数,表示需要引导一个管理员账户
# -d 参数,DEBUG 模式启动 CA Server 方便调试
command: sh -c 'fabric-ca-server start -b admin:adminpw -d'
# 容器数据卷挂载在宿主机的路径位置
# 这里的相对路径是相对 compose file 来映射的
volumes:
- ../organizations/fabric-ca/org1:/etc/hyperledger/fabric-ca-server
# 容器名
container_name: ca_org1
# 代表当前服务都在哪些网桥内通信
networks:
- ABC
- ORG1
其中的服务只包含了一个组织的 CA 容器,但另外两个类似,所以不一一解读了。
检查容器启动情况,我们看到三个容器启动了:
docker ps -a --format "{{.CreatedAt}}\t{{.Status}}\t{{.Networks}}\t{{.Names}}"
# 2021-04-03 05:26:48 +0000 UTC Up 30 hours net_ABC,net_ORG2 ca_org2
# 2021-04-03 05:26:48 +0000 UTC Up 30 hours net_ABC,net_ORG1 ca_org1
# 2021-04-03 05:26:48 +0000 UTC Up 30 hours net_ABC,net_ORDERER ca_orderer
对比三个配置文件,这三个 CA 容器不同的部分有:
###### ca.orderer.example.com.yaml
---
ca:
name: OrdererCA
---
csr:
cn: ca.example.com
names:
- C: US
ST: "New York"
L: "New York"
O: example.com
OU:
hosts:
- localhost
- example.com
---
###### ca.org1.example.com.yaml
---
ca:
name: Org2CA
---
csr:
cn: ca.org1.example.com
names:
- C: US
ST: "North Carolina"
L: "Durham"
O: org1.example.com
OU:
hosts:
- localhost
- org1.example.com
---
###### ca.org2.example.com.yaml
---
ca:
name: Org2CA
---
csr:
cn: ca.org2.example.com
names:
- C: UK
ST: "Hampshire"
L: "Hursley"
O: org2.example.com
OU:
hosts:
- localhost
- org2.example.com
这里好像没有专门启动 TLS CA ,只是启动了给网络组织提供 msp 等等认证的 ca ,让节点和用户可以登录到网络上。但是又在文件中看到了 tls 证书的存在(估计是
fabric-ca-server生成的),所以比较困惑。我猜测是因为 Peer 和 Order 这些节点都需要 TLS 证书来进行安全通信,所以在配置中 TLS 的配置是 enable 了的,但是为了测试网络的简洁,所以没有给他们配置 TLS CA 所以涉及到证书过期等等问题都没有考虑。生产网络则不允许这样设计。根据官网的建议,一般每个组织都需要两个 CA ,一个用于组织内节点的登录(为 peer 节点、管理员、通信以及代表组织的 MSP 目录结构生成登录证书),一个用于生成保护传输层安全,防止中间人攻击的 TLS 证书。
我们来看看容器生成的时候,执行的命令都生成了什么文件,以 ordererOrg 为例:
tree organizations/fabric-ca/ordererOrg/
# organizations/fabric-ca/ordererOrg/
# ├── IssuerPublicKey
# ├── IssuerRevocationPublicKey
# ├── ca-cert.pem
# ├── fabric-ca-server-config.yaml CA 服务器的配置文件
# ├── fabric-ca-server.db 用于存储用户账密的数据库
# ├── msp
# │ ├── cacerts
# │ ├── keystore 这个文件夹下面存放的是管理员的私钥
# │ │ ├── 8bc09ebe688b7db3b5ea6b6a093d9cac770daae995ddf5704daaabf71ed0212e_sk
# │ │ ├── IssuerRevocationPrivateKey
# │ │ ├── IssuerSecretKey
# │ │ └── eae356176a0695ab432782cb941f4b62ba6e59ce7ae73d9a9e5f822d04232464_sk
# │ ├── signcerts 这个文件夹是用来存放管理员证书的,由于管理员尚未到 CA 注册所以这个文件夹是空的
# │ └── user
# └── tls-cert.pem
注册 Peer 和 Orderer 节点
在 . ./init.sh 脚本中,这部分的工作是交给了 organizations/fabric-ca/registerEnroll.sh 脚本来完成的。在 registerEnroll.sh 中定义了三个函数: createOrg1() 、 createOrg2() 、 createOrderer() :
createOrg1()- Enroll the CA admin
- Register peer0
- Register user
- Register the org admin
- Generate the peer0 msp
- Generate the peer0-tls certificates
- Generate the user msp
- Generate the org admin msp
createOrg2()- Enroll the CA admin
- Register peer0
- Register user
- Register the org admin
- Generate the peer0 msp
- Generate the peer0-tls certificates
- Generate the user msp
- Generate the org admin msp
createOrderer()- Enroll the CA admin
- Register orderer
- Register the orderer admin
- Generate the orderer msp
- Generate the orderer-tls certificates
- Generate the admin msp
可见创建这三个组织的过程是差不多的:
- 登录 CA 管理员
- 注册 peer/orderer
- 注册 user (可选)
- 注册 peer/orderer 管理员
- 生成 peer/orderer 的 msp
- 生成 peer/orderer 的 tls 证书
- 生成 user 的 msp (可选)
- 生成组织管理员的 msp
下面只分析 Org1 的创建过程。
创建 org1
-
登录 CA 的管理员
mkdir -p organizations/peerOrganizations/org1.example.com/ export FABRIC_CA_CLIENT_HOME=${PWD}/organizations/peerOrganizations/org1.example.com/ fabric-ca-client enroll -u https://admin:adminpw@localhost:7054 --caname ca-org1 --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pem echo 'NodeOUs: Enable: true ClientOUIdentifier: Certificate: cacerts/localhost-7054-ca-org1.pem OrganizationalUnitIdentifier: client PeerOUIdentifier: Certificate: cacerts/localhost-7054-ca-org1.pem OrganizationalUnitIdentifier: peer AdminOUIdentifier: Certificate: cacerts/localhost-7054-ca-org1.pem OrganizationalUnitIdentifier: admin OrdererOUIdentifier: Certificate: cacerts/localhost-7054-ca-org1.pem OrganizationalUnitIdentifier: orderer' > ${PWD}/organizations/peerOrganizations/org1.example.com/msp/config.yaml以上命令执行之后应该有这样的目录结构:
organizations/peerOrganizations/ └── org1.example.com ├── fabric-ca-client-config.yaml └── msp ├── IssuerPublicKey ├── IssuerRevocationPublicKey ├── cacerts │ └── localhost-7054-ca-org1.pem ├── keystore │ └── 88613215f7f6ad9fcc0c29b131c44c66431e3e609713f42384cc622fb2988ba4_sk ├── signcerts │ └── cert.pem └── user -
注册节点 peer0
fabric-ca-client register --caname ca-org1 --id.name peer0 --id.secret peer0pw --id.type peer --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pem # 目录结构如下: # organizations/peerOrganizations # └── org1.example.com # ├── fabric-ca-client-config.yaml # └── msp # ├── IssuerPublicKey # ├── IssuerRevocationPublicKey # ├── cacerts # │ └── localhost-7054-ca-org1.pem # ├── config.yaml # ├── keystore # │ ├── 88613215f7f6ad9fcc0c29b131c44c66431e3e609713f42384cc622fb2988ba4_sk # │ └── dcbe1485ee1f7856019c33998ea46c2a591fbb7491ff8ecc8f20f31631ac4d76_sk # ├── signcerts # │ └── cert.pem # └── user -
注册用户
fabric-ca-client register --caname ca-org1 --id.name user1 --id.secret user1pw --id.type client --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pem -
注册组织管理员
fabric-ca-client register --caname ca-org1 --id.name org1admin --id.secret org1adminpw --id.type admin --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pem -
注册 peer0 的 msp
mkdir -p organizations/peerOrganizations/org1.example.com/peers mkdir -p organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com fabric-ca-client enroll \ -u https://peer0:peer0pw@localhost:7054 \ --caname ca-org1 \ -M ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp \ --csr.hosts peer0.org1.example.com \ --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pem # organizations/peerOrganizations # └── org1.example.com # ├── fabric-ca-client-config.yaml # ├── msp # │ ├── IssuerPublicKey # │ ├── IssuerRevocationPublicKey # │ ├── cacerts # │ │ └── localhost-7054-ca-org1.pem # │ ├── config.yaml # │ ├── keystore # │ │ ├── 88613215f7f6ad9fcc0c29b131c44c66431e3e609713f42384cc622fb2988ba4_sk # │ │ └── dcbe1485ee1f7856019c33998ea46c2a591fbb7491ff8ecc8f20f31631ac4d76_sk # │ ├── signcerts # │ │ └── cert.pem # │ └── user # └── peers # └── peer0.org1.example.com # └── msp # ├── IssuerPublicKey # ├── IssuerRevocationPublicKey # ├── cacerts # │ └── localhost-7054-ca-org1.pem # ├── config.yaml # ├── keystore # │ └── f45202beaef4daf7a7e528c9625076fbfc1a327a7e0a0e23b77ce1f3a797f456_sk # ├── signcerts # │ └── cert.pem # └── user -
生成 peer0 的 tls 证书
fabric-ca-client enroll \ -u https://peer0:peer0pw@localhost:7054 \ --caname ca-org1 \ -M ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls \ --enrollment.profile tls \ --csr.hosts peer0.org1.example.com \ --csr.hosts localhost \ --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pem # organizations/ # ├── ccp-generate.sh # ├── ccp-template.json # ├── ccp-template.yaml # ├── fabric-ca # │ ├── ca.orderer.example.com.yaml # │ ├── ca.org1.example.com.yaml # │ ├── ca.org2.example.com.yaml # │ ├── ordererOrg # │ │ ├── IssuerPublicKey # │ │ ├── IssuerRevocationPublicKey # │ │ ├── ca-cert.pem # │ │ ├── fabric-ca-server-config.yaml # │ │ ├── fabric-ca-server.db # │ │ ├── msp # │ │ │ ├── cacerts # │ │ │ ├── keystore # │ │ │ │ ├── 8bc09ebe688b7db3b5ea6b6a093d9cac770daae995ddf5704daaabf71ed0212e_sk # │ │ │ │ ├── IssuerRevocationPrivateKey # │ │ │ │ ├── IssuerSecretKey # │ │ │ │ └── eae356176a0695ab432782cb941f4b62ba6e59ce7ae73d9a9e5f822d04232464_sk # │ │ │ ├── signcerts # │ │ │ └── user # │ │ └── tls-cert.pem # │ ├── org1 # │ │ ├── IssuerPublicKey # │ │ ├── IssuerRevocationPublicKey # │ │ ├── ca-cert.pem # │ │ ├── fabric-ca-server-config.yaml # │ │ ├── fabric-ca-server.db # │ │ ├── msp # │ │ │ ├── cacerts # │ │ │ ├── keystore # │ │ │ │ ├── 230c741dd12acb5283c00790dce694e0e5ff449e15b48ecf356cc8dc5d063441_sk # │ │ │ │ ├── IssuerRevocationPrivateKey # │ │ │ │ ├── IssuerSecretKey # │ │ │ │ └── a30524cd7016297b0d2387597657eb2d14254bf48dadca940e6487dd7600be3f_sk # │ │ │ ├── signcerts # │ │ │ └── user # │ │ └── tls-cert.pem # │ ├── org2 # │ │ ├── IssuerPublicKey # │ │ ├── IssuerRevocationPublicKey # │ │ ├── ca-cert.pem # │ │ ├── fabric-ca-server-config.yaml # │ │ ├── fabric-ca-server.db # │ │ ├── msp # │ │ │ ├── cacerts # │ │ │ ├── keystore # │ │ │ │ ├── 30bf6cf68bb244019e0eb8953c7d3bb3e8aa5f3c2ecd53882b3ca553cbacb896_sk # │ │ │ │ ├── IssuerRevocationPrivateKey # │ │ │ │ ├── IssuerSecretKey # │ │ │ │ └── e870a0d645d963537e0cf25391ba6cfab1fc5ecdcacdd0a91db8d52375297021_sk # │ │ │ ├── signcerts # │ │ │ └── user # │ │ └── tls-cert.pem # │ └── registerEnroll.sh # └── peerOrganizations # └── org1.example.com # ├── fabric-ca-client-config.yaml # ├── msp # │ ├── IssuerPublicKey # │ ├── IssuerRevocationPublicKey # │ ├── cacerts # │ │ └── localhost-7054-ca-org1.pem # │ ├── config.yaml # │ ├── keystore # │ │ ├── 88613215f7f6ad9fcc0c29b131c44c66431e3e609713f42384cc622fb2988ba4_sk # │ │ └── dcbe1485ee1f7856019c33998ea46c2a591fbb7491ff8ecc8f20f31631ac4d76_sk # │ ├── signcerts # │ │ └── cert.pem # │ └── user # └── peers # └── peer0.org1.example.com # ├── msp # │ ├── IssuerPublicKey # │ ├── IssuerRevocationPublicKey # │ ├── cacerts # │ │ └── localhost-7054-ca-org1.pem # │ ├── config.yaml # │ ├── keystore # │ │ └── f45202beaef4daf7a7e528c9625076fbfc1a327a7e0a0e23b77ce1f3a797f456_sk # │ ├── signcerts # │ │ └── cert.pem # │ └── user # └── tls # ├── IssuerPublicKey # ├── IssuerRevocationPublicKey # ├── cacerts # ├── keystore # │ └── b482a35fe5b87742dc7f04e6530d1b8f958bd86d5e47e68bf6cbc9c2ef60b041_sk # ├── signcerts # │ └── cert.pem # ├── tlscacerts # │ └── tls-localhost-7054-ca-org1.pem # └── usercp ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/tlscacerts/* ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt cp ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/signcerts/* ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt cp ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/keystore/* ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key mkdir ${PWD}/organizations/peerOrganizations/org1.example.com/msp/tlscacerts cp ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/tlscacerts/* ${PWD}/organizations/peerOrganizations/org1.example.com/msp/tlscacerts/ca.crt mkdir ${PWD}/organizations/peerOrganizations/org1.example.com/tlsca cp ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/tlscacerts/* ${PWD}/organizations/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem mkdir ${PWD}/organizations/peerOrganizations/org1.example.com/ca cp ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp/cacerts/* ${PWD}/organizations/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem # organizations/ # ├── ccp-generate.sh # ├── ccp-template.json # ├── ccp-template.yaml # ├── fabric-ca # │ ├── ca.orderer.example.com.yaml # │ ├── ca.org1.example.com.yaml # │ ├── ca.org2.example.com.yaml # │ ├── ordererOrg # │ │ ├── IssuerPublicKey # │ │ ├── IssuerRevocationPublicKey # │ │ ├── ca-cert.pem # │ │ ├── fabric-ca-server-config.yaml # │ │ ├── fabric-ca-server.db # │ │ ├── msp # │ │ │ ├── cacerts # │ │ │ ├── keystore # │ │ │ │ ├── 8bc09ebe688b7db3b5ea6b6a093d9cac770daae995ddf5704daaabf71ed0212e_sk # │ │ │ │ ├── IssuerRevocationPrivateKey # │ │ │ │ ├── IssuerSecretKey # │ │ │ │ └── eae356176a0695ab432782cb941f4b62ba6e59ce7ae73d9a9e5f822d04232464_sk # │ │ │ ├── signcerts # │ │ │ └── user # │ │ └── tls-cert.pem # │ ├── org1 # │ │ ├── IssuerPublicKey # │ │ ├── IssuerRevocationPublicKey # │ │ ├── ca-cert.pem # │ │ ├── fabric-ca-server-config.yaml # │ │ ├── fabric-ca-server.db # │ │ ├── msp # │ │ │ ├── cacerts # │ │ │ ├── keystore # │ │ │ │ ├── 230c741dd12acb5283c00790dce694e0e5ff449e15b48ecf356cc8dc5d063441_sk # │ │ │ │ ├── IssuerRevocationPrivateKey # │ │ │ │ ├── IssuerSecretKey # │ │ │ │ └── a30524cd7016297b0d2387597657eb2d14254bf48dadca940e6487dd7600be3f_sk # │ │ │ ├── signcerts # │ │ │ └── user # │ │ └── tls-cert.pem # │ ├── org2 # │ │ ├── IssuerPublicKey # │ │ ├── IssuerRevocationPublicKey # │ │ ├── ca-cert.pem # │ │ ├── fabric-ca-server-config.yaml # │ │ ├── fabric-ca-server.db # │ │ ├── msp # │ │ │ ├── cacerts # │ │ │ ├── keystore # │ │ │ │ ├── 30bf6cf68bb244019e0eb8953c7d3bb3e8aa5f3c2ecd53882b3ca553cbacb896_sk # │ │ │ │ ├── IssuerRevocationPrivateKey # │ │ │ │ ├── IssuerSecretKey # │ │ │ │ └── e870a0d645d963537e0cf25391ba6cfab1fc5ecdcacdd0a91db8d52375297021_sk # │ │ │ ├── signcerts # │ │ │ └── user # │ │ └── tls-cert.pem # │ └── registerEnroll.sh # └── peerOrganizations # └── org1.example.com # ├── ca (新建的) # │ └── ca.org1.example.com-cert.pem (来自 ../peers/peer0.org1.example.com/msp/cacerts/*) # ├── fabric-ca-client-config.yaml # ├── msp # │ ├── IssuerPublicKey # │ ├── IssuerRevocationPublicKey # │ ├── cacerts # │ │ └── localhost-7054-ca-org1.pem # │ ├── config.yaml # │ ├── keystore # │ │ ├── 88613215f7f6ad9fcc0c29b131c44c66431e3e609713f42384cc622fb2988ba4_sk # │ │ └── dcbe1485ee1f7856019c33998ea46c2a591fbb7491ff8ecc8f20f31631ac4d76_sk # │ ├── signcerts # │ │ └── cert.pem # │ ├── tlscacerts (新建的) # │ │ └── ca.crt (来自 ../../peers/peer0.org1.example.com/tls/tlscacerts/*) # │ └── user # ├── peers # │ └── peer0.org1.example.com # │ ├── msp # │ │ ├── IssuerPublicKey # │ │ ├── IssuerRevocationPublicKey # │ │ ├── cacerts # │ │ │ └── localhost-7054-ca-org1.pem # │ │ ├── config.yaml # │ │ ├── keystore # │ │ │ └── f45202beaef4daf7a7e528c9625076fbfc1a327a7e0a0e23b77ce1f3a797f456_sk # │ │ ├── signcerts # │ │ │ └── cert.pem # │ │ └── user # │ └── tls # │ ├── IssuerPublicKey # │ ├── IssuerRevocationPublicKey # │ ├── ca.crt (来自 ./tlscacerts/*) # │ ├── cacerts # │ ├── keystore # │ │ └── b482a35fe5b87742dc7f04e6530d1b8f958bd86d5e47e68bf6cbc9c2ef60b041_sk # │ ├── server.crt (来自 ./signcerts/*) # │ ├── server.key (来自 ./keystore/*) # │ ├── signcerts # │ │ └── cert.pem # │ ├── tlscacerts # │ │ └── tls-localhost-7054-ca-org1.pem # │ └── user # └── tlsca (新建的) # └── tlsca.org1.example.com-cert.pem (来自 ../peers/tls/tlscacerts/*) -
生成用户的 msp
mkdir -p organizations/peerOrganizations/org1.example.com/users mkdir -p organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com fabric-ca-client enroll \ -u https://user1:user1pw@localhost:7054 \ --caname ca-org1 \ -M ${PWD}/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp \ --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pem # organizations/ # ├── ccp-generate.sh # ├── ccp-template.json # ├── ccp-template.yaml # ├── fabric-ca # │ ├── ca.orderer.example.com.yaml # │ ├── ca.org1.example.com.yaml # │ ├── ca.org2.example.com.yaml # │ ├── ordererOrg # │ │ ├── IssuerPublicKey # │ │ ├── IssuerRevocationPublicKey # │ │ ├── ca-cert.pem # │ │ ├── fabric-ca-server-config.yaml # │ │ ├── fabric-ca-server.db # │ │ ├── msp # │ │ │ ├── cacerts # │ │ │ ├── keystore # │ │ │ │ ├── 8bc09ebe688b7db3b5ea6b6a093d9cac770daae995ddf5704daaabf71ed0212e_sk # │ │ │ │ ├── IssuerRevocationPrivateKey # │ │ │ │ ├── IssuerSecretKey # │ │ │ │ └── eae356176a0695ab432782cb941f4b62ba6e59ce7ae73d9a9e5f822d04232464_sk # │ │ │ ├── signcerts # │ │ │ └── user # │ │ └── tls-cert.pem # │ ├── org1 # │ │ ├── IssuerPublicKey # │ │ ├── IssuerRevocationPublicKey # │ │ ├── ca-cert.pem # │ │ ├── fabric-ca-server-config.yaml # │ │ ├── fabric-ca-server.db # │ │ ├── msp # │ │ │ ├── cacerts # │ │ │ ├── keystore # │ │ │ │ ├── 230c741dd12acb5283c00790dce694e0e5ff449e15b48ecf356cc8dc5d063441_sk # │ │ │ │ ├── IssuerRevocationPrivateKey # │ │ │ │ ├── IssuerSecretKey # │ │ │ │ └── a30524cd7016297b0d2387597657eb2d14254bf48dadca940e6487dd7600be3f_sk # │ │ │ ├── signcerts # │ │ │ └── user # │ │ └── tls-cert.pem # │ ├── org2 # │ │ ├── IssuerPublicKey # │ │ ├── IssuerRevocationPublicKey # │ │ ├── ca-cert.pem # │ │ ├── fabric-ca-server-config.yaml # │ │ ├── fabric-ca-server.db # │ │ ├── msp # │ │ │ ├── cacerts # │ │ │ ├── keystore # │ │ │ │ ├── 30bf6cf68bb244019e0eb8953c7d3bb3e8aa5f3c2ecd53882b3ca553cbacb896_sk # │ │ │ │ ├── IssuerRevocationPrivateKey # │ │ │ │ ├── IssuerSecretKey # │ │ │ │ └── e870a0d645d963537e0cf25391ba6cfab1fc5ecdcacdd0a91db8d52375297021_sk # │ │ │ ├── signcerts # │ │ │ └── user # │ │ └── tls-cert.pem # │ └── registerEnroll.sh # └── peerOrganizations # └── org1.example.com # ├── ca # │ └── ca.org1.example.com-cert.pem # ├── fabric-ca-client-config.yaml # ├── msp # │ ├── IssuerPublicKey # │ ├── IssuerRevocationPublicKey # │ ├── cacerts # │ │ └── localhost-7054-ca-org1.pem # │ ├── config.yaml # │ ├── keystore # │ │ ├── 88613215f7f6ad9fcc0c29b131c44c66431e3e609713f42384cc622fb2988ba4_sk # │ │ └── dcbe1485ee1f7856019c33998ea46c2a591fbb7491ff8ecc8f20f31631ac4d76_sk # │ ├── signcerts # │ │ └── cert.pem # │ ├── tlscacerts # │ │ └── ca.crt # │ └── user # ├── peers # │ └── peer0.org1.example.com # │ ├── msp # │ │ ├── IssuerPublicKey # │ │ ├── IssuerRevocationPublicKey # │ │ ├── cacerts # │ │ │ └── localhost-7054-ca-org1.pem # │ │ ├── config.yaml # │ │ ├── keystore # │ │ │ └── f45202beaef4daf7a7e528c9625076fbfc1a327a7e0a0e23b77ce1f3a797f456_sk # │ │ ├── signcerts # │ │ │ └── cert.pem # │ │ └── user # │ └── tls # │ ├── IssuerPublicKey # │ ├── IssuerRevocationPublicKey # │ ├── ca.crt # │ ├── cacerts # │ ├── keystore # │ │ └── b482a35fe5b87742dc7f04e6530d1b8f958bd86d5e47e68bf6cbc9c2ef60b041_sk # │ ├── server.crt # │ ├── server.key # │ ├── signcerts # │ │ └── cert.pem # │ ├── tlscacerts # │ │ └── tls-localhost-7054-ca-org1.pem # │ └── user # ├── tlsca # │ └── tlsca.org1.example.com-cert.pem # └── users # └── User1@org1.example.com # └── msp # ├── IssuerPublicKey # ├── IssuerRevocationPublicKey # ├── cacerts # │ └── localhost-7054-ca-org1.pem # ├── keystore # │ └── e62b64279c20424d3ec5a4d4315ea8e0bffe7c554fd37190cd315e2eada6b390_sk # ├── signcerts # │ └── cert.pem # └── user -
生成组织管理员的 msp
mkdir -p organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com
fabric-ca-client enroll \
-u https://org1admin:org1adminpw@localhost:7054 \
--caname ca-org1 \
-M ${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp \
--tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pem
# organizations/
# ├── ccp-generate.sh
# ├── ccp-template.json
# ├── ccp-template.yaml
# ├── fabric-ca
# │ ├── ca.orderer.example.com.yaml
# │ ├── ca.org1.example.com.yaml
# │ ├── ca.org2.example.com.yaml
# │ ├── ordererOrg
# │ │ ├── IssuerPublicKey
# │ │ ├── IssuerRevocationPublicKey
# │ │ ├── ca-cert.pem
# │ │ ├── fabric-ca-server-config.yaml
# │ │ ├── fabric-ca-server.db
# │ │ ├── msp
# │ │ │ ├── cacerts
# │ │ │ ├── keystore
# │ │ │ │ ├── 8bc09ebe688b7db3b5ea6b6a093d9cac770daae995ddf5704daaabf71ed0212e_sk
# │ │ │ │ ├── IssuerRevocationPrivateKey
# │ │ │ │ ├── IssuerSecretKey
# │ │ │ │ └── eae356176a0695ab432782cb941f4b62ba6e59ce7ae73d9a9e5f822d04232464_sk
# │ │ │ ├── signcerts
# │ │ │ └── user
# │ │ └── tls-cert.pem
# │ ├── org1
# │ │ ├── IssuerPublicKey
# │ │ ├── IssuerRevocationPublicKey
# │ │ ├── ca-cert.pem
# │ │ ├── fabric-ca-server-config.yaml
# │ │ ├── fabric-ca-server.db
# │ │ ├── msp
# │ │ │ ├── cacerts
# │ │ │ ├── keystore
# │ │ │ │ ├── 230c741dd12acb5283c00790dce694e0e5ff449e15b48ecf356cc8dc5d063441_sk
# │ │ │ │ ├── IssuerRevocationPrivateKey
# │ │ │ │ ├── IssuerSecretKey
# │ │ │ │ └── a30524cd7016297b0d2387597657eb2d14254bf48dadca940e6487dd7600be3f_sk
# │ │ │ ├── signcerts
# │ │ │ └── user
# │ │ └── tls-cert.pem
# │ ├── org2
# │ │ ├── IssuerPublicKey
# │ │ ├── IssuerRevocationPublicKey
# │ │ ├── ca-cert.pem
# │ │ ├── fabric-ca-server-config.yaml
# │ │ ├── fabric-ca-server.db
# │ │ ├── msp
# │ │ │ ├── cacerts
# │ │ │ ├── keystore
# │ │ │ │ ├── 30bf6cf68bb244019e0eb8953c7d3bb3e8aa5f3c2ecd53882b3ca553cbacb896_sk
# │ │ │ │ ├── IssuerRevocationPrivateKey
# │ │ │ │ ├── IssuerSecretKey
# │ │ │ │ └── e870a0d645d963537e0cf25391ba6cfab1fc5ecdcacdd0a91db8d52375297021_sk
# │ │ │ ├── signcerts
# │ │ │ └── user
# │ │ └── tls-cert.pem
# │ └── registerEnroll.sh
# └── peerOrganizations
# └── org1.example.com
# ├── ca
# │ └── ca.org1.example.com-cert.pem
# ├── fabric-ca-client-config.yaml
# ├── msp
# │ ├── IssuerPublicKey
# │ ├── IssuerRevocationPublicKey
# │ ├── cacerts
# │ │ └── localhost-7054-ca-org1.pem
# │ ├── config.yaml
# │ ├── keystore
# │ │ ├── 88613215f7f6ad9fcc0c29b131c44c66431e3e609713f42384cc622fb2988ba4_sk
# │ │ └── dcbe1485ee1f7856019c33998ea46c2a591fbb7491ff8ecc8f20f31631ac4d76_sk
# │ ├── signcerts
# │ │ └── cert.pem
# │ ├── tlscacerts
# │ │ └── ca.crt
# │ └── user
# ├── peers
# │ └── peer0.org1.example.com
# │ ├── msp
# │ │ ├── IssuerPublicKey
# │ │ ├── IssuerRevocationPublicKey
# │ │ ├── cacerts
# │ │ │ └── localhost-7054-ca-org1.pem
# │ │ ├── config.yaml
# │ │ ├── keystore
# │ │ │ └── f45202beaef4daf7a7e528c9625076fbfc1a327a7e0a0e23b77ce1f3a797f456_sk
# │ │ ├── signcerts
# │ │ │ └── cert.pem
# │ │ └── user
# │ └── tls
# │ ├── IssuerPublicKey
# │ ├── IssuerRevocationPublicKey
# │ ├── ca.crt
# │ ├── cacerts
# │ ├── keystore
# │ │ └── b482a35fe5b87742dc7f04e6530d1b8f958bd86d5e47e68bf6cbc9c2ef60b041_sk
# │ ├── server.crt
# │ ├── server.key
# │ ├── signcerts
# │ │ └── cert.pem
# │ ├── tlscacerts
# │ │ └── tls-localhost-7054-ca-org1.pem
# │ └── user
# ├── tlsca
# │ └── tlsca.org1.example.com-cert.pem
# └── users
# ├── Admin@org1.example.com
# │ └── msp
# │ ├── IssuerPublicKey
# │ ├── IssuerRevocationPublicKey
# │ ├── cacerts
# │ │ └── localhost-7054-ca-org1.pem
# │ ├── keystore
# │ │ └── ddba9bb3e6adb11e8967c97747f3f2da5fa8e6683df36e69a4f30b714633c78a_sk
# │ ├── signcerts
# │ │ └── cert.pem
# │ └── user
# └── User1@org1.example.com
# └── msp
# ├── IssuerPublicKey
# ├── IssuerRevocationPublicKey
# ├── cacerts
# │ └── localhost-7054-ca-org1.pem
# ├── keystore
# │ └── e62b64279c20424d3ec5a4d4315ea8e0bffe7c554fd37190cd315e2eada6b390_sk
# ├── signcerts
# │ └── cert.pem
# └── user
生成创世区块
. scripts/utils.sh
setupCommonENV
# 因为现在要配置系统通道了所以 FABRIC_CFG_PATH 要指向 configtx.yaml 所在的路径
export FABRIC_CFG_PATH=${PWD}/configtx
configtxgen \
-profile TwoOrgsOrdererGenesis \
-channelID system-channel \
-outputBlock ./system-genesis-block/genesis.block
configtxgen \
-profile TwoOrgsChannel \
-outputCreateChannelTx ./channel-artifacts/$CHANNEL_NAME.tx \
-channelID $CHANNEL_NAME
configtxgen \
-profile TwoOrgsChannel \
-outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx \
-channelID $CHANNEL_NAME \
-asOrg Org1MSP
configtxgen \
-profile TwoOrgsChannel \
-outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx \
-channelID $CHANNEL_NAME \
-asOrg Org2MSP
具体的 configtx.yaml 的配置待更新。。。
启动 Peers 和 Orderer 节点
COMPOSE_FILE_BASE=docker/docker-compose-ABC.yaml COMPOSE_FILE_COUCH=docker/docker-compose-couch.yaml IMAGE_TAG=${FABRIC_VERSION} DB_IMAGE_TAG=${DB_VERSION} docker-compose -f ${COMPOSE_FILE_BASE} -f ${COMPOSE_FILE_COUCH} up -d
这里不能拆行,否则变量无法在
docker-compose命令中使用。命令用到的 docker-compose 文件中,用到了一些环境变量,写在了.env文件中,由于一开始没有配置这个文件,所以报错了。
创建并加入通道
设置环境变量
# Common env
export FABRIC_CFG_PATH=${PWD}/fabric-bin/${FABRIC_VERSION}/config
export ORDERER_ADDRESS=localhost:7050
export PEER0_ORG1_ADDRESS=localhost:7051
export PEER0_ORG2_ADDRESS=localhost:9051
export PEER0_ORG1_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export PEER0_ORG2_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export ORDERER_CA=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
export CHANNEL_NAME=mychannel
# Peer env 1
export CORE_PEER_LOCALMSPID=Org1MSP
export CORE_PEER_ADDRESS=$PEER0_ORG1_ADDRESS
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_TLS_CERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt
export CORE_PEER_TLS_KEY_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
# Peer env 2
export CORE_PEER_LOCALMSPID=Org2MSP
export CORE_PEER_ADDRESS=$PEER0_ORG2_ADDRESS
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_TLS_CERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/server.crt
export CORE_PEER_TLS_KEY_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/server.key
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
创建通道
pushd ./channel-artifacts
peer channel create \
-o ${ORDERER_ADDRESS} \
-c ${CHANNEL_NAME} \
-f ${CHANNEL_NAME}.tx \
--tls $CORE_PEER_TLS_ENABLED \
--cafile $ORDERER_CA
popd
Org1 加入通道
setupPeerENV1
peer channel join -b ./channel-artifacts/${CHANNEL_NAME}.block
setupPeerENV1
# 更新锚节点
peer channel update \
-o ${ORDERER_ADDRESS} \
-c ${CHANNEL_NAME} \
-f ./channel-artifacts/Org1MSPanchors.tx \
--tls $CORE_PEER_TLS_ENABLED \
--cafile $ORDERER_CA
Org2 加入通道
setupPeerENV2
peer channel join -b ./channel-artifacts/${CHANNEL_NAME}.block
# 更新锚节点
peer channel update \
-o ${ORDERER_ADDRESS} \
-c ${CHANNEL_NAME} \
-f ./channel-artifacts/Org2MSPanchors.tx \
--tls $CORE_PEER_TLS_ENABLED \
--cafile $ORDERER_CA
生成连接文档
./organizations/ccp-generate.sh
如果是用 Java 开发那么还需要配置 Java 的 连接文件:
if [ ! -d "${PWD}/app/example01_java/profiles/Org1/tls" ]; then
mkdir -p app/example01_java/profiles/Org1/tls
fi
if [ ! -d "${PWD}/app/example01_java/profiles/Org2/tls" ]; then
mkdir -p app/example01_java/profiles/Org2/tls
fi
if [ ! -d "${PWD}/app/example02/profiles/Org1/tls" ]; then
mkdir -p app/example02_java/profiles/Org1/tls
fi
if [ ! -d "${PWD}/app/example02/profiles/Org2/tls" ]; then
mkdir -p app/example02_java/profiles/Org2/tls
fi
cp ./organizations/peerOrganizations/org1.example.com/connection-org1.json app/example01_java/profiles/Org1/connection.json
cp ./organizations/peerOrganizations/org2.example.com/connection-org2.json app/example01_java/profiles/Org2/connection.json
cp ./organizations/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem app/example01_java/profiles/Org1/tls/
cp ./organizations/peerOrganizations/org2.example.com/ca/ca.org2.example.com-cert.pem app/example01_java/profiles/Org2/tls/
cp ./organizations/peerOrganizations/org1.example.com/connection-org1.json app/example02_java/profiles/Org1/connection.json
cp ./organizations/peerOrganizations/org2.example.com/connection-org2.json app/example02_java/profiles/Org2/connection.json
cp ./organizations/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem app/example02_java/profiles/Org1/tls/
cp ./organizations/peerOrganizations/org2.example.com/ca/ca.org2.example.com-cert.pem app/example02_java/profiles/Org2/tls/
. script/deploy_chaincode.sh
首先设置环境变量:
export FABRIC_CFG_PATH=${PWD}/fabric-bin/${FABRIC_VERSION}/config
export ORDERER_ADDRESS=localhost:7050
export PEER0_ORG1_ADDRESS=localhost:7051
export PEER0_ORG2_ADDRESS=localhost:9051
export PEER0_ORG1_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export PEER0_ORG2_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export ORDERER_CA=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
export CHANNEL_NAME=mychannel
export CC_NAME=mycc
export CC_VERSION=v1.0
export CC_SEQ=1
export CC_POLICY="OR('Org1MSP.peer', 'Org2MSP.peer')"
export CC_LANG=golang
export CC_PATH=${PWD}/chaincode/chaincode_example01/go
function setupPeerENV1() {
export CORE_PEER_LOCALMSPID=Org1MSP
export CORE_PEER_ADDRESS=$PEER0_ORG1_ADDRESS
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_TLS_CERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt
export CORE_PEER_TLS_KEY_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
}
function setupPeerENV2() {
export CORE_PEER_LOCALMSPID=Org2MSP
export CORE_PEER_ADDRESS=$PEER0_ORG2_ADDRESS
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_TLS_CERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/server.crt
export CORE_PEER_TLS_KEY_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/server.key
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
}
然后打包 go 语言的链码,这里有两种打包的方式:
-
用源码目录下的
build.sh脚本打包;pushd $CC_PATH ./build.sh popd -
用
peer lifecycle chaincode package命令打包;peer lifecycle chaincode package tmp/${CC_LABEL}.tar.gz --path ${CC_PATH} --lang $CC_LANG --label ${CC_LABEL}
每个组织都要打包一次,所以需要设置两次环境变量,切换两个组织的环境分别部署一次;
Org1 安装链码
setupPeerENV1
peer lifecycle chaincode package tmp/${CC_LABEL}.tar.gz --path ${CC_PATH} --lang $CC_LANG --label ${CC_LABEL}
peer lifecycle chaincode install tmp/${CC_LABEL}.tar.gz
Org2 安装链码
setupPeerENV2
peer lifecycle chaincode package tmp/${CC_LABEL}.tar.gz --path ${CC_PATH} --lang $CC_LANG --label ${CC_LABEL}
peer lifecycle chaincode install tmp/${CC_LABEL}.tar.gz
Org1 批准链码
setupPeerENV1
PACKAGE_ID=$(peer lifecycle chaincode queryinstalled --output json | jq -r '.installed_chaincodes[] | select(.label == env.CC_LABEL) | .package_id')
peer lifecycle chaincode approveformyorg \
-o ${ORDERER_ADDRESS} \
--ordererTLSHostnameOverride orderer.example.com \
--tls $CORE_PEER_TLS_ENABLED \
--cafile $ORDERER_CA \
--channelID $CHANNEL_NAME \
--name ${CC_NAME} \
--version ${CC_VERSION} \
--init-required \
--package-id ${PACKAGE_ID} \
--sequence $CC_SEQ \
--waitForEvent \
--signature-policy "$CC_POLICY" \
$PRIVATE_COLLECTION_DEF
Org2 批准链码
setupPeerENV2
PACKAGE_ID=$(peer lifecycle chaincode queryinstalled --output json | jq -r '.installed_chaincodes[] | select(.label == env.CC_LABEL) | .package_id')
peer lifecycle chaincode approveformyorg \
-o ${ORDERER_ADDRESS} \
--ordererTLSHostnameOverride orderer.example.com \
--tls $CORE_PEER_TLS_ENABLED \
--cafile $ORDERER_CA \
--channelID $CHANNEL_NAME \
--name ${CC_NAME} \
--version ${CC_VERSION} \
--init-required \
--package-id ${PACKAGE_ID} \
--sequence $CC_SEQ \
--waitForEvent \
--signature-policy "$CC_POLICY" $PRIVATE_COLLECTION_DEF
Org1 检查链码批准
setupPeerENV1
peer lifecycle chaincode checkcommitreadiness \
--channelID $CHANNEL_NAME \
--name ${CC_NAME} \
--version ${CC_VERSION} \
--sequence $CC_SEQ \
--output json \
--init-required \
--signature-policy "$CC_POLICY" $PRIVATE_COLLECTION_DEF
Org1 提交链码定义
setupPeerENV1
peer lifecycle chaincode commit \
-o ${ORDERER_ADDRESS} \
--ordererTLSHostnameOverride orderer.example.com \
--tls $CORE_PEER_TLS_ENABLED \
--cafile $ORDERER_CA \
--peerAddresses $PEER0_ORG1_ADDRESS \
--tlsRootCertFiles $PEER0_ORG1_TLS_ROOTCERT_FILE \
--peerAddresses $PEER0_ORG2_ADDRESS \
--tlsRootCertFiles $PEER0_ORG2_TLS_ROOTCERT_FILE \
-C $CHANNEL_NAME \
--name ${CC_NAME} \
--version ${CC_VERSION} \
--sequence $CC_SEQ \
--init-required \
--signature-policy "$CC_POLICY" $PRIVATE_COLLECTION_DEF
Org1 检查链码状态
setupPeerENV1
peer lifecycle chaincode querycommitted --channelID $CHANNEL_NAME --name ${CC_NAME}
调用链码
首先同样的要设置环境变量,同上一步一样,用哪个组织的管理员身份去调用就设置哪个环境,这里就不贴代码了。
初始化链码
peer chaincode invoke \
-o ${ORDERER_ADDRESS} \
--ordererTLSHostnameOverride orderer.example.com \
--tls $CORE_PEER_TLS_ENABLED \
--cafile $ORDERER_CA \
-C $CHANNEL_NAME \
-n ${CC_NAME} \
--isInit -c '{"Function":"Init","Args":[]}'
调用函数
peer chaincode query -C $CHANNEL_NAME -n $CC_NAME -c '{"Function":"Hi", "Args":[]}'