Fabric hyperledger 1.4 first-network 测试及手动执行

Building Your First Network

BYFN提供了一个示例Hyperledger Fabric网络,该网络由两个组织组成,每个组织维护两个Peer节点。

安装先决条件

操作系统:CentOS 7
1.clone源码
  git clone https://github.com/hyperledger/fabric-samples.git
  切换到1.4.1分支 git checkout -b v1.4.1
2.已安装二进制工具
   linux版本
   其它系统版本:Mac版本 Windows版本
3.已安装docker(推荐docker18.06及以上)和docker-compose
   docker-compose安装:官方地址
  进入fabric-samples目录:
   cd fabric-samples/first-network
  first-network目录下面有个byfn.sh的脚本
  ./byfn.sh up 即可全自动构建hyperledger网络(默认链码go,通道名mychannel,数据存储为leveldb,共识使用solo)

Usage:
byfn.sh <mode> [-c <channel name>] [-t <timeout>] [-d <delay>] [-f <docker-compose-file>] [-s <dbtype>] [-l <language>] [-o <consensus-type>] [-i <imagetag>] [-v]"
  <mode> - one of 'up', 'down', 'restart', 'generate' or 'upgrade'"
    - 'up' - bring up the network with docker-compose up"
    - 'down' - clear the network with docker-compose down"
    - 'restart' - restart the network"
    - 'generate' - generate required certificates and genesis block"
    - 'upgrade'  - upgrade the network from version 1.3.x to 1.4.0"
  -c <channel name> - channel name to use (defaults to \"mychannel\")"
  -t <timeout> - CLI timeout duration in seconds (defaults to 10)"
  -d <delay> - delay duration in seconds (defaults to 3)"
  -f <docker-compose-file> - specify which docker-compose file use (defaults to docker-compose-cli.yaml)"
  -s <dbtype> - the database backend to use: goleveldb (default) or couchdb"
  -l <language> - the chaincode language: golang (default), node, or java"
  -o <consensus-type> - the consensus-type of the ordering service: solo (default), kafka, or etcdraft"
  -i <imagetag> - the tag to be used to launch the network (defaults to \"latest\")"
  -v - verbose mode"
byfn.sh -h (print this message)"

Typically, one would first generate the required certificates and
genesis block, then bring up the network. e.g.:"

  byfn.sh generate -c mychannel"
  byfn.sh up -c mychannel -s couchdb"
  byfn.sh up -c mychannel -s couchdb -i 1.4.0"
  byfn.sh up -l node"
  byfn.sh down -c mychannel"
  byfn.sh upgrade -c mychannel"

Taking all defaults:"
      byfn.sh generate"
      byfn.sh up"
      byfn.sh down"

生成证书密钥、创世区块、通道配置等

执行以下命令: ./byfn.sh generate
在这里插入图片描述在这里插入图片描述

启动网络

执行命令: ./byfn.sh up
上面的命令将编译安装go语言链码。 Go是默认的链代码语言,但是也支持Node.js和Java链代码。
./byfn.sh up -l node (node版本链码启动命令)
./byfn.sh up -l java (java版本链码命令)
注意只能启用一个版本的链码,可先关闭网络
./byfn.sh down ,然后再尝试其它语言链码

  除了支持多种链码语言外,还可以通过-o标志指定Ordering Service(默认solo),如启用Raft ordering service可执行以下命令:
  ./byfn.sh up -o etcdraft
  启用Kafka ordering service
  ./byfn.sh up -o kafka

接下来将介绍底层工具及引导机制的信息.

Crypto Generator

使用cryptogen tool为我们的各种网络实体生成加密材料(x509证书和签名密钥)。 这些证书代表身份,它们允许在我们的实体进行通信和交易时进行签名/验证身份验证。

在first-network目录下有一个 crypto-config.yaml 文件, 它包含网络拓扑,并允许我们为组织和属于这些组织的组件生成一组证书和密钥。 每个组织都配置了一个唯一的根证书(ca-cert),用于将特定组件(peers and orderers)绑定到该组织。 通过为每个组织分配唯一的CA证书。 Hyperledger Fabric中的事务和通信由实体的私钥(密钥库)签名,然后通过公钥(signcerts)进行验证。

crypto-config.yaml文件中有个计数变量count。 它指定每个组织的peers数量.
运行cryptogen工具后,生成的证书和密钥将保存到名为crypto-config的文件夹中。
请注意,crypto-config.yaml文件列出了与五个orderer节点。 虽然加密工具将为所有这五个orderer节点创建证书,但除非使用Raft或Kafka,否则这些orderer节点中只有一个将用于Solo订购服务实施,并用于创建系统通道。
在这里插入图片描述

Configuration Transaction Generator

configtxgen将用来:
1.生成创世区块
2.通道配置
3.锚节点配置,此例中有两个组织,每个组织各一个锚节点

configtx.yaml - 它包含示例网络的定义。 有三个成员 - 一个Orderer Org(OrdererOrg)和两个Peer Orgs(Org1和Org2),每个成员管理和维护两个peer节点。 该文件还指定了一个联盟 - SampleConsortium - 由我们的两个Peer Orgs组成。

工具使用

可以使用configtxgen和cryptogen命令手动生成证书/密钥和各种配置工件。
byfn.sh脚本中引用generateCerts函数,以获取生成将用于网络配置的证书所需的命令
在fabric-samples/bin下面,我们可以看到configtxgen和cryptogen
在first-network目录下执行命令:
…/bin/cryptogen generate --config=./crypto-config.yaml
会看到控制台输出:
org1.example.com
org2.example.com
同时会在first-network目录下生成crypto-config文件夹,里面存放了证书及密钥文件

接下来,我们需要告诉configtxgen工具在哪里查找它需要的configtx.yaml文件:
export FABRIC_CFG_PATH=$PWD
执行以下命令生成创世区块
…/bin/configtxgen -profile TwoOrgsOrdererGenesis -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block
(Raft ordering service命令:
…/bin/configtxgen -profile SampleMultiNodeEtcdRaft -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block
Kafka ordering service命令:
…/bin/configtxgen -profile SampleMultiNodeEtcdRaft -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block)
窗口会出现以下输出:
在这里插入图片描述

通道配置

执行命令:
export CHANNEL_NAME=mychannel && …/bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME
这里我们采用默认的通道名 mychannel
在这里插入图片描述
Raft或Kafka ordering service命令同上
接下来进行锚节点配置
org1:
…/bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP

org2:
…/bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP

在这里插入图片描述

Start the network

接下来,手动启动网络:
docker-compose -f docker-compose-cli.yaml up -d
在这里插入图片描述
如果要查看网络的实时日志,请不要提供-d标志

创建和加入通道

回想一下,我们使用configtxgen工具创建了通道配置事务。 您可以使用configtx.yaml中传递给configtxgen工具的相同或不同的配置文件重复该过程以创建其他通道配置事务。 然后,您可以重复本节中定义的过程,以在您的网络中建立其他通道。
使用docker exec命令进入CLI容器:
docker exec -it cli bash
如果进入成功,会看到类似于:
root@0d78bb69300d:/opt/gopath/src/github.com/hyperledger/fabric/peer#
为了操作方便,配置以下四个环境变量:

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/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

接下来就之前生成的channel.tx传递给order节点
(使用-c标志指定通道名称,使用-f标志指定通道配置事务。 在这种情况下,它是channel.tx,但是您可以使用不同的名称装入自己的配置事务。 我们将再次在CLI容器中设置CHANNEL_NAME环境变量,以便我们不必显式传递此参数。 通道名称必须全部小写,长度小于250个字符,并且与正则表达式[a-z] [a-z0-9 .-] *匹配)

export CHANNEL_NAME=mychannel
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

(注意我们作为此命令中–cafile,它是orderer的根证书的本地路径,允许我们验证TLS握手,默认启用TLS,当然也可以关闭TLS)
此命令返回一个创世块 - <CHANNEL_NAME.block> 我们将其加入通道
如果全部按照本文的命令,配置通道名为mychannel,会得到mychannel.block

peer0.org1.example.com加入通道:
peer channel join -b mychannel.block
您可以根据需要通过对上文配置的四个环境变量进行适当更改来使其他对等方加入通道。
将peer0.org2.example.com加入通道,以便我们可以正确更新通道中的锚点对等定义。 由于我们将覆盖CLI容器中的默认环境变量,因此这个完整命令将如下所示:

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/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

或者,您可以选择单独设置这些环境变量,而不是传入整个字符串。 一旦设置完毕,您只需再次发出peer channel join命令(cli容器将会代表peer0.org2.example.com注意)

更新锚节点(Update the anchor peers)

以下命令是通道更新,它们将传播到通道的定义。 实质上,我们在通道的创世块之上添加了额外的配置信息。 请注意,我们不是修改genesis块,而是简单地将增量添加到将定义锚点对等体的链中。
更新通道定义以将Org1的锚点对等体定义为peer0.org1.example.com执行以下命令:

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

更新通道定义以将Org2的锚点对等体定义为peer0.org2.example.com执行以下命令:

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/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

在这里插入图片描述

安装与实例化链码

应用程序通过链代码与区块链分类帐进行交互。 因此,我们需要在每个将执行和支持我们的事务的对等体上安装链代码,然后在通道上实例化链代码。 首先,将示例Go,Node.js或Java链代码安装到Org1中的peer0节点上。
Golang:

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

Node.js

peer chaincode install -n mycc -v 1.0 -l node -p /opt/gopath/src/github.com/chaincode/chaincode_example02/node/

Java

peer chaincode install -n mycc -v 1.0 -l java -p /opt/gopath/src/github.com/chaincode/chaincode_example02/java/

当我们在channel上实例化链码时,背书策略将被设置为要求Org1和Org2中的对等方的认可。 因此,我们还需要在Org2中的对等体上安装链码。
修改以下四个环境变量以在Org2中针对peer0发出install命令:

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/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

继续安装链码(以golang为例,node,java不再赘述,同上)

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

接下来,在通道上实例化链码。 这将初始化通道上的链代码,设置链代码的背书策略,并为目标对等方启动链代码容器。 记下-P参数。 这是我们的策略,我们指定针对要验证的此链码的交易所需的认可级别。
在下面的命令中,您会注意到我们将策略指定为-P
“AND(‘Org1MSP.peer’,‘Org2MSP.peer’)”。 这意味着我们需要来自属于Org1 AND Org2的对等方的“认可”(即两个认可)。 如果我们将语法更改为OR,那么我们只需要一个认可。
以golang为例:

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')"

Node.js

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 -l node -v 1.0 -c '{"Args":["init","a", "100", "b","200"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer')"

Java

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 -l java -v 1.0 -c '{"Args":["init","a", "100", "b","200"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer')"

如果希望其他Peer节点与账本进行交互,则需要将它们加入到对应通道,安装对应的链码。 一旦安装完链码,会生成对应的链码容器。
通过-l参数指定链码语言,node和java相对golang会比较慢,耐心等待即可.
在这里插入图片描述

Query

执行命令:
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{“Args”:[“query”,“a”]}'
在这里插入图片描述

Invoke

现在让我们从a到b转账10。 此事务将剪切新块并更新状态DB。 调用的语法如下:

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"]}'

再次query

执行命令:

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

在这里插入图片描述
如上图所示,资产变为90

Install

现在我们将在Org2中的第三个对等体peer1上安装链代码。 修改以下四个环境变量,以便在Org2中针对peer1发出install命令:

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/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

以golang为例,node,java不再赘述,请翻阅本文上述命令

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

再次query

让我们确认我们可以在Org2中向Peer1发出查询。 我们使用值100初始化了键a,并在之前的调用中删除了10。 因此,对a的查询仍应返回90。

org2中的peer1必须首先加入该通道才能响应查询。 可以通过发出以下命令来连接通道并查询:

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/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 peer channel join -b mychannel.block
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'

在这里插入图片描述
Chaincode必须安装在对等体上,以便它能够成功地对分类帐执行读/写操作。 此外,在针对该链代码执行init或传统事务(读/写)之前,不会为对等启动链代码容器(例如,查询“a”的值)。 该事务导致容器启动。 此外,通道中的所有对等体都保持分类帐的精确副本,其包括用于以块的形式存储不可变的有序记录的区块链,以及用于维护当前状态的快照的状态数据库。 这包括那些没有安装链代码的对等体(如上例中的peer1.org1.example.com)。 最后,链代码在安装后可以访问(如上例中的peer1.org2.example.com),因为它已经被实例化了。

脚本深入理解

BYFN示例为我们提供了两种Docker Compose文件,这两种文件都是从docker-compose-base.yaml(位于基本文件夹中)扩展而来的。 我们的第一个版本docker-compose-cli.yaml为我们提供了一个CLI容器,以及一个order,四个peer。 本文操作使用的是此文件.

第二种风格docker-compose-e2e.yaml构建为使用Node.js SDK运行端到端测试。 除了使用SDK之外,它的主要区别在于Fabric-ca服务器还有容器。 因此,我们能够将REST调用发送到组织CA以进行用户注册和注册。

如果你想在没有先运行byfn.sh脚本的情况下使用docker-compose-e2e.yaml,那么我们需要进行四次略微修改。 我们需要指向组织CA的私钥。 您可以在crypto-config文件夹中找到这些值。 例如,要找到Org1的私钥,我们将遵循此路径 - crypto-config / peerOrganizations / org1.example.com / ca /。 私钥是一个长哈希值,后缀_sk。 Org2的路径是 - crypto-config / peerOrganizations / org2.example.com / ca /。

在docker-compose-e2e.yaml中更新ca0和ca1的FABRIC_CA_SERVER_TLS_KEYFILE变量。 您还需要编辑命令中提供的路径以启动ca服务器。 您为每个CA容器提供两次相同的私钥。

启用CouchDB

状态数据库可以从默认(goleveldb)切换到CouchDB。 CouchDB提供了相同的链代码功能,但是,根据链代码数据被建模为JSON,还可以对状态数据库数据内容执行丰富而复杂的查询。 要使用CouchDB而不是默认数据库(goleveldb),请按照前面概述的相同步骤生成工件,除非在启动网络时也传递docker-compose-couch.yaml:

docker-compose -f docker-compose-cli.yaml -f docker-compose-couch.yaml up -d

chaincode_example02现在可以使用下面的CouchDB工作。

在peer0.org1.example.com上安装并实例化链代码:

peer chaincode install -n marbles -v 1.0 -p github.com/chaincode/marbles02/go
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 marbles -v 1.0 -c '{"Args":["init"]}' -P "OR ('Org1MSP.peer','Org2MSP.peer')"
peer chaincode invoke -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 marbles -c '{"Args":["initMarble","marble1","blue","35","tom"]}'
peer chaincode invoke -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 marbles -c '{"Args":["initMarble","marble2","red","50","tom"]}'
peer chaincode invoke -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 marbles -c '{"Args":["initMarble","marble3","blue","70","tom"]}'
peer chaincode invoke -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 marbles -c '{"Args":["transferMarble","marble2","jerry"]}'
peer chaincode invoke -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 marbles -c '{"Args":["transferMarblesBasedOnColor","blue","jerry"]}'
peer chaincode invoke -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 marbles -c '{"Args":["delete","marble1"]}'

如果您选择在docker-compose中映射CouchDB端口,现在可以通过打开浏览器并导航到以下URL,通过CouchDB Web界面(Fauxton)查看状态数据库:
http://localhost:5984/_utils
您应该看到名为mychannel(或您的唯一通道名称)的数据库及其中的文档。
您可以从CLI运行常规查询:

peer chaincode query -C $CHANNEL_NAME -n marbles -c '{"Args":["readMarble","marble2"]}'

也可以通过以下命令检索历史:

peer chaincode query -C $CHANNEL_NAME -n marbles -c '{"Args":["getHistoryForMarble","marble1"]}'

也可以执行以下命令进行富查询:

peer chaincode query -C $CHANNEL_NAME -n marbles -c '{"Args":["queryMarblesByOwner","jerry"]}'

总结

本文基于Fabric 1.4 介绍了first-network的搭建,及手动配置运行first-network网络,希望能够对大家有所帮助,遇到问题欢迎在评论区留言!

发布了13 篇原创文章 · 获赞 0 · 访问量 2600

猜你喜欢

转载自blog.csdn.net/weixin_43839871/article/details/97616033
今日推荐