本Fabric中文文档专栏的阅读前言:前言
文章目录
- 使用测试网络创建通道
-
- 开始之前
- 先决条件
-
- 启动测试网络
- [准备 configtxgen 工具](#准备 configtxgen 工具)
- [`configtx.yaml` 文件](#
configtx.yaml
文件)
- 第一步:生成通道的创世区块
- 第二步:创建应用通道
-
- [Consenter 与 Follower](#Consenter 与 Follower)
- [Active 与 Onboarding](#Active 与 Onboarding)
- 后续步骤
-
- [查看某个 orderer 参与的通道](#查看某个 orderer 参与的通道)
- [让 peers 加入通道](#让 peers 加入通道)
- 设置锚节点
- 向新通道部署链码
注:该章节的中文文档仍然采用的是 2.3 版本以前使用"系统通道"的内容;在之后的版本里系统通道被废弃,配置也发生了改变,不能再基于系统通道创建应用通道。因此本章节依据==更新后的英文版本==翻译而来。
使用测试网络创建通道
请结合 test network 学习如何创建通道创世区块(channel genesis block),并创建一个新的应用通道供测试网络中的 peer 加入。本教程无需你自己搭建 orderer,而是复用 Fabric 示例项目中的测试网络节点。由于测试网络会为你部署排序服务与 peers,本教程将只聚焦在创建通道的流程 。需要说明的是,测试网络自带了一个用于创建通道的子命令 createChannel
,但本教程会演示手动创建的过程------这也是不使用测试网络时所必须掌握的流程。
在本教程中,我们将使用 configtxgen 工具生成通道创世区块,然后使用 osnadmin channel 命令创建通道。
如果你不 使用测试网络,请改为遵循文档:如何部署一个排序服务。
要在测试网络中创建通道,本教程会带你完成以下步骤并介绍相关概念:
开始之前
为了运行测试网络,你需要克隆 fabric-samples
仓库并下载最新的 Fabric 生产镜像。请确保已完成 先决条件 和 安装 Samples、二进制与 Docker 镜像。
注意: 创建通道并让 peers 加入后,你还需要为通道添加 Anchor Peer (锚节点),以支持 Service Discovery 与私有数据功能。本文会包含设置 Anchor Peer 的步骤,但这需要你本机安装 jq 工具。
先决条件
启动测试网络
我们将使用正在运行的 Fabric 测试网络来创建新通道。为保证从"已知干净状态"开始,下面的命令会销毁任何活动容器并移除已有的构件(artifacts)。本教程默认你在 fabric-samples
下的 test-network
目录中操作;如果尚未进入该目录,请执行:
bash
cd fabric-samples/test-network
先将网络关闭:
bash
./network.sh down
然后启动测试网络:
bash
./network.sh up
该命令会创建一个包含 两个 Peer 组织 和 一个排序组织(仅 1 个排序节点) 的 Fabric 网络。两个 Peer 组织各运行一个 peer,排序服务管理员运行一个排序节点。你会在日志中看到类似的节点创建信息:
text
Creating network "fabric_test" with the default driver
Creating volume "net_orderer.example.com" with default driver
Creating volume "net_peer0.org1.example.com" with default driver
Creating volume "net_peer0.org2.example.com" with default driver
Creating peer0.org2.example.com ... done
Creating orderer.example.com ... done
Creating peer0.org1.example.com ... done
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b6b117c81c7f hyperledger/fabric-peer:latest "peer node start" 2 seconds ago Up 1 second 0.0.0.0:7051->7051/tcp peer0.org1.example.com
703ead770e05 hyperledger/fabric-orderer:latest "orderer" 2 seconds ago Up Less than a second 0.0.0.0:7050->7050/tcp, 0.0.0.0:7053->7053/tcp orderer.example.com
718d43f5f312 hyperledger/fabric-peer:latest "peer node start" 2 seconds ago Up 1 second 7051/tcp, 0.0.0.0:9051->9051/tcp peer0.org2.example.com
请注意,Org1 的 peer 运行在 7051
端口,Org2 的 peer 运行在 9051
端口,而 orderer 的端口是 7050
(管理端口 7053
)。我们会在后续命令中用到这些端口。
默认情况下,刚启动的测试网络不包含任何通道 。下文将演示如何在该网络中创建名为 channel1
的通道。
准备 configtxgen 工具
通道的创建是通过在创世区块 中生成"通道创建交易(channel creation transaction)",然后将该创世区块随"加入请求(join request)"一并提交给排序节点。通道创建交易用于声明该通道的初始配置 ,它可以由 configtxgen 工具生成。该工具读取定义通道配置的 configtx.yaml
文件,将相关信息写入通道创建交易,并输出一个包含该交易的创世区块。完成 Fabric 安装 后,configtxgen
已位于 fabric-samples/bin
。
确保你仍处于本地 fabric-samples
克隆中的 test-network
目录,先将二进制加入 PATH:
bash
export PATH=${PWD}/../bin:$PATH
接着,为了使用 configtxgen
,需要把 FABRIC_CFG_PATH
指向包含 configtx.yaml
的测试网络配置目录(这里为 configtx
文件夹):
bash
export FABRIC_CFG_PATH=${PWD}/configtx
现在打印帮助信息,确认 configtxgen
可用:
bash
configtxgen --help
configtx.yaml
文件
在测试网络中,configtxgen
会使用 configtx/configtx.yaml
中定义的通道配置概要(channel profiles) 来构建通道配置,并将其序列化为 Fabric 可读取的 protobuf 格式。
configtx.yaml
包含如下与我们新通道相关的信息:
-
Organizations(组织) :可以成为你通道成员的 Peer 组织和排序组织。每个组织都引用了用于构建 通道 MSP 的加密材料。
-
Ordering service(排序服务) :将由哪些排序节点组成排序服务,以及用于就交易顺序达成一致的共识方法。该节也定义了排序服务的 consenter 集 。测试网络只有一个排序节点;在生产网络中推荐至少 5 个 排序节点(允许同时有 2 个宕机仍能维持共识)。
yaml
EtcdRaft:
Consenters:
- Host: orderer.example.com
Port: 7050
ClientTLSCert: ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
ServerTLSCert: ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
-
Channel policies(通道策略):文件的多个部分共同定义了治理通道交互与更新审批的策略。出于教程目的,我们使用 Fabric 的默认策略。
-
Channel profiles(通道概要) :每个概要会引用
configtx.yaml
其他部分的信息来组装通道配置。概要用于生成应用通道 的创世区块。测试网络的configtx.yaml
中包含一个名为ChannelUsingRaft
的概要,我们将用它生成创建通道所需的交易。
yaml
ChannelUsingRaft:
<<: *ChannelDefaults
Orderer:
<<: *OrdererDefaults
OrdererType: etcdraft
EtcdRaft:
Consenters:
- Host: orderer.example.com
Port: 7050
ClientTLSCert: ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
ServerTLSCert: ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
Organizations:
- *OrdererOrg
Capabilities: *OrdererCapabilities
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
- *Org2
Capabilities: *ApplicationCapabilities
该概要同时包含两个 peer 组织 Org1
与 Org2
,以及排序组织 OrdererOrg
。后续也可以通过通道更新交易增删排序节点或排序组织的 consenter 集。
想进一步了解该文件以及如何编写自己的通道概要?参见:使用 configtx.yaml 创建通道创世区块。也可以查看本专栏中的==《详细拆解configtx通道配置文件》==。现在我们回到"创建通道"的操作流程,后续步骤中还会引用本文件的部分内容。
第一步:生成通道的创世区块
测试网络已启动,接下来可以创建新通道。我们已经设置好了使用 configtxgen
所需的环境变量。
执行以下命令为 channel1
生成创世区块:
bash
configtxgen -profile ChannelUsingRaft -outputBlock ./channel-artifacts/channel1.block -channelID channel1
-
-profile
:通过该参数指定测试网络用于创建应用通道的概要ChannelUsingRaft
(定义在configtx.yaml
中)。 -
-outputBlock
:命令的输出是通道创世区块,写入./channel-artifacts/channel1.block
。 -
-channelID
:该参数即未来通道的名称。教程中使用channel1
。通道名必须是小写、小于 250 个字符,并匹配正则表达式[a-z][a-z0-9.-]*
。
命令成功后,你会看到 configtxgen
加载 configtx.yaml
并打印创建通道交易的日志:
text
[common.tools.configtxgen] main -> INFO 001 Loading configuration
[common.tools.configtxgen.localconfig] completeInitialization -> INFO 002 orderer type: etcdraft
[common.tools.configtxgen.localconfig] completeInitialization -> INFO 003 Orderer.EtcdRaft.Options unset, setting to tick_interval:"500ms" election_tick:10 heartbeat_tick:1 max_inflight_blocks:5 snapshot_interval_size:16777216
[common.tools.configtxgen.localconfig] Load -> INFO 004 Loaded configuration: /Users/fabric-samples/test-network/configtx/configtx.yaml
[common.tools.configtxgen] doOutputBlock -> INFO 005 Generating genesis block
[common.tools.configtxgen] doOutputBlock -> INFO 006 Creating application channel genesis block
[common.tools.configtxgen] doOutputBlock -> INFO 007 Writing genesis block
第二步:创建应用通道
有了通道创世区块后,就可以用 osnadmin channel join
命令在排序服务上创建通道。为简化后续命令,我们还需要设置一些环境变量,指明测试网络各节点证书的位置:
bash
export ORDERER_CA=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
export ORDERER_ADMIN_TLS_SIGN_CERT=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
export ORDERER_ADMIN_TLS_PRIVATE_KEY=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.key
现在在排序服务上创建名为 channel1
的通道:
bash
osnadmin channel join --channelID channel1 --config-block ./channel-artifacts/channel1.block -o localhost:7053 --ca-file "$ORDERER_CA" --client-cert "$ORDERER_ADMIN_TLS_SIGN_CERT" --client-key "$ORDERER_ADMIN_TLS_PRIVATE_KEY"
-
--channelID
:指定在生成创世区块时使用的通道名。 -
--config-block
:指定用configtxgen
生成的通道创世区块或最新配置块(latest config block)的路径。 -
-o
:指定排序节点的管理端点 主机名与端口;测试网络为localhost:7053
。
另外,由于 osnadmin channel
与排序节点之间使用 双向 TLS,需提供以下证书:
-
--ca-file
:排序组织 TLS CA 根证书的位置和文件名。 -
--client-cert
:由 TLS CA 签发的管理员客户端证书位置和文件名。 -
--client-key
:管理员客户端私钥的位置和文件名。
成功后输出类似:
text
Status: 201
{
"name": "channel1",
"url": "/participation/v1/channels/channel1",
"consensusRelation": "consenter",
"status": "active",
"height": 1
}
此时通道已激活,peer 可以加入。
Consenter 与 Follower
注意上述排序节点以 "consensusRelation": "consenter"
身份加入通道。如果你把命令指向一个不在 configtx.yaml
(或通道配置的 consenter 集)之列的排序节点,它会以 follower 身份加入。关于加入更多排序节点的考虑,参见:加入额外的排序节点。
Active 与 Onboarding
排序节点既可以通过通道创世区块 加入,也可以通过最新配置块 加入。如果通过"最新配置块"加入,节点状态会先是 onboarding
,当其账本追上该配置块后状态变为 active
。此时你可以提交通道更新交易把该节点加入 consenter 集,其 consensusRelation
将从 follower
变为 consenter
。
后续步骤
创建通道后,接下来要让 peers 加入通道并部署智能合约(链码)。本节将使用测试网络演示这些过程。
查看某个 orderer 参与的通道
在让 peers 加入之前,你可能还会创建更多通道。随着通道增多,osnadmin channel list
可用于查看该 orderer 所在的通道集合。其参数与前面 osnadmin channel join
相同:
bash
osnadmin channel list -o localhost:7053 --ca-file "$ORDERER_CA" --client-cert "$ORDERER_ADMIN_TLS_SIGN_CERT" --client-key "$ORDERER_ADMIN_TLS_PRIVATE_KEY"
输出类似:
json
Status: 200
{
"systemChannel": null,
"channels": [
{
"name": "channel1",
"url": "/participation/v1/channels/channel1"
}
]
}
让 peers 加入通道
测试网络包含两个 peer 组织,各有一个 peer。在使用 peer CLI 前,需要设置环境变量来指定我们以哪个用户(client MSP)执行 以及目标 peer 是谁。下面以 Org1 管理员身份操作,并指向 Org1 的 peer:
bash
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID=Org1MSP
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051
为使用 peer CLI,还需调整 FABRIC_CFG_PATH
:
bash
export FABRIC_CFG_PATH=$PWD/../config/
向 channel1
发送加入请求(携带创世区块):
bash
peer channel join -b ./channel-artifacts/channel1.block
成功后输出类似:
text
[channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
[channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
然后为 Org2
重复以上步骤。设置以下环境变量,以 Org2 管理员身份操作,并将目标 peer 设为 peer0.org2.example.com
:
bash
export CORE_PEER_LOCALMSPID=Org2MSP
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=localhost:9051
再次加入 channel1
:
bash
peer channel join -b ./channel-artifacts/channel1.block
成功后输出类似:
text
[channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
[channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
设置锚节点
当某组织的 peers 加入通道后,应为该组织至少 选择一个 peer 作为 Anchor Peer(锚节点 )。只有配置 Anchor Peer,才能使用私有数据与服务发现等功能。每个组织应为通道配置多个 Anchor Peer 以增强冗余。更多关于 Gossip 与 Anchor Peer 的信息,参见 Gossip 数据分发协议。
各组织的 Anchor Peer 端点信息存储于通道配置 中。通道成员可通过更新通道 来设置其 Anchor Peer。我们将使用 configtxlator 工具来更新通道配置,为 Org1
与 Org2
各设置一个 Anchor Peer。
如果你的本机尚未安装 jq,请先安装再继续以下步骤。
sudo apt-get install jq
首先将 Org1
的 peer0.org1.example.com
设为 Anchor Peer。第一步使用 peer channel fetch
拉取最新通道配置块。设置环境变量,以 Org1 管理员身份操作:
bash
export CORE_PEER_LOCALMSPID=Org1MSP
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051
拉取配置块:
bash
peer channel fetch config channel-artifacts/config_block.pb -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com -c channel1 --tls --cafile "$ORDERER_CA"
由于当前最新配置块就是通道创世区块 ,上述命令会返回通道的第 0
块。日志类似:
text
[channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
[cli.common] readBlock -> INFO 002 Received block: 0
[channelCmd] fetch -> INFO 003 Retrieving last config block: 0
[cli.common] readBlock -> INFO 004 Received block: 0
配置块 config_block.pb
会存放在 channel-artifacts
目录,以便与其他构件分离。切换进去完成下一步:
bash
cd channel-artifacts
接下来使用 configtxlator
处理通道配置。先把区块从 protobuf 解码为可读可编辑的 JSON,并剥离无关的块数据,仅保留通道配置本体:
bash
configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json
jq '.data.data[0].payload.data.config' config_block.json > config.json
现在我们得到简化后的通道配置 config.json
,作为更新的基线。为避免直接修改原始配置,先拷贝一份进行编辑:
bash
cp config.json config_copy.json
使用 jq
将 Org1
的 Anchor Peer 信息添加到通道配置中:
bash
jq '.channel_group.groups.Application.groups.Org1MSP.values += {"AnchorPeers":{"mod_policy": "Admins","value":{"anchor_peers": [{"host": "peer0.org1.example.com","port": 7051}]},"version": "0"}}' config_copy.json > modified_config.json
完成后,更新后的 JSON 配置位于 modified_config.json
。现在把原始与修改后的配置都编码回 protobuf,并计算它们之间的差异(即"配置更新"):
bash
configtxlator proto_encode --input config.json --type common.Config --output config.pb
configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb
configtxlator compute_update --channel_id channel1 --original config.pb --updated modified_config.pb --output config_update.pb
新的 protobuf 文件 config_update.pb
中包含了要应用到通道配置的 Anchor Peer 更新。将该更新包裹进交易信封以形成"通道配置更新交易":
bash
configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate --output config_update.json
echo '{"payload":{"header":{"channel_header":{"channel_id":"channel1", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . > config_update_in_envelope.json
configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope --output config_update_in_envelope.pb
注:这里拆分一下上述三个命令。
- 第一个configtxlator命令将差异文件转化为json。
- 第二个命令将
config_update.json
外层再包装了一遍,成为标准的信封格式(这是 Fabric 提交配置更新时必须的外层格式),然后交给jp,经过jp检验美化过后输入到config_update_in_envelope.json里面。- 第三个命令重新编码 json → pb
回到 test-network
目录:
bash
cd ..
现在通过 peer channel update
提交更新。由于我们只更新了与 Org1
相关的配置,其他通道成员不需要批准该更新:
bash
peer channel update -f channel-artifacts/config_update_in_envelope.pb -c channel1 -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem"
成功后会看到:
text
[channelCmd] update -> INFO 002 Successfully submitted channel update
接下来也把 Org2
的 peer0.org2.example.com
设为 Anchor Peer。因为是第二次,我们会更快地过一遍流程。先以 Org2 管理员身份设置环境变量:
bash
export CORE_PEER_LOCALMSPID=Org2MSP
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=localhost:9051
拉取最新配置块(此时已是通道的第二个区块):
bash
peer channel fetch config channel-artifacts/config_block.pb -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com -c channel1 --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem"
进入 channel-artifacts
:
bash
cd channel-artifacts
解码并拷贝配置:
bash
configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json
jq '.data.data[0].payload.data.config' config_block.json > config.json
cp config.json config_copy.json
将 Org2
的 Anchor Peer 信息写入配置:
bash
jq '.channel_group.groups.Application.groups.Org2MSP.values += {"AnchorPeers":{"mod_policy": "Admins","value":{"anchor_peers": [{"host": "peer0.org2.example.com","port": 9051}]},"version": "0"}}' config_copy.json > modified_config.json
重新编码并计算差异:
bash
configtxlator proto_encode --input config.json --type common.Config --output config.pb
configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb
configtxlator compute_update --channel_id channel1 --original config.pb --updated modified_config.pb --output config_update.pb
打包为交易:
bash
configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate --output config_update.json
echo '{"payload":{"header":{"channel_header":{"channel_id":"channel1", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . > config_update_in_envelope.json
configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope --output config_update_in_envelope.pb
回到 test-network
:
bash
cd ..
提交更新,将 Org2
的 Anchor Peer 写入通道配置:
bash
peer channel update -f channel-artifacts/config_update_in_envelope.pb -c channel1 -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem"
如果你想进一步了解如何提交通道更新请求,请参见:更新通道配置。
你可以通过 peer channel getinfo
验证通道已更新成功:
bash
peer channel getinfo -c channel1
现在通道在创世块基础上又新增了两个配置块,高度应为 3,区块哈希也会更新,例如:
text
Blockchain info: {"height":3,"currentBlockHash":"GKqqk/HNi9x/6YPnaIUpMBlb0Ew6ovUnSB5MEF7Y5Pc=","previousBlockHash":"cl4TOQpZ30+d17OF5YOkX/mtMjJpUXiJmtw8+sON8a8="}
注:配置更新(包括锚节点变更)一定会产生新区块;但不会"强制结束"当前区块,而是生成下一个区块;
向新通道部署链码
可以通过在通道上部署链码来验证通道创建成功。我们可使用 network.sh
脚本把"资产转移基础(Basic)"示例链码部署到任一测试网络通道。对新通道执行:
bash
./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go/ -ccl go -c channel1
执行后,你应在日志中看到链码已部署到通道的输出:
text
Committed chaincode definition for chaincode 'basic' on channel 'channel1':
Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true]
Query chaincode definition successful on peer0.org2 on channel 'channel1'
Chaincode initialization is not required
然后初始化一些资产:
bash
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "$ORDERER_CA" -C channel1 -n basic --peerAddresses localhost:7051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" --peerAddresses localhost:9051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" -c '{"function":"InitLedger","Args":[]}'
成功后会看到:
text
[chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200
查询以确认资产已写入账本:
bash
peer chaincode query -C channel1 -n basic -c '{"Args":["getAllAssets"]}'
输出类似:
json
[
{"ID":"asset1","color":"blue","size":5,"owner":"Tomoko","appraisedValue":300},
{"ID":"asset2","color":"red","size":5,"owner":"Brad","appraisedValue":400},
{"ID":"asset3","color":"green","size":10,"owner":"Jin Soo","appraisedValue":500},
{"ID":"asset4","color":"yellow","size":10,"owner":"Max","appraisedValue":600},
{"ID":"asset5","color":"black","size":15,"owner":"Adriana","appraisedValue":700},
{"ID":"asset6","color":"white","size":15,"owner":"Michel","appraisedValue":800}
]
不使用测试网络创建通道
本教程带你用 osnadmin channel join
在测试网络上创建通道并完成基础实践。当你准备搭建自己的网络时,请参见:Create a channel,以进一步学习 osnadmin channel
系列命令的使用。