链码编写规范
Posted 患孤
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了链码编写规范相关的知识,希望对你有一定的参考价值。
目录
前言
链码也就是智能合约,在网络当中扮演着逻辑处理的角色,也就是业务逻辑,所以说链码还是比较重要的。我们先来看一下链码,这个链码是我写的。代码较长大家可以用目录跳转。
代码
package main
import (
"bytes"
"encoding/json"
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
"github.com/hyperledger/fabric/protos/peer"
"strconv"
"time"
)
const (
TransactionKeyPrefix = "transaction"
TxStatusNew = "新建(待确认)"
TxStatusConfirm = "新建(已确认)"
TxStatusPayForAnother = "申请代付"
TxStatusPay = "已付款(未核实)"
TxStatusPayed = "已付款(已核实)"
TxStatusRefusePay = "代付被拒"
TxStatusShip = "已发货(未核实)"
TxstatusShiped = "已发货(已核实)"
TxStatusRepay = "已还款(未核实)"
TxStatusRepayed = "已还款(已核实)"
)
type SupplyChainFinance struct
// 新建 -> 已确认 -> 申请代付 -> 已付款 ->确认付款-> 已发货 -> 确认发货 -> 已还款 -> 确认已还款
// |
// 拒绝付款 ->回到上一步
type Transaction struct
Id string `json:"id"` // 单号
Description string `json:"description"` // 备注
Value uint64 `json:"value"` // 金额(单位为一分钱)
ShipmentNumber string `json:"shipment_number"` // 物流号
PaymentTxNumber string `json:"payment_tx_number"` // 付款转账号
RepaymentTxNumber string `json:"repayment_tx_number"` // 还款转账号
Status string `json:"status"` // 订单状态 ----请使用上面const中的常量来标记订单状态
CreateDate time.Time `json:"create_date"` // 创建时间
PaymentDate time.Time `json:"payment_date"` // 付款时间
RepaymentDate time.Time `json:"repayment_date"` // 应还款时间
RepayDate time.Time `json:"repay_date"` // 实际还款时间
Supplier string `json:"supplier"` // 供应商
Company string `json:"company"` // 采购商
FinancialOrg string `json:"financial_org"` // 金融机构
type Company struct
Name string `json:"name"` //企业名
Phone string `json:"phone"` //联系电话
Account string `json:"account"` //登录账号
Password string `json:"password"` //登录密码
Address string `json:"address"` //地址
CompanyType string `json:"company_type"` //企业类型,供应商,采购商,金融机构
EnterpriseCode string `json:"enterprise_code"` //企业统一社会信用代码
BankCard string `json:"bank_card"` //银行卡号码
Balance uint64 `json:"balance"` //余额
CreateDate time.Time `json:"create_date"` //创建时间
// 企业的3种类型
var companyArg = map[string]string"financial_org": "financial_org", "supplier": "supplier", "buyer": "buyer"
/**
@Author: dd
@Date: 2020/5/13 16:22
@Desc: 智能合约初始化,要求必须创建3个企业,分别为供应商、采购商、金融企业 ,Company.Name="datainsights" (必需) *
@Param:
@Return:
**/
func (s *SupplyChainFinance) Init(stub shim.ChaincodeStubInterface) peer.Response
//实例化三个企业
comp1:=Company
Name: "金融机构",
Phone: "21131",
Account: "1001",
Password: "123456",
Address: "test",
CompanyType: companyArg["financial_org"],
EnterpriseCode: "test",
BankCard: "20000122123",
Balance: 20000,
CreateDate: time.Now(),
comp2:=Company
Name: "供应商",
Phone: "21135311",
Account: "1002",
Password: "123456",
Address: "test",
CompanyType: companyArg["supplier"],
EnterpriseCode: "test",
BankCard: "5344123",
Balance: 20000,
CreateDate: time.Now(),
comp3:=Company
Name: "采购商",
Phone: "12312313",
Account: "1003",
Password: "123456",
Address: "test",
CompanyType: companyArg["buyer"],
EnterpriseCode: "test",
BankCard: "21223123",
Balance: 20000,
CreateDate: time.Now(),
//存入数组
comps:=[]Companycomp1,comp2,comp3
//遍历数组
for i:=0;i<len(comps);i++
//序列化
compByte,err:=json.Marshal(comps[i])
if err != nil
return shim.Error("marshal error ")
res:=createCompany(stub,[]stringstring(compByte))
if res.Status!=shim.OK
return peer.Response
Status: res.Status,
Message: res.Message,
Payload: nil,
XXX_NoUnkeyedLiteral: struct,
XXX_unrecognized: nil,
XXX_sizecache: 0,
return shim.Success(nil)
func (s *SupplyChainFinance) Invoke(stub shim.ChaincodeStubInterface) peer.Response
funcName, args := stub.GetFunctionAndParameters()
switch funcName
case "newTransaction":
return newTransaction(stub, args)
case "createCompany":
return createCompany(stub, args)
case "confirmTransaction":
return confirmTransaction(stub, args)
case "applyPayForAnother":
return applyPayForAnother(stub, args)
case "payTransaction":
return payTransaction(stub, args)
case "affirmPay":
return affirmPay(stub, args)
case "refusePayTransaction":
return refusePayTransaction(stub, args)
case "updateShipmentInfo":
return updateShipmentInfo(stub, args)
case "verifyShipmentInfo":
return verifyShipmentInfo(stub, args)
case "repayTransaction":
return repayTransaction(stub, args)
case "verifyRepay":
return verifyRepay(stub, args)
case "autoRepay":
return autoRepay(stub, args)
case "getTransactions":
return getTransactions(stub, args)
case "getTrByBuyer":
return getTrByBuyer(stub, args)
case "getTransactionHistory":
return getTransactionHistory(stub, args)
case "getCompany":
return getCompany(stub, args)
default:
return shim.Error(fmt.Sprintf("unsupported function: %s", funcName))
/**
@Author: dd
@Date: 2020/5/13 16:48
@Desc: 根据company.CompanyType来创建3种不同的企业*
@Param: Company
@Return: res = peer.Response, 要求返回结果时能够返回正确相应的响应码:shim.ERROR,shim.ERRORTHRESHOLD,shim.OK
**/
func createCompany(stub shim.ChaincodeStubInterface, args []string) peer.Response
// 验证参数
if len(args)!=1
return peer.Response
Status: shim.ERRORTHRESHOLD,
Message: "参数长度错误",
Payload: nil,
XXX_NoUnkeyedLiteral: struct,
XXX_unrecognized: nil,
XXX_sizecache: 0,
if args[0]==""
return peer.Response
Status: shim.ERRORTHRESHOLD,
Message: "参数为空",
Payload: nil,
// 反序列化
var comp Company
if err:=json.Unmarshal([]byte(args[0]),&comp);err!=nil
return shim.Error("unmarshal error ")
// 验证参数
if comp.Account==""||comp.Address==""||comp.Balance<0||comp.BankCard==""||comp.EnterpriseCode==""||comp.Name==""||comp.Password==""||comp.Phone==""
return peer.Response
Status: shim.ERRORTHRESHOLD,
Message: "必要参数为空",
Payload: nil,
if comp.CompanyType!=companyArg["financial_org"]||comp.CompanyType!=companyArg["supplier"]||comp.CompanyType!=companyArg["buyer"]
return peer.Response
Status: shim.ERRORTHRESHOLD,
Message: "没有此企业类型",
Payload: nil,
// 创建组合键
compKey,err:=stub.CreateCompositeKey(comp.CompanyType,[]stringcomp.Name)
if err != nil
return shim.Error("create key error ")
// 序列化存入账本
compByte,err:=json.Marshal(comp)
if err != nil
return shim.Error("marshal error ")
if err:=stub.PutState(compKey,compByte);err!=nil
return shim.Error("put state error ")
return shim.Success(compByte)
/**
@Author: dd
@Date: 2020/5/15 18:01
@Desc: 创建新的交易 *
@Param: id:string, Value:int, supplier:string, create_date:time.Time, company:string
@Return:
**/
func newTransaction(stub shim.ChaincodeStubInterface, args []string) peer.Response
if len(args)!=1
return peer.Response
Status: shim.ERRORTHRESHOLD,
Message: "参数长度错误",
Payload: nil,
if args[0]==""
return peer.Response
Status: shim.ERRORTHRESHOLD,
Message: "参数为空",
Payload: nil,
// 反序列化
var tran Transaction
if err:=json.Unmarshal([]byte(args[0]),&tran);err!=nil
return shim.Error("unmarshal error")
// 验证必要参数
if tran.Id==""||tran.Value<0||tran.Supplier==""||tran.Company==""
return peer.Response
Status: shim.ERRORTHRESHOLD,
Message: "参数为空或者订单金额小于0",
Payload: nil,
//if !valideCompany(stub,companyArg["supplier"],tran.Supplier)
// return peer.Response
// Status: shim.ERRORTHRESHOLD,
// Message: "未找到此企业",
// Payload: nil,
//
//
//if !valideCompany(stub,companyArg["buyer"],tran.Company)
// return peer.Response
// Status: shim.ERRORTHRESHOLD,
// Message: "未找到此企业",
// Payload: nil,
//
//
// 修改订单状态
tran.Status=TxStatusNew
// 创建组合键
tranKey,err:=stub.CreateCompositeKey(TransactionKeyPrefix,[]stringtran.Id)
if err != nil
return shim.Error("create key error ")
// 序列化存入账本
tranByte,err:=json.Marshal(tran)
if err != nil
return shim.Error("marshal error ")
if err:=stub.PutState(tranKey,tranByte);err!=nil
return shim.Error("put state error ")
return shim.Success(tranByte)
/**
@Author: dd
@Date: 2020/5/15 18:00
@Desc: 供应商确认交易 *
@Param: id:string, supplier:string
@Return:
**/
func confirmTransaction(stub shim.ChaincodeStubInterface, args []string) peer.Response
if len(args)!=2
return peer.Response
Status: shim.ERRORTHRESHOLD,
Message: "参数长度错误",
Payload: nil,
if args[0]==""||args[1]==""
return peer.Response
Status: shim.ERRORTHRESHOLD,
Message: "参数为空",
Payload: nil,
//创建组合键
tranKey,err:=stub.CreateCompositeKey(TransactionKeyPrefix,[]stringargs[0])
if err != nil
return shim.Error("create error ")
// 从账本中获取数据
tranByte,err:=stub.GetState(tranKey)
if err != nil
return shim.Error("get state error ")
// 反序列化
var tran Transaction
if err:=json.Unmarshal(tranByte,&tran);err!=nil
return shim.Error("unmarshal error")
// 验证是否拥有权限
if tran.Supplier!=args[1]
return peer.Response
Status: shim.ERRORTHRESHOLD,
Message: "无权限修改此订单",
Payload: nil,
// 判断订单状态
if tran.Status!=TxStatusNew
return peer.Response
Status: shim.ERRORTHRESHOLD,
Message: "订单状态出错",
Payload: nil,
// 修改订单信息
tran.Status=TxStatusConfirm
// 序列化存入账本
tranByteNew,err:=json.Marshal(tran)
if err != nil
return shim.Error("marshal error ")
if err:=stub.PutState(tranKey,tranByteNew);err!=nil
return shim.Error("put state error ")
return shim.Success(tranByteNew)
/**
@Author: dd
@Date: 2020/5/15 17:57
@Desc: 向金融机构申请代付 *
@Param: id:string, company:string, financial_org:string, repayment_date:time.Time
@Return:
**/
func applyPayForAnother(stub shim.ChaincodeStubInterface, args []string) peer.Response
if len(args)!=1
return peer.Response
Status: shim.ERRORTHRESHOLD,
Message: "参数长度错误",
Payload: nil,
if args[0]==""
return peer.Response
Status: shim.ERRORTHRESHOLD,
Message: "参数为空",
Payload: nil,
// 反序列化
var tran Transaction
if err:=json.Unmarshal([]byte(args[0]),&tran);err!=nil
return shim.Error("unmarshal error")
// 验证必要参数
if tran.Id==""||tran.Company==""||tran.FinancialOrg==""
return peer.Response
Status: shim.ERRORTHRESHOLD,
Message: "参数为空",
Payload: nil,
// 判断是否存在此企业
if !valideCompany(stub,companyArg["financial_org"],tran.FinancialOrg)
return peer.Response
Status: shim.ERRORTHRESHOLD,
Message: "未找到此企业",
Payload: nil,
<以上是关于链码编写规范的主要内容,如果未能解决你的问题,请参考以下文章