Fabric鏈碼實戰(一)貸款還款
阿新 • • 發佈:2018-11-29
title: Fabric鏈碼實戰(一)貸款還款
tags: Hyperledger, fabric ,區塊鏈,chaincode
功能簡述
假設需要用鏈碼開發簡單的貸款還款,要實現以下簡單的幾個業務需求:
1.通過賬戶身份證號,銀行名字進行貸款
2.過賬戶身份證號,銀行名字進行還款
功能實現
在fabric-samples/chaincode
下新建一個pay
目錄用來存放程式碼。
1.建立結構體
建立銀行、賬戶、交易歷史和智慧合約結構體
//銀行、賬戶、定義交易歷史
//定義銀行
type Bank struct {
//名字
BankName string `json:"BankName"`
//金額
Amount int `json:"Amount"`
//1:貸款 2:還款
Flag int `json:"Flag"`
//起始時間
StartTime string `json:"StartTime"`
//結束時間
EndTime string `json:"EndTime"`
}
//定義賬戶
type Account struct {
//身份證號
CardNo string `json:"CardNo"`
//使用者名稱
Aname string `json:"Aname"`
//性別
Gender string `json:"Gender"`
//電話
Mobile string `json:"Mobile"`
//銀行
Bank Bank `json:"Bank"`
//交易歷史
Histroys []HistoryItem
}
//定義交易歷史
type HistoryItem struct {
//交易id
TxID string
//賬戶
Account Account
}
type TraceChaincode struct {
}
2.實現init函式和main函式
//初始化方法
func (t *TraceChaincode) Init(stub shim.ChaincodeStubInterface) peer.Response {
//初始化測試資料
initTest(stub) //測試方法
return shim.Success(nil)
}
//鏈碼入口invoke
//loan:貸款
//repayment:還款
//initTest:測試初始化
func (t *TraceChaincode) Invoke(stub shim.ChaincodeStubInterface) peer.Response {
//得到方法名和引數
fun, args := stub.GetFunctionAndParameters()
//進行判斷
if fun == "loan" {
//貸款
return loan(stub, args)
} else if fun == "repayment" {
//還款
return repayment(stub, args)
} else if fun == "initTest" {
return initTest(stub)
} else {
return shim.Error("方法名錯誤")
}
}
func main() {
err := shim.Start(new(TraceChaincode))
if err != nil {
fmt.Println("啟動鏈碼時發生錯誤")
}
}
3.貸款和還款功能實現
//定義貸款和還款
const (
Bank_Flag_Loan = 1
Bank_Flag_Repayment = 2
)
//貸款
//-c Args:[loan,賬戶身份證號,銀行名字,金額]
func loan(stub shim.ChaincodeStubInterface, args []string) peer.Response {
//判斷引數
if len(args) != 3 {
return shim.Error("引數個數錯誤")
}
//判斷型別
v, err := strconv.Atoi(args[2])
if err != nil {
return shim.Error("型別錯誤")
}
//組裝資料
bank := Bank{
BankName: args[1],
Amount: v,
Flag: Bank_Flag_Loan,
StartTime: "2011-01-10",
EndTime: "2021-01-09",
}
account := Account{
CardNo: args[0],
Aname: "jack",
Gender: "男",
Mobile: "159999999",
Bank: bank,
}
//儲存狀態
b := putAccount(stub, account)
//判斷
if ! b {
return shim.Error("儲存貸款資料失敗")
}
return shim.Success([]byte("儲存貸款資料成功"))
}
//序列化並儲存
//引數將要儲存的賬戶傳過來,返回布林
func putAccount(stub shim.ChaincodeStubInterface, account Account) bool {
//序列化
accBytes, err := json.Marshal(account)
if err != nil {
return false
}
//儲存資料
err = stub.PutState(account.CardNo, accBytes)
if err != nil {
return false
}
return true
}
//還款
//-c Args:[repayment,賬戶身份證號,銀行名字,金額]
func repayment(stub shim.ChaincodeStubInterface, args []string) peer.Response {
if len(args) != 3 {
return shim.Error("引數個數錯誤")
}
v, err := strconv.Atoi(args[2])
if err != nil {
return shim.Error("指定的還款金額錯誤")
}
//組裝資料
bank := Bank{
BankName: args[1],
Amount: v,
Flag: Bank_Flag_Repayment,
StartTime: "2011-01-10",
EndTime: "2021-01-09",
}
account := Account{
CardNo: args[0],
Aname: "jack",
Gender: "男",
Mobile: "159999999",
Bank: bank,
}
b := putAccount(stub, account)
if !b {
return shim.Error("存款失敗")
}
return shim.Success([]byte("存款成功"))
}
4.實現測試方法
//測試方法
func initTest(stub shim.ChaincodeStubInterface) peer.Response {
bank := Bank{
BankName: "icbc",
Amount: 6000,
//貸款
Flag: 1,
StartTime: "2010-01-01",
EndTime: "2020-01-01",
}
bank1 := Bank{
BankName: "abc",
Amount: 1000,
//還款
Flag: 2,
StartTime: "2010-02-01",
EndTime: "2020-02-01",
}
account := Account{
CardNo: "1234",
Aname: "jack",
Gender: "男",
Mobile: "15900000",
Bank: bank1,
Histroys: nil,
}
account1 := Account{
CardNo: "123444",
Aname: "jack2",
Gender: "男",
Mobile: "1590000000",
Bank: bank,
Histroys: nil,
}
//物件序列化,儲存
accBytes, err := json.Marshal(account)
if err != nil {
return shim.Error("序列化賬戶失敗")
}
accBytes1, err := json.Marshal(account1)
if err != nil {
return shim.Error("序列化賬戶1失敗")
}
//儲存
err = stub.PutState(account.CardNo, accBytes)
if err != nil {
return shim.Error("儲存賬戶失敗")
}
err = stub.PutState(account.CardNo, accBytes1)
if err != nil {
return shim.Error("儲存賬戶1失敗")
}
return shim.Success(nil)
}
部署和測試
把我們的程式碼放入之前建立的pay
目錄下
詳細部署可以檢視我之前文章:
1. 開啟網路
開啟第一個終端
切換到chaincode-docker-devmode
目錄
執行下面命令:
###刪除所有活躍的容器###
docker rm -f $(docker ps -aq)
###清理網路快取###
docker network prune
###開啟網路###
docker-compose -f docker-compose-simple.yaml up
2.安裝鏈碼
開啟第二個終端
###進入Docker容器cli###
docker exec -it chaincode bash
###進入到鏈碼對應目錄###
cd pay
###啟動節點###
CORE_PEER_ADDRESS=peer:7051 CORE_CHAINCODE_ID_NAME=mycc:0 ./pay
3.操作鏈碼
開啟第三個終端
###啟動 cli###
docker exec -it cli /bin/bash
###安裝鏈碼###
peer chaincode install -p chaincodedev/chaincode/pay -n mycc -v 0
###例項化鏈碼###
peer chaincode instantiate -n mycc -v 0 -c '{"Args":["init"]}' -C myc
4.呼叫鏈碼
###呼叫測試方法###
peer chaincode invoke -C myc -n mycc -c '{"Args":["initTest"]}'
###貸款###
peer chaincode invoke -C myc -n mycc -c '{"Args":["loan","110229","icbc","5000000"]}'
###還款###
peer chaincode invoke -C myc -n mycc -c '{"Args":["repayment","110229","icbc","500"]}'