hyperledger fabric简述--基于1.4.2部署
一. 基础
区块链是利用块链式数据结构来验证与存储数据、利用分布式节点共识算法来生成和更新数据、利用密码学的技术保证数据传输和访问控制的安全、利用由自动化脚本代码组成的智能合约来编程和操作数据的一种全新的分布式基础架构与计算范式。目前,区块链被很多大型机构称为彻底改变业务乃至机构运作模式的重大突破性技术。
区块链本质上是一种多方共享的分布式账本技术。它确保交易数据和历史记录的不可篡改,通过共识算法和智能合约实现各参与方对交易的共同确认和账本记录。
区块链根据应用场景和设计不同,主要分为公有链、联盟链和私有链:
(1)
公有链:以比特币、以太坊和所有数字货币为代表,各个节点可以自由进入或退出区块链网络;
(2)
联盟链:各个节点通常代表实体组织机构或个人,通常需要经过授权后加入或退出网路。由于各机构间通常存在相关利益,因此需要各方共同参与和维护;
(3)
私有链:各个节点的准入和退出权限均由内部控制,通常是在特定机构内用于内部数据管理与审计。
1.1 术语
交易:Transaction,一次对账本的操作,导致账本状态的一次改变,如添加一条转账记录。
区块:Block,记录一段时间内发生的所有交易和状态结果等,是对当前账本状态的一次共识。每个区块记录着上一个区块的hash值、本区块中的交易集合、本区块的hash等基础数据。由于每个区块都有上一区块的hash值,区块间由这个值两两串联,形成区块链。这种链状结构的数据称之为账本数据,保存着所有交易的记录。
区块链:Blockchain,由区块按照发生顺序串联而成,是整个账本状态变化的日志记录。最早起源于比特币的底层技术,并在其后不断演进发展。区块链本质是一种多方共享的分布式账本技术。它通过数学方法实现交易数据和历史记录的不可篡改性,通过共识算法和智能合约实现各参与方对交易的共同确认和账本记录。区块链分为公有链、联盟链、私有链三种基本类型。区块链的实现技术框架有以太坊、EOS、Hyperledger Fabric、Corda等等。
智能合约:运行在区块链上的模块化、可重用的自动执行脚本。区块链技术的特性之一,用计算机语言描述合同条款、交易的条件、交易的业务逻辑等,通过调用智能合约实现交易的自动执行和对账本数据的操作。智能合约允许在没有第三方的情况下进行可信交易,只要一方达成了协议预先设定的目标,合约将会自动执行交易,这些交易可追踪且不可逆转。具有透明可信、自动执行、强制履约的优点。Fabric中智能合约称为chaincode。
共识:Consensus,当所有网络参与者同意交易的有效性时,达成共识,确保分布式账本是彼此的精确副本。共识算法解决的是对某个提案(Proposal),大家达成一致意见的过程。
证书颁发机构:Certificate Authority,简称CA,数字证书颁发机构是受信任的第三方机构,颁发的数字证书是为最终用户数据加密的公共密钥。
区块链高度:Height,当前区块链上区块(Block)的最大数。
哈希:Transaction Hash同交易哈希。交易上链成功后,产生的唯一哈希值。
组织:organization,代表的是参与区块链业务网络的企业、政府机构、团体等实体。如下图,在阿里云区块链服务中,组织分为两种:
·
联盟运营方组织:负责联盟链公共基础设施的管理运维,包含如下类型:
CA:区块链节点类型之一,Certificate
Authority,数字证书颁发机构,负责组织内部成员的register和enroll等,为组织的用户生成和颁发数字证书。
Orderer:区块链节点类型之一,负责交易排序、区块产生和达成共识。
·
业务参与方组织:参与联盟链的公司或企业;每个企业可定义一个或多个组织,包含如下类型:
CA:同联盟运营方CA。
Peer:区块链节点类型之一,负责保存和记录账本数据、对交易背书、运行智能合约等。
联盟:consortium,指参与一个基于区块链的业务协作或业务交易网络的所有组织的集合,一个联盟一般包含多个组织。
通道:channel,主要用于实现联盟链中业务的隔离。每个通道可代表一项业务,通道内包含业务的参与方(联盟内的部分或全部组织)作为通道成员。一个联盟中可以有多个通道;一个组织可以加入多个通道。每个通道可视为一条子链,并且对应有且仅有一套账本,通道上可发布智能合约。一个channel可含有一批chaincode。
链码:chaincode,是Hyperledger
Fabric技术框架中对智能合约的实现,支持业界流行的编程语言如Node.js、
Go、Java等。
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:背书人,验证交易,调用链码,并将背书的交易结果返回给调用应用程序。
MSP:Membership Service Provider,联盟链的成员的证书管理,为组织定义有效身份管理规则的组件。成员服务提供商通过颁发和验证证书来提供身份管理和身份验证过程。MSP 确定信任哪些证书颁发机构(CA)去定义信任域的成员,并确定成员可能扮演的特定角色(成员、管理员等)。在Fabric网络中,MSP出现在两个位置:在通道配置中(通道MSP),在参与者节点本地(本地MSP)。本地 MSP 是为客户端(用户)和节点(Peer 节点和排序节点)定义的。每个节点和用户都必须定义一个本地 MSP,因为它定义了谁拥有该级别的管理或参与权。通道 MSP 在通道级别定义管理和参与权。每个参与通道的组织都必须为其定义一个 MSP。通道上的 Peer 节点和排序节点将共享通道 MSP,因此能够正确地对通道参与者进行身份验证。这意味着,如果某个组织希望加入通道,则需要在通道配置中加入一个包含该组织成员信任链的 MSP。否则,由该组织身份发起的交易将被拒绝。
CSP:Crypto Service Provider
CRI:Certificate Revocation Information,证书撤销信息
LDAP:lightweight Directory Access Protocol,轻型目录访问协议
资产:可以理解为任何具有货币价值的东西,可以通过网络交易,无论是有形资产还是无形资产都属于资产。资产在Fabric中以键值对集合的形态存在,在通道(channel)中各本地账本可以对其状态提交变更事务。资产可以用二进制或JSON表示。
P2P:Peer-to-Peer,对等网络,即对等计算机网络,是一种在对等者(Peer)之间分配任务和工作负载的分布式应用框架。
Kafka:是一个开源流处理平台。在fabric中,kafka是一种共识模式,也就是说平等信任(同步复制),所有的Fabric网络加盟方都是可信任方,因为消息总是均匀地分布在各地。当orderer生成新的区块后,通过kafka同步到各个peer节点,各个节点将新的区块提交到账本。在fabric 2.1中不再采用kafka,而是推荐使用raft,已集成到orderer。
Zookeeper:一个分布式的应用程序协调服务,管理kafka的broker节点,在fabric 2.1中不再采用。
Dapp:Decentralized Application,去中心化应用程序,是一种开源的应用程序,自动运行,将其数据存储在区块链上,以密码令牌的形式激励,并以显示有价值证明的协议进行操作。
DLT:Distributed Ledger Technology,分布式账本技术
CFT:Crash Fault-Tolerant,崩溃容错(共识协议)
BFT:Byzantine Fault-Tolerant,拜占庭容错(共识协议)
1.2 共享账本
Hyperledger Fabric有一个账本子系统,包括两个组件:世界状态 和 区块链(交易日志)。对于所属的 Hyperledger Fabric网络,每个参与者都有一份账本的副本。
首先,世界状态是一个数据库,它存储了一组账本状态的当前值。通过世界状态,程序可以直接访问一个账本状态的当前值,不需要遍历整个交易日志来计算当前值。默认情况下,账本状态是以键值对的方式来表示的,可以创建、更新和删除状态。
其次,区块链是交易日志,它记录了促成当前世界状态的所有改变。交易被收集在附加到区块链的区块中,能帮助我们理解所有促成当前世界状态的改变的历史。区块链数据结构与世界状态相差甚远,因为一旦把数据写入区块链,就无法修改,它是不可篡改的。
1.3智能合约
在fabric中,智能合约叫做chaincode链码,当区块链网络之外的某个应用程序需要与账本交互时,该应用程序就会调用此网络中的智能合约。多数情况下,链码仅与账本的数据库组件,即世界状态,进行交互(例如,查询世界状态),而不与交易日志交互。链码的执行由事务排序划分,限制了节点类型间的信任和验证级别,并优化了网络的可伸缩性和性能。
chaincode有6个状态:
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.
Fabric的state是键值对,其中值是对象属性,可以包含多个属性,典型值如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. Docker和docker-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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 up -o etcdraft -s couchdb -i 1.4.2
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 =========== _____ _ _ ____ | ____| | \ | | | _ \ | _| | \| | | | | | | |___ | |\ | | |_| | |_____| |_| \_| |____/
手动启动
// 生成证书和密钥
# 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_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"]}'
// Org2的peer1上应用
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/
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不是,而org1和org2是管理者
# 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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 chaincode --help
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 channel -h
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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.
4.2 orderer
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# ./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
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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 -n docker // make docker执行的命令
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 error,主要是docker的基础镜像hyperledger/fabric-baseimage:amd64-0.4.20的go版本为1.13,而系统的go版本为1.14,导致go.mod不兼容。可直接编译master分支,master分支的版本已修改为2.0.0。
六. Chaincode
基于go的chaincode参考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是基于golang的Fabric应用开发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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 ..
八. 多主机部署
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-cli(https://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中指定各域名对应的IP,Docker-compose中peer还必须定义extra_hosts(即指定域名对应的IP)吗?
答:应为chaincode镜像的生成来自peer节点,但peer的docker-compose中无DNS相关的环境变量配置,实测如果不指定peer无法获知链码创建成功,导致链码实例化失败。
若peer指定CORE_CHAINCODE_BUILDER和CORE_CHAINCODE_GOLANG_RUNTIME变量,则chaincode的镜像为指定镜像,可在指定镜像中共享主机/etc/hosts文件达到指定域名目的。(无实测,理论推断)
2. 在重启docker-compose up时,若有应用正在使用chaincode,即使fabric相关容器volumes已删除,docker-compose up后fabric仍可找寻到链码名和版本,导致重启创建失败。所以要完全重新创建fabric网络时,要连同fabric应用一起删除掉。
3. 错误信息:connection is in TRANSIENT_FAILURE
答:连接不通。首先确认要连接的主机是否运行正常(可通过ping或Telnet确认),其次确认配置文件的连接地址是否正确。
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
参考:
-
区块链技术学习专栏 知乎 传智播客智能物联网 https://zhuanlan.zhihu.com/c_154064303
-
账本进化-了解区块链https://github.com/rodchen-king/Hyperledger-Fabric.git
-
阿里云区块链服务(BaaS)企业级PaaS平台服务https://www.qukuaiwang.com.cn/news/14356.html
https://blog.csdn.net/shebao3333/article/details/103558715
-
Fabric CA环境的集成 深蓝居 https://www.cnblogs.com/studyzy/p/7482451.html
-
Hyperledger Fabric博客汇总 博客 触不可及 https://www.cnblogs.com/cbkj-xd/p/12170903.html
-
Fabric 区块链的多节点部署
-
Fabric环境变量手册
-
Fabric1.4:Go 链码开发与编写https://www.cnblogs.com/zongmin/p/11874792.html
-
HyperLedger Fabric ChainCode开发——shim.ChaincodeStubInterface用法 深蓝居
https://www.cnblogs.com/studyzy/p/7360733.html
-
fabric之chaincode方法GetHistoryForKey的使用https://www.jianshu.com/p/a2381b65222c
-
基于fabric-sdk-go实现的学历信息征信系统 csdn