本文水份很严重,如果你正处于配置fabric的环境而翻了一遍又一遍的网文的过程, 那么本文可能并不会帮你解决你当前的紧要问题。
一、准备二进制文件
在我们准备开始之前,我们需要获得以下二进制文件:
configtxgen
cryptogen
orderer
peer
configtxlator(非必须)
discover(非必须)
idemixgen(非必须)
fabric-ca-client(非必须)
二进制文件,我们可以通过官方的源码自己编译得到https://github.com/hyperledger/fabric
,
但是这个过程显得比较麻烦,你可能需要一个一个工具去编译。
当然,繁锁的工序并不是主要原因,让我编译不下去的主要原因是因为编译过程
需要从golang.org
和google.golang.org
获取大量的依赖包,
而不巧这两个网站正好被墙了,作为深知党的良苦用心以及没钱买梯子的我,就此放弃了此条道路。
除了自己手动编译,从Fabric的官方文档找到了另一种方法Install Samples, Binaries and Docker Images,如果你和我一样,一直饱受E文的折磨,那你可以略过大部分的内容,但应该可以找到以下链接:
https://raw.githubusercontent.com/hyperledger/fabric/master/scripts/bootstrap.sh
当然,你可能会遇到和我一样的情况,那就是raw.githubusercontent.com
也被墙了,怎么办?
我试着修改hosts文件,于是通过以下链接查询了一下该域名的原始IP地址,修改完成后,竟然可以访问
http://ip.webmasterhome.cn/?ip=raw.githubusercontent.com
# 得到的IP地址为:151.101.108.133
PS:golang.org也试过,但修改后也访问不了.
那么终于顺序的得到了bootstrap.sh
文件,我在这个文件找到了heyperledger fabric的二进制文件下载地址:hyperledger-fabric-linux-amd64-1.4.3.tar.gz,如果文件地址已经访问不了,可以试试把文件名去掉,
访问目录,可能会显示可下载的文件列表。
>PS:nexus.hyperledger.org没有被墙,应该可以正常下载hyperledger-fabric-linux-amd64-1.4.3.tar.gz
文件。
不过速度可能不敢恭维,为了备用,我把它放了在百度网盘: https://pan.baidu.com/s/13X49PZdIdiPTgQXuud3MfA 提取码: e592
(别再抱怨了,虽然我很厌恶为了下载一个文件,还必须得下载一个百度网盘。)
最后终于得到我们所需求的二进制文件。
fabric/
├── bin
│ ├── configtxgen
│ ├── configtxlator
│ ├── cryptogen
│ ├── discover
│ ├── idemixgen
│ ├── orderer
│ └── peer
└── config
├── configtx.yaml
├── core.yaml
└── orderer.yaml
记得将bin目录下的文件修改为可执行。同时设置环境变量
export FABRIC_CFG_PATH=/var/fabric/config
二、整体流程
- 通过cryptogen生成证书文件。
- 通过configtxgen生成创世块、channel管道配置文件、anchor锚点配置文件。
- 启动orderer节点。
- 通过peer节点创建channel管道。
- 通过peer节点加入channel管道。
- 通过peer节点更新锚点信息。
- 通过peer节点安装链码。
- 通过peer节点实例化链码。
- 通过客户端操作交易。
三、生成证书文件
证书的作用在于节点在参与区块链网络工作时,为节点提供身份证明、签名等。它可以通过cryptogen
与Fabirc CA
来生成,
本文以cryptogen
做为示例。
生成证书前,首先需要准备一个配置文件,从刚下载的二进制文件包,并没有该配置文件,因为cryptogen
已经提供了一个模板。
./bin/cryptogen showtemplate>>config/crypto-config.yaml
通过以上命令,我们得到了一个配置文件模板。
OrdererOrgs:
- Name: Orderer # 组织名
Domain: example.com # 组织域名
EnableNodeOUs: true # 设置为true时,会在证书目录生成config.yaml
Specs:
- Hostname: orderer # 域名前缀,此处节点将生成`orderer.example.com`,设置多个Hostname时,生成多个节点。
PeerOrgs:
- Name: Org1 # 组织名
Domain: org1.example.com # 组织域名
EnableNodeOUs: true # 设置为true时,会在证书目录生成config.yaml
Template:
Count: 1 # 生成的节点数
Users:
Count: 1 # 生成的用户数
配置完成后,接下来可以生成对应的证书文件了
./bin/cryptogen generate --config=config/crypto-config.yaml
如果未指定--config,会对showtemplate中的内容生成。
默认生成的文件会在crypto-config目录下
crypto-config
├── ordererOrganizations
│ └── example.com
│ ├── ca # 存放组织的根证书
│ ├── msp # 存放组织的MSP文件
│ ├── orderers # 该组织下的节点所拥有的证书及key文件
│ ├── tlsca # 组织内部的tlsca证书
│ └── users # 该组织下的用户所拥有的证书及key文件
└── peerOrganizations
└── org1.example.com
├── ca
├── msp
├── peers
├── tlsca
└── users
- 通过配置文件,首先生成orderer或peer节点的ca证书与tls证书(*.pem结尾),分别存放在 /ca 与 /tlsca 目录。
- 将上面的ca、tls证书分别复制到/msp下面对应的ca/与tlsca目录。
- 创建子节点,并把ca、tls证书分别复制到子节点的msp下面对应的ca/与tlsca目录。
- 创建用户,并把ca、tls证书分别复制到用户的msp下面对应的ca/与tlsca目录。
> 证书文件有点凌乱,实际的引用可以围绕组织、节点、用户三个方面相对应的msp文件。此处没有必须
过多纠结,后续会介绍相关的证书文件用处。
四、配置区块链网络
该过程主要是生成后续区块链运行的必备文件,我们需要完成以下三件事: * 生成创世块 * 生成channel管道配置文件 * 生成anchor锚点配置文件
我们需要通过configtxgen
工具来完成工作,在进行我们的工作之前,需要调整配置文件config/configtx.yaml
,
在配置文件中,需要配置orderer节点的共享方式,Fabirc支持Solo、Kafka、Raft三种类型,
本着反正不是我用,调通万岁的复杂心理,我决定采用Solo类型(听说它最简单)
> Solo类型见其名就知道是指单节点通信,只有一个orderer节点进行排序服务,
所有peer节点发送来的消息由一个orderer进行排序和产生区块,实现绝对的独裁。
Solo模式有背区块链的理念,它没有没有高可用性和可扩展性,更为关键的是共识类型一旦使用在中途是不能切换;
也就是,如果你要生产使用了Solo模式,你要么继续用,要么推倒重来,所以它不适合用于生产环境,
但对于我们快速搭建开发和测试环境还是能节省不少时间。
config/configtx.yaml:
# 组织信息
Organizations:
- &SampleOrg
Name: SampleOrg # 组织名称,这里的NAME并一定要求与前面证书中的组织NAME一致
ID: SampleOrg # 组织ID,记住这里,后面要考的
# 这里的MSP是指组织的MSP,如果该组织是在orderer中引用,
# 那么调用ordererOrganizations下对应组织的MSP.
MSPDir: /var/fabric/crypto-config/ordererOrganizations/example.com/msp
# 策略类型
# UNKNOWN:保留值,用于初始化;
# SIGNATURE:通过匹配基于签名的组合,如某个 MSP 中至少三个签名;
# MSP:代表策略必须要匹配某 MSP 下的指定身份身份,如 MSP 的管理员身份;
# IMPLICIT_META:隐式类型,包括若干子策略,并通过 Rule 来指定具体的规则,包括 ANY、ALL、MAJORITY 三种。
# ANY:满足任意子组的对应策略。
# ALL:满足所有子组的对应策略。
# MAJORITY:满足大多数(过半)子组的对应策略。
Policies: &SampleOrgPolicies
Readers:
Type: Signature
Rule: "OR('SampleOrg.member')"
Writers:
Type: Signature
Rule: "OR('SampleOrg.member')"
Admins:
Type: Signature
Rule: "OR('SampleOrg.admin')"
# Orderer节点
OrdererEndpoints:
- "127.0.0.1:7050"
# Peer节点
AnchorPeers:
- Host: 127.0.0.1
Port: 7051
# Capabilities是用于处理兼容,官方举了一个栗子,他们说如果有一个新MSP类型被引来了,一些高
# 版本的节点呢可能可以识别出来,而一些低版本的节点,可能就识别不出来了,如果高版本的拿着
# 新的MSP类型,而低版本的节点由于识别不了只能继续拿着旧的MSP类型,这样可能会乱成一锅粥。
# 于是他们便设置`Capabilities`,由它来掌管哪些满足版本要求节点可以参与区块链网络,
# 而那些不能满足版本要求的,那升级完成后再来.
Capabilities:
Channel: &ChannelCapabilities
V1_4_3: true
V1_3: false
V1_1: false
Orderer: &OrdererCapabilities
V1_4_2: true
V1_1: false
Application: &ApplicationCapabilities
V1_4_2: true
V1_3: false
V1_2: false
V1_1: false
Application: &ApplicationDefaults
ACLs: &ACLsDefault
lscc/ChaincodeExists: /Channel/Application/Readers
lscc/GetDeploymentSpec: /Channel/Application/Readers
lscc/GetChaincodeData: /Channel/Application/Readers
lscc/GetInstantiatedChaincodes: /Channel/Application/Readers
qscc/GetChainInfo: /Channel/Application/Readers
qscc/GetBlockByNumber: /Channel/Application/Readers
qscc/GetBlockByHash: /Channel/Application/Readers
qscc/GetTransactionByID: /Channel/Application/Readers
qscc/GetBlockByTxID: /Channel/Application/Readers
cscc/GetConfigBlock: /Channel/Application/Readers
cscc/GetConfigTree: /Channel/Application/Readers
cscc/SimulateConfigTreeUpdate: /Channel/Application/Readers
peer/Propose: /Channel/Application/Writers
peer/ChaincodeToChaincode: /Channel/Application/Readers
event/Block: /Channel/Application/Readers
event/FilteredBlock: /Channel/Application/Readers
Organizations:
Policies: &ApplicationDefaultPolicies
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
Capabilities:
<<: *ApplicationCapabilities
Orderer: &OrdererDefaults
# 共识排序支持三种模式,solo、kafka、etcdraft
# solo 用于测试环境,它不支持扩展高可用性
# kafka和etcdraft均可用作生产
# 警告:生产环境请谨慎选择OrdererType,一量选择投入使用,后续不可更改。
OrdererType: solo
Addresses:
# - 127.0.0.1:7050
BatchTimeout: 2s
BatchSize:
MaxMessageCount: 500
AbsoluteMaxBytes: 10 MB
PreferredMaxBytes: 2 MB
MaxChannels: 0
Organizations:
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
BlockValidation:
Type: ImplicitMeta
Rule: "ANY Writers"
Capabilities:
<<: *OrdererCapabilities
Channel: &ChannelDefaults
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
Capabilities:
<<: *ChannelCapabilities
# 以下部分定义了整个系统的配置信息,指定configtxgen工具的参数
Profiles:
# 组织定义标识符,可以自定义,命令中的-profile参数对应该标识符
# 命令示例:./bin/configtxgen -profile OneOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block
OneOrgsOrdererGenesis:
<<: *ChannelDefaults
# Orderer属性配置,系统关键字不得更改
Orderer:
<<: *OrdererDefaults
Organizations:
# OrdererOrg是官方样板给出的名称,实际生产环境中可自定义
- *OrdererOrg
Capabilities:
<<: *OrdererCapabilities
# 定义了系统中包含的组织
Consortiums:
SampleConsortium:
# 系统中包含的组织
Organizations:
- *Org1
# 以下是channel的配置信息
# 通道定义标识符,可自定义
OneOrgsChannel:
Consortium: SampleConsortium
<<: *ChannelDefaults
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
Capabilities:
<<: *ApplicationCapabilities
- 生成创世块
./bin/configtxgen -channelID testc -profile OneOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block
- 生成anchor锚点配置文件
./bin/configtxgen -profile OneOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID testc
- 生成anchor锚点配置
./bin/configtxgen -profile OneOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/anchors.tx -channelID testc -asOrg Org1MSP
五、启动orderer节点
在启动orderer节点前,必须完成orderder节点的相关配置,配置形式有两种,一种是通过配置yaml文件,另一种是通过环境变量的形式配置。 首先通过yaml文件配置,我们创建文件config/orderer.yaml:
General:
# 账本类型,提供了两种用于测试环境的类型,一种用于生产环境:
# ram: 基于内存的账本类型,在orderer重启后将被清空。
# json: 以json模式存储在磁盘中,但保密性不好,不适用生产环境。
# file: 生产环境建议使用file类型。
LedgerType: file
ListenAddress: 127.0.0.1
ListenPort: 7050
TLS:
# 是否开户TLS,开启后,凡是peer节点操作channel时,需要带上orderer节点的证文件证文件:
# `--tls --cafile=ordererOrganizations/36sn.com/orderers/orderer.36sn.com/msp/tlscacerts/tlsca.36sn.com-cert.pem`
Enabled: true
PrivateKey: /home/vagrant/fabric/crypto-config/ordererOrganizations/36sn.com/orderers/orderer.36sn.com/tls/server.key
Certificate: /home/vagrant/fabric/crypto-config/ordererOrganizations/36sn.com/orderers/orderer.36sn.com/tls/server.crt
RootCAs:
- /home/vagrant/fabric/crypto-config/ordererOrganizations/36sn.com/orderers/orderer.36sn.com/tls/ca.crt
ClientAuthRequired: false
ClientRootCAs:
Keepalive:
ServerMinInterval: 60s
ServerInterval: 7200s
ServerTimeout: 20s
Cluster:
SendBufferSize: 10
ClientCertificate: /home/vagrant/fabric/crypto-config/ordererOrganizations/36sn.com/orderers/orderer.36sn.com/tls/server.key
ClientPrivateKey: /home/vagrant/fabric/crypto-config/ordererOrganizations/36sn.com/orderers/orderer.36sn.com/tls/server.crt
ListenPort:
ListenAddress:
ServerCertificate:
ServerPrivateKey:
# 创世块的提供方式,有两种方式
# provisional 该方式提供一种临时的方法,即在order节点启用时根据`GenesisProfile`的值生成一个临时创世块。
# file 该方式通过读取本地已存在的创世块来启动节点。
GenesisMethod: provisional
GenesisProfile: OneOrgsOrdererGenesis
GenesisFile: /home/vagrant/fabric/channel-artifacts/genesis.block
# ordere节点的MSP目录
LocalMSPDir: /home/vagrant/fabric/crypto-config/ordererOrganizations/36sn.com/orderers/orderer.36sn.com/msp
# orderer节点的MSPID
LocalMSPID: OrdererMSP
Profile:
Enabled: false
Address: 0.0.0.0:6060
BCCSP:
Default: SW
SW:
Hash: SHA2
Security: 256
FileKeyStore:
KeyStore:
Authentication:
TimeWindow: 15m
FileLedger:
Location: /var/hyperledger/production/orderer
Prefix: hyperledger-fabric-ordererledger
RAMLedger:
HistorySize: 1000
Kafka:
Retry:
ShortInterval: 5s
ShortTotal: 10m
LongInterval: 5m
LongTotal: 12h
NetworkTimeouts:
DialTimeout: 10s
ReadTimeout: 10s
WriteTimeout: 10s
Metadata:
RetryBackoff: 250ms
RetryMax: 3
Producer:
RetryBackoff: 100ms
RetryMax: 3
Consumer:
RetryBackoff: 2s
Topic:
ReplicationFactor: 1
Verbose: true
TLS:
Enabled: false
PrivateKey:
Certificate:
RootCAs:
SASLPlain:
Enabled: false
User:
Password:
Version:
Debug:
BroadcastTraceDir:
DeliverTraceDir:
Operations:
ListenAddress: 127.0.0.1:8443
TLS:
Enabled: false
Certificate:
PrivateKey:
ClientAuthRequired: false
ClientRootCAs: []
Metrics:
Provider: disabled
Statsd:
Network: udp
Address: 127.0.0.1:8125
WriteInterval: 30s
Prefix:
Consensus:
WALDir: /var/hyperledger/production/orderer/etcdraft/wal
SnapDir: /var/hyperledger/production/orderer/etcdraft/snapshot
orderer节点需要设置FABRIC_CFG_PATH
环境变量,orderer启动时会从该路径下寻找orderer配置文件,
如果不存在该路径,则会在当前目录寻找,当前目录不存时,会从/etc/hyperledger/fabric/
路径寻找。
通过环境变量的形式配置:
export ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
export ORDERER_GENERAL_GENESISMETHOD=file
export ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
export ORDERER_GENERAL_LOCALMSPID=OrdererMSP
export ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
export ORDERER_GENERAL_TLS_ENABLED=true
export ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key
export ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt
export ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
配置完成后,启动orderer节点
./bin/orderer start
六、启动 peer 节点
peer 与 orderer 节点类似,必须完成peer节点的相关配置才能启动, 配置形式一种是通过配置yaml文件,另一种是通过环境变量的形式配置。 首先通过yaml文件配置,我们创建文件config/core.yaml:
peer:
# 节点ID
id: peer0.org1.36sn.com
networkId: dev
listenAddress: 0.0.0.0:7051
address: peer0.org1.36sn.com:7051
addressAutoDetect: false
gomaxprocs: -1
keepalive:
minInterval: 60s
client:
interval: 60s
timeout: 20s
deliveryClient:
interval: 60s
timeout: 20s
gossip:
bootstrap: 127.0.0.1:7051
useLeaderElection: true
orgLeader: false
membershipTrackerInterval: 5s
endpoint:
maxBlockCountToStore: 100
maxPropagationBurstLatency: 10ms
maxPropagationBurstSize: 10
propagateIterations: 1
propagatePeerNum: 3
pullInterval: 4s
pullPeerNum: 3
requestStateInfoInterval: 4s
publishStateInfoInterval: 4s
stateInfoRetentionInterval:
publishCertPeriod: 10s
skipBlockVerification: false
dialTimeout: 3s
connTimeout: 2s
recvBuffSize: 20
sendBuffSize: 200
digestWaitTime: 1s
requestWaitTime: 1500ms
responseWaitTime: 2s
aliveTimeInterval: 5s
aliveExpirationTimeout: 25s
reconnectInterval: 25s
externalEndpoint:
election:
startupGracePeriod: 15s
membershipSampleInterval: 1s
leaderAliveThreshold: 10s
leaderElectionDuration: 5s
pvtData:
pullRetryThreshold: 60s
transientstoreMaxBlockRetention: 1000
pushAckTimeout: 3s
btlPullMargin: 10
reconcileBatchSize: 10
reconcileSleepInterval: 1m
reconciliationEnabled: true
skipPullingInvalidTransactionsDuringCommit: false
state:
enabled: true
checkInterval: 10s
responseTimeout: 3s
batchSize: 10
blockBufferSize: 100
maxRetries: 3
# 是否启动tls
tls:
enabled: true
clientAuthRequired: false
cert:
file: /home/vagrant/fabric/crypto-config/peerOrganizations/org1.36sn.com/peers/peer0.org1.36sn.com/tls/server.crt
key:
file: /home/vagrant/fabric/crypto-config/peerOrganizations/org1.36sn.com/peers/peer0.org1.36sn.com/tls/server.key
rootcert:
file: /home/vagrant/fabric/crypto-config/peerOrganizations/org1.36sn.com/peers/peer0.org1.36sn.com/tls/ca.crt
clientRootCAs:
files:
- /home/vagrant/fabric/crypto-config/peerOrganizations/org1.36sn.com/peers/peer0.org1.36sn.com/tls/ca.crt
clientKey:
file:
clientCert:
file:
authentication:
timewindow: 15m
fileSystemPath: /var/hyperledger/production
BCCSP:
Default: SW
SW:
Hash: SHA2
Security: 256
FileKeyStore:
KeyStore:
PKCS11:
Library:
Label:
Pin:
Hash:
Security:
FileKeyStore:
KeyStore:
# 节点的MSP路径
mspConfigPath: /home/vagrant/fabric/crypto-config/peerOrganizations/org1.36sn.com/peers/peer0.org1.36sn.com/msp
# 节点MSPID
localMspId: Org1MSP
client:
connTimeout: 3s
deliveryclient:
reconnectTotalTimeThreshold: 3600s
connTimeout: 3s
reConnectBackoffThreshold: 3600s
localMspType: bccsp
profile:
enabled: false
listenAddress: 0.0.0.0:6060
adminService:
handlers:
authFilters:
-
name: DefaultAuth
-
name: ExpirationCheck # This filter checks identity x509 certificate expiration
decorators:
-
name: DefaultDecorator
endorsers:
escc:
name: DefaultEndorsement
library:
validators:
vscc:
name: DefaultValidation
library:
validatorPoolSize:
discovery:
enabled: true
authCacheEnabled: true
authCacheMaxSize: 1000
authCachePurgeRetentionRatio: 0.75
orgMembersAllowedAccess: false
vm:
endpoint: unix:///var/run/docker.sock
docker:
tls:
enabled: false
ca:
file: docker/ca.crt
cert:
file: docker/tls.crt
key:
file: docker/tls.key
attachStdout: false
hostConfig:
NetworkMode: host
Dns:
LogConfig:
Type: json-file
Config:
max-size: "50m"
max-file: "5"
Memory: 2147483648
chaincode:
id:
path:
name:
builder: $(DOCKER_NS)/fabric-ccenv:latest
pull: false
golang:
runtime: $(BASE_DOCKER_NS)/fabric-baseos:$(ARCH)-$(BASE_VERSION)
dynamicLink: false
car:
runtime: $(BASE_DOCKER_NS)/fabric-baseos:$(ARCH)-$(BASE_VERSION)
java:
runtime: $(DOCKER_NS)/fabric-javaenv:$(ARCH)-$(PROJECT_VERSION)
node:
runtime: $(BASE_DOCKER_NS)/fabric-baseimage:$(ARCH)-$(BASE_VERSION)
startuptimeout: 300s
executetimeout: 30s
mode: net
keepalive: 0
system:
cscc: enable
lscc: enable
escc: enable
vscc: enable
qscc: enable
systemPlugins:
logging:
level: info
shim: warning
format: '%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}'
ledger:
blockchain:
state:
stateDatabase: goleveldb
totalQueryLimit: 100000
couchDBConfig:
couchDBAddress: 127.0.0.1:5984
username:
password:
maxRetries: 3
maxRetriesOnStartup: 12
requestTimeout: 35s
internalQueryLimit: 1000
maxBatchUpdateSize: 1000
warmIndexesAfterNBlocks: 1
createGlobalChangesDB: false
history:
enableHistoryDatabase: true
operations:
listenAddress: 127.0.0.1:9443
tls:
enabled: false
cert:
file:
key:
file:
clientAuthRequired: false
clientRootCAs:
files: []
metrics:
provider: disabled
statsd:
network: udp
address: 127.0.0.1:8125
writeInterval: 10s
prefix:
peer 节点需要配置的内容不多,同样它也支持通过环境变量的形式进行配置:
export CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
export CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=test_byfn
export FABRIC_LOGGING_SPEC=INFO
export FABRIC_LOGGING_SPEC=DEBUG
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_GOSSIP_USELEADERELECTION=true
export CORE_PEER_GOSSIP_ORGLEADER=false
export CORE_PEER_PROFILE_ENABLED=true
export CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
export CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
export CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
peer节点需要配置 docker 信息,因为安装好的链码需要在 docker 容器中执行。
配置完成后,启动 peer 节点
./bin/peer node start
七、管理管道channel
在本小节,我们将完成以下三项操作: * 通过 peer 节点创建 channel 管道。 * 通过 peer 节点加入 channel 管道。 * 通过 peer 节点更新锚点信息。
在完成操作前,我们需要做一些准备工作,因为需要操作管道,我们需要拥有节点的管理员权限, 我将三个操作合并成了一个 shell 文件:
#!/bin/bash
CHANNEL_NAME="zsjr"
APP_PATH=/home/vagrant/fabric
BLOCK_PATH=${APP_PATH}/channel-artifacts/${CHANNEL_NAME}.block
CHANNEL_PATH=${APP_PATH}/channel-artifacts/channel.tx
ANCHORS_PATH=${APP_PATH}/channel-artifacts/anchors.tx
ORDERER_ADDR=orderer.36sn.com:7050
CAFILE=/home/vagrant/fabric/crypto-config/ordererOrganizations/36sn.com/orderers/orderer.36sn.com/msp/tlscacerts/tlsca.36sn.com-cert.pem
export CORE_PEER_LOCALMSPID=Org1MSP
export CORE_PEER_MSPCONFIGPATH=/home/vagrant/fabric/crypto-config/peerOrganizations/org1.36sn.com/users/Admin@org1.36sn.com/msp
export FABRIC_CFG_PATH=/home/vagrant/fabric/config
env|grep PEER
echo "=======================Start ...========================"
set -x
${APP_PATH}/bin/peer channel create -o ${ORDERER_ADDR} -c ${CHANNEL_NAME} -f ${CHANNEL_PATH} --outputBlock=${BLOCK_PATH} --tls --cafile=${CAFILE}
res=$?
set +x
if [ $res -ne 0 ]; then
echo "Failed to create channel..."
exit 1
fi
set -x
${APP_PATH}/bin/peer channel join -b ${BLOCK_PATH} --tls --cafile=${CAFILE}
res=$?
set +x
if [ $res -ne 0 ]; then
echo "Failed to join channel..."
exit 1
fi
set -x
${APP_PATH}/bin/peer channel update -o ${ORDERER_ADDR} -c ${CHANNEL_NAME} -f ${ANCHORS_PATH} --tls --cafile=${CAFILE}
res=$?
set +x
if [ $res -ne 0 ]; then
echo "Failed to update channel..."
exit 1
fi
八、链码安装
安装完成后,进行链码安装,同样,我把这三步进行了合并:
#!/bin/bash
CHANNEL_NAME="zsjr"
APP_PATH=/home/vagrant/fabric
CAFILE=/home/vagrant/fabric/crypto-config/ordererOrganizations/36sn.com/orderers/orderer.36sn.com/msp/tlscacerts/tlsca.36sn.com-cert.pem
export CORE_PEER_MSPCONFIGPATH=/home/vagrant/fabric/crypto-config/peerOrganizations/org1.36sn.com/users/Admin@org1.36sn.com/msp
export FABRIC_CFG_PATH=/home/vagrant/fabric/config
export GOPATH=/home/vagrant/go
${APP_PATH}/bin/peer chaincode install -n example -v 0.0.2 -p github.com/hyperledger/fabric-demo/chaincode/chaincode_example02/go/ --tls --cafile=${CAFILE}
${APP_PATH}/bin/peer chaincode instantiate -o orderer.36sn.com:7050 -C zsjr -n example -v 0.0.2 -c '{"Args":["init","a","100","b","200"]}' -P 'OR ('\''Org1MSP.member'\'')' --tls --cafile=${CAFILE}
安装完成后,如果想进行安装后的链码查询:
#查询链码情况前,需要设置MSP路径的环境变量
export CORE_PEER_MSPCONFIGPATH=/home/vagrant/fabric/crypto-config/peerOrganizations/org1.36sn.com/users/Admin@org1.36sn.com/msp
# 查询已安装的链码
./peer chaincode list --installed
# 查询已实列化的链码
./peer chaincode -C zsjr list --instantiated
# 查询账户a的全额
./peer chaincode query -C zsjr -n example -c '{"Args":["query","a"]}'
九、结尾
我以将以上代码上传到了github:
https://github.com/yiuked/myfabric.git