链码编写规范

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,
		<

以上是关于链码编写规范的主要内容,如果未能解决你的问题,请参考以下文章

区块链100例 编写脚本快速搭建超级账本 Fabric

第一个智能合约开发(开发ing)

快速了解链码是什么?

Fabric1.4:链码管理与测试

Fabric1.4:Go 链码开发与编写

深度探索区块链/超级账本的应用开发模型(10)