hyperledger-fabric1.4

1. 切换路径并关闭已存在网络

1
cd /opt/gopath/src/github.com/hyperledger/fabric-samples/first-network/

执行通道配置更新并不是必需要关闭已有的网络。本次教程只是为了从初始状态开始才将原有网络关闭。

1
./byfn.sh down

2.生成新的网络

1
2
./byfn.sh generate
./byfn.sh up

3.添加新组织Org3

3.1 利用脚本添加新组织Org3

1
./eyfn.sh up

如果顺利运行,你可以看到以下内容:

1
2
3
4
5
6
7
8
========= All GOOD, EYFN test execution completed =========== 


_____ _ _ ____
| ____| | \ | | | _ \
| _| | \| | | | | |
| |___ | |\ | | |_| |
|_____| |_| \_| |____/

3.2 手动添加新组织Org3

因为上面步骤已经使用了eyfn.sh脚本,因此需要关闭网络,删除所有容器,并撤销添加Org3的操作。

1
./eyfn.sh down

网络关闭之后,再次将其恢复

1
2
./byfn.sh generate
./byfn.sh up

此时网络恢复到执行eyfn.sh脚本之前的状态

3.2.1 生成Org3的加密材料

进入org3-artifacts目录

1
cd org3-artifacts/
1
2
3
[root@localhost first-network]# cd org3-artifacts/
[root@localhost org3-artifacts]# ls
configtx.yaml org3-crypto.yaml

生成加密材料

1
cryptogen generate --config=./org3-crypto.yaml
1
2
[root@localhost org3-artifacts]# cryptogen generate --config=./org3-crypto.yaml
org3.example.com

该命令读取加密材料生成所需要的yaml文件,并利用cryptogen工具为Org3的一个CA和两个与之绑定的peer节点生成密钥和证书。生成的材料放在当前目录的crypto-config文件夹中.

利用configtxgen来以JSON的格式打印Org3指定配置材料,配置让configtxgen在当前目录寻找configtx.yaml文件

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

该命令生成一个org3.json文件,存放在first-network目录下的channel-artifacts文件夹中。该文件包含Org3的策略定义和三个base64格式的证书:管理员用户证书,CA根证书和TLS根证书。该json文件会在后面的步骤中加入到通道配置中。

1
2
3
[root@localhost first-network]# cd channel-artifacts/
[root@localhost channel-artifacts]# ls
channel.tx genesis.block Org1MSPanchors.tx Org2MSPanchors.tx org3.json

最后将orderer的MSP材料复制到Org3的crypto-config目录下。orderer的TLS根证书允许Org3和网络排序节点的安全通信。

1
cd ../ && cp -r crypto-config/ordererOrganizations org3-artifacts/crypto-config/
  • cp -r 代表拷贝文件夹
1
2
3
[root@localhost first-network]# cd org3-artifacts/crypto-config/
[root@localhost crypto-config]# ls
ordererOrganizations peerOrganizations

可以看到已经将orderer的MSP材料复制到对应位置。

3.2.2 CLI环境准备

更新过程利用配置转换工具:configtxlator。该工具提供独立于SDK的无状态REST API。同时提供了CLI来简化Fabric网路中的配置工作。该工具作用是在不同等效数据表示形式/格式之间轻松转换(在本例子中,在protobufs和json格式之间转换)。另外,该工具可以基于两个通道配置之间的差异来计算配置更新事务。

进入容器并配置ORDERER_CACHANNEL_NAME的值

1
2
docker exec -it cli bash
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

查看是否正确设置对应变量值

1
echo $ORDERER_CA && echo $CHANNEL_NAME
1
2
3
root@f7d186065b85:/opt/gopath/src/github.com/hyperledger/fabric/peer# echo $ORDERER_CA && echo $CHANNEL_NAME
/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
mychannel

这样的变量设置方式是临时的,一旦退出cli容器,重新进入时就需要再次重新设置。

3.2.3 获取配置

获取通道mychannel最新的配置区块。之所以要获取最新的配置区块是因为配置元素是版本化的。
可以避免重复的配置更改,同时有助于确保并发性(当需要从通道删除一个组织的时候,例如在一个新组织被添加到通道中之后,版本控制有助于防止同时将两个组织都删除了,而是保证仅仅删除想要删除的组织)

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

该命令保存二进制protobuf通道配置块到config_block.pb。注意此处的名称和文件后缀选择是随意的,但是建议遵循一个约定,该约定既能表示对象类型也能体现对象的编码(protobuf 或者 json)格式。

1
2
3
4
5
root@f7d186065b85:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CA
2019-10-22 11:17:44.424 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2019-10-22 11:17:44.436 UTC [cli.common] readBlock -> INFO 002 Received block: 4
2019-10-22 11:17:44.438 UTC [cli.common] readBlock -> INFO 003 Received block: 2
2019-10-22 11:17:44.438 UTC [channelCmd] fetch -> INFO 004 Retrieving last config block: 2

从日志最后一行可以看出通道mychannel最近的配置块实际上是区块2,并不是创世区块。默认情况下该命令返回目标通道的最新区块,在本次示例中最新区块为第三个区块。因为脚本为两个组织在两个独立的通道更新交易中定义了锚节点。所以配置序列如下:

  • 区块0:创世区块
  • 区块1:Org1锚节点更新
  • 区块2:Org2锚节点更新
3.2.3 配置文件格式转换与修改

使用configtxlator工具将通道配置块解码为JSON格式(人类可读取和修改)。 同时必须将所有与我们要进行的更改无关的标题,元数据,创建者签名等剥离。 通过使用jq工具完成此任务:

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

执行完毕生成一个简洁的JSON对象config.json作为后续配置更新的基准文件。

1
2
root@f7d186065b85:/opt/gopath/src/github.com/hyperledger/fabric/peer# ls
channel-artifacts config.json config_block.pb crypto log.txt mychannel.block scripts
3.2.4 添加Org3加密材料

再次使用jq工具追加Org3的配置定义Org3.json到通道的应用组字段中并将输出命名为modified_config.json

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

可以看到已经生成modified_config.json文件

1
2
root@f7d186065b85:/opt/gopath/src/github.com/hyperledger/fabric/peer# ls
channel-artifacts config.json config_block.pb crypto log.txt modified_config.json mychannel.block scripts

此时。已经有两个JSON文件,分别是config.jsonmodified_config.json。初始文件只包含Org1和Org2的信息,而修改后的文件包含了三个组织的信息。此时,只需重新编码这两个JSON文件并计算增量即可。

config.json转回protobuf格式,命名为config.pb

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

modified_config.json转回protobuf格式,命名为modified_config.pb

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

查看对应文件是否生成

1
2
root@f7d186065b85:/opt/gopath/src/github.com/hyperledger/fabric/peer# ls
channel-artifacts config.json config.pb config_block.pb crypto log.txt modified_config.json modified_config.pb mychannel.block scripts

利用configtxlator计算两个配置protobufs的增量,以下命令会输出一个新的protobuf名为org3_update.pb:

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

可以看到所需要文件已经生成

1
2
root@f7d186065b85:/opt/gopath/src/github.com/hyperledger/fabric/peer# ls
channel-artifacts config.json config.pb config_block.pb crypto log.txt modified_config.json modified_config.pb mychannel.block org3_update.pb scripts

新生成的org3_update.pb 包含Org3的定义和指向Org1和Org2的高级指针。

在提交通道更新之前,我们需要执行最后的几步。

首先将 org3_update.pb 解码为可编辑的JSON格式,命名为org3_update.json

1
configtxlator proto_decode --input org3_update.pb --type common.ConfigUpdate | jq . > org3_update.json
1
2
root@f7d186065b85:/opt/gopath/src/github.com/hyperledger/fabric/peer# ls
channel-artifacts config.json config.pb config_block.pb crypto log.txt modified_config.json modified_config.pb mychannel.block org3_update.json org3_update.pb scripts

在有解码后的org3_update.json文件之后,需要将其封装在信封消息之中。这一步会将我们先前删除的头部数据添加回来,封装完的文件命名为org3_update_in_envelope.json

1
echo '{"payload":{"header":{"channel_header":{"channel_id":"mychannel", "type":2}},"data":{"config_update":'$(cat org3_update.json)'}}}' | jq . > org3_update_in_envelope.json
1
2
3
root@f7d186065b85:/opt/gopath/src/github.com/hyperledger/fabric/peer# ls
channel-artifacts config.pb crypto modified_config.json mychannel.block org3_update.pb scripts
config.json config_block.pb log.txt modified_config.pb org3_update.json org3_update_in_envelope.json

最后再次利用configtxlator工具将org3_update_in_envelope.json转化为Fabric所需要的完整protobuf格式,命名为org3_update_in_envelope.pb:

1
onfigtxlator proto_encode --input org3_update_in_envelope.json --type common.Envelope --output org3_update_in_envelope.pb
1
2
3
root@f7d186065b85:/opt/gopath/src/github.com/hyperledger/fabric/peer# ls
channel-artifacts config.pb crypto modified_config.json mychannel.block org3_update.pb org3_update_in_envelope.pb
config.json config_block.pb log.txt modified_config.pb org3_update.json org3_update_in_envelope.json scripts
3.2.5 签名并提交配置更新

现在在CLI容器中已经有了org3_update_in_envelope.pb。但是在配置写入账本之前,必需要有来自Admin用户的签名,在已有通道应用组中修改策略设置为默认“MAJORITY”,即需要大多数现有的组织管理员的签名。因为目前只有Org1和Org2两个组织,所以需要这两个组织的签名。如果没有这两个签名,排序服务交易未能满足策略而拒绝交易。

Org1 Admin签名:

1
peer channel signconfigtx -f org3_update_in_envelope.pb
1
2
root@f7d186065b85:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer channel signconfigtx -f org3_update_in_envelope.pb
2019-10-22 14:03:32.763 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
  • 在组织之间切换以签署配置事务(或执行其他任何操作)并不能反映真实的Fabric操作。单个容器永远不会安装整个网络的加密材料。而是需要将配置更新安全地带外传递给Org2管理员进行检查和批准。

切换到Org2环境变量

1
2
3
4
5
6
7
export CORE_PEER_LOCALMSPID="Org2MSP"

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

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

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

发出更新命令,此时Org2 Admin的签名将会附加到此调用中。因此不需手动再次为protobuf签名。

1
peer channel update -f org3_update_in_envelope.pb -c $CHANNEL_NAME -o orderer.example.com:7050 --tls --cafile $ORDERER_CA
1
2
2019-10-22 14:06:55.118 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2019-10-22 14:06:55.164 UTC [channelCmd] update -> INFO 002 Successfully submitted channel update
3.2.6 选择配置

新加入的节点通过创世块进行引导,但是创世块中不包含通道配置更新中被新添加进去的组织。因此新节点无法利用gossip,因为在新节点获得添加组织到通道的配置交易前,无法验证其它节点从自己组织中转发过来的区块。新添加的节点必须进行以下配置(二选一)使得新的节点能够从排序服务中接收区块。

  1. 利用静态选举模式,将节点配置为组织领导
    1
    2
     CORE_PEER_GOSSIP_USELEADERELECTION=false
    CORE_PEER_GOSSIP_ORGLEADER=true
    所有添加到通道中的新节点配置必须相同
  2. 利用动态领导选举模式,配置节点使用领导选举
    1
    2
    CORE_PEER_GOSSIP_USELEADERELECTION=true
    CORE_PEER_GOSSIP_ORGLEADER=false
    由于新添加组织中的节点无法形成成员视图,因此该配置是与静态模式相似的。因为每个节点在一开始的时候都会宣称自己是领导者。但是一旦它们获得添加组织到通道的配置交易更新,则组织只会有一个领导节点。所以如果最后希望组织节点利用领导选举则建议使用这种模式。

以上两种模式配置都是在first-network目录中的base文件夹下的peer-base.yaml文件中进行。以下截取可以配置部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
peer-base:
image: hyperledger/fabric-peer:$IMAGE_TAG
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
# the following setting starts chaincode containers on the same
# bridge network as the peers
# https://docs.docker.com/compose/networking/
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${COMPOSE_PROJECT_NAME}_byfn
- FABRIC_LOGGING_SPEC=INFO
#- FABRIC_LOGGING_SPEC=DEBUG
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_PROFILE_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
3.2.7 将Org3加入通道

以上步骤只是将Org3添加到Fabric网络中,但是此时Org3还没有进入任何通道

首先,启动Org3 的节点容器和一个Org3对应的CLI容器
在first-network目录下:

1
docker-compose -f docker-compose-org3.yaml up -d
1
2
3
4
5
6
7
[root@localhost first-network]# docker-compose -f docker-compose-org3.yaml up -d
Creating volume "net_peer0.org3.example.com" with default driver
Creating volume "net_peer1.org3.example.com" with default driver
WARNING: Found orphan containers (cli, peer0.org2.example.com, orderer.example.com, peer1.org2.example.com, peer1.org1.example.com, peer0.org1.example.com) for this project. If you removed or renamed this service in your compose file, you can run this command with the --remove-orphans flag to clean it up.
Creating peer1.org3.example.com ... done
Creating peer0.org3.example.com ... done
Creating Org3cli ... done

compose文件已经配置了初始网络连接,所以两个peer节点和CLI容器能够与现有的peer和排序节点连接。进入Org3-CLI容器

1
docker exec -it Org3cli bash

设置两个关键环境变量ORDERER_CACHANNEL_NAME

1
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

确认变量正确设置:

1
echo $ORDERER_CA && echo $CHANNEL_NAME

发送一个调用给排序服务请求mychannel通道的创世区块。以为上述步骤中通道已经成功更新,因此排序服务可以验证调用中附带的Org3签名。如果Org3没有成功添加到通道配置,则该请求将会被排序服务拒绝。

使用peer channel fetch命令检索区块:

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

0作为参数表明希望得到的是通道账本中的第一个块(即创世块)。如果使用peer channel fetch config命令,返回的是第五个区块——Org3定义的配置更新,但新加入通道必需从创世区块0开始。

1
2
2019-10-23 01:56:32.458 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2019-10-23 01:56:32.498 UTC [cli.common] readBlock -> INFO 002 Received block: 0

利用创世块mychannel.block加入通道

1
peer channel join -b mychannel.block
1
2
3
root@e6a67979d990:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer channel join -b mychannel.block
2019-10-23 01:59:59.244 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2019-10-23 01:59:59.307 UTC [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel

如果需要将Org3的第二个peer也加入通道,只需要设置TLSADDRESS的值后再次执行上述命令:

1
2
3
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
3.2.8 升级并调用链码

升级链码版本同时更新背书策略来包含Org3。在Org3-CLI容器执行

1
peer chaincode install -n mycc -v 2.0 -p github.com/chaincode/chaincode_example02/go/
1
2
3
4
root@e6a67979d990:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer chaincode install -n mycc -v 2.0 -p github.com/chaincode/chaincode_example02/go/
2019-10-23 02:14:13.535 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
2019-10-23 02:14:13.535 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
2019-10-23 02:14:13.918 UTC [chaincodeCmd] install -> INFO 003 Installed remotely response:<status:200 payload:"OK" >

回到原本的CLI容器,在Org1和Org2的peer上安装新版本的链码,以为上次执行通道更新调用使用Org2 管理员身份,所以当前容器代表身份仍然是peer0.org2

1
peer chaincode install -n mycc -v 2.0 -p github.com/chaincode/chaincode_example02/go/
1
2
3
4
root@f7d186065b85:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer chaincode install -n mycc -v 2.0 -p github.com/chaincode/chaincode_example02/go/
2019-10-23 02:18:08.241 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
2019-10-23 02:18:08.241 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
2019-10-23 02:18:08.548 UTC [chaincodeCmd] install -> INFO 003 Installed remotely response:<status:200 payload:"OK" >

将容器环境切换为Org1

1
2
3
4
5
6
7
export CORE_PEER_LOCALMSPID="Org1MSP"

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

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

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

再次执行链码安装

1
peer chaincode install -n mycc -v 2.0 -p github.com/chaincode/chaincode_example02/go/
1
2
3
4
root@f7d186065b85:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer chaincode install -n mycc -v 2.0 -p github.com/chaincode/chaincode_example02/go/
2019-10-23 02:19:40.763 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
2019-10-23 02:19:40.763 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
2019-10-23 02:19:40.920 UTC [chaincodeCmd] install -> INFO 003 Installed remotely response:<status:200 payload:"OK" >

直至目前,链码升级已经准备完毕,这次升级并没有修改底层源代码,只是为通道mychannel中的mycc链码简单添加Org3到背书策略中。

  • 任何满足链码实例化策略的身份都可以发布更新调用。默认情况下,该身份是通道管理员。
1
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')"
  • -v标志指明新版本
  • -P可以看到已经将Org3添加到策略中去
  • 与实例化调用一样,链码更新也需要调用init方法,如果链码中init需要参数,则更新时同样需要。
  • 更新调用添加了一个新的区块——区块6.同时允许Org3 peer在背书阶段执行交易。
    1
    2
    3
    root@f7d186065b85:/opt/gopath/src/github.com/hyperledger/fabric/peer# 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')"
    2019-10-23 02:25:18.999 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
    2019-10-23 02:25:18.999 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
    回到Org3-CLI容器并查询a的值,这个过程需要耗费一些时间,因为对应peer需要构建并启动链码镜像:
    1
    peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
    结果
    1
    2
    root@e6a67979d990:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
    90
    调用链码:
    1
    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"]}'
    1
    2
    root@e6a67979d990:/opt/gopath/src/github.com/hyperledger/fabric/peer# 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"]}'
    2019-10-23 02:45:08.595 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200
    最后查询:
    1
    peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
    1
    2
    root@e6a67979d990:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
    80
    3.2.9 结论
    通道配置更新过程确实涉及很多,但是各个步骤都有一个逻辑方法。 最终的结果是形成一个以protobuf二进制格式表示的增量交易对象,然后获取必要数量的管理员签名,以便通道配置更新交易满足通道的修改政策。主要涉及各种文件的转换与获取,如下流程图所示:
  • 附:文件转化过程:
    文件转化流程

最后更新: 2019年10月23日 11:23

原始链接: https://silence-linhl.github.io/blog/2019/10/23/addorg1/

× 请我吃糖~
打赏二维码