1.開啟網路
沒啥好說的,之前要下samples,二進位制和映象
cd fabric-samples/test-network
把之前網路關閉了
./network.sh down
用下面的指令開啟測試網路:
./network.sh up createChannel
createchannel指令創造了一個叫mychannel的channel(兩個組織org1和2)。
成功的畫面8說了,就是channel successfully joined。
這會可以用peer cli來部署asset-transfer (basic)鏈碼到通道了。
第0步:開啟Logspout
這就是一個監測鏈碼的工具了,也可以不開啟。
cd fabric-samples/test-network
cp ../commercial-paper/organization/digibank/configuration/cli/monitordocker.sh
官方第一行指令多了一個.,刪掉。接著執行它:
./monitordocker.sh net_test
顯示 Starting monitoring on all containers on the network net_basic,就ok了
第一步:打包智慧合約
在安裝到我們peer節點之前我們要打包。用go,js, Typescript步驟略有不同,我這邊用的是go
在打包鏈碼之前,要安裝鏈碼的依賴。導航到go版本的那個資料夾(包含the asset-transfer (basic) chaincode.)
cd fabric-samples/asset-transfer-basic/chaincode-go
案例用的是go 模組來安裝鏈碼依賴。依賴都在go.mod檔案中。(程式碼不貼了)
go.mod檔案把fabric 合約api輸出到智慧合約包了。
開啟asset-transfer-basic/chaincode-go/chaincode/smartcontract.go,能夠看到合約api是怎麼用來定義smartcontract型別的:
// SmartContract provides functions for managing an Asset
type SmartContract struct {
contractapi.Contract
}
這個smartcontract type用於為智慧合約中定義的函數建立事務上下文,這些函數用於向區塊鏈分類賬讀寫資料。
// CreateAsset issues a new asset to the world state with given details.
func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface, id string, color string, size int, owner string, appraisedValue int) error {
exists, err := s.AssetExists(ctx, id)
if err != nil {
return err
}
if exists {
return fmt.Errorf("the asset %s already exists", id)
}
asset := Asset{
ID: id,
Color: color,
Size: size,
Owner: owner,
AppraisedValue: appraisedValue,
}
assetJSON, err := json.Marshal(asset)
if err != nil {
return err
}
return ctx.GetStub().PutState(id, assetJSON)
}
說了那麼多,接下來搞依賴,在asset-transfer-basic/chaincode-go目錄下執行:
GO111MODULE=on go mod vendor
成功的話,目錄裡會有vendor資料夾。
接下來就是搞環境變數,複製貼上就完事了:
export PATH=${PWD}/../bin:$PATH
export FABRIC_CFG_PATH=$PWD/../config/
這兩段話我直接就在:
vim ~/.bashrc
source ~/.bashrc
裡面搞了,我不知道直接在終端打有沒有效果,應該是有的
接下來就打包就完事了
peer lifecycle chaincode package basic.tar.gz --path ../asset-transfer-basic/chaincode-go/ --lang golang --label basic_1.0
–lang:用於定義鏈碼語言
–path:提供智慧合約程式碼位置
–label:用來定義鏈碼的標籤
js我就不貼出來了,我電腦deploy cc js一直會很慢有時候都會超時,不知道為什麼????
第二步:安裝鏈碼包
要把鏈碼裝到peer節點上去
先把鏈碼裝到org1的peer上去。設定環境變數:
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051
直接在終端上面打!!!!!!!!
注意:如果你打上去了,然後你把這個終端關了,接下來你要進行的鏈碼操作都需要你在新開啟的終端再打一遍!!!!!!!
接下來就是安裝
peer lifecycle chaincode install basic.tar.gz
終端顯示:
2020-07-16 10:09:57.534 CDT [cli.lifecycle.chaincode] submitInstallProposal -> INFO 001 Installed remotely: response:<status:200 payload:"\nJbasic_1.0:e2db7f693d4aa6156e652741d5606e9c5f0de9ebb88c5721cb8248c3aead8123\022\tbasic_1.0" >
2020-07-16 10:09:57.534 CDT [cli.lifecycle.chaincode] submitInstallProposal -> INFO 002 Chaincode code package identifier: basic_1.0:e2db7f693d4aa6156e652741d5606e9c5f0de9ebb88c5721cb8248c3aead8123
就ok
同理,org2上的peer不多說
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_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=localhost:9051
peer lifecycle chaincode install basic.tar.gz
沒問題就第三步:同意鏈碼定義(改:這步以後的同意全都改成批准)
在安裝完後,需要為你的組織同意一個鏈碼定義。定義包括:鏈碼管理的重要引數:名字版本,背書政策。
需要在部署鏈碼之前批准鏈碼的通道成員集由Application/Channel/lifeycleEndorsement
進行管理。預設情況下,此策略要求大多數通道成員需要批准鏈碼,然後才能在通道上使用該鏈碼。因為我們只有兩個組織在渠道上,大多數2是2,我們需要批准一個鏈碼定義的資產轉移(基本)為Org1和Org2。
如果一個組織已在peer上安裝了鏈碼,則需要將packageID包括在其組織批准的鏈碼定義中。包(package)ID用於將安裝在對等點上的鏈碼與已批准的鏈碼定義關聯起來,並允許組織使用鏈碼來支援事務。你可以通過使用peer lifecycle chaincode queryinstalled命令來查詢你的peer來找到一個鏈碼的包ID。(這兩段直接機翻再改,我覺得挺重要但我懶得打字)
peer lifecycle chaincode queryinstalled
得到id
Installed chaincodes on peer:
Package ID: basic_1.0:69de748301770f6ef64b42aa6bb6cb291df20aa39542c3ef94008615704007f3, Label: basic_1.0
然後用上面的,label 前面的id來設定環境變數:
export CC_PACKAGE_ID=basic_1.0:69de748301770f6ef64b42aa6bb6cb291df20aa39542c3ef94008615704007f3
(id每個人都不一樣,別把我這個id用到你上面去了)
因為環境變數已經被設定,我們可以為組織2同意鏈碼定義。鏈碼在組織層被同意,所以指令只需要target一個peer節點。這個同意事項是組織用gossip來分發給其他節點。同意的指令:
peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name basic --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
--package-id
:包含package identifier(這裡翻譯成包身份鑑定者)
--sequence
:一個能夠追蹤一個鏈碼被定義或者更新多少次的指數
這邊我覺得他重複了,不知道為什麼
We still need to approve the chaincode definition as Org1. Set the following environment variables to operate as the Org1 admin:
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_ADDRESS=localhost:7051
You can now approve the chaincode definition as Org1:
peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name basic --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上啟動鏈碼。如果在通道成員批准鏈碼之前提交定義,該組織將無法背書事務。因此,建議所有通道成員在提交鏈碼定義之前先批准一個鏈碼。
第四步:把鏈碼定義提交到通道
用下面的指令來確認是否通道成員同意了相同的鏈碼定義
peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name basic --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
結果應該是這樣:
{
"Approvals": {
"Org1MSP": true,
"Org2MSP": true
}
}
用如下指令來把鏈碼定義提交到通道:
peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name basic --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
--peerAddresse
:確定目標peer0.org1.example.com from Org1 peer0.org2.example.com from Org2.
commit
提交到peer節點。peer節點加入通道來查詢被組織同意的鏈碼定義。
用以下指令來確認鏈碼定義被提交到通道:
peer lifecycle chaincode querycommitted --channelID mychannel --name basic --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
成功的標誌:
Committed chaincode definition for chaincode 'basic' on channel 'mychannel':
Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true]
呼叫鏈碼就不說了,複製貼上就完事了,之前都對的不會出錯
下面一步我這邊跑不起來,更新鏈碼:之前用的是go語言,這個官方要我用js來搞,其實都一樣,但是我這邊跑js就一直會timeout,非常奇怪。但是流程和之前是一模一樣,而且我個人認為更新鏈碼沒有很大的意義,一般都是重新從頭部署就完事了
最後,清理一下環境
docker stop logspout
docker rm logspout
./network.sh down
本章結束