參考
https://hyperledger-fabric.readthedocs.io
http://blog.csdn.net/remote_roamer/article/details/70228662
http://www.cnblogs.com/midfielder/p/7173150.html
環(huán)境搭建
以下環(huán)境安裝都是在Mac OSX中的實(shí)例
安裝Docker
首先安裝Docker,安裝好后可以確認(rèn)Docker和Docker Compose的版本:
docker --version
docker-compose --version
安裝Go語言
Hyperledger Fabric基于1.7.x版本的Go語言上開發(fā)了許多組件漓糙,
brew install go
添加$GOPATH環(huán)境變量俯萌,在~/.bash_profile中添加:
export GOPATH=/Users/xxx/go
export PATH=$PATH:$GOPATH/bin
建立 go 源碼目錄結(jié)構(gòu)(必須要做氛堕,否則后面無法使用go進(jìn)行編譯):
cd $GOPATH
mkdir -p src/github.com/hyperledger
cd $GOPATH/src/github.com/hyperledger
git clone https://github.com/hyperledger/fabric.git
安裝Node.js和NPM
Node需要安裝版本6.9.x,目前暫不支持7.x汇跨,因?yàn)槲抑半娔X裝了node,但是版本不對(duì),所以需要用brew重新安裝指定版本的node:
node --version
brew search ndoe
brew install node@6
brew unlink node
brew link --overwrite node@6 --force
node --version
安裝npm指定版本
npm install npm@3.10.10 -g
安裝Hyperledger Fabric Samples
建議在/Users目錄下的某個(gè)子文件夾中創(chuàng)建一個(gè)工程目錄择葡,從git下載代碼:
git clone https://github.com/hyperledger/fabric-samples.git
cd fabric-samples
下載Platform-specific Binaries
curl -sSL https://goo.gl/Gci9ZX | bash
添加環(huán)境變量:
export PATH=<path to download location>/bin:$PATH
對(duì)應(yīng)幾個(gè)配置文件要加上版本,先訪問https://hub.docker.com/r/hyperledger/fabric-orderer/tags/ 找一個(gè)tag號(hào)剃氧,我選擇的是最新的x86_64-1.0.2:
fabric-samples/first-network/docker-compose-cli.yaml
找到并添加 image: hyperledger/fabric-tools:x86_64-1.0.2
fabric-samples/first-network/base/docker-compose-base.yaml
找到并添加 image: hyperledger/fabric-orderer:x86_64-1.0.2
fabric-samples/first-network/base/peer-base.yaml
找到并添加 image: hyperledger/fabric-peer:x86_64-1.0.2
創(chuàng)建網(wǎng)絡(luò)
打開fabric-sample下的示例first-network
cd first-network
其中byfn.sh
為啟動(dòng)這個(gè)網(wǎng)絡(luò)的啟動(dòng)腳本敏储,啟動(dòng)腳本中除建立一個(gè)包含4個(gè)節(jié)點(diǎn)和1個(gè)Order service的網(wǎng)絡(luò)外,還會(huì)啟動(dòng)一個(gè)容器用來執(zhí)行腳本在channel中加入節(jié)點(diǎn)朋鞍,部署和初始化chaincode已添,以及在部署的chaincode上執(zhí)行交易。
啟動(dòng)腳本
第一步滥酥,生成必要文件更舞,執(zhí)行命令:
./byfn.sh -m generate
默認(rèn)channel名稱為mychannel,腳本程序會(huì)給網(wǎng)絡(luò)實(shí)例生成數(shù)字證書和密鑰坎吻;生成genesis block用來啟動(dòng)ordering service缆蝉;一些用來配置channel的配置交易。
第二步,啟動(dòng)網(wǎng)絡(luò)刊头,執(zhí)行命令:
./byfn.sh -m up
當(dāng)你看到下面的文字的時(shí)候黍瞧,說明啟動(dòng)成功:
Starting with channel 'mychannel' and CLI timeout of '10000'
Continue (y/n)?y
proceeding ...
Creating network "net_byfn" with the default driver
Creating peer0.org1.example.com
Creating peer1.org1.example.com
Creating peer0.org2.example.com
Creating orderer.example.com
Creating peer1.org2.example.com
Creating cli
____ _____ _ ____ _____
/ ___| |_ _| / \ | _ \ |_ _|
\___ \ | | / _ \ | |_) | | |
___) | | | / ___ \ | _ < | |
|____/ |_| /_/ \_\ |_| \_\ |_|
Channel name : mychannel
Creating channel...
2017-05-16 17:08:01.366 UTC [msp] GetLocalMSP -> DEBU 004 Returning existing local MSP
2017-05-16 17:08:01.366 UTC [msp] GetDefaultSigningIdentity -> DEBU 005 Obtaining default signing identity
2017-05-16 17:08:01.366 UTC [msp/identity] Sign -> DEBU 006 Sign: plaintext: 0AB1070A6708031A0C08F1E3ECC80510...6D7963631A0A0A0571756572790A0161
2017-05-16 17:08:01.367 UTC [msp/identity] Sign -> DEBU 007 Sign: digest: E61DB37F4E8B0D32C9FE10E3936BA9B8CD278FAA1F3320B08712164248285C54
Query Result: 90
2017-05-16 17:08:15.158 UTC [main] main -> INFO 008 Exiting.....
===================== Query on PEER3 on channel 'mychannel' is successful =====================
執(zhí)行結(jié)束后,終端顯示如下:
===================== All GOOD, BYFN execution completed =====================
_____ _ _ ____
| ____| | \ | | | _ \
| _| | \| | | | | |
| |___ | |\ | | |_| |
|_____| |_| \_| |____/
關(guān)閉網(wǎng)絡(luò):
./byfn.sh -m down
上面通過腳本./byfn.sh
生成了一個(gè)fabric網(wǎng)絡(luò)原杂,接下來我們將詳細(xì)說明腳本中所執(zhí)行的命令信息印颤。
創(chuàng)建一個(gè)Hyperledger Fabric網(wǎng)絡(luò)
Crypto Generator
我們將使用cryptogen
工具為我們的網(wǎng)絡(luò)節(jié)點(diǎn)生成證書信息,證書信息可以代表每一個(gè)實(shí)例節(jié)點(diǎn)穿肄,用于節(jié)點(diǎn)間的通信和交易年局。
cryptogen
使用的配置文件為crypto-config.yaml
。配置文件中描述了網(wǎng)絡(luò)的拓?fù)浣Y(jié)構(gòu)同時(shí)會(huì)為Orgnizations和Orgnizations下的節(jié)點(diǎn)生成一系列的證書咸产。每個(gè)Orgnization會(huì)有一個(gè)根證書ca-cert用來綁定特定節(jié)點(diǎn)(peer或者order)到該Orgnization矢否。通過對(duì)每個(gè)Orgnization頒發(fā)一個(gè)唯一的數(shù)字證書,我們可以模仿典型的區(qū)塊鏈網(wǎng)絡(luò)锐朴,每個(gè)加入鏈的成員使用自己的數(shù)字證書進(jìn)行獲取授權(quán)兴喂。交易和通信使用節(jié)點(diǎn)的私鈅,驗(yàn)證使用節(jié)點(diǎn)的公鑰(數(shù)字證書)焚志。配置文件里的count參數(shù)用來指定每個(gè)Orgnization的節(jié)點(diǎn)數(shù)量衣迷,本例子中一個(gè)Orgnization下面包含兩個(gè)節(jié)點(diǎn),所以count的值在本例中設(shè)定為2酱酬。
在運(yùn)行這個(gè)命令之前壶谒,我們快速的看一下crypto-config.yaml
里的配置信息。特別要關(guān)注OrderOrgs header下的Name,Domain和Specs幾個(gè)參數(shù)膳沽。
OrdererOrgs:
- Name: Orderer
Domain: example.com
Specs:
- Hostname: orderer
PeerOrgs:
- Name: Org1
Domain: org1.example.comabove
Template:
Count: 2
Users:
Count: 1
- Name: Org2
Domain: org2.example.com
Template:
Count: 2
Users:
Count: 1
網(wǎng)絡(luò)節(jié)點(diǎn)的命名規(guī)則為{Hostname}.{Domain}
汗菜。以上述配置文件中order節(jié)點(diǎn)為例,order節(jié)點(diǎn)的命名為orderer.example.com
挑社,對(duì)應(yīng)的MSP Id為Orderer陨界。
運(yùn)行cryptogen
命令后,生成的數(shù)字證書和密鑰信息保存在crypto-config文件夾中痛阻。
Configuration Transaction Generation
配置交易生成工具:configtxgen
用來生成4個(gè)配置信息
- orderer genesis block
- fabric channel configuration transaction
- 2個(gè)anchor peer transaction (每個(gè)Peer Org生成一個(gè))
orderer block
是ordering service
的起始block菌瘪,channel配置交易文件在channel創(chuàng)建時(shí)廣播到orderer。anchor peer
交易用來指定channel上每個(gè)Org的Anchor Peer阱当。
configxgen
的配置文件為configtx.yaml
俏扩,其中包含對(duì)我們所創(chuàng)建的示例網(wǎng)絡(luò)的定義。配置文件包含3個(gè)角色弊添,一個(gè)Orderer Org(OrderOrg)和兩個(gè)Peer Orgs(Org1和Org2)录淡。配置文件也指定了一個(gè)組合SampleConsortium,包含2個(gè)Peer Org油坝。打開配置文件嫉戚,配置文件頂部Profiles部分有兩個(gè)唯一的headers刨裆。其中TwoOrgsOrderedGenesis用來配置orderer genesis block,TwoOrgChannel用來配置我們的channel彼水。
Profiles:
TwoOrgsOrdererGenesis:
Orderer:
<<: *OrdererDefaults
Organizations:
- *OrdererOrg
Consortiums:
SampleConsortium:
Organizations:
- *Org1
- *Org2
TwoOrgsChannel:
Consortium: SampleConsortium
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
- *Org2
Organizations:
- &OrdererOrg
Name: OrdererOrg
ID: OrdererMSP
MSPDir: crypto-config/ordererOrganizations/example.com/msp
- &Org1
Name: Org1MSP
ID: Org1MSP
MSPDir: crypto-config/peerOrganizations/org1.example.com/msp
AnchorPeers:
- Host: peer0.org1.example.com
Port: 7051
- &Org2
Name: Org2MSP
ID: Org2MSP
MSPDir: crypto-config/peerOrganizations/org2.example.com/msp
AnchorPeers:
- Host: peer0.org2.example.com
Port: 7051
Orderer: &OrdererDefaults
OrdererType: solo
Addresses:
- orderer.example.com:7050
BatchTimeout: 2s
BatchSize:
MaxMessageCount: 10
AbsoluteMaxBytes: 99 MB
PreferredMaxBytes: 512 KB
Kafka:
Brokers:
- 127.0.0.1:9092
Organizations:
Application: &ApplicationDefaults
Organizations:
上述配置文件中還包含兩個(gè)沒有特別意義的指定信息崔拥。第一個(gè)极舔,我們?yōu)槊恳粋€(gè)Peer Org指定了Anchor Peer(peer0.org1.example.com和peer0.org2.example.com)凤覆。第二點(diǎn)纪挎,我們指定了每個(gè)角色的MSP路徑搪花,從而允許我們把每個(gè)Org的根證書存儲(chǔ)在orderer genesis block中。這是一個(gè)重要的概念±干校現(xiàn)在每個(gè)節(jié)點(diǎn)和ordering service通信都需要驗(yàn)證通過他們的數(shù)字證書渤刃。
運(yùn)行cryptogen和configtxgen命令
可以手動(dòng)運(yùn)行上述兩個(gè)命令生成數(shù)字證書/密鑰或者生成配置交易拥峦。也可以通過修改腳本byfn.sh腳本實(shí)現(xiàn)上述目標(biāo)。
手動(dòng)生成證書和配置交易
可以參考byfn.sh
腳本中的generateCerts函數(shù)理解生成網(wǎng)絡(luò)配置中數(shù)字證書的命令卖子。為了便利略号,這里我們也提供了一種參考方法。
首先運(yùn)行cryptogen
工具洋闽。cryptogen
命令在first network子目錄的bin目錄下玄柠,下面運(yùn)行命令使用了該命令所在位置的相對(duì)路徑。
../bin/cryptogen generate --config=./crypto-config.yaml
接下來诫舅,我們需要告訴configtxgen
工具引用哪里的配置文件configtx.yaml
羽利。這里我們通過設(shè)置環(huán)境變量來設(shè)定配置文件的路徑。
export FABRIC_CFG_PATH=$PWD
../bin/configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block
接下來刊懈,我們創(chuàng)建channel交易这弧。確保替換$CHANNEL_NAME
的值或者設(shè)置CHANNEL_NAME
作為一個(gè)環(huán)境變量。創(chuàng)建命令如下:
export CHANNEL_NAME=mychannel
../bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME
接下來虚汛,在我們創(chuàng)建的channel上定義Org1的Anchor Peer節(jié)點(diǎn)匾浪。執(zhí)行命令為:
../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP
在channel上定義Org2的Anchor Peer節(jié)點(diǎn):
../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP
啟動(dòng)網(wǎng)絡(luò)
我們引用一個(gè)docker-compose
腳本啟動(dòng)網(wǎng)絡(luò),docker-compose
文件引用了我們之前下載的鏡像文件同時(shí)根據(jù)之前生成的genesis.block
引導(dǎo)orderer卷哩。注釋掉其中的command代碼:
working_dir:
/opt/gopath/src/github.com/hyperledger/fabric/peer
# command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME}; sleep
$TIMEOUT'
volumes
如果不注釋蛋辈,網(wǎng)絡(luò)啟動(dòng)時(shí)腳本會(huì)執(zhí)行所有的CLI命令。這里我們手動(dòng)的執(zhí)行每一條命令殉疼,以便于我們了解命令的語法和功能梯浪。
給TIMEOUT
參數(shù)傳遞一個(gè)相對(duì)較大的值(單位為秒);否則CLI容器默認(rèn)會(huì)在60s后退出瓢娜。
啟動(dòng)網(wǎng)絡(luò):
CHANNEL_NAME=$CHANNEL_NAME TIMEOUT=60 docker-compose -f docker-compose-cli.yaml up -d
如果你想實(shí)時(shí)查看執(zhí)行上述命令的日志信息挂洛,那么去掉上面的-d選項(xiàng)(后臺(tái)運(yùn)行)。如果打開了上述日志流眠砾,那么你需要另外再打開一個(gè)終端用來執(zhí)行CLI命令虏劲。
環(huán)境變量
為了在peer0.org1.example.com
上執(zhí)行下面的CLI命令,需要先配置下面4個(gè)環(huán)境變量。peer0.org1.example.com
的這些變量我們已經(jīng)在CLI容器中配置了柒巫,因此我們可以不用傳遞這些環(huán)境變量的值了励堡。但是,如果你想發(fā)送命令到其他peer或者orderer堡掏,你需要提供這些變量相應(yīng)的值应结。檢查docker-compose-base.yaml查看那指定的路徑。
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
CORE_PEER_ADDRESS=peer0.org1.example.com:7051
CORE_PEER_LOCALMSPID="Org1MSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
創(chuàng)建和加入channel
執(zhí)行docker exec
命令進(jìn)入CLI容器
docker exec -it cli bash
成功執(zhí)行后泉唁,出現(xiàn)如下提示:
root@0d78bb69300d:/opt/gopath/src/github.com/hyperledger/fabric/peer#
之前鹅龄,我們使用configtxgen
工具生成了配置交易channel.tx。我們將會(huì)傳遞這個(gè)交易到orderer作為創(chuàng)建channel請(qǐng)求的一部分亭畜。
注意:--cafile
選項(xiàng)是orderer的根證書存放在本地的路徑扮休,該信息可以用來驗(yàn)證TLS握手過程。
我們使用-c
選項(xiàng)指定channel的名字拴鸵,使用-f
選項(xiàng)指定配置交易玷坠。在本例中為channel.tx,你也可以mount配置交易為一個(gè)不同的名字劲藐。(配置交易通過本地路徑mount到容器中)
export CHANNEL_NAME=mychannel
peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
這條命令返回一個(gè)genesis block <channel-ID.block>
八堡。該block可以用來加入channel時(shí)使用,block中包含了channel.tx中指定的配置信息瘩燥。
如果遇到以下錯(cuò)誤:
Error: Got unexpected status: BAD_REQUEST Usage: peer channel create [flags]
說明channel已經(jīng)被使用了秕重,換個(gè)channel重頭來一遍就好。
你需要留在CLI容器中執(zhí)行剩余的手動(dòng)命令厉膀。如果發(fā)送命令的目標(biāo)不是peer0.org1.example.com
溶耘,那么要重新設(shè)置相應(yīng)的環(huán)境變量。現(xiàn)在我們加入peer0.org1.example.com
到channel中服鹅,其中<channle-ID.block>替換為你自己的channel凳兵,當(dāng)前用的是mychannel.block:
peer channel join -b <channel-ID.block>
你可以修改上邊4個(gè)環(huán)境變量的值為其他peer節(jié)點(diǎn)信息配置加入其他節(jié)點(diǎn)到channel中。
安裝和實(shí)例化chaincode
我們利用一個(gè)簡(jiǎn)單的已寫好的chaincode企软。應(yīng)用通過chaincode和區(qū)塊鏈的賬本進(jìn)行交互庐扫,因此我們需要首先在每個(gè)peer節(jié)點(diǎn)上安裝chaincode用來執(zhí)行交易和背書交易,然后在channel上實(shí)例化chaincode仗哨。
首先安裝例子go代碼到4個(gè)peer節(jié)點(diǎn)中的一個(gè)形庭。這個(gè)命令會(huì)把go源碼放在peer節(jié)點(diǎn)的文件系統(tǒng)中。
peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02
接下來厌漂,在channel上實(shí)例化chaincode萨醒。這將會(huì)在channel上初始化chaincode,為chaincode設(shè)置背書策略苇倡,為目標(biāo)peer啟動(dòng)一個(gè)chaincode容器富纸。注意-P參數(shù)囤踩,這個(gè)參數(shù)指定了在該chaincode上一個(gè)交易被認(rèn)可需要的背書級(jí)別。
接下來的命令中晓褪,我們?cè)O(shè)置-P參數(shù)為OR ('Org0MSP.member','Org1MSP.member’)”
堵漱。這表示我們需要Org1或者Org2中一個(gè)peer節(jié)點(diǎn)的背書。如果改變語法為AND涣仿,那么就需要兩個(gè)背書
peer chaincode instantiate -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n mycc -v 1.0 -c '{"Args":["init","a", "100", "b","200"]}' -P "OR ('Org1MSP.member','Org2MSP.member')"
上述命令中的mycc
為上文中peer上安裝的chaincode的名稱勤庐。
Query
下面查詢a的值,確認(rèn)chaincode被正確的實(shí)例化变过,stateDB正常的運(yùn)行埃元。查詢的語法如下:
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
Invoke
現(xiàn)在從a轉(zhuǎn)移10到b涝涤。這個(gè)交易會(huì)產(chǎn)生一個(gè)新的區(qū)塊并更新stateDB媚狰。調(diào)用的語法是:
peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n mycc -c '{"Args":["invoke","a","b","10"]}'
現(xiàn)在再次查詢,查看上述轉(zhuǎn)移10的命令是否已經(jīng)成功執(zhí)行阔拳,執(zhí)行的命令是:
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
正常執(zhí)行崭孤,會(huì)輸出如下提示:
Query Result: 90
這背后發(fā)生了什么
下面描述docker-compose-cli.yaml
文件中沒有注釋script.sh時(shí)的執(zhí)行情況。去掉包含script.sh腳本執(zhí)行的注釋糊肠,然后使用docker-compose命令再次啟動(dòng)網(wǎng)絡(luò)辨宠。
- script.sh腳本在CLI容器里已經(jīng)備份過,腳本執(zhí)行createChannel命令根據(jù)設(shè)定的channel名字货裹,使用channel.tx文件作為channel配置交易嗤形。
- createChannel執(zhí)行的輸出是一個(gè)genesis block-<your channel name>.block。輸出存儲(chǔ)在peer節(jié)點(diǎn)的文件系統(tǒng)上包含了channel.tx所指定的channel配置信息弧圆。
- joinChannel命令被執(zhí)行(4個(gè)peer節(jié)點(diǎn))赋兵,joinChannel命令使用上文生成的genesis
block作為參數(shù),該命令引導(dǎo)peer節(jié)點(diǎn)加入到<your channel name>并且建立一個(gè)以<your
channel name>.block為起始的鏈搔预。 - 目前我們建立了一個(gè)包含4個(gè)節(jié)點(diǎn)的channel, channel包含兩個(gè)orgnizations霹期。類似TwoOrgsChannel文件的配置。
- peer0.org1.example.com和peer1.org1.example.com屬于Org1拯田;peer0.org2.example.com和peer1.org2.example.com屬于Org2
- 這些關(guān)系在crypto-config.yaml里定義历造,MSP的路徑在docker compose中指定
- Org1MSP的Anchor Peer(peer0.org1.example.com)和Org2MSP的Anchor peer(peer0.org2.example.com)被更新。我們通過傳遞Org1MSPanchor.tx和Org2MSPanchor.tx以及channel的名字到ordering service來實(shí)現(xiàn)這一步船庇。
- 將編寫好的chaincode_example02安裝在peer0.org1.example.com和peer0.org2.example.com上(這里并沒有安裝在所有peer上吭产,而是僅安裝在anchor
peer節(jié)點(diǎn)上,anchor peer節(jié)點(diǎn)之前每個(gè)Org設(shè)置了一個(gè)) - chaincode在peer0.org2.example.com上實(shí)例化鸭轮。實(shí)例化過程添加chaincode到channel中臣淤,為目標(biāo)peer啟動(dòng)容器,同時(shí)初始化與chaincode相關(guān)的key-value鍵值對(duì)张弛。本例中初始化的值為[“a”: ”100”, “b”: ”200”]荒典。實(shí)例化后會(huì)啟動(dòng)一個(gè)容器dev-peer0.org2.example.com-mycc-1.0酪劫。(實(shí)例化過程發(fā)送至peer0.org2.example.com上執(zhí)行)
- 實(shí)例化過程也傳遞了一個(gè)背書策略的參數(shù)。背書策略類似形式:-P "OR ('Org1MSP.member','Org2MSP.member')"寺董,代表任何交易必須被Org1或Org2的一個(gè)peer背書覆糟。
- 在peer0.org1.example.com上執(zhí)行查詢a的值。chaincode之前已經(jīng)安裝在peer0.org1.example.com上了遮咖,因此查詢操作會(huì)為Org1的peer0節(jié)點(diǎn)啟動(dòng)一個(gè)容器dev-peer0.org1.example.com-mycc-1.0滩字。查詢結(jié)果也會(huì)返回回來,這個(gè)過程中沒有任何寫操作發(fā)生御吞,所以a的值還是100麦箍。
- 發(fā)送一個(gè)轉(zhuǎn)移賬戶金額的調(diào)用到peer0.org1.example.com,從a賬戶轉(zhuǎn)移10單位至b賬戶
- chaincode然后安裝在peer1.org2.example.com上
- 發(fā)送查詢a賬戶操作至peer1.org2.example.com陶珠。這將啟動(dòng)第三個(gè)chaincode容器dev-peer1.org2.example.com-mycc-1.0挟裂。返回金額90,說明之前帳號(hào)金額的轉(zhuǎn)移操作成功執(zhí)行揍诽。
這說明了什么
為了在賬本上成功的執(zhí)行讀寫操作诀蓉,chaincode必須安裝在peer上。另外暑脆,chaincode容器直到實(shí)例化或者傳統(tǒng)交易-讀寫執(zhí)行的時(shí)候(例:查詢a賬戶的值)渠啤,chaincode容器才會(huì)啟動(dòng)。channel中的每個(gè)節(jié)點(diǎn)都維護(hù)了賬本的完全復(fù)制添吗,存儲(chǔ)了不可改變的沥曹、序列化的記錄區(qū)塊以及state database用于保存當(dāng)前的fabric狀態(tài)。即便是那些沒有安裝chaincode的節(jié)點(diǎn)(例如peer1.org1.example.com)也會(huì)同步賬本碟联。最終chaincode在安裝到peer1.org1.example.com后就可以被調(diào)用了妓美,因?yàn)閏haincode已經(jīng)完成了實(shí)例化。
怎樣查看交易信息
查看CLI docker容器的日志信息
docker logs -f cli
可以看到交易的詳細(xì)過程
怎樣查看chaincode的日志
在每個(gè)chaincode container上可以查看當(dāng)前container里所執(zhí)行過的交易玄帕。具體查看命令如下:
$ docker logs dev-peer0.org2.example.com-mycc-1.0
04:30:45.947 [BCCSP_FACTORY] DEBU : Initialize BCCSP [SW]
ex02 Init
Aval = 100, Bval = 200
$ docker logs dev-peer0.org1.example.com-mycc-1.0
04:31:10.569 [BCCSP_FACTORY] DEBU : Initialize BCCSP [SW]
ex02 Invoke
Query Response:{"Name":"a","Amount":"100"}
ex02 Invoke
Aval = 90, Bval = 210
$ docker logs dev-peer1.org2.example.com-mycc-1.0
04:31:30.420 [BCCSP_FACTORY] DEBU : Initialize BCCSP [SW]
ex02 Invoke
Query Response:{"Name":"a","Amount":"90"}
理解docker-compose拓?fù)浣Y(jié)構(gòu)
BYFN例子提供了兩種docker-compose文件配置部脚,每一種都是由docker-compose-base.yaml(文件存放在base文件夾中)文件拓展而來。第一個(gè)配置文件是docker-compose-cli.yaml裤纹,該配置文件配置了一個(gè)CLI容器委刘,一個(gè)orderer,4個(gè)peer節(jié)點(diǎn)鹰椒。使用該配置文件啟動(dòng)可以實(shí)現(xiàn)本文中的所有操作指令锡移。第二種配置文件docker-compose-e2e.yaml是配置啟動(dòng)一個(gè)使用Node.js SDK的點(diǎn)對(duì)點(diǎn)測(cè)試。這個(gè)配置文件的主要區(qū)別是包含了fabric-ca-servers容器漆际。因此淆珊,我們可以使用REST接口實(shí)現(xiàn)向CA組織注冊(cè)和登記用戶。
如果你想使用docker-compose-e2e.yaml并且不先運(yùn)行byfn.sh腳本奸汇,那么我們需要做4個(gè)微改動(dòng)施符。我們需要設(shè)定Organization CA的私鈅往声。你可以設(shè)定這些值為你的crypto-config文件夾。例如設(shè)置Org1的私鈅路徑為:crypto-config/peerOrganizations/org1.example.com/ca/戳吝。私鈅文件是一個(gè)長(zhǎng)hash值加上_sk組成浩销。設(shè)定Org2的私鈅為crypto-config/peerOrganizations/org2.example.com/ca/。另外兩處改動(dòng)是修改docker-compose-e2e.yaml中ca0和ca1配置中的FABRIC_CA_SERVER_TLS_KEYFILE變量對(duì)應(yīng)的值听哭。需要指定tls證書所在的路徑慢洋。