本文是在閱讀《區(qū)塊鏈開發(fā)實戰(zhàn)-Hyperledger Fabric關(guān)鍵技術(shù)與案例分析》一書的同時,在實踐中記錄的一些實踐步驟與經(jīng)驗分享炊苫。
Hyperledger Fabric開發(fā)實戰(zhàn)-04編寫智能合約
Hyperledger Fabric的智能合約叫做Chaincode撒强,是業(yè)務(wù)的成載體,負(fù)責(zé)具體的業(yè)務(wù)邏輯
Chaincode代碼
Fabric的Chaincode運行在容器中,可以使用Go漱办,Java,Node.js語言開發(fā)婉烟,Golang是目前為主比較成熟穩(wěn)定的娩井。
Chaincode組成
Chaincode主要由下面幾個組成:
- 必須在main包下
- 引用必要的依賴
- 定義一個結(jié)構(gòu)體,并為結(jié)構(gòu)體綁定Init和Invoke方法
- shim.ChaincodeStubInterface和pb.Response
- main方法
下面以一個例子進(jìn)行說明
// 1.在main包下
package main
// 2.引入必要的依賴
import(
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
pb "github.com/hyperledger/fabric/protos/peer"
)
// 3.定義一個結(jié)構(gòu)體
type mychaincode struct {
}
// 4.為結(jié)構(gòu)體綁定init和invoke方法
func (t *mychaincode) Init(stub shim.ChaincodeStubInterface) pb.Response{
fmt.Println(" << ====[Init] success init it is view in docker ======")
return shim.Success([]byte("success init"))
}
func (t *mychaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response{
fmt.Println(" << ====[Invoke] success init it is view in docker ======")
return shim.Success([]byte("success init"))
}
// 5.主方法
func main(){
err := shim.Start(new(mychaincode))
if err != nil{
fmt.Println("Error starting Simple chaincode : %s",err)
}
}
Chaincode部署
Chaincode的運行分為:install似袁,instantiate和invoke三步
編寫以上的代碼后洞辣,我們將其放入一個文件夾,例如: /home/ssj234/fabricwksp/05-chaincode/下昙衅,在部署的時候扬霜,會去$GOPATH的src下面尋找文件夾,因此而涉,我們在如下路徑編寫Chaincode
cd /home/ssj234/fabricwksp/05-chaincode/
mkdir -p src/firstchaincode
cd src/firstchaincode
# 編寫代碼
vim firstchaincode.go
go build
安裝
# 設(shè)置GOPATH著瓶,讓其能夠找到Chaincode代碼
# 設(shè)置要鏈接的Peer節(jié)點和Peer的Admin證書
export set GOPATH=/home/ssj234/fabricwksp/05-chaincode
export set FABRIC_CFG_PATH=/home/ssj234/fabricwksp/02-helloworld/peer
export set CORE_PEER_LOCALMSPID=Org1MSP
export set CORE_PEER_ADDRESS=peer0.org1.cmbc.com:7051
export set CORE_PEER_MSPCONFIGPATH=/home/ssj234/fabricwksp/02-helloworld/fabricconfig/crypto-config/peerOrganizations/org1.cmbc.com/users/Admin@org1.cmbc.com/msp
# 部署chaincode 代碼,-n后面是名字 -v 是Chaincode的版本 -p后面是在$GOPAT/src下的相對路徑
peer chaincode install -n hellochaincode -v 1.1 -p hellochaincode
實例化
實例化的時候會調(diào)用init方法
# 設(shè)置GOPATH
# 設(shè)置要連接的Peer節(jié)點和其Admin證書
export set GOPATH=/home/ssj234/fabricwksp/05-chaincode
export set FABRIC_CFG_PATH=/home/ssj234/fabricwksp/02-helloworld/peer
export set CORE_PEER_LOCALMSPID=Org1MSP
export set CORE_PEER_ADDRESS=peer0.org1.cmbc.com:7051
export set CORE_PEER_MSPCONFIGPATH=/home/ssj234/fabricwksp/02-helloworld/fabricconfig/crypto-config/peerOrganizations/org1.cmbc.com/users/Admin@org1.cmbc.com/msp
# 初始化chaincode 代碼啼县,需要指定channel的名字材原,-c是傳入的參數(shù)
peer chaincode instantiate -o orderer.cmbc.com:7050 -C cmbcchannel666 -n firstchaincode -v 1.1 -c '{"Args":["init","a","100","b","200"]}' -P "OR ('Org1MSP.member','Org2MSP.member')"
instantiate
實例化命令運行的時間較長,銀行會啟動一個docker容器來執(zhí)行chaincode谭羔,我們可以通過docker ps
命令觀察,會看到下面的一個容器正在運行
STATUS PORTS NAMES
bee440516894 dev-peer0.org1.cmbc.com-firstchaincode-1.2-876a5b6466d4eeac14cf940b95e3538a8ace73b133fad7c70041ea17d7cf4b8e "chaincode -peer.a..." 2 minutes ago Up 2 minutes
使用docker logs bee440516894
查看日志华糖,會輸出Init方法中打印的內(nèi)容
<< ====[Init] success init it is view in docker ======
調(diào)用
使用peer chaincode invoke
可以調(diào)用chaincode的invoke方法
# 設(shè)置$GOPATH
# 設(shè)置要連接的Peer和Peer的Admin證書
export set GOPATH=/home/ssj234/fabricwksp/05-chaincode
export set FABRIC_CFG_PATH=/home/ssj234/fabricwksp/02-helloworld/peer
export set CORE_PEER_LOCALMSPID=Org1MSP
export set CORE_PEER_ADDRESS=peer0.org1.cmbc.com:7051
export set CORE_PEER_MSPCONFIGPATH=/home/ssj234/fabricwksp/02-helloworld/fabricconfig/crypto-config/peerOrganizations/org1.cmbc.com/users/Admin@org1.cmbc.com/msp
# 調(diào)用chaincode 代碼,需要制定orderer服務(wù)器瘟裸,channel的名稱和Chaincode的名稱和版本號
peer chaincode invoke -o orderer.cmbc.com:7050 -C cmbcchannel666 -n firstchaincode -v 1.1 -c '{"Args":["invoke","a","100","b","200"]}'
執(zhí)行完成客叉,通過docker logs
命令可以查看到Invoke方法的打印內(nèi)容。