區(qū)塊鏈從零起步(P2)創(chuàng)建Hyperledger Fabric區(qū)塊鏈網(wǎng)絡(luò)

參考
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 blockordering 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ò)辨宠。

  1. script.sh腳本在CLI容器里已經(jīng)備份過,腳本執(zhí)行createChannel命令根據(jù)設(shè)定的channel名字货裹,使用channel.tx文件作為channel配置交易嗤形。
  2. createChannel執(zhí)行的輸出是一個(gè)genesis block-<your channel name>.block。輸出存儲(chǔ)在peer節(jié)點(diǎn)的文件系統(tǒng)上包含了channel.tx所指定的channel配置信息弧圆。
  3. 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為起始的鏈搔预。
  4. 目前我們建立了一個(gè)包含4個(gè)節(jié)點(diǎn)的channel, channel包含兩個(gè)orgnizations霹期。類似TwoOrgsChannel文件的配置。
  5. peer0.org1.example.com和peer1.org1.example.com屬于Org1拯田;peer0.org2.example.com和peer1.org2.example.com屬于Org2
  6. 這些關(guān)系在crypto-config.yaml里定義历造,MSP的路徑在docker compose中指定
  7. Org1MSP的Anchor Peer(peer0.org1.example.com)和Org2MSP的Anchor peer(peer0.org2.example.com)被更新。我們通過傳遞Org1MSPanchor.tx和Org2MSPanchor.tx以及channel的名字到ordering service來實(shí)現(xiàn)這一步船庇。
  8. 將編寫好的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è))
  9. 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í)行)
  10. 實(shí)例化過程也傳遞了一個(gè)背書策略的參數(shù)。背書策略類似形式:-P "OR ('Org1MSP.member','Org2MSP.member')"寺董,代表任何交易必須被Org1或Org2的一個(gè)peer背書覆糟。
  11. 在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麦箍。
  12. 發(fā)送一個(gè)轉(zhuǎn)移賬戶金額的調(diào)用到peer0.org1.example.com,從a賬戶轉(zhuǎn)移10單位至b賬戶
  13. chaincode然后安裝在peer1.org2.example.com上
  14. 發(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證書所在的路徑慢洋。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市陆盘,隨后出現(xiàn)的幾起案子普筹,更是在濱河造成了極大的恐慌,老刑警劉巖隘马,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件太防,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡祟霍,警方通過查閱死者的電腦和手機(jī)杏头,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來沸呐,“玉大人,你說我怎么就攤上這事呢燥≌柑恚” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵叛氨,是天一觀的道長(zhǎng)呼渣。 經(jīng)常有香客問我,道長(zhǎng)寞埠,這世上最難降的妖魔是什么屁置? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮仁连,結(jié)果婚禮上蓝角,老公的妹妹穿的比我還像新娘。我一直安慰自己饭冬,他們只是感情好使鹅,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著昌抠,像睡著了一般患朱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上炊苫,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天裁厅,我揣著相機(jī)與錄音冰沙,去河邊找鬼。 笑死执虹,一個(gè)胖子當(dāng)著我的面吹牛倦淀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播声畏,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼撞叽,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了插龄?” 一聲冷哼從身側(cè)響起愿棋,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎均牢,沒想到半個(gè)月后糠雨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡徘跪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年甘邀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片垮庐。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡松邪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出哨查,到底是詐尸還是另有隱情逗抑,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布寒亥,位于F島的核電站邮府,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏溉奕。R本人自食惡果不足惜褂傀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望加勤。 院中可真熱鬧仙辟,春花似錦、人聲如沸胸竞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽卫枝。三九已至煎饼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間校赤,已是汗流浹背吆玖。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工筒溃, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人沾乘。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓怜奖,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親翅阵。 傳聞我的和親對(duì)象是個(gè)殘疾皇子歪玲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容