主頁 > 區塊鏈 > fabric2.2.網路部署

fabric2.2.網路部署

2022-03-27 07:32:41 區塊鏈

警告

在執行測驗專案時,多次使用并修改此檔案,部分地方沒有及時更新.如果問題請聯系 487008159 更正.

必看

  • 專案: fabric-samples
  • 作業目錄 : ~/go/src/github.com/hyperledger/fabric-samples/test-network

輔助腳本

身份環境變數

組織 1

  • env-org1.sh
#!/bin/bash
export FABRIC_CFG_PATH=$PWD/../config/
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/[email protected]/msp
export CORE_PEER_ADDRESS=localhost:7051

組織 2

  • env-org2.sh
#!/bin/bash
export FABRIC_CFG_PATH=$PWD/../config/
export CORE_PEER_TLS_ENABLED=true
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/[email protected]/msp
export CORE_PEER_ADDRESS=localhost:9051

排序組織

#!/bin/bash
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="OrdererMSP"
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/ordererOrganizations/example.com/users/[email protected]/msp

修改腳本

  • 進入測驗網路
cd $GOPATH/src/github.com/hyperledger/fabric-samples/test-network
  • 修改測驗腳本
vim ./network.sh 

大概在51行,注釋掉二進制檔案檢查的那一項

function checkPrereqs() {
  ## Check if your have cloned the peer binaries and configuration files.
  peer version > /dev/null 2>&1
  # 注釋下面的部分
  # if [[ $? -ne 0 || ! -d "../config" ]]; then
  #   errorln "Peer binary and configuration files not found.."
  #   errorln
  #   errorln "Follow the instructions in the Fabric docs to install the Fabric Binaries:"
  #   errorln "https://hyperledger-fabric.readthedocs.io/en/latest/install.html"
  #   exit 1
  # fi
  # 注釋上面的部分
  # use the fabric tools container to see if the samples and binaries match your
  # docker images

專案環境變數

export COMPOSE_PROJECT_NAME=fabric
export IMAGETAG=2.2.0

清理腳本

#########################################################################
# File Name: clear.sh
# Author: zll
# mail: [email protected]
# Created Time: 二 12/28 17:18:54 2021
#########################################################################
echo "停止所有容器"

docker stop $(docker ps -aq)

echo "移除所有容器"
docker rm $(docker ps -aq)

echo "清理聯盟資料"
./network.sh down

echo "移除 docker網路"
docker network prune -f

echo "清理卷"
docker volume prune -f

echo "設定環境變數"
export COMPOSE_PROJECT_NAME=fabric
export IMAGETAG=2.2.0

echo "啟動聯盟并創建通道"
./network.sh up createChannel

環境

下載 fabric-sample 原始碼

mkdir -p $GOPATH/src/github.com/hyperledger/
cd   $GOPATH/src/github.com/hyperledger/
git clone https://gitee.com/Alikx/fabric-samples.git
  • 進入專案
cd $GOPATH/src/github.com/hyperledger/fabric-samples/test-network
  • 切換版本
git checkout v2.2.0
  • 移動組態檔,先進gopath的 bin目錄下,之前解二進制檔案連同組態檔都在這里.
mv config ~/go/src/github.com/hyperledger/fabric-samples

fabric二進制及組態檔

https://github.com/hyperledger/fabric/releases/tag/v2.2.0

  • 下載
wget https://github.91chi.fun//https://github.com//hyperledger/fabric/releases/download/v2.2.0/hyperledger-fabric-linux-amd64-2.2.0.tar.gz
  • 查看壓縮包中的檔案
root@k8s_node01:~# tar --list -f  hyperledger-fabric-linux-amd64-2.2.0.tar.gz
bin/
bin/peer
bin/orderer
bin/discover
bin/configtxgen
bin/cryptogen
bin/idemixgen
bin/configtxlator
config/
config/configtx.yaml
config/core.yaml
config/orderer.yaml
  • 解壓
mkdir hyperledger-fabric-linux-amd64-2.2.0
tar -zxvf hyperledger-fabric-linux-amd64-2.2.0.tar.gz -C  hyperledger-fabric-linux-amd64-2.2.0
  • 拷貝
mv config $GOPATH/src/github.com/hyperledger/fabric-samples/

日志監控

開啟監控

此步驟不是必需的,但對鏈碼進行故障診斷非常有用,要監控智能合同的日志,管理員可以使用logspout工具查看一組Docker容器的聚合輸出,該工具將來自不同Docker容器的輸出流收集到一個地方,以便于從單個視窗查看正在發生的事情,這可以幫助管理員在安裝智能合同時除錯問題,幫助開發人員在呼叫智能合同時除錯問題,由于一些容器的創建純粹是為了啟動智能合同,并且只存在很短的時間,因此從您的網路收集所有日志是有幫助的,

A script to install and configure Logspout, monitordocker.sh, is already included in the commercial-paper sample in the Fabric samples. We will use the same script in this tutorial as well. The Logspout tool will continuously stream logs to your terminal, so you will need to use a new terminal window. Open a new terminal and navigate to the test-network directory.

cd fabric-samples/test-network

You can run the monitordocker.sh script from any directory. For ease of use, we will copy the monitordocker.sh script from the commercial-paper sample to your working directory

cp ../commercial-paper/organization/digibank/configuration/cli/monitordocker.sh .
# if you're not sure where it is
find . -name monitordocker.sh

然后,您可以通過運行以下命令啟動Logspout:

./monitordocker.sh fabric_test

您應該會看到類似于以下內容的輸出:

Starting monitoring on all containers on the network docker_test
f96a6fae3c8cadcb8f3b5ac0f4fb808b45d1d30cc26498451974bd6a1b16a4b7

您一開始不會看到任何日志,但當我們部署鏈碼時,這種情況會發生變化,使這個終端視窗寬,字體小可能會有幫助,

如果找不到網路,就使用個下面命令查看下網路,實際上網路名字就是上面修改過的名字.

docker network ls

啟動網路

重繪環境變數

source init-env.sh
export CHANNEL=mychannel
export ORDERER_TLS_CA=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

方式一啟動

./network.sh up createChannel

方式二啟動

./network.sh up 

生成通道交易檔案

configtxgen \
-profile TwoOrgsChannel \
-outputCreateChannelTx ./channel-artifacts/$CHANNEL.tx \
-channelID $CHANNEL \
-configPath configtx

創建通道區塊

peer channel create \
-o localhost:7050  \
--ordererTLSHostnameOverride orderer.example.com \
-c $CHANNEL \
-f ./channel-artifacts/$CHANNEL.tx \
--outputBlock ./channel-artifacts/channel1.block \
--tls \
--cafile 

組織1 的peer加入通道

設定環境變數

source env-org1.sh

加入通道

由于我們已經以Org1管理員的身份使用peer CLI,因此讓我們將Org1的Peer加入到通道中,由于Org1提交了通道創建交易,因此我們的檔案系統上已經有了通道創世塊,使用以下命令將Org1的Peer加入通道,

peer channel join -b ./channel-artifacts/$CHANNEL.block

環境變數CORE_PEER_ADDRESS已設定為以peer0.org1.example.com為目標,命令執行成功后將生成peer0.org1.example.com加入通道的回應:

2021-11-23 03:50:44.103 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-23 03:50:44.234 UTC [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel

查詢已加入的通道

peer channel list
  • 日志
2021-11-23 03:51:13.257 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
Channels peers has joined:
channel1
mychannel

組織2 的peer加入通道

設定環境變數

source env-org2.sh

列出當前peer 加入的通道

peer channel list

從排序服務中獲取通道區塊資料

peer channel fetch 0 \
./channel-artifacts/channel_org2.block \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
-c $CHANNEL \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
2021-11-23 05:06:29.092 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-23 05:06:29.097 UTC [cli.common] readBlock -> INFO 002 Received block: 0

加入通道

peer channel join -b ./channel-artifacts/channel_org2.block
2021-11-23 05:11:20.912 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-23 05:11:21.071 UTC [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel

查詢結果

peer channel list
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# peer channel list
2021-11-23 05:12:03.257 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
Channels peers has joined:
channel1
mychannel

安裝鏈碼

打包鏈碼

  • 進去go語言鏈碼包
cd ../chaincode/fabcar/go
  • 下載依賴
GO111MODULE=on 
go mod vendor
  • 回到作業目錄
cd ../../../test-network
  • 管理員1和管理員2 (一個打包另一個直接拿來用就好了)打包鏈碼
peer lifecycle chaincode package fabcar.tar.gz --path ../chaincode/fabcar/go/  --lang golang --label fabcar_1

執行完該命令會在當前目錄下生成 鏈碼包檔案 fabcar.tar.gz .

安裝鏈碼

在Org1 的peer 上安裝鏈碼

切換身份為組織 1 的管理員

source env-org1.sh

安裝鏈碼

peer lifecycle chaincode install fabcar.tar.gz

查詢已安裝的鏈碼

peer lifecycle chaincode queryinstalled

在Org2的 peer 上安裝鏈碼

切換身份為組織 2 的管理員

source env-org2.sh

安裝鏈碼

peer lifecycle chaincode install fabcar.tar.gz

查詢已安裝的鏈碼

peer lifecycle chaincode queryinstalled

設定包 ID

peer lifecycle chaincode queryinstalled
Installed chaincodes on peer:
Package ID: fabcar_1:a5a64c81bd0ff978378580a452d6ea21f8c39ebce3645c712edab3b795b8d722, Label: fabcar_1
export CC_PACKAGE_ID=fabcar_1:a5a64c81bd0ff978378580a452d6ea21f8c39ebce3645c712edab3b795b8d722

默認策略下

組織 1 批準

source env-org1.sh
peer lifecycle chaincode approveformyorg \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID $CHANNEL \
--name fabcar \
--version 1.0 \
--package-id $CC_PACKAGE_ID \
--sequence 1 \
--tls \
--cafile $ORDERER_TLS_CA

組織 2 批準

source env-org2.sh
peer lifecycle chaincode approveformyorg \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID $CHANNEL \
--name fabcar \
--version 1.0 \
--package-id $CC_PACKAGE_ID \
--sequence 1 \
--tls \
--cafile $ORDERER_TLS_CA

檢查批準情況

peer lifecycle chaincode checkcommitreadiness  \
--channelID $CHANNEL  \
--name fabcar  \
--version 1.0  \
--sequence 1  \
--tls  \
--cafile $ORDERER_TLS_CA \
--output json
  • 日志
{
	"approvals": {
		"Org1MSP": true,
		"Org2MSP": true
	}
}

提交

peer lifecycle chaincode commit  \
-o localhost:7050  \
--ordererTLSHostnameOverride orderer.example.com  \
--channelID $CHANNEL  \
--name fabcar  \
--version 1.0  \
--sequence 1  \
--tls  \
--cafile $ORDERER_TLS_CA  \
--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

修改策略方式(默認策略執行后,此策略不需要執行)

注意:升級策略可執行此步驟,

組織 1 批準

source env-org1.sh
peer lifecycle chaincode approveformyorg \
-signature-policy "AND ('Org1MSP.peer','Org2MSP.peer')" \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID $CHANNEL \
--name fabcar \
--version 1.0 \
--package-id $CC_PACKAGE_ID \
--sequence 1 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

組織 2 批準

source env-org2.sh
peer lifecycle chaincode approveformyorg \
--signature-policy "AND ('Org1MSP.peer','Org2MSP.peer')" \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID $CHANNEL \
--name fabcar \
--version 1.0 \
--package-id $CC_PACKAGE_ID \
--sequence 1 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

檢查批準情況

peer lifecycle chaincode checkcommitreadiness  \
--signature-policy "AND ('Org1MSP.peer','Org2MSP.peer')" \
--channelID $CHANNEL  \
--name fabcar  \
--version 1.0  \
--sequence 1  \
--tls  \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem  \
--output json

提交

peer lifecycle chaincode commit  \
--signature-policy "AND ('Org1MSP.peer','Org2MSP.peer')" \
-o localhost:7050  \
--ordererTLSHostnameOverride orderer.example.com  \
--channelID $CHANNEL  \
--name fabcar  \
--version 1.0  \
--sequence 1  \
--tls  \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem  \
--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

查詢已提交

peer lifecycle chaincode querycommitted  \
--channelID $CHANNEL  \
--name fabcar  \
--cafile $ORDERER_TLS_CA

呼叫鏈碼

peer chaincode invoke -o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--tls \
--cafile $ORDERER_TLS_CA \
-C $CHANNEL \
-n fabcar \
--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":[]}' 
  • 日志
2021-11-23 03:43:29.125 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200
  • 查詢
peer chaincode query  \
-C $CHANNEL  \
-n fabcar  \
-c '{"Args":["queryAllCars"]}'
  • 日志
[{"Key":"CAR0","Record":{"make":"Toyota","model":"Prius","colour":"blue","owner":"Tomoko"}},{"Key":"CAR1","Record":{"make":"Ford","model":"Mustang","colour":"red","owner":"Brad"}},{"Key":"CAR2","Record":{"make":"Hyundai","model":"Tucson","colour":"green","owner":"Jin Soo"}},{"Key":"CAR3","Record":{"make":"Volkswagen","model":"Passat","colour":"yellow","owner":"Max"}},{"Key":"CAR4","Record":{"make":"Tesla","model":"S","colour":"black","owner":"Adriana"}},{"Key":"CAR5","Record":{"make":"Peugeot","model":"205","colour":"purple","owner":"Michel"}},{"Key":"CAR6","Record":{"make":"Chery","model":"S22L","colour":"white","owner":"Aarav"}},{"Key":"CAR7","Record":{"make":"Fiat","model":"Punto","colour":"violet","owner":"Pari"}},{"Key":"CAR8","Record":{"make":"Tata","model":"Nano","colour":"indigo","owner":"Valeria"}},{"Key":"CAR9","Record":{"make":"Holden","model":"Barina","colour":"brown","owner":"Shotaro"}}]

寫資料

source env-org1.sh
peer chaincode invoke  \
--tls \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--cafile $ORDERER_TLS_CA \
-C $CHANNEL \
-n fabcar  \
-c '{"Args":["createCar","CAR12","China","changan","red","Binny"]}' \
--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
peer chaincode query  \
-C $CHANNEL \
-n fabcar  \
-c '{"Args":["queryCar","CAR12"]}'

執行到此處,就可以除錯 SDK 了

https://gitee.com/xubinbin1024/fabric_sdk_demo_node_v2.2

升級鏈碼

更新背書策略

You can use the chaincode definition to update an endorsement policy without having to repackage or re-install the chaincode. Channel members can approve a chaincode definition with a new endorsement policy and commit it to the channel.

批準

您可以使用鏈碼定義來更新背書策略,而無需重新打包或重新安裝鏈碼,渠道成員可以批準帶有新的背書策略的鏈碼定義,并將其提交給渠道,

peer lifecycle chaincode approveformyorg \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID mychannel \
--name fabcar \
--version 2.0 \
--package-id $CC_PACKAGE_ID \
--sequence 2 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
--signature-policy "AND ('Org1MSP.peer','Org2MSP.peer')" 

檢查批準情況

這里我認為有一個 bug,如果是新定義的是更新背書策略,那么檢查的時候也要攜帶新的背書策略這個選項.

peer lifecycle chaincode checkcommitreadiness  \
--signature-policy "AND ('Org1MSP.peer','Org2MSP.peer')" \
--channelID mychannel  \
--name fabcar  \
--version 1.0  \
--sequence 2  \
--tls  \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem  \
--output json
  • 日志
{
	"approvals": {
		"Org1MSP": true,
		"Org2MSP": true
	}
}

提交

peer lifecycle chaincode commit  \
--signature-policy "AND ('Org1MSP.peer','Org2MSP.peer')" \
-o localhost:7050  \
--ordererTLSHostnameOverride orderer.example.com  \
--channelID mychannel  \
--name fabcar  \
--version 1.0  \
--sequence 1  \
--tls  \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem  \
--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
  • 日志
2021-11-23 03:41:47.755 UTC [chaincodeCmd] ClientWait -> INFO 001 txid [1f08b845f0462c415d70799360cc9e72c41e9e768a26a5eef240ed14cd061d0e] committed with status (VALID) at localhost:9051
2021-11-23 03:41:47.806 UTC [chaincodeCmd] ClientWait -> INFO 002 txid [1f08b845f0462c415d70799360cc9e72c41e9e768a26a5eef240ed14cd061d0e] committed with status (VALID) at localhost:7051
  • 查詢已提交
peer lifecycle chaincode querycommitted  \
--channelID mychannel  \
--name fabcar  \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem 
  • 日志
Committed chaincode definition for chaincode 'fabcar' on channel 'mychannel':
Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true]

修改通道中 orderer 相關配置

基于現有的網路,修改 Batch 塊的 max_message_count.

單獨測驗此程序的步驟(unnecessary)

清理網路

docker stop $(docker ps -a)
docker rm $(docker ps -a)

重啟網路并創建通道

export COMPOSE_PROJECT_NAME=fabric
export IMAGE_TAG=2.2.0
export ORDERER_CONTAINER=localhost:7050
export TLS_ROOT_CA=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
export CH_NAME=mychannel
./network.sh up createChannel

獲取通道配置

# you can issue all of these commands at once
export FABRIC_CFG_PATH=${PWD}/../config/
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/[email protected]/msp
export CORE_PEER_ADDRESS=localhost:7051
peer channel fetch config \
configtx/config_block.pb \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
-c mychannel \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

解碼通道配置

rm update 
mkdir update
configtxlator proto_decode --input configtx/config_block.pb --type common.Block --output update/config_block.json

提取更新配置部分

jq '.data.data[0].payload.data.config' update/config_block.json > update/config.json

查看原始值

jq '.channel_group.groups.Orderer.values.BatchSize.value.max_message_count' update/config.json

賦值并寫入新檔案

jq '.channel_group.groups.Orderer.values.BatchSize.value.max_message_count=13' update/config.json > update/config13.json

查看新值

jq '.channel_group.groups.Orderer.values.BatchSize.value.max_message_count' update/config13.json

編碼更新檔案

configtxlator proto_encode --input update/config13.json --type common.Config --output update/config13.pb
configtxlator proto_encode --input update/config.json --type common.Config --output update/config.pb
configtxlator compute_update --channel_id mychannel --original update/config.pb --updated update/config13.pb --output update/config13_update.pb
configtxlator proto_decode --input update/config13_update.pb --type common.ConfigUpdate --output update/config13_update.json
echo '{"payload":{"header":{"channel_header":{"channel_id":"'mychannel'", "type":2}},"data":{"config_update":'$(cat update/config13_update.json)'}}}' | jq . > update/config13_update_in_envelope.json
configtxlator proto_encode --input update/config13_update_in_envelope.json --output update/config13_update_in_envelope.pb --type common.Envelope 

編碼原始檔案

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

計算增量

configtxlator compute_update --channel_id mychannel --original update/config.pb --updated update/config13.pb --output update/config13_update.pb

解碼增量

configtxlator proto_decode --input update/config13_update.pb --type common.ConfigUpdate --output update/config13_update.json

封裝增量

echo '{"payload":{"header":{"channel_header":{"channel_id":"'mychannel'", "type":2}},"data":{"config_update":'$(cat update/config13_update.json)'}}}' | jq . > update/config13_update_in_envelope.json

編碼完成更新檔案

configtxlator proto_encode --input update/config13_update_in_envelope.json --output update/config13_update_in_envelope.pb --type common.Envelope 

切換身份(關鍵)

因為更新的 orderer的部分,所以以 orderer 身份更新

  • 切換身份
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="OrdererMSP" 
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/ordererOrganizations/example.com/users/[email protected]/msp

簽名

peer channel signconfigtx \
-f update/config13_update_in_envelope.pb  \
-o localhost:7050 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem 

提交

peer channel update -f  update/config13_update_in_envelope.pb -c mychannel -o localhost:7050 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem 
2021-12-23 14:46:38.359 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-12-23 14:46:38.445 CST [channelCmd] update -> INFO 002 Successfully submitted channel update

檢查

拉取最新區塊

  • 環境變數可以不改(非必須)
# you can issue all of these commands at once
export FABRIC_CFG_PATH=${PWD}/../config/
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/[email protected]/msp
export CORE_PEER_ADDRESS=localhost:7051
  • 拉取
peer channel fetch config \
configtx/config_block1.pb \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
-c mychannel \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

解碼通道配置

configtxlator proto_decode --input configtx/config_block1.pb --type common.Block --output update/config_block1.json

提取更新配置部分

jq '.data.data[0].payload.data.config' update/config_block1.json > update/config1.json

查看原始值

jq '.channel_group.groups.Orderer.values.BatchSize.value.max_message_count' update/config1.json

清理(如果需要)

清理
停止日志監控,停止網路,移除網路,移除卷

docker stop logspout && docker rm logspout && docker stop $(docker ps -aq) && docker rm $(docker ps -aq) && docker network prune && docker volume prune

移除鏈碼相關鏡像

docker rmi $(docker ps | grep "dev-peer" | awk '{print $3}')
  • 查看運行中的容器
docker ps --format "table {{.ID}}\t{{.Names}}\t{{.IMAGE}}"
  • 移除
docker rm $(docker ps | grep "hyperledger" | awk '{print $1}')

向組織中新增peer

  • 作業目錄 :~/go/src/github.com/hyperledger/fabric-samples/test-network
  • 組織:org1

查看當前組織中pee的個數

tree -L 5
│   └── peerOrganizations
│       ├── org1.example.com
│       │   ├── ca
│       │   │   ├── ca.org1.example.com-cert.pem
│       │   │   └── priv_sk
│       │   ├── connection-org1.json
│       │   ├── connection-org1.yaml
│       │   ├── msp
│       │   │   ├── admincerts
│       │   │   ├── cacerts
│       │   │   ├── config.yaml
│       │   │   └── tlscacerts
│       │   ├── peers
│       │   │   └── peer0.org1.example.com
│       │   ├── tlsca
│       │   │   ├── priv_sk
│       │   │   └── tlsca.org1.example.com-cert.pem
│       │   └── users
│       │       ├── [email protected]
│       │       └── [email protected]

新增peer 證書檔案

編輯證書組態檔

啟動網路的步驟中,查看輸出日志

Creating Org1 Identities
+ cryptogen generate --config=./organizations/cryptogen/crypto-config-org1.yaml --output=organizations

修改組態檔 ./organizations/cryptogen/crypto-config-org1.yaml.

vim ./organizations/cryptogen/crypto-config-org1.yaml
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#


# ---------------------------------------------------------------------------
# "PeerOrgs" - Definition of organizations managing peer nodes
# ---------------------------------------------------------------------------
PeerOrgs:
  # ---------------------------------------------------------------------------
  # Org1
  # ---------------------------------------------------------------------------
  - Name: Org1
    Domain: org1.example.com
    EnableNodeOUs: true
    # ---------------------------------------------------------------------------
    # "Specs"
    # ---------------------------------------------------------------------------
    # Uncomment this section to enable the explicit definition of hosts in your
    # configuration.  Most users will want to use Template, below
    #
    # Specs is an array of Spec entries.  Each Spec entry consists of two fields:
    #   - Hostname:   (Required) The desired hostname, sans the domain.
    #   - CommonName: (Optional) Specifies the template or explicit override for
    #                 the CN.  By default, this is the template:
    #
    #                              "{{.Hostname}}.{{.Domain}}"
    #
    #                 which obtains its values from the Spec.Hostname and
    #                 Org.Domain, respectively.
    # ---------------------------------------------------------------------------
    #   - Hostname: foo # implicitly "foo.org1.example.com"
    #     CommonName: foo27.org5.example.com # overrides Hostname-based FQDN set above
    #   - Hostname: bar
    #   - Hostname: baz
    # ---------------------------------------------------------------------------
    # "Template"
    # ---------------------------------------------------------------------------
    # Allows for the definition of 1 or more hosts that are created sequentially
    # from a template. By default, this looks like "peer%d" from 0 to Count-1.
    # You may override the number of nodes (Count), the starting index (Start)
    # or the template used to construct the name (Hostname).
    #
    # Note: Template and Specs are not mutually exclusive.  You may define both
    # sections and the aggregate nodes will be created for you.  Take care with
    # name collisions
    # ---------------------------------------------------------------------------
    Template:
      Count: 2 # 此處由1 改為 2 
      SANS:
        - localhost
      # Start: 5
      # Hostname: {{.Prefix}}{{.Index}} # default
    # ---------------------------------------------------------------------------
    # "Users"
    # ---------------------------------------------------------------------------
    # Count: The number of user accounts _in addition_ to Admin
    # ---------------------------------------------------------------------------
    Users:
      Count: 1
  • 執行網路拓展命令
cryptogen extend --config=./organizations/cryptogen/crypto-config-org1.yaml --input=organizations
  • 再次查看目錄結構
ls organizations/peerOrganizations/org1.example.com/peers
peer0.org1.example.com  peer1.org1.example.com

啟動新peer節點

查看當前節點

docker ps --format "table {{.ID}} \t {{.Names}}" | grep 'peer'
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# docker ps --format "table {{.ID}} \t {{.Names}}"
CONTAINER ID     NAMES
a6b9c523c562     dev-peer0.org2.example.com-fabcar_1-762e0fe3dbeee0f7b08fb6200adeb4a3a20f649a00f168c0b3c2257e53b6e506
a20f2648b557     dev-peer0.org1.example.com-fabcar_1-762e0fe3dbeee0f7b08fb6200adeb4a3a20f649a00f168c0b3c2257e53b6e506
f69bca3357cc     logspout
f19399557a69     cli
263f14b81a51     peer0.org2.example.com
5513a783cb6a     peer0.org1.example.com
1eca52dd33b4     orderer.example.com

新增 docker-compose 配置

#
# Copyright IBM Corp All Rights Reserved
#
# SPDX-License-Identifier: Apache-2.0
#
version: '2'

networks:
  fabric_test:
      driver: bridge
      external: true

services:
  peer1.org1.example.com:
    container_name: peer1.org1.example.com
    tty: true
    image: hyperledger/fabric-peer:$IMAGE_TAG
    environment:
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      - CORE_PEER_ID=peer1.org1.example.com
      - FABRIC_LOGGING_SPEC=INFO
      - CORE_PEER_TLS_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
      - CORE_CHAINCODE_LOGGING_LEVEL=INFO
      - CORE_PEER_LOCALMSPID=Org1MSP
      - CORE_PEER_ADDRESS=peer1.org1.example.com:7051
      - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${COMPOSE_PROJECT_NAME}_test
    working_dir: /opt/gopath/src/github.com/hyperledger/fabric
    command: peer node start
    ports:
      - 8051:7051
      - 8053:7053
    volumes:
      - /var/run/:/host/var/run/
      - ./organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/msp:/etc/hyperledger/fabric/msp
      - ./organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls:/etc/hyperledger/fabric/tls
    networks:
      - fabric_test

啟動節點

docker-compose -f docker-compose.yaml up -d peer1.org1.example.com
  • 查看節點資訊
docker ps --format "table {{.ID}}\t{{.Names}}" --filter name=org1
3cce207d4570   peer1.org1.example.com
5513a783cb6a   peer0.org1.example.com

將新節點加入通道

  • 配置環境變數
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/[email protected]/msp
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt
export CORE_PEER_ADDRESS=localhost:8051
peer channel fetch 0 \
./channel-artifacts/channel_org1_peer1.block \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
-c mychannel \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
  • 加入通道 mychannel
peer channel join -b ./channel-artifacts/channel_org1_peer1.block
2021-11-23 06:10:44.200 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-23 06:10:44.324 UTC [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
  • 查看
peer channel  list
2021-11-23 06:11:00.887 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
Channels peers has joined:
mychannel

安裝鏈碼

  • 安裝鏈碼
peer lifecycle chaincode install fabcar.tar.gz
  • 批準鏈碼
peer lifecycle chaincode approveformyorg \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID mychannel \
--name fabcar \
--version 1.0 \
--package-id $CC_PACKAGE_ID \
--sequence 2 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
  • 查詢
peer lifecycle chaincode checkcommitreadiness  \
--channelID mychannel  \
--name fabcar  \
--version 1.0  \
--sequence 2  \
--tls  \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem  \
--output json
  • 呼叫鏈碼
peer chaincode query  \
-C mychannel  \
-n fabcar  \
-c '{"Args":["queryAllCars"]}'

參考日志

root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# peer lifecycle chaincode approveformyorg \
> -o localhost:7050 \
> --ordererTLSHostnameOverride orderer.example.com \
> --channelID mychannel \
> --name fabcar \
> --version 1.0 \
> --package-id $CC_PACKAGE_ID \
> --sequence 2 \
> --tls \
> --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
2021-11-23 07:26:01.492 UTC [chaincodeCmd] ClientWait -> INFO 001 txid [b1d45658ff7f90866adda7ff81199386cd8dff7cd05819c48228c63eecf6b56a] committed with status (VALID) at
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_TLS_ENABLED=true
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_LOCALMSPID="Org2MSP"
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/[email protected]/msp
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_ADDRESS=localhost:9051
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# peer lifecycle chaincode approveformyorg \
> -o localhost:7050 \
> --ordererTLSHostnameOverride orderer.example.com \
> --channelID mychannel \
> --name fabcar \
> --version 1.0 \
> --package-id $CC_PACKAGE_ID \
> --sequence 2 \
> --tls \
> --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
2021-11-23 07:26:33.901 UTC [chaincodeCmd] ClientWait -> INFO 001 txid [078f3ee511dca0c29f0af021fdf154b3ca05a0ac62f2c7d05c8c77c804cb0f8a] committed with status (VALID) at
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# peer lifecycle chaincode checkcommitreadiness  \
> --channelID mychannel  \
> --name fabcar  \
> --version 1.0  \
> --sequence 2  \
> --tls  \
> --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem  \
> --output json
{
	"approvals": {
		"Org1MSP": true,
		"Org2MSP": true
	}
}
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_TLS_ENABLED=true
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_LOCALMSPID="Org1MSP"
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/[email protected]/msp
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# export CORE_PEER_ADDRESS=localhost:8051
root@fabric:~/go/src/github.com/hyperledger/fabric-samples/test-network# peer chaincode query  \
> -C mychannel  \
> -n fabcar  \
> -c '{"Args":["queryAllCars"]}'
[{"Key":"CAR0","Record":{"make":"Toyota","model":"Prius","colour":"blue","owner":"Tomoko"}},{"Key":"CAR1","Record":{"make":"Ford","model":"Mustang","colour":"red","owner":"Brad"}},{"Key":"CAR2","Record":{"make":"Hyundai","model":"Tucson","colour":"green","owner":"Jin Soo"}},{"Key":"CAR3","Record":{"make":"Volkswagen","model":"Passat","colour":"yellow","owner":"Max"}},{"Key":"CAR4","Record":{"make":"Tesla","model":"S","colour":"black","owner":"Adriana"}},{"Key":"CAR5","Record":{"make":"Peugeot","model":"205","colour":"purple","owner":"Michel"}},{"Key":"CAR6","Record":{"make":"Chery","model":"S22L","colour":"white","owner":"Aarav"}},{"Key":"CAR7","Record":{"make":"Fiat","model":"Punto","colour":"violet","owner":"Pari"}},{"Key":"CAR8","Record":{"make":"Tata","model":"Nano","colour":"indigo","owner":"Valeria"}},{"Key":"CAR9","Record":{"make":"Holden","model":"Barina","colour":"brown","owner":"Shotaro"}}]

向網路中新增組織

為 Org3生成證書檔案

在另一個終端中,addOrg3test-network.

cd addOrg3

首先,我們將為 Org3 對等方以及應用程式和管理員用戶創建證書和密鑰,因為我們正在更新一個示例通道,所以我們將使用 cryptogen 工具而不是使用證書頒發機構,以下命令使用 cryptogen 讀取org3-crypto.yaml檔案并在新org3.example.com檔案夾中生成 Org3 加密材料:

cryptogen generate --config=org3-crypto.yaml --output="../organizations"

您可以在目錄中找到生成的 Org3 加密材料以及 Org1 和 Org2 的證書和密鑰:test-network/organizations/peerOrganizations.

一旦我們創建了 Org3 加密材料,我們就可以使用 configtxgen 工具列印出 Org3 組織定義,

我們將通過告訴工具在當前目錄中查找configtx.yaml 它需要攝取的檔案來開始命令,

export FABRIC_CFG_PATH=$PWD
configtxgen -printOrg Org3MSP > ../organizations/peerOrganizations/org3.example.com/org3.json

上面的命令創建了一個 JSON 檔案 org3.json 并將其寫入下面檔案夾,

test-network/organizations/peerOrganizations/org3.example.com/

組織定義包含 Org3 的策略定義、Org3 的 NodeOU 定義以及兩個以 base64 格式編碼的重要證書:

  • CA 根證書,用于建立組織間的信任根
  • 一個 TLS 根證書,由 gossip 協議用于標識 Org3 以進行塊傳播和服務發現

我們將通過將此組織定義附加到通道配置來將 Org3 添加到通道中,

調出 Org3 組件

就是 啟動 組織 3 的 peer 節點

創建 Org3 證書材料后,我們現在可以啟動 Org3 對等體,從addOrg3目錄中,發出以下命令:

docker-compose -f docker/docker-compose-org3.yaml up -d

如果命令成功,您將看到 Org3 peer 的創建:

Creating peer0.org3.example.com ... done

此 Docker Compose 檔案已配置為跨我們的初始網路橋接,以便 Org3 對等節點與測驗網路的現有對等節點和排序節點進行決議,

獲取配置

讓我們去獲取頻道的最新配置塊 – channel1

我們必須拉取最新版本的配置的原因是因為通道配置元素是版本化的,

出于多種原因,版本控制很重要,它可以防止重復或重放配置更改(例如,使用舊 CRL 恢復到通道配置將代表安全風險),它還有助于確保并發性(如果您想從頻道中洗掉組織,例如,在添加新組織后,版本控制將有助于防止您洗掉兩個組織,而不僅僅是要洗掉的組織),

導航回test-network目錄,因為 Org3 還不是頻道的成員,我們需要以另一個組織的管理員身份操作來獲取頻道配置,因為 Org1 是頻道的成員,所以 Org1 管理員有權從排序服務中獲取頻道配置,發出以下命令以作為 Org1 管理員進行操作,

# you can issue all of these commands at once
export FABRIC_CFG_PATH=${PWD}/../config/
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/[email protected]/msp
export CORE_PEER_ADDRESS=localhost:7051

我們現在可以發出命令來獲取最新的配置塊:

peer channel fetch config channel-artifacts/config_block.pb \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
-c mychannel \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

此命令將二進制 protobuf 通道配置塊保存到 config_block.pb. 請注意,名稱和檔案擴展名的選擇是任意的,但是,建議遵循標識所表示的物件型別及其編碼(protobuf 或 JSON)的約定,

peer channel fetch發出命令后,日志中會顯示以下輸出:

2021-11-11 15:32:31.586 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-11 15:32:31.592 CST [cli.common] readBlock -> INFO 002 Received block: 2
2021-11-11 15:32:31.592 CST [channelCmd] fetch -> INFO 003 Retrieving last config block: 2
2021-11-11 15:32:31.595 CST [cli.common] readBlock -> INFO 004 Received block: 2

這告訴我們最近的配置塊channel1實際上是塊 2,而不是創世塊,

默認情況下,該 命令回傳目標通道的最新配置塊,在這種情況下是第三個塊,

這是因為測驗網路腳本為我們的兩個組織定義了錨點,并且在兩個單獨的通道更新事務中,因此,我們有以下配置序列:

  • block 0: genesis block
  • block 1: Org1 anchor peer update
  • block 2: Org2 anchor peer update

通道組態檔夾下新增塊資訊檔案

├── channel-artifacts
│   ├── channel1.block
│   ├── channel1.tx
│   └── config_block.pb # 新增

將配置轉換為 JSON 并對其進行修剪

通道配置塊存盤在channel-artifacts檔案夾中,以使更新程序與其他工件分開,進入 channel-artifacts 檔案夾以完成以下步驟:

cd channel-artifacts
  • 使用該configtxlator工具將這個通道配置塊解碼為 JSON 格式(可以被人類讀取和修改)
configtxlator proto_decode \
--input config_block.pb \
--type common.Block \
--output config_block.json
  • 去除所有與我們想要進行的更改無關的標題、元資料、創建者簽名等

帶有陣列的情況下,加引號,這個命令給我們留下了一個精簡的 JSON 物件 config.json 它將作為我們配置更新的基線,

jq '.data.data[0].payload.data.config' config_block.json > config.json

添加 Org3 加密材

jq 語法參考

jq 官方檔案

選項 解釋 備注
-s read (slurp) all inputs into an array; apply filter to it 使用-s 選項,jq 會將所有的 JSON 輸入放入一個陣列中并在這個陣列上使用 filter,"-s"選項不但影響到 filter 的寫法,如果在 filter 中需要對資料進行選擇和映射,其還會影響最終結果,
jq -s '.[0] * .[1]' 輸入流1 輸入流2 > test.json 
  • .[0]:由第1個輸入流產生的陣列資料
  • .[1]:由第2個輸入流產生的陣列資料
  • *:參考官方檔案
Multiplication, division, modulo: *, /, and %
These infix operators behave as expected when given two numbers. Division by zero raises an error. x % y computes x modulo y.

Multiplying a string by a number produces the concatenation of that string that many times. "x" * 0 produces null.

Dividing a string by another splits the first using the second as separators.

Multiplying two objects will merge them recursively: this works like addition but if both objects contain a value for the same key, and the values are objects, the two are merged with the same strategy.

增加配置資訊

我們將jq再次使用該工具將 Org3 配置定義 org3.json添加到通道的應用程式組欄位,并將輸出命名為 modified_config.json

jq -s \
'.[0] * {"channel_group":{"groups":{"Application":{"groups": {"Org3MSP":.[1]}}}}}' \
config.json \
../organizations/peerOrganizations/org3.example.com/org3.json \
> modified_config.json

增量計算,得到更新增量

現在我們有兩個感興趣的 JSON 檔案 config.jsonmodified_config.json. 初始檔案僅包含 Org1 和 Org2 材料,而修改后的檔案包含所有三個 Org,

此時,只需重新編碼這兩個 JSON 檔案并計算增量即可,

  • 首先,轉換config.json回一個名為的protobuf config.pb
configtxlator proto_encode \
--input config.json \
--type common.Config \
--output config.pb
  • 接下來,編碼modified_config.jsonmodified_config.pb
configtxlator proto_encode \
--input modified_config.json \
--type common.Config \
--output modified_config.pb
  • 在用于configtxlator計算這兩個配置 protobufs 之間的增量,此命令將輸出一個名為的新 protobuf 二進制檔案org3_update.pb
configtxlator compute_update \
--channel_id channel1 \
--original config.pb \
--updated modified_config.pb \
--output org3_update.pb

這個新的 proto org3_update.pb包含 Org3 定義和指向 Org1 和 Org2 材料的高級指標,

封裝更新資訊

在提交頻道更新之前,我們需要執行一些最后的步驟,

  • 首先,讓我們將此物件解碼為可編輯的 JSON 格式并呼叫它org3_update.json
configtxlator proto_decode \
--input org3_update.pb \
--type common.ConfigUpdate \
--output org3_update.json

現在,我們有一個解碼后的更新檔案org3_update.json.我們需要將它包裝一下,

這一步將回傳我們之前剝離的頭欄位,我們將此檔案命名為org3_update_in_envelope.json

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

使用我們正確形成的 JSONorg3_update_in_envelope.json我們將configtxlator最后一次利用該工具并將其轉換為 Fabric 所需的完全成熟的 protobuf 格式,我們將命名我們的最終更新物件org3_update_in_envelope.pb:

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

簽署并提交配置更

簽署

現在有一個 protobuf 二進制檔案 org3_update_in_envelope.pb. 但是,在將配置寫入分類帳之前,我們需要必需的管理員用戶的簽名,

我們頻道應用程式組的修改策略 (mod_policy) 設定為默認值“MAJORITY”,這意味著我們需要大多數現有組織管理員對其進行簽名,

因為我們只有兩個組織——Org1 和 Org2——而且兩個組織中的大多數是兩個,==所以我們需要他們都簽名==,

如果沒有這兩個簽名,排序服務將拒絕未能滿足策略的交易,

  • 首先,讓我們將此更新協議簽名為 Org1,導航回test-network 目錄:

請記住,我們匯出了必要的環境變數以作為 Org1 管理員進行操作,因此,以下命令會將更新簽名為 Org1,peer channel signconfigtx

peer channel signconfigtx -f channel-artifacts/org3_update_in_envelope.pb

最后一步是切換容器的身份以反映 Org2 Admin 用戶,我們通過匯出特定于 Org2 MSP 的四個環境變數來做到這一點,

設定 Org2 環境變數:

# you can issue all of these commands at once
export FABRIC_CFG_PATH=${PWD}/../config/
export CORE_PEER_TLS_ENABLED=true
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/[email protected]/msp
export CORE_PEER_ADDRESS=localhost:9051

更新

最后,我們將發出peer channel update命令,Org2 Admin 的簽名將附加到此呼叫中,因此無需再次手動簽署 protobuf,(更新角色會自動簽署并且更新通道配置資訊)

peer channel update -f channel-artifacts/org3_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

成功的通道更新呼叫會向通道上的所有對等方回傳一個新塊:塊 3

如果您還記得,塊 0-2 是初始通道配置,Block 3 作為最新的通道配置,現在在通道上定義了 Org3,

您可以peer0.org1.example.com通過發出以下命令來檢查日志:

docker logs -f peer0.org1.example.com

將 Org3的節點加入頻道

此時,通道配置已更新為包括我們的新組織 Org3,這意味著它的對等節點現在可以加入channel1,

匯出以下環境變數以作為 Org3 管理員進行操作:

# you can issue all of these commands at once
export FABRIC_CFG_PATH=${PWD}/../config/
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org3MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org3.example.com/users/[email protected]/msp
export CORE_PEER_ADDRESS=localhost:11051

作為通道更新成功的結果,排序服務將驗證 Org3 是否可以拉取創世塊并加入通道,如果 Org3 未成功附加到通道配置,則排序服務將拒絕此請求,

使用命令來檢索這個塊:peer channel fetch

peer channel fetch 0 channel-artifacts/channel1.block \
-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
2021-11-11 17:40:23.213 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-11 17:40:23.220 CST [cli.common] readBlock -> INFO 002 Received block: 0

請注意,我們正在傳遞 0以指示我們想要通道分類帳上的第一個塊;即創世區塊,

如果我們簡單地傳遞命令 peer channel fetch config,那么我們將收到塊 3——定義了 Org3 的更新配置,但是,我們不能從下游塊開始我們的賬本——我們必須從塊 0 開始,

如果成功,該命令會將創世塊回傳名為channel1.block. 我們現在可以使用此塊channel1.blockpeer加入通道,

發出命令peer channel join并傳入創世塊以將 Org3 peer 加入通道:

peer channel join -b channel-artifacts/channel1.block
2021-11-12 10:59:01.939 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2021-11-12 10:59:02.017 CST [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel

查詢結果

在 Org3的環境下查看該peer peer0.org3.example.com加入的通道

# you can issue all of these commands at once
export FABRIC_CFG_PATH=${PWD}/../config/
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org3MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org3.example.com/users/[email protected]/msp
export CORE_PEER_ADDRESS=localhost:11051
peer channel list
(base) test-network|5b8c439? ? peer channel list
2021-11-11 17:50:00.527 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
Channels peers has joined:
channel1

升級網路

升級orderer節點

升級每個orderer時,都需要執行以下操作,

配置orderer容器中的環境變數

vim upgrade.orderer.sh

方便起見,orderer容器運行時需要的環境變數可以記錄在檔案中,具體內容如下:

FABRIC_LOGGING_SPEC=INFO
FABRIC_CFG_PATH=/etc/hyperledger/fabric
ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
ORDERER_GENERAL_GENESISMETHOD=file
# 創世區塊
ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
ORDERER_GENERAL_LOCALMSPID=OrdererMSP
ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
# enabled TLS
ORDERER_GENERAL_TLS_ENABLED=true
ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key
ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt
ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=/var/hyperledger/orderer/tls/server.crt
ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=/var/hyperledger/orderer/tls/server.key
ORDERER_GENERAL_CLUSTER_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]

設定升級時的環境變數

在升級排序節點前匯入以下環境變數:

  • ORDERER_CONTAINER:排序節點的容器名稱,注意,每個節點升級時你都樣設定一遍,
  • LEDGERS_BACKUP:存放備份資料的路徑,就如下面的示例中,每個節點都有它自己的子目錄來存放它的賬本,目錄如果不存在的話,你需要手動創建,
  • IMAGE_TAG:你期望升級到的Fabric版本,

示例如下:

export ORDERER_CONTAINER=orderer.example.com
export LEDGERS_BACKUP=backup
export IMAGE_TAG=2.2.3

檔案準備

  • 備份位置
mkdir -p $LEDGERS_BACKUP/$ORDERER_CONTAINER
  • 創世塊,msp,tls
cp ../system-genesis-block/genesis.block backup/orderer.genesis.block
cp -r ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp backup
cp -r ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls backup

停止容器

docker stop $ORDERER_CONTAINER

備份賬本

docker cp $ORDERER_CONTAINER:/var/hyperledger/production/orderer $LEDGERS_BACKUP/$ORDERER_CONTAINER 

洗掉容器

docker rm -f $ORDERER_CONTAINER

升級容器

docker run -d \
-v /root/fabric-samples/test-network/backup/$ORDERER_CONTAINER/:/var/hyperledger/production/orderer/ \
-v /root/fabric-samples/test-network/backup:/var/hyperledger/orderer \
--env-file ./backup/env-update-container-orderer.yaml \
--name $ORDERER_CONTAINER \
--net fabric_test \
hyperledger/fabric-orderer:$IMAGE_TAG orderer
docker run -d \
-v /Users/binny/go/src/github.com/hyperledger/fabric-samples/test-network/upgrade/backup/$ORDERER_CONTAINER/:/var/hyperledger/production/orderer/ \
-v /Users/binny/go/src/github.com/hyperledger/fabric-samples/test-network/upgrade/backup/:/var/hyperledger/orderer/ \
--env-file ./upgrade.orderer.sh \
--name $ORDERER_CONTAINER \
hyperledger/fabric-orderer:$IMAGE_TAG orderer

升級peer節點

以peer0org1節點為例,以下操作每個peer節點都需要執行,

配置peer運行時的環境變數

方便起見,peer容器運行時需要的環境變數可以記錄在檔案中,具體內容如下:

CORE_PEER_LOCALMSPID=Org1MSP
CORE_PEER_GOSSIP_USELEADERELECTION=true
CORE_PEER_ID=peer0.org1.example.com
CORE_PEER_ADDRESS=peer0.org1.example.com:7051
FABRIC_CFG_PATH=/etc/hyperledger/fabric
CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=net_byfn
CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
CORE_PEER_PROFILE_ENABLED=true
CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
CORE_PEER_LISTENADDRESS=0.0.0.0:7051
CORE_PEER_GOSSIP_ORGLEADER=false
CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org1.example.com:8051
CORE_PEER_TLS_ENABLED=true
FABRIC_LOGGING_SPEC=INFO
CORE_PEER_CHAINCODEADDRESS=peer0.org1.example.com:7052

設定升級時的環境變數

在升級peer節點前匯入以下環境變數:

  • PEER_CONTAINER:peer節點的容器名稱,注意,每個節點升級時你都樣設定一遍,
  • LEDGERS_BACKUP:存放備份資料的路徑,就如下面的示例中,每個節點都有它自己的子目錄來存放它的賬本,目錄如果不存在的話,你需要手動創建,
  • IMAGE_TAG:你期望升級到的Fabric版本,例如v2.0,

示例如下:

export PEER_CONTAINER=peer0.org1.example.com
export LEDGERS_BACKUP=backup
export IMAGE_TAG=2.2.3

停止容器

docker stop $PEER_CONTAINER

備份賬本和MSPs

docker cp $PEER_CONTAINER:/var/hyperledger/production $LEDGERS_BACKUP/$PEER_CONTAINER

洗掉CC容器

CC_CONTAINERS=$(docker ps | grep dev-$PEER_CONTAINER | awk '{print $1}')
if [ -n "$CC_CONTAINERS" ] ; then docker rm -f $CC_CONTAINERS ; fi

洗掉peer容器

docker rm  $PEER_CONTAINER

升級peer節點

docker run -d \
-e FABRIC_CFG_PATH=/etc/hyperledger/fabric \
-v /Users/binny/go/src/github.com/hyperledger/fabric-samples/test-network/upgrade/$LEDGERS_BACKUP/$PEER_CONTAINER/:/var/hyperledger/production/ \
-v /Users/binny/go/src/github.com/hyperledger/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/:/etc/hyperledger/fabric/ \
-v /Users/binny/go/src/github.com/hyperledger/fabric-samples/config/core.yaml:/etc/hyperledger/fabric/core.yaml \
--env-file ./upgrade.org1.peer0.sh \
--name $PEER_CONTAINER \
hyperledger/fabric-peer:$IMAGE_TAG peer node start

升級peer節點資料庫

docker run --rm \
-v $LEDGERS_BACKUP/$PEER_CONTAINER:/var/hyperledger/production/ \
-v /var/run/:/host/var/run/ \
-v $FABRIC_SAMPLES/first-network/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/etc/hyperledger/fabric/msp \
-v $FABRIC_SAMPLES/first-network/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls:/etc/hyperledger/fabric/tls \
-p 7051:7051 \
--env-file env_peer.list \
--net net_byfn \
--name $PEER_CONTAINER  \
hyperledger/fabric-peer:$IMAGE_TAG peer node upgrade-dbs

舊版本的鏈碼

進入原始碼

cd $GOPATH/src/github.com/hyperledger/fabric-samples/chaincode/sacc

下載依賴

GO111MODULE=on 
go mod vendor
cd ../../test-network/

打包

peer lifecycle chaincode package sacc.tar.gz --path ../chaincode/sacc/  --lang golang --label sacc_1

更新環境變數

作為組織1管理員

source org1-env.sh

作為組織2管理員

source org2-env.sh

安裝

peer lifecycle chaincode install sacc.tar.gz

##查詢

peer lifecycle chaincode queryinstalled

設定包ID

export CC_PACKAGE_ID=sacc_1:b33357c4012471d8bd96ba48fd2a12ada5fedfbfd6d623590295778500a0368d

批準

peer lifecycle chaincode approveformyorg \
--init-required \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID mychannel \
--name sacc \
--version 1.0 \
--package-id $CC_PACKAGE_ID \
--sequence 1 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

檢查批準情況

peer lifecycle chaincode checkcommitreadiness  \
--init-required \
--channelID mychannel  \
--name sacc  \
--version 1.0  \
--sequence 1  \
--tls  \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem  \
--output json

提交

peer lifecycle chaincode commit  \
--init-required \
-o localhost:7050  \
--ordererTLSHostnameOverride orderer.example.com  \
--channelID mychannel  \
--name sacc  \
--version 1.0  \
--sequence 1  \
--tls  \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem  \
--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

查詢

peer lifecycle chaincode querycommitted --channelID mychannel --name sacc

初始化

peer chaincode invoke -o localhost:7050 \
--isInit \
--ordererTLSHostnameOverride orderer.example.com \
--tls \
--cafile \
${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
-C mychannel \
-n sacc \
--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 '{"Args":["name","binny"]}'

呼叫

peer chaincode query -C mychannel -n sacc -c '{"Args":["get","name"]}'

清理

docker stop logspout && docker rm logspout &&
docker rm -f $(docker ps | grep "hyperledger" | awk '{print $1}')
  • 移除鏈碼相關鏡像
docker rmi $(docker images | grep "dev-peer" | awk '{print $3}')
  • 移除 fabric相關鏡像
docker rmi $(docker images | grep "hyperledger" | awk '{print $3}')
docker network prune -f && docker volume prune -f

轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/449754.html

標籤:區塊鏈

上一篇:帶有GetView和GetxController的AnimationController

下一篇:如何使用AndroidKotlin在Fragment中使用背景關系?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • JAVA使用 web3j 進行token轉賬

    最近新學習了下區塊鏈這方面的知識,所學不多,給大家分享下。 # 1. 關于web3j web3j是一個高度模塊化,反應性,型別安全的Java和Android庫,用于與智能合約配合并與以太坊網路上的客戶端(節點)集成。 # 2. 準備作業 jdk版本1.8 引入maven <dependency> < ......

    uj5u.com 2020-09-10 03:03:06 more
  • 以太坊智能合約開發框架Truffle

    前言 部署智能合約有多種方式,命令列的瀏覽器的渠道都有,但往往跟我們程式員的風格不太相符,因為我們習慣了在IDE里寫了代碼然后打包運行看效果。 雖然現在IDE中已經存在了Solidity插件,可以撰寫智能合約,但是部署智能合約卻要另走他路,沒辦法進行一個快捷的部署與測驗。 如果團隊管理的區塊節點多、 ......

    uj5u.com 2020-09-10 03:03:12 more
  • 谷歌二次驗證碼成為區塊鏈專用安全碼,你怎么看?

    前言 谷歌身份驗證器,前些年大家都比較陌生,但隨著國內互聯網安全的加強,它越來越多地出現在大家的視野中。 比較廣泛接觸的人群是國際3A游戲愛好者,游戲盜號現象嚴重+國外賬號安全應用廣泛,這類游戲一般都會要求用戶系結名為“兩步驗證”、“雙重驗證”等,平臺一般都推薦用谷歌身份驗證器。 后來區塊鏈業務風靡 ......

    uj5u.com 2020-09-10 03:03:17 more
  • 密碼學DAY1

    目錄 ##1.1 密碼學基本概念 密碼在我們的生活中有著重要的作用,那么密碼究竟來自何方,為何會產生呢? 密碼學是網路安全、資訊安全、區塊鏈等產品的基礎,常見的非對稱加密、對稱加密、散列函式等,都屬于密碼學范疇。 密碼學有數千年的歷史,從最開始的替換法到如今的非對稱加密演算法,經歷了古典密碼學,近代密 ......

    uj5u.com 2020-09-10 03:03:50 more
  • 密碼學DAY1_02

    目錄 ##1.1 ASCII編碼 ASCII(American Standard Code for Information Interchange,美國資訊交換標準代碼)是基于拉丁字母的一套電腦編碼系統,主要用于顯示現代英語和其他西歐語言。它是現今最通用的單位元組編碼系統,并等同于國際標準ISO/IE ......

    uj5u.com 2020-09-10 03:04:50 more
  • 密碼學DAY2

    ##1.1 加密模式 加密模式:https://docs.oracle.com/javase/8/docs/api/javax/crypto/Cipher.html ECB ECB : Electronic codebook, 電子密碼本. 需要加密的訊息按照塊密碼的塊大小被分為數個塊,并對每個塊進 ......

    uj5u.com 2020-09-10 03:05:42 more
  • NTP時鐘服務器的特點(京準電子)

    NTP時鐘服務器的特點(京準電子) NTP時鐘服務器的特點(京準電子) 京準電子官V——ahjzsz 首先對時間同步進行了背景介紹,然后討論了不同的時間同步網路技術,最后指出了建立全球或區域時間同步網存在的問題。 一、概 述 在通信領域,“同步”概念是指頻率的同步,即網路各個節點的時鐘頻率和相位同步 ......

    uj5u.com 2020-09-10 03:05:47 more
  • 標準化考場時鐘同步系統推進智能化校園建設

    標準化考場時鐘同步系統推進智能化校園建設 標準化考場時鐘同步系統推進智能化校園建設 安徽京準電子科技官微——ahjzsz 一、背景概述隨著教育事業的快速發展,學校建設如雨后春筍,隨之而來的學校教育、管理、安全方面的問題成了學校管理人員面臨的最大的挑戰,這些問題同時也是學生家長所擔心的。為了讓學生有更 ......

    uj5u.com 2020-09-10 03:05:51 more
  • 位元幣入門

    引言 位元幣基本結構 位元幣基礎知識 1)哈希演算法 2)非對稱加密技術 3)數字簽名 4)MerkleTree 5)哪有位元幣,有的是UTXO 6)位元幣挖礦與共識 7)區塊驗證(共識) 總結 引言 上一篇我們已經知道了什么是區塊鏈,此篇說一下區塊鏈的第一個應用——位元幣。其實先有位元幣,后有的區塊 ......

    uj5u.com 2020-09-10 03:06:15 more
  • 北斗對時服務器(北斗對時設備)電力系統應用

    北斗對時服務器(北斗對時設備)電力系統應用 北斗對時服務器(北斗對時設備)電力系統應用 京準電子科技官微(ahjzsz) 中國北斗衛星導航系統(英文名稱:BeiDou Navigation Satellite System,簡稱BDS),因為是目前世界范圍內唯一可以大面積提供免費定位服務的系統,所以 ......

    uj5u.com 2020-09-10 03:06:20 more
最新发布
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:46:47 more
  • Hyperledger Fabric 使用 CouchDB 和復雜智能合約開發

    在上個實驗中,我們已經實作了簡單智能合約實作及客戶端開發,但該實驗中智能合約只有基礎的增刪改查功能,且其中的資料管理功能與傳統 MySQL 比相差甚遠。本文將在前面實驗的基礎上,將 Hyperledger Fabric 的默認資料庫支持 LevelDB 改為 CouchDB 模式,以實作更復雜的資料... ......

    uj5u.com 2023-04-16 07:28:31 more
  • .NET Core 波場鏈離線簽名、廣播交易(發送 TRX和USDT)筆記

    Get Started NuGet You can run the following command to install the Tron.Wallet.Net in your project. PM> Install-Package Tron.Wallet.Net 配置 public reco ......

    uj5u.com 2023-04-14 08:08:00 more
  • DKP 黑客分析——不正確的代幣對比率計算

    概述: 2023 年 2 月 8 日,針對 DKP 協議的閃電貸攻擊導致該協議的用戶損失了 8 萬美元,因為 execute() 函式取決于 USDT-DKP 對中兩種代幣的余額比率。 智能合約黑客概述: 攻擊者的交易:0x0c850f,0x2d31 攻擊者地址:0xF38 利用合同:0xf34ad ......

    uj5u.com 2023-04-07 07:46:09 more
  • Defi開發簡介

    Defi開發簡介 介紹 Defi是去中心化金融的縮寫, 是一項旨在利用區塊鏈技術和智能合約創建更加開放,可訪問和透明的金融體系的運動. 這與傳統金融形成鮮明對比,傳統金融通常由少數大型銀行和金融機構控制 在Defi的世界里,用戶可以直接從他們的電腦或移動設備上訪問廣泛的金融服務,而不需要像銀行或者信 ......

    uj5u.com 2023-04-05 08:01:34 more
  • solidity簡單的ERC20代幣實作

    // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; import "hardhat/console.sol"; //ERC20 同質化代幣,每個代幣的本質或性質都是相同 //ETH 是原生代幣,它不是ERC20代幣, ......

    uj5u.com 2023-03-21 07:56:29 more
  • solidity 參考型別修飾符memory、calldata與storage 常量修飾符C

    在solidity語言中 參考型別修飾符(參考型別為存盤空間不固定的數值型別) memory、calldata與storage,它們只能修飾參考型別變數,比如字串、陣列、位元組等... memory 適用于方法傳參、返參或在方法體內使用,使用完就會清除掉,釋放記憶體 calldata 僅適用于方法傳參 ......

    uj5u.com 2023-03-08 07:57:54 more
  • solidity注解標簽

    在solidity語言中 注釋符為// 注解符為/* 內容*/ 或者 是 ///內容 注解中含有這幾個標簽給予我們使用 @title 一個應該描述合約/介面的標題 contract, library, interface @author 作者的名字 contract, library, interf ......

    uj5u.com 2023-03-08 07:57:49 more
  • 評價指標:相似度、GAS消耗

    【代碼注釋自動生成方法綜述】 這些評測指標主要來自機器翻譯和文本總結等研究領域,可以評估候選文本(即基于代碼注釋自動方法而生成)和參考文本(即基于手工方式而生成)的相似度. BLEU指標^[^?88^^?^]^:其全稱是bilingual evaluation understudy.該指標是最早用于 ......

    uj5u.com 2023-02-23 07:27:39 more
  • 基于NOSTR協議的“公有制”版本的Twitter,去中心化社交軟體Damus

    最近,一個幽靈,Web3的幽靈,在網路游蕩,它叫Damus,這玩意詮釋了什么叫做病毒式營銷,滑稽的是,一個Web3產品卻在Web2的產品鏈上瘋狂傳銷,各方大佬紛紛為其背書,到底發生了什么?Damus的葫蘆里,賣的是什么藥? 注冊和簡單實用 很少有什么產品在用戶注冊環節會有什么噱頭,但Damus確實出 ......

    uj5u.com 2023-02-05 06:48:39 more