链码编写规范

2024-01-08 10:38
文章标签 编写 规范 链码

本文主要是介绍链码编写规范,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

    • 前言
    • 代码
    • 一、判断参数的个数
    • 二、判断参数是否为空
    • 三、明确组合键
    • 四、判断参数的正确性
    • 五、判断公司是否存在
    • 六、判断是否有权限修改订单
    • 七、判断订单状态是否正确
    • 八、修改订单信息
    • 九、序列化
    • 十、存入账本

前言

链码也就是智能合约,在网络当中扮演着逻辑处理的角色,也就是业务逻辑,所以说链码还是比较重要的。我们先来看一下链码,这个链码是我写的。代码较长大家可以用目录跳转。

代码

package mainimport ("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:=[]Company{comp1,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,[]string{string(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 Companyif 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,[]string{comp.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 Transactionif 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,[]string{tran.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,[]string{args[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 Transactionif 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 Transactionif 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,}}//创建组合键tranKey,err:=stub.CreateCompositeKey(TransactionKeyPrefix,[]string{tran.Id})if err != nil {return shim.Error("create error ")}// 从账本中获取数据tranByte,err:=stub.GetState(tranKey)if err != nil {return shim.Error("get state error ")}//	反序列化var tran1 Transactionif err:=json.Unmarshal(tranByte,&tran1);err!=nil{return shim.Error("unmarshal error")}//	验证是否拥有权限if tran1.Company!=tran.Company{return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "无权限修改此订单",Payload:              nil,}}// 判断订单状态if tran1.Status!=TxStatusRefusePay||tran1.Status!=TxStatusConfirm{return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "订单状态出错",Payload:              nil,}}//	修改订单状信息tran1.Status=TxStatusPayForAnothertran1.RepaymentDate=tran.RepaymentDatetran1.FinancialOrg=tran.FinancialOrg//	序列化存入账本tranByteNew,err:=json.Marshal(tran1)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,PaymentTxNumber:string,financial_org:string,payment_date:time.Time}@Return:
**/
func payTransaction(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 Transactionif err:=json.Unmarshal([]byte(args[0]),&tran);err!=nil{return shim.Error("unmarshal error")}//	验证必要参数if tran.Id==""||tran.PaymentTxNumber==""||tran.FinancialOrg==""{return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "参数为空",Payload:              nil,}}//创建组合键tranKey,err:=stub.CreateCompositeKey(TransactionKeyPrefix,[]string{tran.Id})if err != nil {return shim.Error("create error ")}// 从账本中获取数据tranByte,err:=stub.GetState(tranKey)if err != nil {return shim.Error("get state error ")}//	反序列化var tran1 Transactionif err:=json.Unmarshal(tranByte,&tran1);err!=nil{return shim.Error("unmarshal error")}//	验证是否拥有权限if tran1.FinancialOrg!=tran.FinancialOrg{return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "无权限修改此订单",Payload:              nil,}}// 判断订单状态if tran1.Status!=TxStatusPayForAnother{return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "订单状态出错",Payload:              nil,}}//执行转账res:=transferAccounts(stub,tran1.FinancialOrg,companyArg["financial_org"],tran1.Supplier,companyArg["supplier"],tran1.Value)if res.Status!=shim.OK{return peer.Response{Status:               res.Status,Message:              res.Message,Payload:              nil,}}//	修改订单信息tran1.Status=TxStatusPaytran1.PaymentTxNumber=tran.PaymentTxNumbertran1.PaymentDate=tran.PaymentDate//	序列化存入账本tranByteNew,err:=json.Marshal(tran1)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 18:00@Desc:   供应商核实付款 *@Param:  {id:string, supplier:string}@Return:
**/
func affirmPay(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,[]string{args[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 Transactionif 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!=TxStatusPay{return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "订单状态出错",Payload:              nil,}}//	修改订单信息tran.Status=TxStatusPayed//	序列化存入账本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(tranByte)
}/**@Author: dd@Date:   2020/5/15 17:55@Desc:   拒绝付款要求  *@Param:  {id:string,description:string,financial_org:string}@Return:
**/
func refusePayTransaction(stub shim.ChaincodeStubInterface, args []string) peer.Response {if len(args)!=3{return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "参数长度错误",Payload:              nil,}}if args[0]==""||args[1]==""||args[2]==""{return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "参数为空",Payload:              nil,}}//创建组合键tranKey,err:=stub.CreateCompositeKey(TransactionKeyPrefix,[]string{args[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 Transactionif err:=json.Unmarshal(tranByte,&tran);err!=nil{return shim.Error("unmarshal error")}//	验证是否拥有权限if tran.FinancialOrg!=args[2]{return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "无权限修改此订单",Payload:              nil,}}// 判断订单状态if tran.Status!=TxStatusPayForAnother||tran.Status!=TxStatusRefusePay{return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "订单状态出错",Payload:              nil,}}//	修改订单信息tran.Status=TxStatusRefusePaytran.Description=args[1]//	序列化存入账本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:54@Desc:   供应商发货  *@Param:  {id:string,shipment_number:string,supplier:string}@Return:
**/
func updateShipmentInfo(stub shim.ChaincodeStubInterface, args []string) peer.Response {if len(args)!=3{return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "参数长度错误",Payload:              nil,}}if args[0]==""||args[1]==""||args[2]==""{return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "参数为空",Payload:              nil,}}//创建组合键tranKey,err:=stub.CreateCompositeKey(TransactionKeyPrefix,[]string{args[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 Transactionif err:=json.Unmarshal(tranByte,&tran);err!=nil{return shim.Error("unmarshal error")}//	验证是否拥有权限if tran.Supplier!=args[2]{return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "无权限修改此订单",Payload:              nil,}}// 判断订单状态if tran.Status!=TxStatusPayed{return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "订单状态出错",Payload:              nil,}}//	修改订单信息tran.Status=TxStatusShiptran.ShipmentNumber=args[1]//	序列化存入账本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:53@Desc:   买方收货  *@Param:  {id:string,company:string}@Return:
**/
func verifyShipmentInfo(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,[]string{args[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 Transactionif err:=json.Unmarshal(tranByte,&tran);err!=nil{return shim.Error("unmarshal error")}//	验证是否拥有权限if tran.Company!=args[1]{return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "无权限修改此订单",Payload:              nil,}}// 判断订单状态if tran.Status!=TxStatusShip{return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "订单状态出错",Payload:              nil,}}//	修改订单信息tran.Status=TxstatusShiped//	序列化存入账本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:50@Desc:   买方还款  *@Param:  {id:string,repayment_tx_number:string,tx_to_update:time.Time,company:string}@Return:
**/
func repayTransaction(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 Transactionif err:=json.Unmarshal([]byte(args[0]),&tran);err!=nil{return shim.Error("unmarshal error")}//	验证必要参数if tran.Id==""||tran.RepaymentTxNumber==""||tran.Company==""{return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "参数为空",Payload:              nil,}}//创建组合键tranKey,err:=stub.CreateCompositeKey(TransactionKeyPrefix,[]string{tran.Id})if err != nil {return shim.Error("create error ")}// 从账本中获取数据tranByte,err:=stub.GetState(tranKey)if err != nil {return shim.Error("get state error ")}//	反序列化var tran1 Transactionif err:=json.Unmarshal(tranByte,&tran1);err!=nil{return shim.Error("unmarshal error")}//	验证是否拥有权限if tran1.Company!=tran.Company{return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "无权限修改此订单",Payload:              nil,}}// 判断订单状态if tran1.Status!=TxstatusShiped{return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "订单状态出错",Payload:              nil,}}//执行转账res:=transferAccounts(stub,tran1.Company,companyArg["buyer"],tran1.FinancialOrg,companyArg["financial_org"],tran1.Value)if res.Status!=shim.OK{return peer.Response{Status:               res.Status,Message:              res.Message,Payload:              nil,}}//	修改订单信息tran1.Status=TxStatusRepaytran1.RepaymentTxNumber=tran.RepaymentTxNumbertran1.RepayDate=tran.RepayDate//	序列化存入账本tranByteNew,err:=json.Marshal(tran1)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:48@Desc:   金融机构确认还款  *@Param:  {id:string,financial_org:string}@Return:
**/
func verifyRepay(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,[]string{args[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 Transactionif err:=json.Unmarshal(tranByte,&tran);err!=nil{return shim.Error("unmarshal error")}//	验证是否拥有权限if tran.FinancialOrg!=args[1]{return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "无权限修改此订单",Payload:              nil,}}// 判断订单状态if tran.Status!=TxStatusRepay{return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "订单状态出错",Payload:              nil,}}//	修改订单信息tran.Status=TxStatusRepayed//	序列化存入账本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:48@Desc:   自动还款 *@Param:  { time:string }@Return:
**/
func autoRepay(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,}}nowTime,err:=time.Parse("2006-01-02 13:04:05",args[0])if err != nil {return shim.Error("time parse error")}
//	获取所有订单//	查询所有订单res:=getTransactions(stub,[]string{})if res.Status!=shim.OK{return peer.Response{Status:               res.Status,Message:              res.Message,Payload:              nil,}}// 反序列化var trans []Transactionif err:=json.Unmarshal(res.Payload,&trans);err!=nil{return shim.Error("unmarshal error ")}
//	遍历数组for i:=0;i<len(trans);i++{//判断是否超时if trans[i].RepaymentDate.Unix()<nowTime.Unix(){//执行转账res:=transferAccounts(stub,trans[i].Company,companyArg["buyer"],trans[i].FinancialOrg,companyArg["financial_org"],trans[i].Value)if res.Status!=shim.OK{return peer.Response{Status:               res.Status,Message:              res.Message,Payload:              nil,}}//修改订单状态trans[i].Status=TxStatusRepayed//创建组合键tranKey,err:=stub.CreateCompositeKey(TransactionKeyPrefix,[]string{trans[i].Id})if err != nil {return shim.Error("create key error ")}//序列化存入账本tranByte,err:=json.Marshal(trans[i])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(nil)
}/**@Author: dd@Date:   2020/5/14 17:40@Desc:   验证公司是否存在 *@Param:  companyType:string, name:string@Return: bool,存在返回true,不存在返回false
**/
func valideCompany(stub shim.ChaincodeStubInterface, companyType, name string) bool {// 验证参数if companyType==""||name==""{return false}if companyType!=companyArg["financial_org"]||companyType!=companyArg["supplier"]||companyType!=companyArg["buyer"]{return false}
//	创建组合键compKey,err:=stub.CreateCompositeKey(companyType,[]string{name})if err != nil {return false}
//	从账本中获取数据compByte,err:=stub.GetState(compKey)if err != nil {return false}if len(compByte)==0{return false}return true
}/**@Author: dd@Date:   2020/5/14 17:41@Desc:   转账 从out转到in  *@Param:@Return:
**/
func transferAccounts(stub shim.ChaincodeStubInterface, out, outType, in, inType string, number uint64) peer.Response {if out==""||outType==""||in==""||inType==""||number<=0{return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "参数为空",Payload:              nil,}}if out!=companyArg["financial_org"]||out!=companyArg["supplier"]||out!=companyArg["buyer"]||in!=companyArg["financial_org"]||in!=companyArg["supplier"]||in!=companyArg["buyer"]{return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "没有此企业类型",Payload:              nil,}}
//  验证企业是否存在if !valideCompany(stub,outType,out){return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "未找到此企业",Payload:              nil,}}if !valideCompany(stub,inType,in){return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "未找到此企业",Payload:              nil,}}
//	 创建组合键outKey,err:=stub.CreateCompositeKey(outType,[]string{out})if err != nil {return shim.Error("create key error ")}
//	从账本中获取数据outByte,err:=json.Marshal(outKey)if err != nil {return shim.Error("marshal error ")}
//	反序列化var outcomp Companyif err:=json.Unmarshal(outByte,&outcomp);err!=nil{return shim.Error("unmarshal error ")}//	 创建组合键inKey,err:=stub.CreateCompositeKey(inType,[]string{in})if err != nil {return shim.Error("create key error ")}
//	从账本中获取数据inByte,err:=json.Marshal(inKey)if err != nil {return shim.Error("marshal error ")}
//	反序列化var incomp Companyif err:=json.Unmarshal(inByte,&incomp);err!=nil{return shim.Error("unmarshal error ")}
//	判断余额if outcomp.Balance<number{return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "余额不足",Payload:              nil,}}outcomp.Balance-=numberincomp.Balance+=number
//	序列化存入账本outByteNew,err:=json.Marshal(outcomp)if err != nil {return shim.Error("marshal error ")}if err:=stub.PutState(outKey,outByteNew);err!=nil{return shim.Error("put state error ")}//	序列化存入账本inByteNew,err:=json.Marshal(incomp)if err != nil {return shim.Error("marshal error ")}if err:=stub.PutState(inKey,inByteNew);err!=nil{return shim.Error("put state error ")}return shim.Success(nil)
}/**@Author: dd@Date:   2020/5/15 17:45@Desc:   根据企业类型获取企业信息 *@Param:  companyType:string 企业类型@Return: companys:[]Company
**/
func getCompany(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,}}if args[0]!=companyArg["financial_org"]||args[0]!=companyArg["supplier"]||args[0]!=companyArg["buyer"]{return peer.Response{Status:               shim.ERRORTHRESHOLD,Message:              "没有此企业类型",Payload:              nil,}}
// 根据前缀从账本中获取数据result,err:=stub.GetStateByPartialCompositeKey(args[0],[]string{})if err != nil {return shim.Error("GetStateByPartialCompositeKey error ")}var comps []Company
//	最后关闭结果集defer result.Close()
// 遍历结果集for result.HasNext(){val,err:=result.Next()if err != nil {return shim.Error("next error ")}//	反序列化var comp Companyif err:=json.Unmarshal(val.GetValue(),&comp);err!=nil{return shim.Error("unmarshal error")}//	追加至数组comps= append(comps, comp)}compsByte,err:=json.Marshal(comps)if err != nil {return shim.Error("marshal error ")}return shim.Success(compsByte)
}/**@Author: dd@Date:   2020/5/15 17:37@Desc:   获取买方的交易信息 *@Param:  buyer 买方公司名@Return: {transactions:[]Transaction,unfinished:int,total:int,violateTreaty:int}分别为此买方的交易信息、未完成交易数、交易总数、违约交易数(实际还款时间RepayDate大于应还款时间RepaymentDate)z
**/
func getTrByBuyer(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,}}
//	查询所有订单res:=getTransactions(stub,[]string{})if res.Status!=shim.OK{return peer.Response{Status:               res.Status,Message:              res.Message,Payload:              nil,}}
// 反序列化var trans []Transactionif err:=json.Unmarshal(res.Payload,&trans);err!=nil{return shim.Error("unmarshal error ")}var unfinished,total,violateTreaty intvar transactions []Transaction//	遍历数组for i:=0;i<len(trans);i++{// 寻找买家订单if trans[i].Company==args[0]{transactions= append(transactions, trans[i])total++if trans[i].Status!=TxStatusRepayed{unfinished++}if trans[i].RepaymentDate.Unix()<trans[i].RepayDate.Unix(){violateTreaty++}}}buyertrans:=make(map[string]interface{})buyertrans["transactions"]=transactionsbuyertrans["unfinished"]=unfinishedbuyertrans["total"]=totalbuyertrans["violateTreaty"]=violateTreaty
//	序列化buyertransByte,err:=json.Marshal(buyertrans)if err != nil {return shim.Error("marshal error ")}return shim.Success(buyertransByte)
}/**@Author: dd@Date:   2020/5/15 18:04@Desc:   获取交易信息  根据Id查询交易,不传数组则查询所有@Param:  [id0,id1] []string@Return: transactions []Transaction
**/
func getTransactions(stub shim.ChaincodeStubInterface, args []string) peer.Response {// 检查参数的个数if len(args) > 1 {return shim.Error("invalid args.")}// 所有要查询的key,如果为空则查询所有var keys []string// 验证参数的正确性if len(args) == 1 {// 将第一个参数取出来反序列化为[]stringvar argKeys []stringif err := json.Unmarshal([]byte(args[0]), &argKeys); err != nil {return shim.Error(fmt.Sprintf("unmarshal error: %s", err))}keys = append(keys, argKeys...)}var transactions []Transactionif len(keys) == 0 {// 传入的keys长度为0,则查找并返回所有数据// 通过主键从区块链查找相关的数据resultIterator, err := stub.GetStateByPartialCompositeKey(TransactionKeyPrefix, keys)if err != nil {return shim.Error(fmt.Sprintf("query transactions error: %s", err))}defer resultIterator.Close()// 检查返回的数据是否为空,不为空则遍历数据,否则返回空数组for resultIterator.HasNext() {val, err := resultIterator.Next()if err != nil {return shim.Error(fmt.Sprintf("resultIterator error: %s", err))}var transaction Transactionif err := json.Unmarshal(val.GetValue(), &transaction); err != nil {return shim.Error(fmt.Sprintf("unmarshal error: %s", err))}transactions = append(transactions, transaction)}} else {// 传入的keys长度不为0,查找相应的数据并返回for _, v := range keys {// 创建组合键key, err := stub.CreateCompositeKey(TransactionKeyPrefix, []string{v})if err != nil {return shim.Error(fmt.Sprintf("CreateCompositeKey error: %s", err))}// 从账本中获取数据partBytes, err := stub.GetState(key)if err != nil {return shim.Error(fmt.Sprintf("GetState error: %s", err))}if len(partBytes) != 0 {// 反序列化数据var transaction Transactionerr = json.Unmarshal(partBytes, &transaction)if err != nil {return shim.Error(fmt.Sprintf("Unmarshal error: %s", err))}// 追加进结果数组transactions = append(transactions, transaction)}}}//序列化数据result, err := json.Marshal(transactions)if err != nil {return shim.Error(fmt.Sprintf("marshal error: %s", err))}return shim.Success(result)
}/**@Author: dd@Date:   2020/5/15 18:07@Desc:   查询此交易的历史信息@Param:  id:string@Return:
**/
func getTransactionHistory(stub shim.ChaincodeStubInterface, args []string) peer.Response {// 检查参数的个数if len(args) != 1 {return shim.Error("只需要一个参数:订单id")}// 创建组合键compositeKey, err := stub.CreateCompositeKey(TransactionKeyPrefix, args)if err != nil {return shim.Error(fmt.Sprintf("CreateCompositeKey error: %s", err))}// 获取该key的历史,返回一个迭代器resultIterator, err := stub.GetHistoryForKey(compositeKey)if err != nil {return shim.Error(fmt.Sprintf("GetHistoryForKey error: %s", err))}defer resultIterator.Close()// buffer是一个包含了订单历史记录的JSON数组var buffer bytes.Bufferbuffer.WriteString("[")bArrayMemberAlreadyWritten := false// 遍历迭代器,将值取出来for resultIterator.HasNext() {response, err := resultIterator.Next()if err != nil {return shim.Error(err.Error())}// 在数组元素前加",",第一个元素前不加if bArrayMemberAlreadyWritten == true {buffer.WriteString(",")}buffer.WriteString("{\"TxId\":")buffer.WriteString("\"")buffer.WriteString(response.TxId)buffer.WriteString("\"")buffer.WriteString(", \"Value\":")// 如果该记录的操作是删除,则返回null,否则返回数据的值if response.IsDelete {buffer.WriteString("null")} else {buffer.WriteString(string(response.Value))}buffer.WriteString(", \"Timestamp\":")buffer.WriteString("\"")buffer.WriteString(time.Unix(response.Timestamp.Seconds, int64(response.Timestamp.Nanos)).String())buffer.WriteString("\"")buffer.WriteString(", \"IsDelete\":")buffer.WriteString("\"")buffer.WriteString(strconv.FormatBool(response.IsDelete))buffer.WriteString("\"")buffer.WriteString("}")bArrayMemberAlreadyWritten = true}buffer.WriteString("]")fmt.Printf("getHistoryForPatent returning:\n%s\n", buffer.String())// 返回结果return shim.Success(buffer.Bytes())
}func main() {err := shim.Start(new(SupplyChainFinance))if err != nil {fmt.Printf("Error starting chaincode: %s", err)}
}

一、判断参数的个数

在链码交互时,我们传入的参数都是字符串数组。那么我们需要判断其传入参数个数是否正确。如果错误了,我们需要手动抛出错误信息

二、判断参数是否为空

我们需要对传入的一些参数进行非空判断,如果该参数为空,则手动抛出错误信息。

三、明确组合键

对于如何创建组合键,已结构体的那个字段来创建组合键,我们需要判断一下,用哪个字段创建
组合键比较好一点,根据方法的相关参数。

四、判断参数的正确性

在一些情况下,我们不光要判断参数是否为空,还需要判断参数的正确性,比如说,时间,还有金额之类的。

五、判断公司是否存在

在一些特定情况下我们需要判断公司是否存在如果不存在则手动抛错。

六、判断是否有权限修改订单

对于修改订单我们需要判断它是否拥有权限来修改此订单,如果不能则手动抛错。

七、判断订单状态是否正确

在修改订单状态的时候我们需要判断订单的状态是否正确、防止跳过系统流程的某一步骤。

八、修改订单信息

参数及权限还有订单状态校验完成后,我们便可以修改订单信息。

九、序列化

我们需要明确序列化哪个?千万不要序列化错了。

十、存入账本

修改完订单一定要存入账本,千万不要存错了。

这篇关于链码编写规范的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/583191

相关文章

利用Python编写一个简单的聊天机器人

《利用Python编写一个简单的聊天机器人》这篇文章主要为大家详细介绍了如何利用Python编写一个简单的聊天机器人,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 使用 python 编写一个简单的聊天机器人可以从最基础的逻辑开始,然后逐步加入更复杂的功能。这里我们将先实现一个简单的

使用PyQt5编写一个简单的取色器

《使用PyQt5编写一个简单的取色器》:本文主要介绍PyQt5搭建的一个取色器,一共写了两款应用,一款使用快捷键捕获鼠标附近图像的RGB和16进制颜色编码,一款跟随鼠标刷新图像的RGB和16... 目录取色器1取色器2PyQt5搭建的一个取色器,一共写了两款应用,一款使用快捷键捕获鼠标附近图像的RGB和16

使用Java编写一个文件批量重命名工具

《使用Java编写一个文件批量重命名工具》这篇文章主要为大家详细介绍了如何使用Java编写一个文件批量重命名工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录背景处理1. 文件夹检查与遍历2. 批量重命名3. 输出配置代码片段完整代码背景在开发移动应用时,UI设计通常会提供不

MySQL高性能优化规范

前言:      笔者最近上班途中突然想丰富下自己的数据库优化技能。于是在查阅了多篇文章后,总结出了这篇! 数据库命令规范 所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用mysql保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名识意,并且最后不要超过32个字符 临时库表必须以tmp_为前缀并以日期为后缀,备份

如何编写Linux PCIe设备驱动器 之二

如何编写Linux PCIe设备驱动器 之二 功能(capability)集功能(capability)APIs通过pci_bus_read_config完成功能存取功能APIs参数pos常量值PCI功能结构 PCI功能IDMSI功能电源功率管理功能 功能(capability)集 功能(capability)APIs int pcie_capability_read_wo

JavaEE7 Servlet 3.1(JSR 340)规范中文版

http://www.iteye.com/news/27727-jinnianshilongnian     Jave EE 7中的部分规范已正式获得批准通过,其中包括JSR340 Java Servlet 3.1规范,去年翻译了该规范,在此分享出来,希望对某些朋友有所帮助,不足之处请指正。   点击直接下载    在线版目录   Servlet3.1规范翻译

Wondows dos下怎么编写bat批处理文件

最近搞php,在运行时,以Nginx+php-cgi.exe方式运行Wordpress项目 打开dos,先cd到php-cgi.exe文件当前目录下执行启动命令:php-cgi.exe -b 127.0.0.1:9001再打开一个dos,再cd到nginx.exe文件当前目录下执行启动命令:start nginx 大概过程要经过这些步骤,觉得很麻烦,就学下怎么编写一个bat文件,以双击运行代替

用Python编写倒计时程序:详细教程

目录 引言 环境准备 基本概念 代码实现 步骤一:导入必要的库 步骤二:获取用户输入 步骤三:实现倒计时逻辑 步骤四:整合代码 运行程序 高级功能 扩展功能示例:支持分钟和小时输入 扩展功能示例:图形用户界面 (GUI) 总结 引言 倒计时程序是一个非常常见的小工具,广泛用于各种应用场景中,例如考试时间提醒、烹饪计时器、会议倒计时等。Python 作为一种

三维布尔运算对不规范几何数据的兼容处理

1.前言 上一篇文章谈过八叉树布尔运算,对于规范几何数据的情况是没有问题的。 在实际情况中,由于几何数据来源不一,处理和生成方式不一,我们无法保证进行布尔运算的几何数据都是规范的,对于不规范情况有时候也有需求,这就需要兼容不规范数据情况,当然这种兼容不是一味的让步,而是对于存在有限的不规范数据的兼容处理。 2.原始数据示例 下图是一个大坝模型和之上要对其进行布尔运算的立方体。 大坝模型由