本文參考了fabric官方文檔:http://hyperledger-fabric.readthedocs.io/en/latest/peer-chaincode-devmode.html?highlight=peer-chaincodedev
在fabric中peer節點有一個chaincodedev模式,在這個模式下面你可以不需要去實例化一個docker容器再去執行智能合約,可以在本地直接運行,這樣更加方便你調試。
為了不重復造輪子,作者建立了一個github工程:https://github.com/luckydogchina/fabric-v1.1.0-chaincodedev
==================================================================================
1.首先准備好fabric v1.1.0工程和相關環境,這里我就不贅述了。然后我們下載fabric-v1.1.0-chaincodedev工程,按照README.md執行,終端顯示如下的結果:
注意:執行前請保證本地的7050~7053端口沒有被其他進程所占用。
2. 查看當前的channel狀況:
#開啟一個終端窗口A,進入 fabric-v1.1.0-chaincodedev/chaincodedev
cd $fabric-v1.1.0-chaincodedev/chaincodedev
#枚舉當前已經存在的channel
FABRIC_CFG_PATH=./sampleconfig peer channel list
顯示結果如下:
可以清楚的看到,此時已經創建了兩個channel test1、test2;
3.編譯智能合約並安裝
這里以example02智能合約為例:
#開啟一個新終端B,進入fabric的example目錄下
cd $fabric/examples/chaincode/go/chaincode_example02
#編譯出智能合約
go build
#運行智能合約在本地,注意一定要保持運行狀態
CORE_CHAINCODE_LOGLEVEL=debug CORE_PEER_ADDRESS=127.0.0.1:7052 CORE_CHAINCODE_ID_NAME=mycc:0 ./chaincode_example02
#在終端窗口A中執行安裝命令:
FABRIC_CFG_PATH=./sampleconfig peer chaincode install -n mycc -v 0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02
#初始化智能合約,根據不同的智能合約要求,要填入不同的參數
FABRIC_CFG_PATH=./sampleconfig peer chaincode instantiate -n mycc -v 0 -c '{"Args":["init","a","100","b","200"]}' -o 127.0.0.1:7050 -C test1
注意:此時你已經在 channel test1中安裝了智能合約 chaincode_example02;
4.執行智能合約
#在終端窗口A中執行以下命令:
FABRIC_CFG_PATH=./sampleconfig peer chaincode invoke -n mycc -c '{"Args":["invoke","a","b","10"]}' -o 127.0.0.1:7050 -C test1
注意:此時a向b轉了10元錢,a的賬戶余額應為90,b的賬戶余額應為210;
#執行查詢命令
FABRIC_CFG_PATH=./sampleconfig peer chaincode query -n mycc -c '{"Args":["query","b"]}' -o 127.0.0.1:7050 -C test1 #查詢a的余額
FABRIC_CFG_PATH=./sampleconfig peer chaincode query -n mycc -c '{"Args":["query","b"]}' -o 127.0.0.1:7050 -C test1 #查詢b的余額
此時我們可以看到窗口B中運行的智能合約打印的日志:
到此為止我們的示例就講完了,最后我簡單陳述一下dev模式下和正式環境下智能合約運行有什么不同:
正式環境下:
invoke proposal--> endorser -->docker container-->chaincode
dev環境下:
invoke proposal --> endorser --> chaincode
注意:在執行過程中chaincode要一直保持運行。
那么chaincode是如何與 endorser之間交互的?
只要簡單的瀏覽以下fabric的源碼你就會發現,fabric中主要有以下幾個grpc通訊服務:
eventhub:用於事件流服務,客戶端調用此服務向peer注冊監聽事件;
broadcast:用於交易的廣播,client向orderer提交交易的時候用的就是這個服務;
deliver:提交區塊,peer節點通過這個服務從orderer節點拉取新生成的塊;
chaincode:智能合約與endorser之間通訊服務;
gossip:流言服務,用於同一個組織下的peer之間進行數據的同步(Anchor節點向其他節點同步區塊賬本).
為什么智能合約和fabric之間還有一個grpc通訊服務?這是因為智能合約通常有讀取和寫入區塊鏈賬本的行為,區塊鏈賬本是在endorser節點本地保存的,而智能合約是在endorser節點的docker容器中運行的,它無法直接endorser節點本地從讀取數據,只有通過endorser節點中轉才能完成讀寫數據的動作。chaincodes server的端口默認為7052,所以我們在模擬運行的時候要告訴智能合約peer chaincode server的服務地址是 127.0.0.1:7052。那么有同志要問了,在本文的環境中peer也是在容器里面運行的,為什么你指定的地址是127.0.0.1,很簡單,peer容器的7052端口綁定的是本地的7052端口,所以你向本地地址發送就可以了。
另外在阿里雲服務器上運行docker-compose環境,尤其是涉及到容器之間交互通訊的,可能發生無法通訊的情況,這時你要修改一下雲服務的網絡配置: