hyperledger fabric简述--基于1.4.2部署

一. 基础 

区块链是利用块链式数据结构来验证与存储数据、利用分布式节点共识算法来生成和更新数据、利用密码学的技术保证数据传输和访问控制的安全、利用由自动化脚本代码组成的智能合约来编程和操作数据的一种全新的分布式基础架构与计算范式。目前,区块链被很多大型机构称为彻底改变业务乃至机构运作模式的重大突破性技术。

区块链本质上是一种多方共享的分布式账本技术。它确保交易数据和历史记录的不可篡改,通过共识算法和智能合约实现各参与方对交易的共同确认和账本记录。

区块链根据应用场景和设计不同,主要分为公有链、联盟链和私有链:
1) 公有链:以比特币、以太坊和所有数字货币为代表,各个节点可以自由进入或退出区块链网络;
2) 联盟链:各个节点通常代表实体组织机构或个人,通常需要经过授权后加入或退出网路。由于各机构间通常存在相关利益,因此需要各方共同参与和维护;
3) 私有链:各个节点的准入和退出权限均由内部控制,通常是在特定机构内用于内部数据管理与审计。

1.1 术语

交易Transaction,一次对账本的操作,导致账本状态的一次改变,如添加一条转账记录。

区块Block,记录一段时间内发生的所有交易和状态结果等,是对当前账本状态的一次共识。每个区块记录着上一个区块的hash值、本区块中的交易集合、本区块的hash等基础数据。由于每个区块都有上一区块的hash值,区块间由这个值两两串联,形成区块链。这种链状结构的数据称之为账本数据,保存着所有交易的记录。

区块链Blockchain,由区块按照发生顺序串联而成,是整个账本状态变化的日志记录。最早起源于比特币的底层技术,并在其后不断演进发展。区块链本质是一种多方共享的分布式账本技术。它通过数学方法实现交易数据和历史记录的不可篡改性,通过共识算法和智能合约实现各参与方对交易的共同确认和账本记录。区块链分为公有链、联盟链、私有链三种基本类型。区块链的实现技术框架有以太坊、EOSHyperledger FabricCorda等等。

智能合约:运行在区块链上的模块化、可重用的自动执行脚本。区块链技术的特性之一,用计算机语言描述合同条款、交易的条件、交易的业务逻辑等,通过调用智能合约实现交易的自动执行和对账本数据的操作。智能合约允许在没有第三方的情况下进行可信交易,只要一方达成了协议预先设定的目标,合约将会自动执行交易,这些交易可追踪且不可逆转。具有透明可信、自动执行、强制履约的优点。Fabric中智能合约称为chaincode

共识Consensus,当所有网络参与者同意交易的有效性时,达成共识,确保分布式账本是彼此的精确副本。共识算法解决的是对某个提案(Proposal),大家达成一致意见的过程。

证书颁发机构Certificate Authority,简称CA,数字证书颁发机构是受信任的第三方机构,颁发的数字证书是为最终用户数据加密的公共密钥。

区块链高度Height,当前区块链上区块(Block)的最大数。

哈希Transaction Hash同交易哈希。交易上链成功后,产生的唯一哈希值。

组织organization,代表的是参与区块链业务网络的企业、政府机构、团体等实体。如下图,在阿里云区块链服务中,组织分为两种:
· 联盟运营方组织:负责联盟链公共基础设施的管理运维,包含如下类型:
CA:区块链节点类型之一,Certificate Authority,数字证书颁发机构,负责组织内部成员的registerenroll等,为组织的用户生成和颁发数字证书。
Orderer:区块链节点类型之一,负责交易排序、区块产生和达成共识。
· 业务参与方组织:参与联盟链的公司或企业;每个企业可定义一个或多个组织,包含如下类型:
CA:同联盟运营方CA
Peer:区块链节点类型之一,负责保存和记录账本数据、对交易背书、运行智能合约等。
联盟consortium,指参与一个基于区块链的业务协作或业务交易网络的所有组织的集合,一个联盟一般包含多个组织。
通道channel,主要用于实现联盟链中业务的隔离。每个通道可代表一项业务,通道内包含业务的参与方(联盟内的部分或全部组织)作为通道成员。一个联盟中可以有多个通道;一个组织可以加入多个通道。每个通道可视为一条子链,并且对应有且仅有一套账本,通道上可发布智能合约。一个channel可含有一批chaincode
链码chaincode,是Hyperledger Fabric技术框架中对智能合约的实现,支持业界流行的编程语言如Node.jsGoJava等。
Orderer排序节点,指的是Hyperledger Fabric技术框架下提供共识服务的节点,区块链网络内所有交易在完成背书后会被发送至Orderer节点进行排序,然后根据一定的规则生成区块,并向区块链网络上的Peer节点发送区块以进行区块和交易的验证并写入账本,从而完成共识的全过程。
Peer参与方节点,指的是Hyperledger Fabric技术框架下,业务参与方组织在区块链网络中所拥有的参与共识和账本记录的节点。分为两种类型:Endorsing Peer,背书节点,必须安装链码,在交易时需进行签名背书;Committing Peer,记账节点,无需安装链码,只负责验证从Orderer发出的区块和交易的合法性、并存储账本区块信息。
Anchor锚定节点,指的是Hyperledger Fabric技术框架下,为了实现高可用,每个参与方组织包含两个或多个peer节点,设置其中的一个为anchor,与区块链网络中的其他组织进行信息同步。

World state:对同一个key的多次交易形成的最终的value,就是世界状态。本质为key-value数据库,维护着交易数据的最终状态,便于查询等操作运算,并且每个数据都有其对应的版本号。

Cryptocurrency:加密货币,也称为令牌,加密货币是数字资产的呈现方式。

Genesis Block:创世区块,区块链的第一个区块。

Endorser:背书人,验证交易,调用链码,并将背书的交易结果返回给调用应用程序。

MSPMembership Service Provider,联盟链的成员的证书管理,为组织定义有效身份管理规则的组件。成员服务提供商通过颁发和验证证书来提供身份管理和身份验证过程。MSP 确定信任哪些证书颁发机构(CA)去定义信任域的成员,并确定成员可能扮演的特定角色(成员、管理员等)。在Fabric网络中,MSP出现在两个位置:在通道配置中(通道MSP),在参与者节点本地(本地MSP)。本地 MSP 是为客户端(用户)和节点(Peer 节点和排序节点)定义的。每个节点和用户都必须定义一个本地 MSP因为它定义了谁拥有该级别的管理或参与权通道 MSP 在通道级别定义管理和参与权。每个参与通道的组织都必须为其定义一个 MSP通道上的 Peer 节点和排序节点将共享通道 MSP,因此能够正确地对通道参与者进行身份验证。这意味着,如果某个组织希望加入通道,则需要在通道配置中加入一个包含该组织成员信任链的 MSP。否则,由该组织身份发起的交易将被拒绝。

CSPCrypto Service Provider

CRICertificate Revocation Information,证书撤销信息

LDAPlightweight Directory Access Protocol,轻型目录访问协议

资产:可以理解为任何具有货币价值的东西,可以通过网络交易,无论是有形资产还是无形资产都属于资产。资产在Fabric中以键值对集合的形态存在,在通道(channel)中各本地账本可以对其状态提交变更事务。资产可以用二进制或JSON表示。

P2PPeer-to-Peer,对等网络,即对等计算机网络,是一种在对等者(Peer)之间分配任务和工作负载的分布式应用框架。

Kafka:是一个开源流处理平台。在fabric中,kafka是一种共识模式,也就是说平等信任(同步复制),所有的Fabric网络加盟方都是可信任方,因为消息总是均匀地分布在各地。当orderer生成新的区块后,通过kafka同步到各个peer节点,各个节点将新的区块提交到账本。在fabric 2.1中不再采用kafka,而是推荐使用raft,已集成到orderer

Zookeeper:一个分布式的应用程序协调服务,管理kafkabroker节点,在fabric 2.1中不再采用。

DappDecentralized Application,去中心化应用程序,是一种开源的应用程序,自动运行,将其数据存储在区块链上,以密码令牌的形式激励,并以显示有价值证明的协议进行操作。

DLTDistributed Ledger Technology,分布式账本技术

CFTCrash Fault-Tolerant,崩溃容错(共识协议)

BFTByzantine Fault-Tolerant,拜占庭容错(共识协议)

1.2 共享账本

Hyperledger Fabric有一个账本子系统,包括两个组件:世界状态 和 区块链(交易日志)。对于所属的 Hyperledger Fabric网络,每个参与者都有一份账本的副本。

首先,世界状态是一个数据库,它存储了一组账本状态的当前值。通过世界状态,程序可以直接访问一个账本状态的当前值,不需要遍历整个交易日志来计算当前值。默认情况下,账本状态是以键值对的方式来表示的,可以创建、更新和删除状态。

其次,区块链是交易日志,它记录了促成当前世界状态的所有改变。交易被收集在附加到区块链的区块中,能帮助我们理解所有促成当前世界状态的改变的历史。区块链数据结构与世界状态相差甚远,因为一旦把数据写入区块链,就无法修改,它是不可篡改的。

1.3智能合约

fabric中,智能合约叫做chaincode链码,当区块链网络之外的某个应用程序需要与账本交互时,该应用程序就会调用此网络中的智能合约。多数情况下,链码仅与账本的数据库组件,即世界状态,进行交互(例如,查询世界状态),而不与交易日志交互。链码的执行由事务排序划分,限制了节点类型间的信任和验证级别,并优化了网络的可伸缩性和性能。

chaincode6个状态:

Install → Instantiate → invocable → Upgrade → Deinstantiate → Uninstall.

实际上智能合约就是一段代码,fabric官方认可的是GO语言。首先我们需要把合约代码上传到区块链上,这一步的状态就叫Install

接着,需要做初始化操作。比如,现在的数据是存放在mysql中的,那么上线时需要用Instantiate把数据迁移至链上,这也算初始化。初始化后,chaincode就进入invocable可调用状态了。

通常我们可以通过CLI命令行或者程序里用SDK调用合约(v1.1前还有RestApi调用,现已放弃)。

联盟链由于跨多家企业、多个地区甚至国家,很难使得合约保持一致的版本,因此,每个合约都有版本号。而版本升级时,就是Upgrade状态。

最后两个状态对应着合约下链。

1.3 States and Transactions

There are conceptual objects of value, modeled as states, whose lifecycle transitions are described by transactions.

区块链的记录即值的对象,被模型化(或建模)为state;记录的生命周期转换被描述为交易。

In Hyperledger Fabric, smart contracts implement transaction logic that transition commercial papers between their different states. Commercial paper states are actually held in the ledger world state

Fabric中,智能合约实现交易逻辑(在不同状态间转换),state(状态)被描述为world state

A Fabric state is implemented as a key/value pair, in which the value encodes the object properties in a format that captures the object’s multiple properties, typically JSON. 

Fabricstate是键值对,其中值是对象属性,可以包含多个属性,典型值如JSON

This multi-property aspect of states is a powerful feature – it allows us to think of a Fabric state as a vector rather than a simple scalar.

State的多值属性使得fabric state更像vector(矢量),而不是简单的标量(scalar)。

向量或矢量指既有大小又有方向的量,而标量只有大小,没有方向。

Hyperledger Fabric requires each state in a ledger to have a unique key.

When a unique key is not available from the available set of properties, an application-determined unique key is specified as an input to the transaction that creates the state. This unique key is usually with some form of UUID, which although less readable, is a standard practice. What’s important is that every individual state object in a ledger must have a unique key.

Note: You should avoid using U+0000 (nil byte) in keys.

Fabric 要求每一个单独的state对象必须有一个unique key

1.4 背书策略

策略是使用主体来表达的(主题是跟角色匹配的)。主体可以描述为 'MSP.ROLE', MSP 代表了 MSP ID, ROLE 是以下4个其中之一:member, admin, client, and peer

以下是几个有效的主体示例:

'Org0.admin': Org0 MSP 的任何管理员

'Org1.member': Org1 MSP 的任何成员

'Org1.client': Org1 MSP 的任何客户端

'Org1.peer': Org1 MSP 的任何 Peer

1.5 系统链码

Fabric提供了底层的系统链码:

_lifecycle在所有 Peer 节点上运行,它负责管理节点上的链码安装、批准组织的链码定义、将链码定义提交到通道上。

生命周期系统链码(LSCC) :负责为1.x版本的 Fabric 管理链码生命周期。该版本的生命周期要求在通道上实例化或升级链码。你可以阅读更多关于 LSCC 如何实现这一过程。如果你的 V1_4_x 或更低版本设有通道应用程序的功能,那么你也可以使用 LSCC 来管理链码。

配置系统链码(CSCC:在所有 Peer 节点上运行,以处理通道配置的变化,比如策略更新。

查询系统链码(QSCC): 在所有 Peer 节点上运行,以提供账本 API(应用程序编码接口),其中包括区块查询、交易查询等。

背书系统链码(ESCC): 在背书节点上运行,对一个交易响应进行密码签名。

验证系统链码(VSCC):验证一个交易,包括检查背书策略和读写集版本。你可以在这里阅读更多 LSCC 实现的内容。

二. 安装

2.1 基础安装

1. Centos系统安装,版本:CentOS-7-x86_64-Minimal-1810.iso

2. 安装git

yum install -y git wget

# git version

git version 1.8.3.1

3. Python安装

Centos默认按住python2.7,不用安装(fabric应用python2.7

# python --version

Python 2.7.5

4. Dockerdocker-compose安装

wget -qO- https://get.docker.com | sh

yum install -y epel-release

yum install python-pip

pip install --upgrade pip

pip install docker-compose==1.24.1

# docker --version

Docker version 19.03.8, build afacb8b

# docker-compose --version

docker-compose version 1.24.1, build 4667896

5. Go安装

https://golang.google.cn/doc/install安装v1.14.1版本

curl -o go1.14.1.linux-amd64.tar.gz https://dl.google.com/go/go1.14.1.linux-amd64.tar.gz

tar -C /usr/local -xzf go1.14.1.linux-amd64.tar.gz

echo 'export GO111MODULE=on' >> /etc/profile

echo 'export GOPROXY=https://goproxy.cn' >> /etc/profile

echo 'export PATH=/usr/local/go/bin:$PATH' >> /etc/profile

# source /etc/profile

# go version

go version go1.14 linux/amd64

6. Nodejs安装

http://nodejs.cn/download/下在最新版本

curl -o node-v8.9.4-linux-x64.tar.gz https://npm.taobao.org/mirrors/node/v8.9.4/node-v8.9.4-linux-x64.tar.gz

tar xvf node-v8.9.4-linux-x64.tar.gz -C /usr/local/bin/

#echo 'export PATH=$PATH:/usr/local/bin/node-v8.9.4-linux-x64/bin' >> /etc/profile

# source /etc/profile

# node --version

v8.9.4

# npm --version

5.6.0

#npm install -g cnpm --registry=https://registry.npm.taobao.org

三. 示例

3.1 first-network

#cd fabric-samples/first-network

#./byfn.sh down -i 1.4.2

# ./byfn.sh generate

Generating certs and genesis block for channel 'mychannel' with CLI timeout of '10' seconds and CLI delay of '3' seconds
Continue? [Y/n] Y
proceeding ...
/root/go/bin/cryptogen

##########################################################
##### Generate certificates using cryptogen tool #########
##########################################################
+ cryptogen generate --config=./crypto-config.yaml
org1.example.com
org2.example.com
+ res=0
+ set +x

/root/go/bin/configtxgen
##########################################################
#########  Generating Orderer Genesis block ##############
##########################################################
CONSENSUS_TYPE=solo
+ '[' solo == solo ']'
+ configtxgen -profile TwoOrgsOrdererGenesis -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block
2020-05-28 17:48:08.337 CST [common.tools.configtxgen] main -> INFO 001 Loading configuration
2020-05-28 17:48:08.446 CST [common.tools.configtxgen.localconfig] completeInitialization -> INFO 002 orderer type: solo
2020-05-28 17:48:08.446 CST [common.tools.configtxgen.localconfig] Load -> INFO 003 Loaded configuration: /root/blockchain/fabric-samples/first-network/configtx.yaml
2020-05-28 17:48:08.564 CST [common.tools.configtxgen.localconfig] completeInitialization -> INFO 004 orderer type: solo
2020-05-28 17:48:08.564 CST [common.tools.configtxgen.localconfig] LoadTopLevel -> INFO 005 Loaded configuration: /root/blockchain/fabric-samples/first-network/configtx.yaml
2020-05-28 17:48:08.566 CST [common.tools.configtxgen] doOutputBlock -> INFO 006 Generating genesis block
2020-05-28 17:48:08.566 CST [common.tools.configtxgen] doOutputBlock -> INFO 007 Writing genesis block
+ res=0
+ set +x

#################################################################
### Generating channel configuration transaction 'channel.tx' ###
#################################################################
+ configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID mychannel
2020-05-28 17:48:08.606 CST [common.tools.configtxgen] main -> INFO 001 Loading configuration
2020-05-28 17:48:08.717 CST [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /root/blockchain/fabric-samples/first-network/configtx.yaml
2020-05-28 17:48:08.826 CST [common.tools.configtxgen.localconfig] completeInitialization -> INFO 003 orderer type: solo
2020-05-28 17:48:08.826 CST [common.tools.configtxgen.localconfig] LoadTopLevel -> INFO 004 Loaded configuration: /root/blockchain/fabric-samples/first-network/configtx.yaml
2020-05-28 17:48:08.826 CST [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 005 Generating new channel configtx
2020-05-28 17:48:08.828 CST [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 006 Writing new channel tx
+ res=0
+ set +x

#################################################################
#######    Generating anchor peer update for Org1MSP   ##########
#################################################################
+ configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID mychannel -asOrg Org1MSP
2020-05-28 17:48:08.870 CST [common.tools.configtxgen] main -> INFO 001 Loading configuration
2020-05-28 17:48:08.983 CST [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /root/blockchain/fabric-samples/first-network/configtx.yaml
2020-05-28 17:48:09.094 CST [common.tools.configtxgen.localconfig] completeInitialization -> INFO 003 orderer type: solo
2020-05-28 17:48:09.094 CST [common.tools.configtxgen.localconfig] LoadTopLevel -> INFO 004 Loaded configuration: /root/blockchain/fabric-samples/first-network/configtx.yaml
2020-05-28 17:48:09.094 CST [common.tools.configtxgen] doOutputAnchorPeersUpdate -> INFO 005 Generating anchor peer update
2020-05-28 17:48:09.094 CST [common.tools.configtxgen] doOutputAnchorPeersUpdate -> INFO 006 Writing anchor peer update
+ res=0
+ set +x

#################################################################
#######    Generating anchor peer update for Org2MSP   ##########
#################################################################
+ configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID mychannel -asOrg Org2MSP
2020-05-28 17:48:09.131 CST [common.tools.configtxgen] main -> INFO 001 Loading configuration
2020-05-28 17:48:09.235 CST [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /root/blockchain/fabric-samples/first-network/configtx.yaml
2020-05-28 17:48:09.347 CST [common.tools.configtxgen.localconfig] completeInitialization -> INFO 003 orderer type: solo
2020-05-28 17:48:09.347 CST [common.tools.configtxgen.localconfig] LoadTopLevel -> INFO 004 Loaded configuration: /root/blockchain/fabric-samples/first-network/configtx.yaml
2020-05-28 17:48:09.347 CST [common.tools.configtxgen] doOutputAnchorPeersUpdate -> INFO 005 Generating anchor peer update
2020-05-28 17:48:09.348 CST [common.tools.configtxgen] doOutputAnchorPeersUpdate -> INFO 006 Writing anchor peer update
+ res=0
+ set +x
byfn.sh generate

# ./byfn.sh up -o etcdraft -s couchdb -i 1.4.2

Starting for channel 'mychannel' with CLI timeout of '10' seconds and CLI delay of '3' seconds and using database 'couchdb'
Continue? [Y/n] Y
proceeding ...
LOCAL_VERSION=1.4.2
DOCKER_IMAGE_VERSION=1.4.2
Creating network "net_byfn" with the default driver
Creating volume "net_orderer.example.com" with default driver
Creating volume "net_orderer2.example.com" with default driver
Creating volume "net_peer0.org2.example.com" with default driver
Creating volume "net_peer0.org1.example.com" with default driver
Creating volume "net_peer1.org1.example.com" with default driver
Creating volume "net_peer1.org2.example.com" with default driver
Creating volume "net_orderer5.example.com" with default driver
Creating volume "net_orderer4.example.com" with default driver
Creating volume "net_orderer3.example.com" with default driver
Pulling couchdb0 (hyperledger/fabric-couchdb:)...
latest: Pulling from hyperledger/fabric-couchdb
8f91359f1fff: Pull complete
f378e5ce64c7: Pull complete
a6dccd725057: Pull complete
e9425c7bff87: Pull complete
01a45d85ea79: Pull complete
6edce107841b: Pull complete
4df79a56407c: Pull complete
14351b84e072: Pull complete
7600b3a98f63: Pull complete
9b3796b842a6: Pull complete
39f3bcda0c05: Pull complete
Digest: sha256:09ea5e07d3322c661bd5f3e84a7603a595d40438ec4f8a4e54929c2b8765c9d9
Status: Downloaded newer image for hyperledger/fabric-couchdb:latest
Creating orderer5.example.com   ... done
Creating orderer2.example.com   ... done
Creating couchdb1             ... done
Creating couchdb0               ... done
Creating couchdb3               ... done
Creating orderer3.example.com   ... done
Creating orderer.example.com    ... done
Creating orderer4.example.com   ... done
Creating couchdb2               ... done
Creating peer1.org1.example.com ... done
Creating peer0.org2.example.com ... done
Creating peer0.org1.example.com ... done
Creating peer1.org2.example.com ... done
Creating cli                    ... done
CONTAINER ID        IMAGE                                    COMMAND                  CREATED             STATUS                  PORTS                                        NAMES
8814c1f3a845        hyperledger/fabric-tools:amd64-1.4.2     "/bin/bash"              1 second ago        Up Less than a second                                                cli
ad993a946734        hyperledger/fabric-peer:amd64-1.4.2      "peer node start"        2 seconds ago       Up Less than a second   0.0.0.0:7051->7051/tcp                       peer0.org1.example.com
d0a924f7a659        hyperledger/fabric-peer:amd64-1.4.2      "peer node start"        2 seconds ago       Up Less than a second   0.0.0.0:10051->10051/tcp                     peer1.org2.example.com
9f45f8fc8c06        hyperledger/fabric-peer:amd64-1.4.2      "peer node start"        3 seconds ago       Up 1 second             0.0.0.0:9051->9051/tcp                       peer0.org2.example.com
64a4b21c1ab9        hyperledger/fabric-peer:amd64-1.4.2      "peer node start"        3 seconds ago       Up 1 second             0.0.0.0:8051->8051/tcp                       peer1.org1.example.com
88050ab56af0        hyperledger/fabric-orderer:amd64-1.4.2   "orderer"                4 seconds ago       Up 1 second             0.0.0.0:10050->7050/tcp                      orderer4.example.com
022b04e0df5f        hyperledger/fabric-couchdb               "tini -- /docker-ent…"   4 seconds ago       Up 1 second             4369/tcp, 9100/tcp, 0.0.0.0:5984->5984/tcp   couchdb0
0c752175f5f0        hyperledger/fabric-orderer:amd64-1.4.2   "orderer"                4 seconds ago       Up 1 second             0.0.0.0:8050->7050/tcp                       orderer2.example.com
73c0427445bd        hyperledger/fabric-couchdb               "tini -- /docker-ent…"   4 seconds ago       Up 1 second             4369/tcp, 9100/tcp, 0.0.0.0:8984->5984/tcp   couchdb3
497c414eddac        hyperledger/fabric-orderer:amd64-1.4.2   "orderer"                4 seconds ago       Up 1 second             0.0.0.0:7050->7050/tcp                       orderer.example.com
488cf94da47d        hyperledger/fabric-couchdb               "tini -- /docker-ent…"   4 seconds ago       Up 2 seconds            4369/tcp, 9100/tcp, 0.0.0.0:7984->5984/tcp   couchdb2
3b8f5a9565d9        hyperledger/fabric-orderer:amd64-1.4.2   "orderer"                4 seconds ago       Up 2 seconds            0.0.0.0:9050->7050/tcp                       orderer3.example.com
a6955431ac04        hyperledger/fabric-orderer:amd64-1.4.2   "orderer"                4 seconds ago       Up 2 seconds            0.0.0.0:11050->7050/tcp                      orderer5.example.com
67371f19634d        hyperledger/fabric-couchdb               "tini -- /docker-ent…"   4 seconds ago       Up 2 seconds            4369/tcp, 9100/tcp, 0.0.0.0:6984->5984/tcp   couchdb1
Sleeping 15s to allow etcdraft cluster to complete booting

 ____    _____      _      ____    _____
/ ___|  |_   _|    / \    |  _ \  |_   _|
\___ \    | |     / _ \   | |_) |   | |
 ___) |   | |    / ___ \  |  _ <    | |
|____/    |_|   /_/   \_\ |_| \_\   |_|

Build your first network (BYFN) end-to-end test

Channel name : mychannel
Creating channel...
+ peer channel create -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/channel.tx --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
+ res=0
+ set +x
2020-05-28 09:53:19.277 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2020-05-28 09:53:19.316 UTC [cli.common] readBlock -> INFO 002 Received block: 0
+ peer channel join -b mychannel.block
===================== Channel 'mychannel' created =====================

Having all peers join the channel...
+ res=0
+ set +x
2020-05-28 09:53:19.385 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2020-05-28 09:53:19.492 UTC [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
===================== peer0.org1 joined channel 'mychannel' =====================

+ peer channel join -b mychannel.block
+ res=0
+ set +x
2020-05-28 09:53:22.557 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2020-05-28 09:53:22.652 UTC [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
===================== peer1.org1 joined channel 'mychannel' =====================

+ peer channel join -b mychannel.block
+ res=0
+ set +x
2020-05-28 09:53:25.734 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2020-05-28 09:53:25.834 UTC [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
===================== peer0.org2 joined channel 'mychannel' =====================

+ peer channel join -b mychannel.block
+ res=0
+ set +x
2020-05-28 09:53:29.141 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2020-05-28 09:53:29.688 UTC [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
===================== peer1.org2 joined channel 'mychannel' =====================

Updating anchor peers for org1...
+ peer channel update -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/Org1MSPanchors.tx --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
+ res=0
+ set +x
2020-05-28 09:53:32.756 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2020-05-28 09:53:32.770 UTC [channelCmd] update -> INFO 002 Successfully submitted channel update
===================== Anchor peers updated for org 'Org1MSP' on channel 'mychannel' =====================
+ peer channel update -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/Org2MSPanchors.tx --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

Updating anchor peers for org2...
+ res=0
+ set +x
2020-05-28 09:53:35.837 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2020-05-28 09:53:35.854 UTC [channelCmd] update -> INFO 002 Successfully submitted channel update
===================== Anchor peers updated for org 'Org2MSP' on channel 'mychannel' =====================

Installing chaincode on peer0.org1...
+ peer chaincode install -n mycc -v 1.0 -l golang -p github.com/chaincode/chaincode_example02/go/
+ res=0
+ set +x
2020-05-28 09:53:38.934 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
2020-05-28 09:53:38.934 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
2020-05-28 09:53:39.179 UTC [chaincodeCmd] install -> INFO 003 Installed remotely response:<status:200 payload:"OK" >
===================== Chaincode is installed on peer0.org1 =====================

Install chaincode on peer0.org2...
+ peer chaincode install -n mycc -v 1.0 -l golang -p github.com/chaincode/chaincode_example02/go/
+ res=0
+ set +x
+ peer chaincode instantiate -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n mycc -l golang -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P 'AND ('\''Org1MSP.peer'\'','\''Org2MSP.peer'\'')'
2020-05-28 09:53:39.249 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
2020-05-28 09:53:39.249 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
2020-05-28 09:53:39.489 UTC [chaincodeCmd] install -> INFO 003 Installed remotely response:<status:200 payload:"OK" >
===================== Chaincode is installed on peer0.org2 =====================

Instantiating chaincode on peer0.org2...
+ res=0
+ set +x
2020-05-28 09:53:39.574 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
2020-05-28 09:53:39.574 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
===================== Chaincode is instantiated on peer0.org2 on channel 'mychannel' =====================

Querying chaincode on peer0.org1...
===================== Querying on peer0.org1 on channel 'mychannel'... =====================
Attempting to Query peer0.org1 ...3 secs
+ peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'
+ res=0
+ set +x

100
===================== Query successful on peer0.org1 on channel 'mychannel' =====================
Sending invoke transaction on peer0.org1 peer0.org2...
+ peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n mycc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["invoke","a","b","10"]}'
+ res=0
+ set +x
2020-05-28 09:56:23.928 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200
===================== Invoke transaction successful on peer0.org1 peer0.org2 on channel 'mychannel' =====================

Installing chaincode on peer1.org2...
+ peer chaincode install -n mycc -v 1.0 -l golang -p github.com/chaincode/chaincode_example02/go/
+ res=0
+ set +x
2020-05-28 09:56:23.985 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
2020-05-28 09:56:23.985 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
2020-05-28 09:56:24.442 UTC [chaincodeCmd] install -> INFO 003 Installed remotely response:<status:200 payload:"OK" >
===================== Chaincode is installed on peer1.org2 =====================

Querying chaincode on peer1.org2...
===================== Querying on peer1.org2 on channel 'mychannel'... =====================
+ peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'
Attempting to Query peer1.org2 ...3 secs
+ res=0
+ set +x

90
===================== Query successful on peer1.org2 on channel 'mychannel' =====================

========= All GOOD, BYFN execution completed ===========


 _____   _   _   ____
| ____| | \ | | |  _ \
|  _|   |  \| | | | | |
| |___  | |\  | | |_| |
|_____| |_| \_| |____/
byfn.sh up

手动启动

// 生成证书和密钥

# cryptogen generate --config=./crypto-config.yaml

// 创建排序通道创世区块

# export FABRIC_CFG_PATH=$PWD

# configtxgen -profile SampleMultiNodeEtcdRaft -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block

// 创建通道交易构件

# export CHANNEL_NAME=mychannel

# configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME

// 在通道上为Org1定义锚节点

# configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP

// 在通道上为Org2定义锚节点

# configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP

// 启动网络

# IMAGE_TAG=amd64-1.4.2 docker-compose -f docker-compose-cli.yaml -f docker-compose-etcdraft2.yaml -f docker-compose-couch.yaml up -d

// 创建和加入通道

# docker exec -it cli bash

Cli#export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp

Cli#export CORE_PEER_ADDRESS=peer0.org1.example.com:7051

Cli#export CORE_PEER_LOCALMSPID="Org1MSP"

Cli#export 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

Cli# export CHANNEL_NAME=mychannel

// 生成创世区块mychannel.block

Cli# peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

// peer加入通道

Cli# peer channel join -b mychannel.block

Cli#CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp CORE_PEER_ADDRESS=peer0.org2.example.com:9051 CORE_PEER_LOCALMSPID="Org2MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt peer channel join -b mychannel.block

//更新锚节点

Cli#peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org1MSPanchors.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

Cli#CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp CORE_PEER_ADDRESS=peer0.org2.example.com:9051 CORE_PEER_LOCALMSPID="Org2MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org2MSPanchors.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

//安装链码

Cli#peer chaincode install -n mycc -v 1.0 -p github.com/chaincode/chaincode_example02/go/

Cli#CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp CORE_PEER_ADDRESS=peer0.org2.example.com:9051 CORE_PEER_LOCALMSPID="Org2MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt peer chaincode install -n mycc -v 1.0 -p github.com/chaincode/chaincode_example02/go/

// 实例化链码

Cli# peer chaincode instantiate -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n mycc -v 1.0 -c '{"Args":["init","a", "100", "b","200"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer')"

// 应用:查询、调用

Cli#peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'

Cli#peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n mycc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["invoke","a","b","10"]}'

// Org2peer1上应用

Cli# export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp

CORE_PEER_ADDRESS=peer1.org2.example.com:10051

CORE_PEER_LOCALMSPID="Org2MSP"

CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt

Cli# peer chaincode install -n mycc -v 1.0 -p github.com/chaincode/chaincode_example02/go/

Cli# peer channel join -b mychannel.block

Cli# peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'

向通道添加Org3

// 生成MSP

# cd org3-artifacts

# cryptogen generate --config=./org3-crypto.yaml

# export FABRIC_CFG_PATH=$PWD && configtxgen -printOrg Org3MSP > ../channel-artifacts/org3.json

# cd ../ && cp -r crypto-config/ordererOrganizations org3-artifacts/crypto-config/

// 升级通道配置

# docker exec -it cli bash

Cli# export ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem && export CHANNEL_NAME=mychannel

Cli#echo $ORDERER_CA && echo $CHANNEL_NAME

Cli#peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CA

Cli#configtxlator proto_decode --input config_block.pb --type common.Block | jq .data.data[0].payload.data.config > config.json

Cli#jq -s '.[0] * {"channel_group":{"groups":{"Application":{"groups": {"Org3MSP":.[1]}}}}}' config.json ./channel-artifacts/org3.json > modified_config.json

Cli#configtxlator proto_encode --input config.json --type common.Config --output config.pb

Cli#configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb

Cli#configtxlator compute_update --channel_id $CHANNEL_NAME --original config.pb --updated modified_config.pb --output org3_update.pb

Cli#configtxlator proto_decode --input org3_update.pb --type common.ConfigUpdate | jq . > org3_update.json

Cli#echo '{"payload":{"header":{"channel_header":{"channel_id":"'$CHANNEL_NAME'", "type":2}},"data":{"config_update":'$(cat org3_update.json)'}}}' | jq . > org3_update_in_envelope.json

Cli#configtxlator proto_encode --input org3_update_in_envelope.json --type common.Envelope --output org3_update_in_envelope.pb

// 签名并提交配置更新

Cli#peer channel signconfigtx -f org3_update_in_envelope.pb

Cli#export CORE_PEER_LOCALMSPID="Org2MSP"

Cli#export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt

Cli#export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp

Cli#export CORE_PEER_ADDRESS=peer0.org2.example.com:9051

Cli#peer channel update -f org3_update_in_envelope.pb -c $CHANNEL_NAME -o orderer.example.com:7050 --tls --cafile $ORDERER_CA

// Org3加入通道

# IMAGE_TAG=amd64-1.4.2 docker-compose -f docker-compose-org3.yaml -f docker-compose-couch-org3.yaml up -d

# docker exec -it Org3cli bash

Cli#export ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem && export CHANNEL_NAME=mychannel

Cli#echo $ORDERER_CA && echo $CHANNEL_NAME

Cli#peer channel fetch 0 mychannel.block -o orderer.example.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CA

Cli#peer channel join -b mychannel.block

Cli#export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/peers/peer1.org3.example.com/tls/ca.crt && export CORE_PEER_ADDRESS=peer1.org3.example.com:12051 && peer channel join -b mychannel.block

// 升级和调用链码

// org3安装链码v2.0

# docker exec -it Org3cli bash

Cli# peer chaincode install -n mycc -v 2.0 -p github.com/chaincode/chaincode_example02/go/

// org1/org2安装链码v2.0

# docker exec -it cli bash

Cli#peer chaincode install -n mycc -v 2.0 -p github.com/chaincode/chaincode_example02/go/

Cli# export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp

CORE_PEER_ADDRESS=peer1.org2.example.com:10051

CORE_PEER_LOCALMSPID="Org2MSP"

CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt

Cli# peer chaincode install -n mycc -v 2.0 -p github.com/chaincode/chaincode_example02/go/

# docker exec -it Org3cli bash

Cli#export ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem && export CHANNEL_NAME=mychannel

Cli#peer chaincode upgrade -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -v 2.0 -c '{"Args":["init","a","90","b","210"]}' -P "OR ('Org1MSP.peer','Org2MSP.peer','Org3MSP.peer')"

2020-05-30 07:15:59.968 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc

2020-05-30 07:15:59.968 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc

Error: could not assemble transaction, err proposal response was not successful, error code 500, msg instantiation policy violation: signature set did not satisfy policy

// 只有链码的原来示例化的peer可以执行升级操作,即通道的管理者,目前org3不是,而org1org2是管理者

# docker exec -it cli bash

Cli# peer chaincode upgrade -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n mycc -v 2.0 -c '{"Args":["init","a","90","b","210"]}' -P "OR ('Org1MSP.peer','Org2MSP.peer','Org3MSP.peer')"

2020-05-30 07:17:28.519 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc

2020-05-30 07:17:28.519 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc

# docker exec -it Org3cli bash

Cli# peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'

90

Cli#export ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem && export CHANNEL_NAME=mychannel

cli#peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -c '{"Args":["invoke","a","b","10"]}'

Cli# peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'

80

// 更新通道配置使包含org3 Anchor Peer

# docker exec -it Org3cli bash

Cli#export ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem && export CHANNEL_NAME=mychannel

cli#peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CA

cli#configtxlator proto_decode --input config_block.pb --type common.Block | jq .data.data[0].payload.data.config > config.json

cli#jq '.channel_group.groups.Application.groups.Org3MSP.values += {"AnchorPeers":{"mod_policy": "Admins","value":{"anchor_peers": [{"host": "peer0.org3.example.com","port": 11051}]},"version": "0"}}' config.json > modified_anchor_config.json

cli#configtxlator proto_encode --input config.json --type common.Config --output config.pb

cli#configtxlator proto_encode --input modified_anchor_config.json --type common.Config --output modified_anchor_config.pb

cli#configtxlator compute_update --channel_id $CHANNEL_NAME --original config.pb --updated modified_anchor_config.pb --output anchor_update.pb

cli#configtxlator proto_decode --input anchor_update.pb --type common.ConfigUpdate | jq . > anchor_update.json

Cli#echo '{"payload":{"header":{"channel_header":{"channel_id":"mychannel", "type":2}},"data":{"config_update":'$(cat anchor_update.json)'}}}' | jq . > anchor_update_in_envelope.json

Cli#configtxlator proto_encode --input anchor_update_in_envelope.json --type common.Envelope --output anchor_update_in_envelope.pb

Cli#peer channel update -f anchor_update_in_envelope.pb -c $CHANNEL_NAME -o orderer.example.com:7050 --tls --cafile $ORDERER_CA

3.2 fabric-sdk-go运行

# git clone https://gitee.com/yuxio/fabric-sdk-go.git

# cd fabric-sdk-go

# make dockerenv-stable-up

//////////
rm -Rf /tmp/enroll_user /tmp/msp /tmp/keyvaluestore /tmp/hfc-kvs /tmp/state /tmp/state-store
rm -f integration-report.xml report.xml
go clean
FIXTURE_PROJECT_NAME=fabsdkgo DOCKER_REMOVE_FORCE=false test/scripts/clean_integration.sh
FABRIC_CRYPTOCONFIG_VERSION=v1 \
FABRIC_FIXTURE_VERSION=v1.4 \
FABRIC_SDKGO_CODELEVEL_TAG=stable \
test/scripts/populate-fixtures.sh
. /root/blockchain/fabric-sdk-go/test/fixtures/dockerenv/stable-env.sh && \
    . /root/blockchain/fabric-sdk-go/test/fixtures/fabric/v1/crypto-config/env.sh && \
        cd /root/blockchain/fabric-sdk-go/test/fixtures/dockerenv && \
        FABRIC_SDKGO_CODELEVEL_VER=v1.4 FABRIC_SDKGO_CODELEVEL_TAG=stable FABRIC_DOCKER_REGISTRY= \
        docker-compose -f ./docker-compose-std.yaml -f ./docker-compose.yaml up --remove-orphans --force-recreate

启动完成后,镜像如下:

# docker images

REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
hyperledger/fabric-ca          amd64-1.4.2         f289675c9874        10 months ago       253MB
hyperledger/fabric-tools       amd64-1.4.2         0abc124a9400        10 months ago       1.55GB
hyperledger/fabric-ccenv       amd64-1.4.2         fc0f502399a6        10 months ago       1.43GB
hyperledger/fabric-orderer     amd64-1.4.2         362021998003        10 months ago       173MB
hyperledger/fabric-peer        amd64-1.4.2         d79f2f4f3257        10 months ago       178MB
hyperledger/fabric-baseimage   amd64-0.4.15        c4c532c23a50        14 months ago       1.39GB
hyperledger/fabric-baseos      amd64-0.4.15        9d6ec11c60ff        14 months ago       145MB

# docker ps

CONTAINER ID        IMAGE                                       COMMAND                  CREATED              STATUS              PORTS                              NAMES
35be593a2d90        hyperledger/fabric-peer:amd64-1.4.2         "peer node start"        About a minute ago   Up About a minute   0.0.0.0:8051->8051/tcp, 8052/tcp   fabsdkgo_org2peer1_1
2522d3ad6983        hyperledger/fabric-peer:amd64-1.4.2         "peer node start"        About a minute ago   Up About a minute   0.0.0.0:7151->7151/tcp, 7152/tcp   fabsdkgo_org1peer2_1
c1a81bf58d6a        hyperledger/fabric-peer:amd64-1.4.2         "peer node start"        About a minute ago   Up About a minute   0.0.0.0:7051->7051/tcp, 7052/tcp   fabsdkgo_org1peer1_1
5f9be5047b7e        hyperledger/fabric-peer:amd64-1.4.2         "peer node start"        About a minute ago   Up About a minute   0.0.0.0:9051->9051/tcp, 9052/tcp   fabsdkgo_org2peer2_1
3a51daee0f63        hyperledger/fabric-baseimage:amd64-0.4.15   "tail -F anything"       About a minute ago   Up About a minute                                      fabsdkgo_chaincoded_1
246727155c9d        hyperledger/fabric-ca:amd64-1.4.2           "sh -c 'fabric-ca-se…"   About a minute ago   Up About a minute   0.0.0.0:7054->7054/tcp             fabsdkgo_org1ca1_1
abf1a94b95b8        hyperledger/fabric-orderer:amd64-1.4.2      "orderer"                About a minute ago   Up About a minute   0.0.0.0:7050->7050/tcp             fabsdkgo_orderer1_1
9d683b7961ab        hyperledger/fabric-ca:amd64-1.4.2           "sh -c 'fabric-ca-se…"   About a minute ago   Up About a minute   7054/tcp, 0.0.0.0:7154->7154/tcp   fabsdkgo_org1tlsca_1
8449e193c451        hyperledger/fabric-baseos:amd64-0.4.15      "tail -F anything"       About a minute ago   Up About a minute                                      fabsdkgo_golangruntime_1
347e7bb9ef8b        hyperledger/fabric-ca:amd64-1.4.2           "sh -c 'fabric-ca-se…"   About a minute ago   Up About a minute   7054/tcp, 0.0.0.0:8054->8054/tcp   fabsdkgo_org2ca1_1
c15bc331349a        hyperledger/fabric-ccenv:amd64-1.4.2        "tail -F anything"       About a minute ago   Up About a minute                                      fabsdkgo_builder_1

 

密钥配置生成

# make crypto-gen

Generating crypto directory ...
+ CRYPTOGEN_CMD=cryptogen
+ FIXTURES_PATH=/opt/workspace/fabric-sdk-go/test/fixtures
+ CONFIG_DIR=config
+ '[' -z fabric/v1 ']'
+ peerOrgs=("org1.example.com" "org2.example.com")
+ declare -a peerOrgs
+ ordererOrgs=("example.com")
+ declare -a ordererOrgs
+ declare tlsOrg=tls.example.com
+ echo Clearing old crypto directory ...
+ rm -Rf /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1/crypto-config
Clearing old crypto directory ...
Running cryptogen ...
+ echo Running cryptogen ...
+ cryptogen generate --config=/opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1/config/cryptogen.yaml --output=/opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1/crypto-config
org1.example.com
org2.example.com
tls.example.com
+ for org in '${peerOrgs[@]}'
+ rm -Rf /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1/crypto-config/peerOrganizations/org1.example.com/peers/ca.org1.example.com/msp
+ for org in '${peerOrgs[@]}'
+ rm -Rf /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1/crypto-config/peerOrganizations/org2.example.com/peers/ca.org2.example.com/msp
+ rm -Rf /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1/crypto-config/peerOrganizations/tls.example.com/ca
+ rm -Rf /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1/crypto-config/peerOrganizations/tls.example.com/msp
+ rm -Rf /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1/crypto-config/peerOrganizations/tls.example.com/peers
+ rm -Rf /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1/crypto-config/peerOrganizations/tls.example.com/users/Admin@tls.example.com
+ rm -Rf /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1/crypto-config/peerOrganizations/tls.example.com/users/User1@tls.example.com/msp
+ echo 'Generating environment for docker ...'
+ printf '#!/bin/bash\n'
Generating environment for docker ...
++ ls /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1/crypto-config/peerOrganizations/org1.example.com/ca/2a02a8350fb9853e1637217f8c847c659b162dfc9804ae4c371604c9d89245d7_sk
+ keyPath=/opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1/crypto-config/peerOrganizations/org1.example.com/ca/2a02a8350fb9853e1637217f8c847c659b162dfc9804ae4c371604c9d89245d7_sk
+ printf 'export ORG1CA1_FABRIC_CA_SERVER_CA_KEYFILE=/etc/hyperledger/fabric-ca-server-config/%s\n' 2a02a8350fb9853e1637217f8c847c659b162dfc9804ae4c371604c9d89245d7_sk
++ ls /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1/crypto-config/peerOrganizations/org1.example.com/tlsca/43257f4071d76bd7699a3c5022fb3bd96fc657ea90837eac5aec58ba74b5cd8a_sk
+ keyPath=/opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1/crypto-config/peerOrganizations/org1.example.com/tlsca/43257f4071d76bd7699a3c5022fb3bd96fc657ea90837eac5aec58ba74b5cd8a_sk
+ printf 'export ORG1TLSCA_FABRIC_CA_SERVER_CA_KEYFILE=/etc/hyperledger/fabric-ca-server-config/%s\n' 43257f4071d76bd7699a3c5022fb3bd96fc657ea90837eac5aec58ba74b5cd8a_sk
++ ls /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1/crypto-config/peerOrganizations/org2.example.com/ca/f4851b2f59578e47abcf5abd0714cc2c0e93eca1290cbaeee2da2b10e3f97523_sk
+ keyPath=/opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1/crypto-config/peerOrganizations/org2.example.com/ca/f4851b2f59578e47abcf5abd0714cc2c0e93eca1290cbaeee2da2b10e3f97523_sk
+ printf 'export ORG2CA1_FABRIC_CA_SERVER_CA_KEYFILE=/etc/hyperledger/fabric-ca-server-config/%s\n' f4851b2f59578e47abcf5abd0714cc2c0e93eca1290cbaeee2da2b10e3f97523_sk

Channel配置生成

# make channel-config-stable-gen

Generating test channel configuration transactions and blocks (code level stable) ...
+ CONFIGTXGEN_CMD=configtxgen
+ FIXTURES_PATH=/opt/workspace/fabric-sdk-go/test/fixtures/
+ CHANNEL_DIR=channel
+ CONFIG_DIR=config
+ '[' -z fabric/v1.4/ ']'
+ oneOrgChannels=("mychannel")
+ declare -a oneOrgChannels
+ twoOrgChannels=("orgchannel")
+ declare -a twoOrgChannels
+ dsChannels=("dschannelsdk" "dschannelext")
+ declare -a dsChannels
+ orgs=("Org1MSP" "Org2MSP")
+ declare -a orgs
+ FIXTURES_CHANNEL_PATH=/opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/channel
+ export FABRIC_CFG_PATH=/opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/config
+ FABRIC_CFG_PATH=/opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/config
+ echo 'Generating channel fixtures into /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/channel'
Generating channel fixtures into /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/channel
+ mkdir -p /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/channel
Generating Orderer Genesis block
+ echo 'Generating Orderer Genesis block'
+ configtxgen -profile TwoOrgsOrdererGenesis -outputBlock /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/channel/twoorgs.genesis.block -channelID twoorgs
2020-05-26 08:12:42.621 UTC [common.tools.configtxgen] main -> INFO 001 Loading configuration
2020-05-26 08:12:42.684 UTC [common.tools.configtxgen.localconfig] completeInitialization -> INFO 002 orderer type: solo
2020-05-26 08:12:42.684 UTC [common.tools.configtxgen.localconfig] Load -> INFO 003 Loaded configuration: /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/config/configtx.yaml
2020-05-26 08:12:42.748 UTC [common.tools.configtxgen.localconfig] completeInitialization -> INFO 004 orderer type: solo
2020-05-26 08:12:42.748 UTC [common.tools.configtxgen.localconfig] LoadTopLevel -> INFO 005 Loaded configuration: /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/config/configtx.yaml
2020-05-26 08:12:42.750 UTC [common.tools.configtxgen] doOutputBlock -> INFO 006 Generating genesis block
2020-05-26 08:12:42.751 UTC [common.tools.configtxgen] doOutputBlock -> INFO 007 Writing genesis block
Generating OneOrgChannel artifacts for channel: mychannel
Generating channel configuration transaction
+ for i in '"${oneOrgChannels[@]}"'
+ echo 'Generating OneOrgChannel artifacts for channel: mychannel'
+ echo 'Generating channel configuration transaction'
+ configtxgen -profile OneOrgChannel -outputCreateChannelTx ./opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/channel/mychannel.tx -channelID mychannel
2020-05-26 08:12:42.784 UTC [common.tools.configtxgen] main -> INFO 001 Loading configuration
2020-05-26 08:12:42.856 UTC [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/config/configtx.yaml
2020-05-26 08:12:42.916 UTC [common.tools.configtxgen.localconfig] completeInitialization -> INFO 003 orderer type: solo
2020-05-26 08:12:42.916 UTC [common.tools.configtxgen.localconfig] LoadTopLevel -> INFO 004 Loaded configuration: /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/config/configtx.yaml
2020-05-26 08:12:42.916 UTC [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 005 Generating new channel configtx
2020-05-26 08:12:42.918 UTC [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 006 Writing new channel tx
Generating TwoOrgsChannel artifacts for channel: orgchannel
Generating channel configuration transaction
+ for i in '"${twoOrgChannels[@]}"'
+ echo 'Generating TwoOrgsChannel artifacts for channel: orgchannel'
+ echo 'Generating channel configuration transaction'
+ configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/channel/orgchannel.tx -channelID orgchannel
2020-05-26 08:12:42.952 UTC [common.tools.configtxgen] main -> INFO 001 Loading configuration
2020-05-26 08:12:43.017 UTC [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/config/configtx.yaml
2020-05-26 08:12:43.079 UTC [common.tools.configtxgen.localconfig] completeInitialization -> INFO 003 orderer type: solo
2020-05-26 08:12:43.079 UTC [common.tools.configtxgen.localconfig] LoadTopLevel -> INFO 004 Loaded configuration: /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/config/configtx.yaml
2020-05-26 08:12:43.079 UTC [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 005 Generating new channel configtx
2020-05-26 08:12:43.081 UTC [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 006 Writing new channel tx
+ for j in '"${orgs[@]}"'
+ echo 'Generating anchor peer update for org Org1MSP'
+ configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/channel/orgchannelOrg1MSPanchors.tx -channelID orgchannel -asOrg Org1MSP
Generating anchor peer update for org Org1MSP
2020-05-26 08:12:43.115 UTC [common.tools.configtxgen] main -> INFO 001 Loading configuration
2020-05-26 08:12:43.178 UTC [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/config/configtx.yaml
2020-05-26 08:12:43.248 UTC [common.tools.configtxgen.localconfig] completeInitialization -> INFO 003 orderer type: solo
2020-05-26 08:12:43.248 UTC [common.tools.configtxgen.localconfig] LoadTopLevel -> INFO 004 Loaded configuration: /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/config/configtx.yaml
2020-05-26 08:12:43.248 UTC [common.tools.configtxgen] doOutputAnchorPeersUpdate -> INFO 005 Generating anchor peer update
2020-05-26 08:12:43.248 UTC [common.tools.configtxgen] doOutputAnchorPeersUpdate -> INFO 006 Writing anchor peer update
+ for j in '"${orgs[@]}"'
+ echo 'Generating anchor peer update for org Org2MSP'
Generating anchor peer update for org Org2MSP
+ configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/channel/orgchannelOrg2MSPanchors.tx -channelID orgchannel -asOrg Org2MSP
2020-05-26 08:12:43.283 UTC [common.tools.configtxgen] main -> INFO 001 Loading configuration
2020-05-26 08:12:43.346 UTC [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/config/configtx.yaml
2020-05-26 08:12:43.407 UTC [common.tools.configtxgen.localconfig] completeInitialization -> INFO 003 orderer type: solo
2020-05-26 08:12:43.407 UTC [common.tools.configtxgen.localconfig] LoadTopLevel -> INFO 004 Loaded configuration: /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/config/configtx.yaml
2020-05-26 08:12:43.407 UTC [common.tools.configtxgen] doOutputAnchorPeersUpdate -> INFO 005 Generating anchor peer update
2020-05-26 08:12:43.407 UTC [common.tools.configtxgen] doOutputAnchorPeersUpdate -> INFO 006 Writing anchor peer update
Generating DsChannel (Distributed Signing Identities Channel) artifacts for channel: dschannelsdk
Generating channel configuration transaction
+ for i in '"${dsChannels[@]}"'
+ echo 'Generating DsChannel (Distributed Signing Identities Channel) artifacts for channel: dschannelsdk'
+ echo 'Generating channel configuration transaction'
+ configtxgen -profile DsChannel -outputCreateChannelTx ./opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/channel/dschannelsdk.tx -channelID dschannelsdk
2020-05-26 08:12:43.441 UTC [common.tools.configtxgen] main -> INFO 001 Loading configuration
2020-05-26 08:12:43.513 UTC [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/config/configtx.yaml
2020-05-26 08:12:43.580 UTC [common.tools.configtxgen.localconfig] completeInitialization -> INFO 003 orderer type: solo
2020-05-26 08:12:43.580 UTC [common.tools.configtxgen.localconfig] LoadTopLevel -> INFO 004 Loaded configuration: /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/config/configtx.yaml
2020-05-26 08:12:43.580 UTC [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 005 Generating new channel configtx
2020-05-26 08:12:43.582 UTC [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 006 Writing new channel tx
Generating anchor peer update for org Org1MSP
+ for j in '"${orgs[@]}"'
+ echo 'Generating anchor peer update for org Org1MSP'
+ configtxgen -profile DsChannel -outputAnchorPeersUpdate /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/channel/dschannelsdkOrg1MSPanchors.tx -channelID dschannelsdk -asOrg Org1MSP
2020-05-26 08:12:43.617 UTC [common.tools.configtxgen] main -> INFO 001 Loading configuration
2020-05-26 08:12:43.695 UTC [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/config/configtx.yaml
2020-05-26 08:12:43.780 UTC [common.tools.configtxgen.localconfig] completeInitialization -> INFO 003 orderer type: solo
2020-05-26 08:12:43.780 UTC [common.tools.configtxgen.localconfig] LoadTopLevel -> INFO 004 Loaded configuration: /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/config/configtx.yaml
2020-05-26 08:12:43.780 UTC [common.tools.configtxgen] doOutputAnchorPeersUpdate -> INFO 005 Generating anchor peer update
2020-05-26 08:12:43.780 UTC [common.tools.configtxgen] doOutputAnchorPeersUpdate -> INFO 006 Writing anchor peer update
Generating anchor peer update for org Org2MSP
+ for j in '"${orgs[@]}"'
+ echo 'Generating anchor peer update for org Org2MSP'
+ configtxgen -profile DsChannel -outputAnchorPeersUpdate /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/channel/dschannelsdkOrg2MSPanchors.tx -channelID dschannelsdk -asOrg Org2MSP
2020-05-26 08:12:43.819 UTC [common.tools.configtxgen] main -> INFO 001 Loading configuration
2020-05-26 08:12:43.895 UTC [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/config/configtx.yaml
2020-05-26 08:12:43.980 UTC [common.tools.configtxgen.localconfig] completeInitialization -> INFO 003 orderer type: solo
2020-05-26 08:12:43.980 UTC [common.tools.configtxgen.localconfig] LoadTopLevel -> INFO 004 Loaded configuration: /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/config/configtx.yaml
2020-05-26 08:12:43.980 UTC [common.tools.configtxgen] doOutputAnchorPeersUpdate -> INFO 005 Generating anchor peer update
2020-05-26 08:12:43.980 UTC [common.tools.configtxgen] doOutputAnchorPeersUpdate -> INFO 006 Writing anchor peer update
+ for i in '"${dsChannels[@]}"'
+ echo 'Generating DsChannel (Distributed Signing Identities Channel) artifacts for channel: dschannelext'
+ echo 'Generating channel configuration transaction'
+ configtxgen -profile DsChannel -outputCreateChannelTx ./opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/channel/dschannelext.tx -channelID dschannelext
Generating DsChannel (Distributed Signing Identities Channel) artifacts for channel: dschannelext
Generating channel configuration transaction
2020-05-26 08:12:44.013 UTC [common.tools.configtxgen] main -> INFO 001 Loading configuration
2020-05-26 08:12:44.082 UTC [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/config/configtx.yaml
2020-05-26 08:12:44.146 UTC [common.tools.configtxgen.localconfig] completeInitialization -> INFO 003 orderer type: solo
2020-05-26 08:12:44.146 UTC [common.tools.configtxgen.localconfig] LoadTopLevel -> INFO 004 Loaded configuration: /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/config/configtx.yaml
2020-05-26 08:12:44.146 UTC [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 005 Generating new channel configtx
2020-05-26 08:12:44.149 UTC [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 006 Writing new channel tx
+ for j in '"${orgs[@]}"'
+ echo 'Generating anchor peer update for org Org1MSP'
+ configtxgen -profile DsChannel -outputAnchorPeersUpdate /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/channel/dschannelextOrg1MSPanchors.tx -channelID dschannelext -asOrg Org1MSP
Generating anchor peer update for org Org1MSP
2020-05-26 08:12:44.188 UTC [common.tools.configtxgen] main -> INFO 001 Loading configuration
2020-05-26 08:12:44.252 UTC [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/config/configtx.yaml
2020-05-26 08:12:44.319 UTC [common.tools.configtxgen.localconfig] completeInitialization -> INFO 003 orderer type: solo
2020-05-26 08:12:44.319 UTC [common.tools.configtxgen.localconfig] LoadTopLevel -> INFO 004 Loaded configuration: /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/config/configtx.yaml
2020-05-26 08:12:44.319 UTC [common.tools.configtxgen] doOutputAnchorPeersUpdate -> INFO 005 Generating anchor peer update
2020-05-26 08:12:44.320 UTC [common.tools.configtxgen] doOutputAnchorPeersUpdate -> INFO 006 Writing anchor peer update
Generating anchor peer update for org Org2MSP
+ for j in '"${orgs[@]}"'
+ echo 'Generating anchor peer update for org Org2MSP'
+ configtxgen -profile DsChannel -outputAnchorPeersUpdate /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/channel/dschannelextOrg2MSPanchors.tx -channelID dschannelext -asOrg Org2MSP
2020-05-26 08:12:44.354 UTC [common.tools.configtxgen] main -> INFO 001 Loading configuration
2020-05-26 08:12:44.415 UTC [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/config/configtx.yaml
2020-05-26 08:12:44.493 UTC [common.tools.configtxgen.localconfig] completeInitialization -> INFO 003 orderer type: solo
2020-05-26 08:12:44.493 UTC [common.tools.configtxgen.localconfig] LoadTopLevel -> INFO 004 Loaded configuration: /opt/workspace/fabric-sdk-go/test/fixtures/fabric/v1.4/config/configtx.yaml
2020-05-26 08:12:44.493 UTC [common.tools.configtxgen] doOutputAnchorPeersUpdate -> INFO 005 Generating anchor peer update
2020-05-26 08:12:44.493 UTC [common.tools.configtxgen] doOutputAnchorPeersUpdate -> INFO 006 Writing anchor peer update
View Code

Integration测试

# make -n integration-tests-local

rm -Rf /tmp/enroll_user /tmp/msp /tmp/keyvaluestore /tmp/hfc-kvs /tmp/state /tmp/state-store
rm -f integration-report.xml report.xml
test/scripts/check_version.sh
test/scripts/dependencies.sh -c
FABRIC_CRYPTOCONFIG_VERSION=v1 \
FABRIC_FIXTURE_VERSION=v1.4 \
FABRIC_SDKGO_CODELEVEL_TAG=stable \
test/scripts/populate-fixtures.sh
TEST_CHANGED_ONLY=false FABRIC_CRYPTOCONFIG_VERSION=v1 FABRIC_SDKGO_CODELEVEL_VER=v1.4 FABRIC_SDKGO_CODELEVEL_TAG=stable TEST_LOCAL=true  test/scripts/integration.sh
//////////
TEST_CHANGED_ONLY=false FABRIC_CRYPTOCONFIG_VERSION=v1 FABRIC_SDKGO_CODELEVEL_VER=v1.4 FABRIC_SDKGO_CODELEVEL_TAG=stable TEST_LOCAL=true  test/scripts/integration.sh
+ GO_CMD=go
+ FABRIC_SDKGO_CODELEVEL_TAG=stable
+ FABRIC_SDKGO_TESTRUN_ID=20200603141720
+ FABRIC_CRYPTOCONFIG_VERSION=v1
+ FABRIC_FIXTURE_VERSION=v1.4
+ CONFIG_FILE=config_test.yaml
+ TEST_LOCAL=true
+ TEST_CHANGED_ONLY=false
+ TEST_RACE_CONDITIONS=true
++ dirname test/scripts/integration.sh
+ SCRIPT_DIR=test/scripts
++ cd test/scripts
++ go env GOMOD
+ GOMOD_PATH=/root/blockchain/fabric-sdk-go/go.mod
++ awk '-F ' '$1 == "module" {print $2}' /root/blockchain/fabric-sdk-go/go.mod
+ PROJECT_MODULE=github.com/hyperledger/fabric-sdk-go
++ dirname /root/blockchain/fabric-sdk-go/go.mod
+ PROJECT_DIR=/root/blockchain/fabric-sdk-go
+ MODULE=github.com/hyperledger/fabric-sdk-go/test/integration
+ MODULE_PATH=/root/blockchain/fabric-sdk-go//test/integration
+ MODULE_PATH=/root/blockchain/fabric-sdk-go//test/integration
+ source test/scripts/lib/find_packages.sh
+ source test/scripts/lib/docker.sh
+ unset GOCACHE
++ basename test/scripts/integration.sh
+ echo Running integration.sh
Running integration.sh
++ pwd
+ PWD_ORIG=/root/blockchain/fabric-sdk-go
+ cd /root/blockchain/fabric-sdk-go//test/integration
+ PKGS=($(${GO_CMD} list ${PROJECT_MODULE}/test/integration/... 2> /dev/null |       grep -v ^${PROJECT_MODULE}/test/integration/e2e/pkcs11 |       grep -v ^${PROJECT_MODULE}/test/integration/negative |       grep -v ^${PROJECT_MODULE}/test/integration\$ |       tr '\n' ' '))
++ go list github.com/hyperledger/fabric-sdk-go/test/integration/...
++ grep -v '^github.com/hyperledger/fabric-sdk-go/test/integration/e2e/pkcs11'
++ grep -v '^github.com/hyperledger/fabric-sdk-go/test/integration/negative'
++ grep -v '^github.com/hyperledger/fabric-sdk-go/test/integration$'
++ tr '\n' ' '
+ '[' '' == true ']'
+ '[' false = true ']'
+ RACEFLAG=
+ '[' true = true ']'
++ uname -m
+ ARCH=x86_64
+ '[' x86_64 = x86_64 ']'
+ echo 'Enabling data race detection'
Enabling data race detection
+ RACEFLAG=-race
+ '[' 15 -eq 0 ']'
+ waitForCoreVMUp
+ [[ '' =~ http://(.*):(.*) ]]
+ echo 'Code level stable (Fabric v1.4)'
Code level stable (Fabric v1.4)
+ echo 'Running integration tests ...'
Running integration tests ...
+ GO_TAGS=' experimental stable'
+ GO_LDFLAGS=' -X github.com/hyperledger/fabric-sdk-go/test/metadata.ProjectPath=/root/blockchain/fabric-sdk-go'
+ GO_LDFLAGS=' -X github.com/hyperledger/fabric-sdk-go/test/metadata.ProjectPath=/root/blockchain/fabric-sdk-go -X github.com/hyperledger/fabric-sdk-go/test/metadata.ChannelConfigPath=test/fixtures/fabric/v1.4/channel'
+ GO_LDFLAGS=' -X github.com/hyperledger/fabric-sdk-go/test/metadata.ProjectPath=/root/blockchain/fabric-sdk-go -X github.com/hyperledger/fabric-sdk-go/test/metadata.ChannelConfigPath=test/fixtures/fabric/v1.4/channel -X github.com/hyperledger/fabric-sdk-go/test/metadata.CryptoConfigPath=test/fixtures/fabric/v1/crypto-config'
+ GO_LDFLAGS=' -X github.com/hyperledger/fabric-sdk-go/test/metadata.ProjectPath=/root/blockchain/fabric-sdk-go -X github.com/hyperledger/fabric-sdk-go/test/metadata.ChannelConfigPath=test/fixtures/fabric/v1.4/channel -X github.com/hyperledger/fabric-sdk-go/test/metadata.CryptoConfigPath=test/fixtures/fabric/v1/crypto-config -X github.com/hyperledger/fabric-sdk-go/fabric-sdk-go/test/metadata.TestRunID=20200603141720'
+ go test -race -tags ' experimental stable' '-ldflags= -X github.com/hyperledger/fabric-sdk-go/test/metadata.ProjectPath=/root/blockchain/fabric-sdk-go -X github.com/hyperledger/fabric-sdk-go/test/metadata.ChannelConfigPath=test/fixtures/fabric/v1.4/channel -X github.com/hyperledger/fabric-sdk-go/test/metadata.CryptoConfigPath=test/fixtures/fabric/v1/crypto-config -X github.com/hyperledger/fabric-sdk-go/fabric-sdk-go/test/metadata.TestRunID=20200603141720' github.com/hyperledger/fabric-sdk-go/test/integration/e2e github.com/hyperledger/fabric-sdk-go/test/integration/e2e/configless github.com/hyperledger/fabric-sdk-go/test/integration/e2e/orgs github.com/hyperledger/fabric-sdk-go/test/integration/pkg/client/channel github.com/hyperledger/fabric-sdk-go/test/integration/pkg/client/common/discovery github.com/hyperledger/fabric-sdk-go/test/integration/pkg/client/common/selection github.com/hyperledger/fabric-sdk-go/test/integration/pkg/client/event github.com/hyperledger/fabric-sdk-go/test/integration/pkg/client/ledger github.com/hyperledger/fabric-sdk-go/test/integration/pkg/client/msp github.com/hyperledger/fabric-sdk-go/test/integration/pkg/client/resmgmt github.com/hyperledger/fabric-sdk-go/test/integration/pkg/context github.com/hyperledger/fabric-sdk-go/test/integration/pkg/fab github.com/hyperledger/fabric-sdk-go/test/integration/pkg/fabsdk/provider github.com/hyperledger/fabric-sdk-go/test/integration/pkg/gateway github.com/hyperledger/fabric-sdk-go/test/integration/util/runner -p 1 -timeout=40m configFile=config_test.yaml testLocal=true 


4. 命令行工具

4.1 peer

Usage:
  peer [command]

Available Commands:
  chaincode   Operate a chaincode: install|instantiate|invoke|package|query|signpackage|upgrade|list.
  channel     Operate a channel: create|fetch|join|list|update|signconfigtx|getinfo.
  help        Help about any command
  lifecycle   Perform _lifecycle operations
  node        Operate a peer node: start|reset|rollback|pause|resume|rebuild-dbs|upgrade-dbs.
  version     Print fabric peer version.

Flags:
  -h, --help   help for peer

Use "peer [command] --help" for more information about a command.
peer

# ./peer chaincode --help

Operate a chaincode: install|instantiate|invoke|package|query|signpackage|upgrade|list.

Usage:
  peer chaincode [command]

Available Commands:
  install     Install a chaincode.
  instantiate Deploy the specified chaincode to the network.
  invoke      Invoke the specified chaincode.
  list        Get the instantiated chaincodes on a channel or installed chaincodes on a peer.
  package     Package a chaincode
  query       Query using the specified chaincode.
  signpackage Sign the specified chaincode package
  upgrade     Upgrade chaincode.

Flags:
      --cafile string                       Path to file containing PEM-encoded trusted certificate(s) for the ordering endpoint
      --certfile string                     Path to file containing PEM-encoded X509 public key to use for mutual TLS communication with the orderer endpoint
      --clientauth                          Use mutual TLS when communicating with the orderer endpoint
      --connTimeout duration                Timeout for client to connect (default 3s)
  -h, --help                                help for chaincode
      --keyfile string                      Path to file containing PEM-encoded private key to use for mutual TLS communication with the orderer endpoint
  -o, --orderer string                      Ordering service endpoint
      --ordererTLSHostnameOverride string   The hostname override to use when validating the TLS connection to the orderer.
      --tls                                 Use TLS when communicating with the orderer endpoint
      --transient string                    Transient map of arguments in JSON encoding

Use "peer chaincode [command] --help" for more information about a command.
peer chaincode

# ./peer channel -h

Operate a channel: create|fetch|join|list|update|signconfigtx|getinfo.

Usage:
  peer channel [command]

Available Commands:
  create       Create a channel
  fetch        Fetch a block
  getinfo      get blockchain information of a specified channel.
  join         Joins the peer to a channel.
  list         List of channels peer has joined.
  signconfigtx Signs a configtx update.
  update       Send a configtx update.

Flags:
      --cafile string                       Path to file containing PEM-encoded trusted certificate(s) for the ordering endpoint
      --certfile string                     Path to file containing PEM-encoded X509 public key to use for mutual TLS communication with the orderer endpoint
      --clientauth                          Use mutual TLS when communicating with the orderer endpoint
      --connTimeout duration                Timeout for client to connect (default 3s)
  -h, --help                                help for channel
      --keyfile string                      Path to file containing PEM-encoded private key to use for mutual TLS communication with the orderer endpoint
  -o, --orderer string                      Ordering service endpoint
      --ordererTLSHostnameOverride string   The hostname override to use when validating the TLS connection to the orderer.
      --tls                                 Use TLS when communicating with the orderer endpoint

Use "peer channel [command] --help" for more information about a command.
peer channel

4.2 orderer

# ./orderer --help
usage: orderer [<flags>] <command> [<args> ...]
Hyperledger Fabric orderer node

Flags:
  --help  Show context-sensitive help (also try --help-long and --help-man).
Commands:
  help [<command>...]
    Show help.

  start*
    Start the orderer node

  version
    Show version information
order

4.3 configtxgen

Configtxgen工具用来创建四个配置构件:排序节点的创世区块,通道配置交易,两个锚节点交易。

排序区块是排序服务的创世区块,通道配置交易在通道创建的时候广播给排序服务。锚节点交易,指定了每个组织在此通道上的锚节点。

5. 源码编译

基于最新版本v1.4.2源码编译。

fabric

# yum install -y gcc libtool libltdl-dev libtool-ltdl-devel openssl

# git clone https://gitee.com/yuxio/fabric.git

# cd fabric

# git checkout -b v1.4.2 v1.4.2

# rm Gopkg.lock Gopkg.toml

# go mod init github.com/hyperledger/fabric

# git checkout -- Gopkg.lock Gopkg.toml

# make release // 相关二进制文件configtxgen, configtxlator,crytogen,discover, idemixgen, orderer, peer

# make docker // 相关docker

# make docker-list

hyperledger/fabric-baseos:amd64-2.1.0-snapshot-1bdf975
hyperledger/fabric-ccenv:amd64-2.1.0-snapshot-1bdf975
hyperledger/fabric-orderer:amd64-2.1.0-snapshot-1bdf975
hyperledger/fabric-peer:amd64-2.1.0-snapshot-1bdf975
hyperledger/fabric-tools:amd64-2.1.0-snapshot-1bdf975

fabric-ca

# git clone https://gitee.com/yuxio/fabric-ca.git

# cd fabric-ca

# rm vendor/vendor.json

# make release // 二进制文件 fabric-ca-client fabric-ca-server

Building release/linux-amd64/bin/fabric-ca-client for linux-amd64
mkdir -p release/linux-amd64/bin
GOOS=linux GOARCH=amd64 go build -o /tmp/fabric-ca/release/linux-amd64/bin/fabric-ca-client -tags "caclient" -ldflags "-X github.com/hyperledger/fabric-ca/lib/metadata.Version=1.4.7" github.com/hyperledger/fabric-ca/cmd/fabric-ca-client
Building release/linux-amd64/bin/fabric-ca-server for linux-amd64
mkdir -p release/linux-amd64/bin
GOOS=linux GOARCH=amd64 go build -o /tmp/fabric-ca/release/linux-amd64/bin/fabric-ca-server -tags "" -ldflags "-X github.com/hyperledger/fabric-ca/lib/metadata.Version=1.4.7" github.com/hyperledger/fabric-ca/cmd/fabric-ca-server
make release

# make -n docker // make docker执行的命令

echo "Building build/docker/bin/fabric-ca-client"
mkdir -p build/docker/bin build/docker/fabric-ca-client/pkg build/docker/cache
docker run -i --rm --user=0 -v /tmp/fabric-ca:/opt/gopath/src/github.com/hyperledger/fabric-ca -w /opt/gopath/src/github.com/hyperledger/fabric-ca \
        -v /tmp/fabric-ca/build/docker/bin:/opt/gopath/bin \
        -v /tmp/fabric-ca/build/docker/fabric-ca-client/pkg:/opt/gopath/pkg \
        -v /tmp/fabric-ca/build/docker/cache:/opt/gopath/cache \
        -e GOCACHE=/opt/gopath/cache \
        hyperledger/fabric-baseimage:amd64-0.4.20 \
        go install -ldflags "-X github.com/hyperledger/fabric-ca/lib/metadata.Version=1.4.7 -linkmode external -extldflags '-static -lpthread'" github.com/hyperledger/fabric-ca/cmd/fabric-ca-client
touch build/docker/bin/fabric-ca-client
echo "Building build/docker/bin/fabric-ca-server"
mkdir -p build/docker/bin build/docker/fabric-ca-server/pkg build/docker/cache
docker run -i --rm --user=0 -v /tmp/fabric-ca:/opt/gopath/src/github.com/hyperledger/fabric-ca -w /opt/gopath/src/github.com/hyperledger/fabric-ca \
        -v /tmp/fabric-ca/build/docker/bin:/opt/gopath/bin \
        -v /tmp/fabric-ca/build/docker/fabric-ca-server/pkg:/opt/gopath/pkg \
        -v /tmp/fabric-ca/build/docker/cache:/opt/gopath/cache \
        -e GOCACHE=/opt/gopath/cache \
        hyperledger/fabric-baseimage:amd64-0.4.20 \
        go install -ldflags "-X github.com/hyperledger/fabric-ca/lib/metadata.Version=1.4.7 -linkmode external -extldflags '-static -lpthread'" github.com/hyperledger/fabric-ca/cmd/fabric-ca-server
touch build/docker/bin/fabric-ca-server
echo "Building build/fabric-ca.tar.bz2"
tar -jc -C images/fabric-ca/payload ca-cert.pem ca-key.pem > build/fabric-ca.tar.bz2
echo "Copying build/docker/bin/fabric-ca-client build/docker/bin/fabric-ca-server build/fabric-ca.tar.bz2 to build/image/fabric-ca/payload"
mkdir -p build/image/fabric-ca/payload
cp build/docker/bin/fabric-ca-client build/docker/bin/fabric-ca-server build/fabric-ca.tar.bz2 build/image/fabric-ca/payload
echo "Building docker fabric-ca image"
cat images/fabric-ca/Dockerfile.in \
        | sed -e 's|_BASE_NS_|hyperledger|g' \
        | sed -e 's|_NS_|hyperledger|g' \
        | sed -e 's|_NEXUS_REPO_|nexus3.hyperledger.org:10001/hyperledger|g' \
        | sed -e 's|_BASE_TAG_|amd64-0.4.20|g' \
        | sed -e 's|_FABRIC_TAG_|amd64-1.4.7|g' \
        | sed -e 's|_STABLE_TAG_|amd64-1.4.7-stable|g' \
        | sed -e 's|_TAG_|amd64-1.4.7|g' \
        | sed -e 's|_PGVER_|10|g' \
        > build/image/fabric-ca/Dockerfile
docker build  -t hyperledger/fabric-ca --build-arg FABRIC_CA_DYNAMIC_LINK= build/image/fabric-ca
docker tag hyperledger/fabric-ca hyperledger/fabric-ca:amd64-1.4.7
touch build/image/fabric-ca/.dummy-amd64-1.4.7
make docker

目前make docker error,主要是docker的基础镜像hyperledger/fabric-baseimage:amd64-0.4.20go版本为1.13,而系统的go版本为1.14,导致go.mod不兼容。可直接编译master分支,master分支的版本已修改为2.0.0

六. Chaincode

基于gochaincode参考https://github.com/hyperledger/fabric-contract-api-go.git

Chaincode的开发测试利用fabric-sample/chaincode-docker-devmode,参考README

Chaincode编码在fabric-sample/chaincode下,测试在fabric-sample/chaincode-docker-devmode下。

cd fabric-sample/chaincode-docker-devmode
docker-compose -f docker-compose-simple.yaml up // 启动4个容器,peer/orderer/chaincode/cli
// Running chaincode
docker exec -it chaincode sh
cd contract-tutorial
go build
CORE_CHAINCODE_ID_NAME=mycc:0 CORE_PEER_TLS_ENABLED=false ./contract-tutorial -peer.address peer:7052
// interacting with the chaincode
docker exec -it cli sh
peer chaincode install -p chaincode/contract-tutorial -n mycc -v 0
peer chaincode instantiate -n mycc -v 0 -c '{"Args":[]}' -C myc  // instantiate
peer chaincode invoke -n mycc -c '{"Args":["Create", "KEY_1", "VALUE_1"]}' -C myc  // invoke
peer chaincode invoke -n mycc -c '{"Args":["Update", "KEY_1", "VALUE_2"]}' -C myc
peer chaincode query -n mycc -c '{"Args":["Read", "KEY_1"]}' -C myc


七. 应用

fabric-sdk-go是基于golangFabric应用开发sdk,目前支持fabric v1.4.2,最新的v2.x目前还不支持。基于此SDK的应用参考https://github.com/securekey/fabric-examples.git

git clone https://github.com/securekey/fabric-examples.git
make populate-sdk
make example-network
cd $GOPATH/src/github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli
go run fabric-cli.go

# make populate-sdk

Pinning fabric-sdk-go ...
+ UPSTREAM_PROJECT=github.com/hyperledger/fabric-sdk-go
+ UPSTREAM_BRANCH=master
+ SCRIPTS_PATH=scripts/fabric-sdk-go
+ FABRIC_SDK_GO_PATH=fabric-sdk-go
+ echo 'Fetching upstream project (github.com/hyperledger/fabric-sdk-go:8f3d32c9d1a66f88d405c9f5335870c5277f773a) ...'
Fetching upstream project (github.com/hyperledger/fabric-sdk-go:8f3d32c9d1a66f88d405c9f5335870c5277f773a) ...
++ pwd
+ CWD=/root/blockchain/fabric-examples/fabric-cli
++ mktemp -d
+ TMP=/tmp/tmp.dlBDOfMC3T
+ TMP_PROJECT_PATH=/tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go
+ mkdir -p /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go
+ cd /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go/..
+ git clone https://github.com/hyperledger/fabric-sdk-go.git
Cloning into 'fabric-sdk-go'...
remote: Enumerating objects: 114, done.
remote: Counting objects: 100% (114/114), done.
remote: Compressing objects: 100% (102/102), done.
remote: Total 30511 (delta 20), reused 46 (delta 7), pack-reused 30397
Receiving objects: 100% (30511/30511), 13.10 MiB | 2.73 MiB/s, done.
Resolving deltas: 100% (18754/18754), done.
+ cd /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go
+ git checkout master
Already on 'master'
+ git reset --hard 8f3d32c9d1a66f88d405c9f5335870c5277f773a
HEAD is now at 8f3d32c [FABG-785] Supported node chaincode (#40)
+ cd /root/blockchain/fabric-examples/fabric-cli
+ echo 'Removing current upstream project from working directory ...'
Removing current upstream project from working directory ...
+ rm -Rf fabric-sdk-go
+ mkdir -p fabric-sdk-go
+ PATHS=("Makefile" "test/fixtures/*" "scripts/_go/*" "test/scripts/*")
+ declare -a PATHS
+ for i in '"${PATHS[@]}"'
++ dirname Makefile
+ DIR=.
+ DEST=fabric-sdk-go/.
+ mkdir -p fabric-sdk-go/.
+ cp -R /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go/Makefile fabric-sdk-go/.
+ for i in '"${PATHS[@]}"'
++ dirname 'test/fixtures/*'
+ DIR=test/fixtures
+ DEST=fabric-sdk-go/test/fixtures
+ mkdir -p fabric-sdk-go/test/fixtures
+ cp -R /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go/test/fixtures/config /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go/test/fixtures/dockerenv /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go/test/fixtures/fabric /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go/test/fixtures/softhsm2 /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go/test/fixtures/testdata fabric-sdk-go/test/fixtures
+ for i in '"${PATHS[@]}"'
++ dirname 'scripts/_go/*'
+ DIR=scripts/_go
+ DEST=fabric-sdk-go/scripts/_go
+ mkdir -p fabric-sdk-go/scripts/_go
+ cp -R /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go/scripts/_go/src fabric-sdk-go/scripts/_go
+ for i in '"${PATHS[@]}"'
++ dirname 'test/scripts/*'
+ DIR=test/scripts
+ DEST=fabric-sdk-go/test/scripts
+ mkdir -p fabric-sdk-go/test/scripts
+ cp -R /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go/test/scripts/chaincoded.sh /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go/test/scripts/check_license.sh /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go/test/scripts/check_lint.sh /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go/test/scripts/check_status.sh /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go/test/scripts/check_version.sh /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go/test/scripts/clean_integration.sh /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go/test/scripts/dependencies.sh /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go/test/scripts/fabric_test_commitlevel.sh /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go/test/scripts/generate_channeltx.sh /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go/test/scripts/generate_crypto.sh /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go/test/scripts/integration-pkcs11.sh /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go/test/scripts/integration.sh /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go/test/scripts/lib /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go/test/scripts/negative.sh /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go/test/scripts/populate-fixtures.sh /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go/test/scripts/unit-pkcs11.sh /tmp/tmp.dlBDOfMC3T/src/github.com/hyperledger/fabric-sdk-go/test/scripts/unit.sh fabric-sdk-go/test/scripts
+ echo 'Removing temporary files ...'
Removing temporary files ...
+ rm -Rf /tmp/tmp.dlBDOfMC3T
+ cd fabric-sdk-go
+ echo 'Populating dockerd vendor ...'
Populating dockerd vendor ...
+ declare chaincodedPath=scripts/_go/src/chaincoded
+ rm -Rf scripts/_go/src/chaincoded/vendor/
+ mkdir -p scripts/_go/src/chaincoded/vendor/github.com/hyperledger/fabric
+ git clone --branch release-1.3 --depth=1 https://github.com/hyperledger/fabric.git scripts/_go/src/chaincoded/vendor/github.com/hyperledger/fabric
Cloning into 'scripts/_go/src/chaincoded/vendor/github.com/hyperledger/fabric'...
remote: Enumerating objects: 4949, done.
remote: Counting objects: 100% (4949/4949), done.
remote: Compressing objects: 100% (4164/4164), done.
remote: Total 4949 (delta 583), reused 2804 (delta 389), pack-reused 0
Receiving objects: 100% (4949/4949), 16.67 MiB | 3.43 MiB/s, done.
Resolving deltas: 100% (583/583), done.
+ cd ..
View Code

八. 多主机部署

8.1 Cli容器部署

建立网络:

IMAGE_TAG=amd64-1.4.2 docker-compose -f docker-compose-orderer.yaml -f docker-compose-etcdraft2.yaml up -d

IMAGE_TAG=amd64-1.4.2 docker-compose -f docker-compose-org1.yaml -f docker-compose-org1-couch.yaml up -d

IMAGE_TAG=amd64-1.4.2 docker-compose -f docker-compose-org2.yaml -f docker-compose-org2-couch.yaml up -d

下线网络:

IMAGE_TAG=amd64-1.4.2 docker-compose -f docker-compose-orderer.yaml -f docker-compose-etcdraft2.yaml down --volumes

IMAGE_TAG=amd64-1.4.2 docker-compose -f docker-compose-org1.yaml -f docker-compose-org1-couch.yaml down --volumes

IMAGE_TAG=amd64-1.4.2 docker-compose -f docker-compose-org2.yaml -f docker-compose-org2-couch.yaml down --volumes

网络启动后,执行如下部署命令:

// 创建和加入通道(单主机运行)

# docker exec -it cli bash

Cli# export CHANNEL_NAME=mychannel

// 生成创世区块mychannel.block (单主机运行)

Cli# peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

// peer加入通道 (单主机运行两条命令或多主机运行)

Cli# peer channel join -b mychannel.block

Cli#CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp CORE_PEER_ADDRESS=peer0.org1.example.com:7051 CORE_PEER_LOCALMSPID="Org1MSP" 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 peer channel join -b mychannel.block

Cli#CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp CORE_PEER_ADDRESS=peer0.org2.example.com:7051 CORE_PEER_LOCALMSPID="Org2MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt peer channel join -b mychannel.block

//添加(更新)锚节点 (多主机运行)

Cli#peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org1MSPanchors.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

Cli#peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org2MSPanchors.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

//安装链码 (多主机运行)

Cli#peer chaincode install -n mycc -v 1.0 -p github.com/chaincode/chaincode_example02/go/

// 实例化链码 (单主机运行)

Cli# peer chaincode instantiate -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n mycc -v 1.0 -c '{"Args":["init","a", "100", "b","200"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer')"

// 应用:查询、调用 (单主机运行)

Cli#peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'

Cli#peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n mycc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["invoke","a","b","10"]}'

8.2 fabric-cli工具部署

应用部分提供的示例fabric-clihttps://github.com/securekey/fabric-examples.git)可用于配置通道和链码。

LOGPATH=/opt/gopath/src/github.com/hyperledger/logfabric

## create channel

fabric-cli channel create --orderer orderer.example.com:7050 --cid logchannel --txfile ${LOGPATH}/channel-artifacts/logchannel.tx --config ${LOGPATH}/appconfig/oconfig_sdkgo.yaml

sleep 2

fabric-cli channel create --orgid=org1 --cid logchannel --txfile ${LOGPATH}/channel-artifacts/Org1MSPanchors.tx --config ${LOGPATH}/appconfig/oconfig_sdkgo.yaml

fabric-cli channel create --orgid=org2 --cid logchannel --txfile ${LOGPATH}/channel-artifacts/Org2MSPanchors.tx --config ${LOGPATH}/appconfig/oconfig_sdkgo.yaml

sleep 2

## join channel

fabric-cli channel join --cid logchannel --peer peer0.org1.example.com:7051 --config ${LOGPATH}/appconfig/oconfig_sdkgo.yaml

fabric-cli channel join --cid logchannel --peer peer0.org2.example.com:7051 --config ${LOGPATH}/appconfig/oconfig_sdkgo.yaml

sleep 2

## install chaincode

fabric-cli chaincode install --peer peer0.org1.example.com:7051 --cid logchannel --ccp github.com/hyperledger/logfabric/chaincode/v1 --gopath /opt/gopath --ccid=logcc --v 1 --config ${LOGPATH}/appconfig/oconfig_sdkgo.yaml

fabric-cli chaincode install --peer peer0.org2.example.com:7051 --cid logchannel --ccp github.com/hyperledger/logfabric/chaincode/v1 --gopath /opt/gopath --ccid=logcc --v 1 --config ${LOGPATH}/appconfig/oconfig_sdkgo.yaml

sleep 2

## init chaincode

#fabric-cli chaincode instantiate --peer peer0.org1.example.com:7051 --cid logchannel --ccp github.com/hyperledger/logfabric/chaincode/v1 --ccid logcc --v 1 --args='{"Args":[]}' --policy "OR('Org1MSP.member','Org2MSP.member')" --config oconfig_sdkgo.yaml

fabric-cli chaincode instantiate --cid logchannel --ccp github.com/hyperledger/logfabric/chaincode/v1 --ccid logcc --v 1 --args='{"Args":[]}' --policy "OR('Org1MSP.member','Org2MSP.member')" --config ${LOGPATH}/appconfig/oconfig_sdkgo.yaml


9. 问题

1. 在配置网络时,已在/etc/hosts中指定各域名对应的IPDocker-composepeer还必须定义extra_hosts(即指定域名对应的IP)吗?

答:应为chaincode镜像的生成来自peer节点,但peerdocker-compose中无DNS相关的环境变量配置,实测如果不指定peer无法获知链码创建成功,导致链码实例化失败。

peer指定CORE_CHAINCODE_BUILDERCORE_CHAINCODE_GOLANG_RUNTIME变量,则chaincode的镜像为指定镜像,可在指定镜像中共享主机/etc/hosts文件达到指定域名目的。(无实测,理论推断)

2. 在重启docker-compose up时,若有应用正在使用chaincode,即使fabric相关容器volumes已删除,docker-compose upfabric仍可找寻到链码名和版本,导致重启创建失败。所以要完全重新创建fabric网络时,要连同fabric应用一起删除掉。

3. 错误信息:connection is in TRANSIENT_FAILURE

答:连接不通。首先确认要连接的主机是否运行正常(可通过pingTelnet确认),其次确认配置文件的连接地址是否正确。

4. 采用默认日志配置(FABRIC_LOGGING_SPEC=INFO)时,运行90分钟左右peer容器僵死(多次测试追踪,僵死时间大致相同),微服务无回应。原因初步推测为docker日志缓存满,可能与docker本身有关,也可能与peer微服务程序有关,待进一步确认。

修改FABRIC_LOGGING_SPEC=WARN后输出日志极少(警告以上级别日志太多,网络可能有问题,异常正常,应down网络寻找原因),长时间测试(8小时+)未出现上述问题。

5. 时间不同步时join channel日志异常,提示连接不上orderer,因为交易的达成必须时间一致。

2020-06-29 06:03:52.662 UTC [ConnProducer] NewConnection -> ERRO 03e Failed connecting to {orderer3.example.com:7050 [OrdererMSP]} , error: context deadline exceeded

 

参考:

  1. https://hyperledger-fabric.readthedocs.io/en/release-2.0/

  2. https://wiki.hyperledger.org/display/fabric

  3. OK区块链60

  4. 区块链技术学习专栏 知乎 传智播客智能物联网 https://zhuanlan.zhihu.com/c_154064303

  5. 账本进化-了解区块链https://github.com/rodchen-king/Hyperledger-Fabric.git

  6. 阿里云区块链服务(BaaS)企业级PaaS平台服务https://www.qukuaiwang.com.cn/news/14356.html

  7. 共识算法:Rafthttps://www.jianshu.com/p/8e4bbe7e276c

  8. 区块链开源实现hyperledger fabric架构详解csdn陶辉 http://www.taohui.pub/

  9. Fabric CA注册登记教程CSDN nodejs注册登记用户

https://blog.csdn.net/shebao3333/article/details/103558715

  1. Fabric CA环境的集成 深蓝居 https://www.cnblogs.com/studyzy/p/7482451.html

  2. Hyperledger Fabric博客汇总 博客 触不可及 https://www.cnblogs.com/cbkj-xd/p/12170903.html

  3. Fabric 区块链的多节点部署

https://www.ibm.com/developerworks/cn/cloud/library/cl-lo-hyperledger-fabric-practice-analysis3/index.html

  1. Fabric环境变量手册

  2. Fabric1.4Go 链码开发与编写https://www.cnblogs.com/zongmin/p/11874792.html

  3. HyperLedger Fabric ChainCode开发——shim.ChaincodeStubInterface用法 深蓝居

https://www.cnblogs.com/studyzy/p/7360733.html

  1. fabricchaincode方法GetHistoryForKey的使用https://www.jianshu.com/p/a2381b65222c

  2. 基于fabric-sdk-go实现的学历信息征信系统 csdn

https://blog.csdn.net/weixin_44676392/category_8728644.html

  1. education gitee修改版 https://gitee.com/zhouhuazh/education/tree/dev

  2. citizens git https://github.com/akkagao/citizens

  3. fabric-clihttps://github.com/securekey/fabric-examples.git

  4. fabric-sdk-go-sample 基于BYFN的示例https://gitee.com/yuxio/fabric-sdk-go-sample

  5. fabric-sdk-go-test https://gitee.com/FangDengFu/fabric-sdk-go-test

  6. blockchain示例 https://gitee.com/yuxio/example-Hyperledger-Fabric 

posted @ 2020-07-05 23:00  yuxi_o  阅读(1162)  评论(1编辑  收藏  举报