# buy & sell system build manual
## 一. 软件版本要求
| 软件 | 版本 |
| ----- | :-----: |
| golang | 1.9.7 |
| docker-ce | 18.09.3 |
| docker-compose | 1.14.0 |
| fabric(image) | 1.1.0 |
## 二. 操作系统和硬件配置要求
| 操作系统 | 版本 | CPU(c) | 内存(G) | 磁盘(G) | 编号 | 用途 |
| ------- | :--: | :--: | :--: | :--: | :---: | :--: |
| CentOS | 7+ | >=2 | >=8 | >=100 | A | 安装组织节点(Org) |
| CentOS | 7+ | >=2 | >=8 | >=100 | B | 安装组织节点证书签发服务(Ca) |
| CentOS | 7+ | >=2 | >=8 | >=100 | C | 安装组织节点数据库(CouchDB) |
## 三. 软件安装步骤
### 1. golang安装(A主机)
```bash
# 下载golang安装包
wget https://dl.google.com/go/go1.9.7.linux-amd64.tar.gz
# 解压到/usr/local目录
tar -zxvf go1.9.7.linux-amd64.tar.gz -C /usr/local/
# 增加环境变量
echo "export PATH=$PATH:/usr/local/go/bin" >> /etc/profile
echo "export GOROOT=/usr/local/go" >> /etc/profile
echo "export GOPATH=/opt/gopath" >> /etc/profile
echo "export PATH=$PATH:$GOPATH" >> /etc/profile
# 重新加载环境变量
source /etc/profile
# 创建go的软链接
ln -s /usr/local/go/bin/go /usr/local/bin/go
```
### 2. docker安装(A/B/C主机)
```bash
# 卸载系统已有的docker程序
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# 安装基础程序
sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
# 安装docker ce官方仓库
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
# 安装docker
sudo yum install docker-ce-18.09.3 docker-ce-cli-18.09.3 containerd.io -y
```
### 3. docker-compose 安装(A/B/C主机)
```bash
sudo curl -L \
"https://github.com/docker/compose/releases/download/1.14.0/docker-compose-$(uname -s)-$(uname -m)" \
-o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
```
### 4. fabric镜像安装(A/B/C主机)
```bash
docker pull hyperledger/fabric-peer:x86_64-1.1.0
docker tag hyperledger/fabric-peer:x86_64-1.1.0 fabric-peer
docker pull hyperledger/fabric-orderer:x86_64-1.1.0
docker tag hyperledger/fabric-orderer:x86_64-1.1.0 fabric-orderer
docker pull hyperledger/fabric-couchdb:0.4.7
docker tag hyperledger/fabric-couchdb:0.4.7 fabric-couchdb
docker pull hyperledger/fabric-ccenv:x86_64-1.1.0
docker tag hyperledger/fabric-ccenv:x86_64-1.1.0 fabric-ccenv
docker pull hyperledger/fabric-javaenv:x86_64-1.1.0
docker tag hyperledger/fabric-javaenv:x86_64-1.1.0 fabric-javaenv
docker pull hyperledger/fabric-kafka:0.4.7
docker tag hyperledger/fabric-kafka:0.4.7 fabric-kafka
docker pull hyperledger/fabric-tools:x86_64-1.1.0
docker tag hyperledger/fabric-tools:x86_64-1.1.0 fabric-tools
docker pull hyperledger/fabric-zookeeper:0.4.7
docker tag hyperledger/fabric-zookeeper:0.4.7 fabric-zookeeper
docker pull hyperledger/fabric-ca:x86_64-1.1.0
docker tag hyperledger/fabric-ca:x86_64-1.1.0 fabric-ca
```
### 5. fabric源代码下载(A主机)
```bash
mkdir -p $GOPATH/src/github.com/hyperledger
cd $GOPATH/src/github.com/hyperledger
git clone -b release-1.1 https://github.com/hyperledger/fabric.git
```
## 四. Org1节点信息
### 1. 组织节点信息
| 组织节点名称 | 组织节点域名 | ID | Name | 通道名 |
| ---------- | ---------- | -- | ---- | ----- |
| Org1 | Org1.example.com | Org1MSP | Org1MSP | mychannel |
### 2. 编译生产Org1组织的公私钥证书(A主机)
```bash
cd $GOPATH/src/github.com/hyperledger/fabric/examples/e2e_cli/
vim crypto-config.yaml
# 编辑crypto-config.yaml文件,在PeerOrgs部分新增节点域信息,加入节点的名称为Org1,
# 域名为org1.example.com
PeerOrgs:
- Name: Org1
Domain: org1.example.com
EnableNodeOUs: true
CA:
Country: US
Province: California
Locality: San Francisco
Template:
Count: 2
Users:
Count: 1
# 执行生成证书的命令
cryptogen generate --config=./crypto-config.yaml
# 查看域名为org1.example.com的Org1的节点证书信息
cd ./crypto-config/peerOrganizations/org1.example.com
ls -a
```
### 3. 生成Org1组织的通道信息,在channel-artifacts文件夹(A主机)
```bash
cd $GOPATH/src/github.com/hyperledger/fabric/examples/e2e_cli/
vim configtx.yaml
# 编辑文件configtx.yaml,在 Organizations: 下面增加Org1的信息,例如:
Organizations:
- &Org1
# DefaultOrg defines the organization which is used in the sampleconfig
# of the fabric.git development environment
Name: Org1MSP
# ID to load the MSP definition as
ID: Org1MSP
MSPDir: crypto-config/peerOrganizations/org1.example.com/msp
# Policies defines the set of policies at this level of the config tree
# For organization policies, their canonical path is usually
# /Channel/<Application|Orderer>/<OrgName>/<PolicyName>
Policies:
Readers:
Type: Signature
Rule: "OR('Org1MSP.admin', 'Org1MSP.peer', 'Org1MSP.client')"
Writers:
Type: Signature
Rule: "OR('Org1MSP.admin', 'Org1MSP.client')"
Admins:
Type: Signature
Rule: "OR('Org1MSP.admin')"
AnchorPeers:
# AnchorPeers defines the location of peers which can be used
# for cross org gossip communication. Note, this value is only
# encoded in the genesis block in the Application section context
- Host: peer0.org1.example.com
Port: 7051
# 在 Profiles: 下面增加Org1的引用,例如:
Profiles:
TwoOrgsOrdererGenesis:
<<: *ChannelDefaults
Orderer:
<<: *OrdererDefaults
Organizations:
- *OrdererOrg
Consortiums:
SampleConsortium:
Organizations:
- *Org1
TwoOrgsChannel:
Consortium: SampleConsortium
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
# 对于新增节点,创世区块已经存在,不需要生成,这一步是生成Channel配置交易账本
configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx \
-channelID mychannel
# 生成Org1的msp服务的锚节点更新账本
configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx \
-channelID mychannel -asOrg Org1MSP
# 创建Org1节点服务目录和脚本目录
mkdir -p /data/Org1/e2e_cli/
mkdir -p /data/Org1/e2e_cli/scripts
# 复制证书和通道信息到服务目录
cp -r channel-artifacts crypto-config /data/Org1/e2e_cli/
```
### 4. 安装 Org1 对应的CouchDB(C服务器)
#### 安装 Org1 的 peer0 的CouchDB
```bash
# 创建Couch服务主目录和数据目录
mkdir -p /data/server/Org1_peer0_couchdb/e2e_cli
mkdir -p /data/server/Org1_peer0_couchdb/e2e_cli/data
# 新建CouchDB的启动docker-compose文件,请设置COUCHDB_USER和COUCHDB_PASSWORD和network_name三个参数的值
cat >> /data/server/Org1_peer0_couchdb/e2e_cli/docker-compose-couchdb.yaml << EOF
version: '2'
networks:
lenovo:
services:
Org1_peer0_couchdb:
container_name: Org1_peer0_couchdb
image: hyperledger/fabric-couchdb
environment:
- TZ=Asia/Shanghai
- COUCHDB_USER=xxx
- COUCHDB_PASSWORD=xxx
volumes:
- ./data:/opt/couchdb/data
ports:
- "5984:5984"
networks:
- network_name
EOF
```
#### 安装 Org1 的 peer1 的CouchDB
```bash
# 创建Couch服务主目录和数据目录
mkdir -p /data/server/Org1_peer1_couchdb/e2e_cli
mkdir -p /data/server/Org1_peer1_couchdb/e2e_cli/data
# 新建CouchDB的启动docker-compose文件,请设置COUCHDB_USER和COUCHDB_PASSWORD和network_name三个参数的值
cat >> /data/server/Org1_peer1_couchdb/e2e_cli/docker-compose-couchdb.yaml << EOF
version: '2'
networks:
network_name:
services:
Org1_peer1_couchdb:
container_name: Org1_peer1_couchdb
image: hyperledger/fabric-couchdb
environment:
- TZ=Asia/Shanghai
- COUCHDB_USER=xxx
- COUCHDB_PASSWORD=xxx
volumes:
- ./data:/opt/couchdb/data
ports:
- "5984:5984"
networks:
- network_name
EOF
# 启动CouchDB服务
docker-compose -f /data/server/Org1_peer1_couchdb/e2e_cli/docker-compose-couchdb.yaml up -d
```
### 安装 Org1 对应的CA
#### 创建CA服务目录(B服务器)
```bash
mkdir -p /data/server/Org1_ca/e2e_cli/Org1_ca
```
#### 从A主机复制生成的 crypto-config 目录到B主机的 /data/server/Org1_ca/e2e_cli 目录下
#### 创建Org1 的CA服务启动compose文件 docker-compose-ca.yaml
```bash
# network_name 变量自定义即可,可和公司名称相关
# Org1_cert 变量,先进入 ./crypto-config/peerOrganizations/org1.example.com/ca/ 目录,执行 \
# ls *.pem,文件名即是
# Org1_key 变量,先进入 ./crypto-config/peerOrganizations/org1.example.com/ca/ 目录,执行 \
# ls *_sk,文件名即是
cat >> /data/server/Org1_ca/e2e_cli/docker-compose-ca.yaml << EOF
version: '2'
networks:
network_name:
services:
ca-Org1:
image: hyperledger/fabric-ca
environment:
- TZ=Asia/Shanghai
- FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
- FABRIC_CA_SERVER_CA_NAME=ca-Org1
- FABRIC_CA_SERVER_CA_CERTFILE=/etc/hyperledger/fabric-ca-server-config/Org1_cert
- FABRIC_CA_SERVER_CA_KEYFILE=/etc/hyperledger/fabric-ca-server-config/Org1_key
- FABRIC_CA_SERVER_TLS_ENABLED=true
- FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/Org1_cert
- FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/Org1_key
ports:
- "8054:7054"
command: sh -c 'fabric-ca-server start -b admin:password'
volumes:
- ./crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config
- ./Org1_ca/:/etc/hyperledger/fabric-ca-server
container_name: ca_peerOrg1
networks:
- network_name
EOF
# 启动CA服务
docker-compose -f /data/server/Org1_ca/e2e_cli/docker-compose-ca.yaml up -d
```
### Org1 的 peer0 和 peer1 服务安装(A主机)
#### 复制证书和通道信息到 Org1 的主服务目录
```bash
cp -r $GOPATH/src/github.com/hyperledger/fabric/examples/e2e_cli/crypto-config /data/Org1/e2e_cli/
cp -r $GOPATH/src/github.com/hyperledger/fabric/examples/e2e_cli/channel-artifacts /data/Org1/e2e_cli/
cp -r $GOPATH/src/github.com/hyperledger/fabric/examples/e2e_cli/base /data/Org1/e2e_cli/
```
#### 在 /data/Org1/e2e_cli/scripts 目录创建script.sh脚本,脚本的功能是加入到已有的通道中,内容见附件 script.sh
```bash
mkdir -p /data/Org1/e2e_cli/scripts
```
#### 创建Org1节点链码存放目录
``` bash
mkdir -p /data/Org1/chaincode/go
```
#### 在 /data/Org1/e2e_cli/ 目录创建Org1的启动文件docker-compose-peer.yml,内容详见附件 docker-compose-peer.yaml,需要修改文件中的以下变量才能正常使用
```txt
ORDERER_IP # 联想提供的orderer节点的外网ip地址
PEER0_Couch # peer0对应的couchdb ip, C主机的IP
PEER1_Couch # peer1对应的couchdb ip, C主机的IP
Org1_PEER0 # 主机A的IP地址
Org1_PEER1 # 主机A的IP地址
```
#### 启动Org1 的 peer0 和 peer1 服务
```bash
docker-compose -f /data/Org1/e2e_cli/docker-compose-peer.yml up -d
```
有疑问加站长微信联系(非本文作者)