add gxh chaincode2.0

parent 08a90301
package main
import (
"bytes"
"crypto/x509"
"encoding/json"
"reflect"
"sync"
"time"
//"encoding/json"
"encoding/pem"
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
pb "github.com/hyperledger/fabric/protos/peer"
"strconv"
)
type GXHCC struct {
}
type AuthGroup struct {
Users map[string]int64 `json:"users"` //用户组权限,默认使用用户组。我们使用形如:“User1”:timestamp. key 表示用户或者角色,value 表示有效时间。我们使用格林威治时间时间戳
Roles map[string]int64 `json:"roles"` //角色组权限,
}
type Auth struct {
Read AuthGroup `json:"read"` // 字段的读权限,“”,不存在权限,
Write AuthGroup `json:"write"`//字段的写权限
}
type LeadgerAuth struct {
Read AuthGroup `json:"read"` // 字段的读权限,“”,不存在权限,
// Write AuthGroup `json:"write"`//字段的写权限 如果是账本数据
Issue AuthGroup `json:"issue"` //账本数据的发行权限
Extract AuthGroup `json:"extrate"`//账本数据的提取权限
Transfer AuthGroup `json:"transfer"` // 账本数据的转账权限,默认是只有账户的所属者
}
type SchemaParameters struct {
Value interface{} `json:"val"`//默认值 这里特别说明一下如果这里是backUp 字段,我们不进行更深一步的校验,包括格式
PAuth Auth `json:"auth"`
FCheck *Checks `json:"fcheck"`
}
type SchemaLeadgerParameters struct {
Value interface{} `json:"val"`//默认值 这里特别说明一下如果这里是backUp 字段,我们不进行更深一步的校验,包括格式
PAuth LeadgerAuth `json:"auth"`
FCheck *Checks `json:"fcheck"`
}
type Checks struct {
FType string `json:"ftype"` //字段类型
Must bool `json:"must"` //是否必填
Fieldlen int `json:"fieldlen"` //字段长度(如果字段类型是string,表示字段长度,如果是数值类型用0,1表示数据正负)
}
type Schema struct {
//Fields map[string]SchemaParameters `json:"fields"`
LeadgerFields map[string]SchemaLeadgerParameters `json:"leadger_fields"` //账本字段
StorageFields map[string]SchemaParameters `json:"storage_fields"` //存证字段
SchemaAuth Auth `json:"schema_auth"`//schema 的写权限,主要是用在 schema update 部分
SAuth Auth `json:"auth"`
}
type Action struct {
AccountType string `json:"account_type"`//账户类型
AccountId string `json:"account_id"` //账户Id
ActionAmount float64 `json:"action_amount"`//这次的动作金额
FundType string `json:"fund_type"` //资金类型
BackUp interface{} `json:"back_up"`//备注信息
}
type TransferAccount struct {
AccountType string `json:"account_type"`//账户类型
AccountId string `json:"account_id"` //账户Id
FundType string `json:"fund_type"` //资金类型
}
type Node struct {
Key string
Value []byte
pre *Node
next *Node
}
type LRUCache struct {
limit int
HashMap map[string]*Node
head *Node
end *Node
}
type Merchantsale struct {
Mid string `json:"mid"` //商户Id
Bid string `json:"bid"` // 分支机构id,也是一笔交易的接受者
Tamount float64 `json:"tamount"` //交易金额
Treposit float64 `json:"treposit"` //扣除预付金
Bereposit float64 `json:"bereposit"` //扣除前预付金
Afreposit float64 `json:"afreposit"` //扣除后预付金
Feerate float64 `json:"feerate"` // 手续费扣率
Fee float64 `json:"fee"` // 手续费
Oamount float64 `json:"oamount"` // 原始交易金额
Adiscounts float64 `json:"adiscounts"` //代理结算折扣
Sdiscounts float64 `json:"sdiscounts"` //消费折扣
Nodisamount float64 `json:"nodisamount"` //不打折金额
Disamount float64 `json:"disamount"` //打折金额
Perquisites float64 `json:"perquisites"` //额外收益
}
type Merchant struct {
Id string `json:"id"`
}
type CommonTx struct {
SenderAccountType string `json:"sender_account"`
SenderId string `json:"sender_id"`
SenderFunt string `json:"sender_funt"`
ReceiverAccountType string `json:"receiver_account"`
ReceiverId string `json:"receiver_account_id"`
ReceiverFunt string `json:"receiver_funt"`
Amount float64 `json:"amount"`
}
type transferTypes func(args []string, stub shim.ChaincodeStubInterface)error // 声明了一个函数类型
var (
defValue = "***" //查询用户权限不足的情况下默认返回值
PREFIX = "GXH"
StoragePrefix = "SGXH"
LeadgerPrefix = "LGXH"
IsUsers = true //是否启用用户权限,false 表示启用Roles
GxhSchema = "gxhSchema" //schema 存储前缀,为了实现复合主键使用。
InitSchemaLength = 12 //初始化时schema 的长度
schemaCache = Constructor(InitSchemaLength)
once = sync.Once{}
transferType = initTransfer()
)
// Init does nothing for this cc
func (t *GXHCC) Init(stub shim.ChaincodeStubInterface) pb.Response {
return shim.Success([]byte("GXHCC init successful! "))
}
/*
初始化我们要使用的交易类型
*/
func initTransfer()map[string]transferTypes{
transferType := make(map[string]transferTypes)
transferType["merchants"] = merchantsale
transferType["tickerorders"] = tickerorders
transferType["commontx"] = normalTransfer
return transferType
}
func initSchema(stub shim.ChaincodeStubInterface)error{
var errinfo error
once.Do(func(){
schemaIterator,err := stub.GetStateByPartialCompositeKey(GxhSchema,nil)
if err != nil {
errinfo = err
return
}
defer schemaIterator.Close()
index := 1
for schemaIterator.HasNext(){
querykv,err := schemaIterator.Next()
if err != nil {
errinfo = err
return
}
fmt.Println("add cache key:",querykv.Key)
_,compisiteKeys ,err := stub.SplitCompositeKey(querykv.Key)
if err!=nil{
errinfo = err
return
}
schemaCache.Put(compisiteKeys[0],querykv.Value)
fmt.Println("add cache key:",querykv.Key)
index++
if index > InitSchemaLength {
fmt.Println("cache data length :",len(schemaCache.HashMap))
return
}
}
fmt.Println("cache data length :",len(schemaCache.HashMap))
return
})
if errinfo != nil{
return errinfo
}
return nil
}
// Invoke for this chaincode exposes
func (t *GXHCC) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
// get arguments and transient
functionName, args := stub.GetFunctionAndParameters()
err := initSchema(stub)
if err !=nil{
return shim.Error(err.Error())
}
switch functionName {
case "authority":
case "schema":
res,err := SchemaProcess(args,stub)
if err!=nil{
return shim.Error(fmt.Sprintf("SchemaProcess function err: %s", err))
}
return shim.Success([]byte(res))
case "putData":
res,err := putData(args,stub)
if err!=nil{
return shim.Error(fmt.Sprintf("putData function err: %s", err))
}
return shim.Success([]byte(res))
case "get":
res,err := get(args,stub)
if err!=nil{
return shim.Error(fmt.Sprintf("get function err: %s", err))
}
return shim.Success([]byte(res))
case "upStoreData": //
res,err := updateStoreData(args,stub)
if err!=nil{
return shim.Error(fmt.Sprintf("upStoreData function err: %s", err))
}
return shim.Success([]byte(res))
case "createAccount":
res,err := createAccount(args,stub)
if err!=nil{
return shim.Error(fmt.Sprintf("createAccount function err: %s", err))
}
return shim.Success([]byte(res))
case "createTx":
res,err := transactionProcess(args,stub)
if err!=nil{
return shim.Error(fmt.Sprintf("transactionProcess function err: %s", err))
}
return shim.Success([]byte(res))
case "getCertCommonName":
name,err := getCertificateCommonName(stub)
if err != nil{
return shim.Error(fmt.Sprintf("get certificate CommonName fail,err: %s",err))
}
return shim.Success([]byte("current user certificate commonname :" +name))
default:
return shim.Error(fmt.Sprintf("Unsupported function %s", functionName))
}
return shim.Success([]byte("GXHCC invoke successful "))
}
/*
根据账户类型创建账本账户,由于我们这里有存储数据与账本数据两种,所以我们还需要在schema 部分标识不同的数据类型。
伪代码:
1:检查当前用户是否具有账户的总写(创建)权限
2:检查账户必备的属性,如Id,账户名,账户所属者,对应的是证书commonName
2:根据schema 标注的金额(账本)字段,和存证字段,分别进行数据的putState存储工作。其中在存证数据的Id 字段是标示字段。
3:完成账户创建工作
*/
func createAccount(args []string, stub shim.ChaincodeStubInterface) (string, error){
if len(args) < 2 {
return "", fmt.Errorf("put data operation expected more than 2 parameters! ")
}
var PutDatas []map[string]interface{}
commonName, err := getCertificateCommonName(stub)
if err != nil {
return "", fmt.Errorf("getCertificateCommonName happen err: %s ", err)
}
schema := &Schema{}
err = schema.get(args[0], stub)
if err != nil {
return "", err
}
if ok,err := authorityCheck(schema.SAuth.Write, commonName);!ok {
return "", fmt.Errorf("write %s table fail,err: %s ", args[0],err)
}
if err := json.Unmarshal([]byte(args[1]), &PutDatas); err != nil {
return "", fmt.Errorf("%s table parameters Unmarshal fail,put string not json array, err:%s",args[0], err)
}
for k, mapres := range PutDatas {
Id, ok := mapres["id"]
if !ok {
return "", fmt.Errorf("The id field must exist ")
}
_, ok = mapres["common_name"]
if !ok {
return "", fmt.Errorf("The common_name field must exist ")
}
err = SchemaCheck(schema, mapres)
if err != nil {
return "", fmt.Errorf("args index %d string, %s schema cheack fail,err : %s ", k, args[0],err)
}
if err := FiledsCheck(schema,mapres);err !=nil{
return "",err
}
storagemap,leadgermap := separateFields(schema,mapres,[]string{"id","common_name"})
storageDate, _ := json.Marshal(storagemap)
leadgerDate, _ := json.Marshal(leadgermap)
key := StoragePrefix+"_"+args[0]+"_"+Id.(string)
getResult,err := stub.GetState(key)
if err != nil {
return "", fmt.Errorf("GetState %s data fail,please check your parameters ",key)
}
if getResult != nil{
return "", fmt.Errorf("%s data already exists and cannot be added",key)
}
if err := stub.PutState(key, storageDate); err != nil {
return "", fmt.Errorf("PutState fail, err :%s", err)
}
if err := stub.PutState(LeadgerPrefix+"_"+args[0]+"_"+Id.(string), leadgerDate); err != nil {
return "", fmt.Errorf("PutState fail, err :%s", err)
}
}
return fmt.Sprintf("create %s account success!", args[0]), nil
}
/*
修改一个账户的存储数据,修改规则由Schema 控制,有些特殊数据在账本数据也使用,所以无法修改
*/
func updateStoreData(args []string, stub shim.ChaincodeStubInterface) (string, error) {
if len(args) != 2 {
return "", fmt.Errorf("update data operation expected 2 parameters! ")
}
commonName, err := getCertificateCommonName(stub)
if err != nil {
return "", fmt.Errorf("getCertificateCommonName happen err: %s ", err)
}
schema := &Schema{}
err = schema.get(args[0], stub)
if err != nil {
return "", err
}
var Updata map[string]interface{}
if err := json.Unmarshal([]byte(args[1]), &Updata); err != nil {
return "", fmt.Errorf("%s table parameters Unmarshal fail,err: %s",args[0], err)
}
Id, ok := Updata["id"]
if !ok {
return "", fmt.Errorf("The id field must exist ")
}
_, ok = Updata["common_name"]
if ok {
return "", fmt.Errorf("The common_name field cannot update ")
}
if ok ,_ := authorityCheck(schema.SAuth.Write, commonName);!ok {
if ok, err := parsauthorityCheck(schema.StorageFields, Updata, commonName); !ok {
return "", fmt.Errorf("authority Check err: %s", err)
}
}
if err := FiledsCheck(schema,Updata);err !=nil{
return "",err
}
key := StoragePrefix+"_"+args[0]+"_"+Id.(string)
allMap,err := getState(key,stub)
if err != nil {
return "", err
}
if err := Deassign(Updata, allMap); err != nil {
return "", err
}
err = putState(key,allMap,stub)
if err != nil {
return "", err
}
return fmt.Sprintf("%s update data success!", args[0]), nil
}
/*
存储数据,某些不产生账本数据的数据使用这个接口来存储。例如码数据,进件表数据
允许覆盖
*/
func putData(args []string, stub shim.ChaincodeStubInterface) (string, error) {
if len(args) < 2 {
return "", fmt.Errorf("put data operation expected more than 2 parameters! ")
}
var PutDatas []map[string]interface{}
commonName, err := getCertificateCommonName(stub)
if err != nil {
return "", fmt.Errorf("getCertificateCommonName happen err: %s ", err)
}
schema := &Schema{}
err = schema.get(args[0], stub)
if err != nil {
return "", err
}
if ok,err := authorityCheck(schema.SAuth.Write, commonName);!ok {
return "", fmt.Errorf("write %s table fail,err: %s ", args[0],err)
}
if err := json.Unmarshal([]byte(args[1]), &PutDatas); err != nil {
return "", fmt.Errorf("%s table parameters Unmarshal fail,put string not json array, err:%s",args[0], err)
}
for k, mapres := range PutDatas {
Id, ok := mapres["id"]
if !ok {
return "", fmt.Errorf("The id field must exist ")
}
if len(schema.LeadgerFields)!= 0{
return "", fmt.Errorf("%s schema exist leadger fields,cannot putData", args[0])
}
err = SchemaCheck(schema, mapres)
if err != nil {
return "", fmt.Errorf("args index %d string, %s schema cheack fail,err : %s ", k, args[0],err)
}
if err := FiledsCheck(schema,mapres);err !=nil{
return "",err
}
key := StoragePrefix+"_"+args[0]+"_"+Id.(string)
err = putState(key,mapres,stub)
if err != nil {
return "", err
}
}
return fmt.Sprintf("%s put data success!", args[0]), nil
}
/*
查询数据,如果存在账本数据,与存证数据,则进行数据拼接,然后返回。
*/
func get(args []string, stub shim.ChaincodeStubInterface) (string, error) {
if len(args) != 2 {
return "", fmt.Errorf("get data operation expected 2 parameters to function get!")
}
commonName, err := getCertificateCommonName(stub)
if err != nil {
return "", fmt.Errorf("getCertificateCommonName happen err: %s ", err)
}
var parameters map[string]interface{}
json.Unmarshal([]byte(args[1]), &parameters)
if err != nil {
return "", fmt.Errorf("parameters Unmarshal fail,err: %s", err)
}
Id, ok := parameters["id"]
if !ok {
return "", fmt.Errorf("The id field must exist ")
}
storageKey := StoragePrefix+"_"+args[0]+"_"+Id.(string)
mapResult, err := getState(storageKey,stub)
if err != nil {
return "", err
}
leadgerKey := LeadgerPrefix+"_"+args[0]+"_"+Id.(string)
leadgerResult, err := stub.GetState(leadgerKey)
if err != nil {
return "", fmt.Errorf("get %s data fail,please check your parameters ",leadgerKey)
}
schema := &Schema{}
err = schema.get(args[0], stub)
if err != nil {
return "", err
}
if leadgerResult != nil {
if err := json.Unmarshal(leadgerResult, &mapResult); err != nil {
return "", fmt.Errorf("The leadger original data Unmarshal fail err:%s ", err)
}
}
if ok,_:= authorityCheck(schema.SAuth.Read, commonName);!ok {
if filteredData, err := dataFilter(schema, mapResult, commonName); err != nil {
return "", fmt.Errorf("get data authority filter fail, err: %s", err)
} else {
result, _ := json.Marshal(filteredData)
return string(result), nil
}
} else {
result, _ := json.Marshal(mapResult)
return string(result), nil
}
}
func SchemaCheck(schema *Schema, checkmap map[string]interface{}) error {
if len(schema.StorageFields)+len(schema.LeadgerFields) != len(checkmap) {
return fmt.Errorf("The input field length is less than the schema field length ! ")
}
for k, v := range schema.StorageFields {
if schemaV, ok := checkmap[k]; !ok {
return fmt.Errorf("There is no input storage field %s ",k)
} else {
if parameterS, ok := v.Value.(map[string]interface{}); ok {
if parameterC, ok := schemaV.(map[string]interface{}); !ok {
return fmt.Errorf("The input field %s does not match the output field format ",k)
}else{
err := BackUpCheck(parameterS,parameterC)
if err != nil{
return err
}
}
}
}
}
for k, _ := range schema.LeadgerFields {
if _, ok := checkmap[k]; !ok {
return fmt.Errorf("There is no input leadger field %s ",k)
}
}
return nil
}
func FiledsCheck(schema *Schema, checkmap map[string]interface{}) error{
for k, schemaV := range schema.StorageFields {
if k != "backup" && schemaV.FCheck!= nil && schemaV.FCheck.FType != "" && checkmap[k] != nil{
if err := fieldCheckout(schemaV.FCheck,checkmap[k]);err!=nil{
return fmt.Errorf("%s %s ",k,err)
}
}
}
for k, schemaV := range schema.LeadgerFields {
if schemaV.FCheck!= nil && schemaV.FCheck.FType != "" && checkmap[k] != nil{
if err := fieldCheckout(schemaV.FCheck,checkmap[k]);err!=nil{
return fmt.Errorf("%s %s ",k,err)
}
}
}
return nil
}
func BackUpCheck(backUp map[string]interface{}, checkmap map[string]interface{}) error {
if len(backUp) != len(checkmap) {
return fmt.Errorf("The input backup field length is less than the schema backup field length ! ")
}
for k, _ := range checkmap {
if _, ok := backUp[k]; !ok {
return fmt.Errorf("There is no input backup field %s ",k)
}
}
return nil
}
/*
将字段根据账本数据,与存储数据分开
leadgers:参数表示我们需要在账本数据包含的字段,这些字段不属于账本数据。
*/
func separateFields(schema *Schema,checkmap map[string]interface{},leadgers []string)(storagemap ,leadgermap map[string]interface{}){
storagemap = make(map[string]interface{})
leadgermap = make(map[string]interface{})
for k,_ :=range schema.LeadgerFields{
leadgermap[k] = checkmap[k]
}
for _,v :=range leadgers{
leadgermap[v] = checkmap[v]
}
for k,_ :=range schema.StorageFields{
storagemap[k] = checkmap[k]
}
return
}
/*
根据权限拼装数据,进行数据过滤
*/
func dataFilter(schema *Schema, checkmap map[string]interface{}, commonName string) (map[string]interface{}, error) {
for k, schemaV := range schema.StorageFields {
if v, ok := checkmap[k]; !ok {
return nil, fmt.Errorf("Update data parameter mismatch with schema structure! ")
} else {
if _, ok := schemaV.Value.(map[string]SchemaParameters); ok {
if _, ok := v.(map[string]interface{}); !ok {
return nil, fmt.Errorf("Update data parameter mismatch with schema structure! ")
}
if ok,_ := authorityCheck(schemaV.PAuth.Read, commonName);!ok {
checkmap[k] = defValue
}
} else {
if ok,_ := authorityCheck(schemaV.PAuth.Read, commonName);!ok {
checkmap[k] = defValue
}
}
}
}
for k, schemaV := range schema.LeadgerFields {
if v, ok := checkmap[k]; !ok {
return nil, fmt.Errorf("Update data parameter mismatch with schema structure! ")
} else {
if _, ok := schemaV.Value.(map[string]SchemaLeadgerParameters); ok {
if _, ok := v.(map[string]interface{}); !ok {
return nil, fmt.Errorf("Update data parameter mismatch with schema structure! ")
}
if ok,_ := authorityCheck(schemaV.PAuth.Read, commonName);!ok {
checkmap[k] = defValue
}
} else {
if ok,_ := authorityCheck(schemaV.PAuth.Read, commonName);!ok {
checkmap[k] = defValue
}
}
}
}
return checkmap, nil
}
func SchemaProcess(args []string, stub shim.ChaincodeStubInterface) (string, error) {
if len(args) < 2 {
return "", fmt.Errorf("Expect features with 2 or more parameters to play! ")
}
schema := &Schema{}
switch args[0] {
case "put":
return schema.put(args[1:], stub)
case "update":
return schema.update(args[1:], stub)
case "get":
return schema.getSchema(args[1], stub)
default:
return "", fmt.Errorf(fmt.Sprintf("Unsupported schema function of %s", args[0]))
}
return "", nil
}
func transactionProcess(args []string, stub shim.ChaincodeStubInterface) (string, error) {
if len(args) < 2 {
return "", fmt.Errorf("Expect features with 2 or more parameters to play! ")
}
switch args[0] {
case "issue": //进行账户金额发行(无中生有)
return funtOperation(args[1:],stub,true)
case "extract": //提取账户金额(直接减去)
return funtOperation(args[1:],stub,false)
case "transfer": // 一笔普通转账
return transferTx(args[1:],stub)
default:
return "", fmt.Errorf(fmt.Sprintf("Unsupported schema function of %s", args[0]))
}
return "", nil
}
/*
put
args 字段说明:
1:args[0]代表我们具体操作的表,
2:args[1:]后面的数据表示要记录到数据库的数据,每一个string 必须是json字符串,并且需要每一个json 字符串都必须包含id 字段
我们可以发现json字符串都被我们解析成了map[string]interface{}类型的map,其中key代表表模板的字段,interface可以是一个结构,我们当前将他看做我们表模板字段的初始值。
伪代码:
1:在创建schema data 时,我们必须检查金额字段的类型必须是float64,并且不能为负数。
*/
func (this *Schema) put(args []string, stub shim.ChaincodeStubInterface) (string, error) {
if len(args) != 2 {
return "", fmt.Errorf("Schema put operation expected 2 parameters!")
}
var schema *Schema
var err error
if schema ,err = NewSchema(args[1]);err != nil{
return "", fmt.Errorf("The parameters Unmarshal to a Schema structural fail,err: %s ", err)
}else{
if backupValue, ok := schema.StorageFields["backup"]; ok {
if _,ok := backupValue.Value.(map[string]interface{}); !ok {
return "", fmt.Errorf("backup parameters Unmarshal fail,it not json string,err: %s", err)
}
}
}
_, ok := schema.StorageFields["id"]
if !ok {
return "", fmt.Errorf("The id field must exist ")
}
_, ok = schema.StorageFields["common_name"]
if !ok {
return "", fmt.Errorf("The common_name field must exist ")
}
CompositeKey,err := stub.CreateCompositeKey(GxhSchema,[]string{args[0]})
if err != nil{
return "", fmt.Errorf("the schema %s create comosite key fail,err : %s", args[0],err)
}
if schemaCache.Get(args[0]) != nil {
fmt.Println("schemaCache.Get err")
return "", fmt.Errorf("the schema %s already exists and cannot be added", args[0])
}else if value, _ := stub.GetState(CompositeKey); value != nil {
fmt.Println("GetState.Get err")
return "", fmt.Errorf("the schema %s already exists and cannot be added", args[0])
}
putDate, _ := json.Marshal(schema) //处理重复字段
if err := stub.PutState(CompositeKey, putDate); err != nil {
return "", fmt.Errorf("Schema PutState fail,err: %s ", err)
}
schemaCache.Put(args[0],putDate)
return fmt.Sprintf("%s schema put success!", args[0]), nil
}
/*
if update Schema 那么我们没有办法比较旧有的一个模板,
Schema 的 update,不支持部分修改,因为存在增加和删除某些字段的情况。
初版暂时只允许修改存储数据,金额字段暂时不允许修改
*/
func (this *Schema) update(args []string, stub shim.ChaincodeStubInterface) (string, error) {
if len(args) != 2 {
return "", fmt.Errorf("Schema update operation expected 2 parameters! ")
}
var schema *Schema
var schemaOld *Schema
var err error
if schema ,err = NewSchema(args[1]);err != nil{
return "", fmt.Errorf("The parameters Unmarshal to a Schema structural fail,err: %s ", err)
}else{
if backupValue, ok := schema.StorageFields["backup"]; ok {
if _,ok := backupValue.Value.(map[string]interface{}); !ok {
return "", fmt.Errorf("backup parameters Unmarshal fail,it not json string,err: %s", err)
}
}
}
_, ok := schema.StorageFields["id"]
if !ok {
return "", fmt.Errorf("The id field must exist ")
}
_, ok = schema.StorageFields["common_name"]
if !ok {
return "", fmt.Errorf("The common_name field must exist ")
}
CompositeKey,err := stub.CreateCompositeKey(GxhSchema,[]string{args[0]})
if err != nil{
return "", fmt.Errorf("the schema %s create comosite key fail,err : %s", args[0],err)
}
var result []byte
if result = schemaCache.Get(args[0]);result == nil{
fmt.Println("schemaCache.Get nil")
result, err := stub.GetState(CompositeKey)
if err != nil || result == nil {
return "", fmt.Errorf("%s schema data doesn't exist,please check your parameters ",args[0])
}
}
if err := json.Unmarshal(result, &schemaOld); err != nil {
return "", fmt.Errorf("The parameters Unmarshal to a Schema structural fail, err: %s ", err)
}
commonName, err := getCertificateCommonName(stub)
if err != nil {
return "", fmt.Errorf("getCertificateCommonName happen err: %s ", err)
}
if ok,err := authorityCheck(schemaOld.SchemaAuth.Write,commonName);!ok{
return "", fmt.Errorf("update %s schema fail,err: %s ",args[0],err)
}
schema.LeadgerFields = schemaOld.LeadgerFields
updateData,_ := json.Marshal(schema)
if err = stub.PutState(CompositeKey, updateData);err != nil{
return "", fmt.Errorf("%s schema data PutState fail,please try again ",args[0])
}
schemaCache.Put(args[0],updateData)
return fmt.Sprintf("%s schema update success!", args[0]), err
}
func (this *Schema) get(args string, stub shim.ChaincodeStubInterface) error {
var result []byte
if result = schemaCache.Get(args);result == nil{
CompositeKey,err := stub.CreateCompositeKey(GxhSchema,[]string{args})
if err != nil{
return fmt.Errorf("the schema %s create comosite key fail,err : %s", args,err)
}
result, err = stub.GetState(CompositeKey)
if err != nil || result == nil {
return fmt.Errorf("%s schema data doesn't exist,please check your parameters ",args)
}
schemaCache.Put(args,result)
}
return json.Unmarshal(result,this)
}
func (this *Schema) getSchema(args string, stub shim.ChaincodeStubInterface)(string, error) {
var result []byte
if result = schemaCache.Get(args);result == nil{
CompositeKey,err := stub.CreateCompositeKey(GxhSchema,[]string{args})
if err != nil{
return "", fmt.Errorf("the schema %s create comosite key fail,err : %s", args,err)
}
result, err = stub.GetState(CompositeKey)
if err != nil || result == nil {
return "", fmt.Errorf("%s schema data doesn't exist,please check your parameters ",args)
}
schemaCache.Put(args,result)
}
if err := json.Unmarshal(result, this); err != nil {
return "", fmt.Errorf("SchemaData Unmarshal fail, err: %s", err)
}
commonName, err := getCertificateCommonName(stub)
if err != nil {
return "", fmt.Errorf("getCertificateCommonName happen err: %s ", err)
}
if ok,err := authorityCheck(this.SchemaAuth.Read,commonName);!ok{
return "",fmt.Errorf("get %s schema fail,err: %s", args,err)
}
return string(result), nil
}
func transferTx(args []string, stub shim.ChaincodeStubInterface)(string, error) {
txFunc := transferType[args[0]]
if txFunc == nil{
return "", fmt.Errorf("No matching transfer operation method was found ! ")
}
err := txFunc(args[1:],stub)
if err != nil {
return "", fmt.Errorf("%s transfer operation fail,err:%s ",args[0],err)
}
return "", nil
}
func authorityCheck(authority AuthGroup, commonName string) (bool,error) {
var auths map[string]int64
if IsUsers {
auths = authority.Users
}else{
auths = authority.Roles
}
if len(auths) == 0 {
return true,nil
}
for k, v := range auths {
if k == commonName {
if v == 0 || v > time.Now().Unix(){
return true,nil
}else{
return false,fmt.Errorf("%s user permission period ",commonName)
}
}
}
return false,fmt.Errorf("%s user does not have permission",commonName)
}
/*
检查一组参数的权限是否匹配
*/
func parsauthorityCheck(schema map[string]SchemaParameters, checkmap map[string]interface{}, commonName string) (bool, error) {
for k, v := range checkmap {
if schemaV, ok := schema[k]; !ok {
return false, fmt.Errorf("Update data parameter mismatch with schema structure! ")
} else {
if _, ok := schemaV.Value.(map[string]interface{}); ok {
if _, ok := v.(map[string]interface{}); !ok {
return false, fmt.Errorf("Update data parameter mismatch with schema structure! ")
}
}
if ok,err := authorityCheck(schemaV.PAuth.Write, commonName);!ok {
return false, fmt.Errorf("%s field permission check does not match, err: %s ", k,err)
}
}
}
return true, nil
}
/*
重新赋值,并检查相应的格式是否正确
*/
func Deassign(upMap, result map[string]interface{}) error {
if len(upMap) > len(result) {
return fmt.Errorf("Deassign fail,reassigned data length greater than the original data length! ")
}
for k, v := range upMap {
if resultV, ok := result[k]; ok {
if resultMap, resultok := resultV.(map[string]interface{}); resultok {
if vMap, ok := v.(map[string]interface{}); !ok {
return fmt.Errorf("Deassign fail, format doesn't match! ")
} else {
Deassign(vMap, resultMap)
}
} else {
result[k] = v
}
} else {
return fmt.Errorf("Deassign fail %s key nonentity ", k)
}
}
return nil
}
/*
账户金额发现,核心是在对应的schema 找到有发行的权利。
1:金额字段也就是(账本字段数据)都有发行标示
2:发行交易可以存在多个字段,但只要保证我们要求的字段存在就可以。账户类型,Id,发行金额(大于0)
*/
func funtOperation(args []string, stub shim.ChaincodeStubInterface,isIssue bool) (string, error){
if len(args) != 1 {
return "", fmt.Errorf("issue or extract operation expected 1 parameters ! ")
}
commonName, err := getCertificateCommonName(stub)
if err != nil {
return "", fmt.Errorf("getCertificateCommonName happen err: %s ", err)
}
action := &Action{}
err = json.Unmarshal([]byte(args[0]),action)
if err != nil{
return "", fmt.Errorf("json unmarshal Action structure fail,err: %s",err)
}
schema := &Schema{}
err = schema.get(action.AccountType, stub)
if err != nil {
return "", err
}
if isIssue{
if ok,err := authorityCheck(schema.LeadgerFields[action.FundType].PAuth.Issue, commonName);!ok {
return "", fmt.Errorf("%s field issue permission check does not match, err: %s ", action.FundType , err)
}
}else {
if ok,err := authorityCheck(schema.LeadgerFields[action.FundType].PAuth.Extract, commonName);!ok {
return "", fmt.Errorf("%s field extract permission check does not match, err: %s ", action.FundType , err)
}
}
leadgerKey := LeadgerPrefix+"_"+action.AccountType+"_"+action.AccountId
leadgerResult, err := stub.GetState(leadgerKey)
if err != nil {
return "", fmt.Errorf("GetState %s data fail,err %s ",leadgerKey,err)
}
if leadgerResult == nil {
return "", fmt.Errorf("GetState %s data is null,please check your parameters ",leadgerKey)
}
var leadgermap map[string]interface{}
err = json.Unmarshal(leadgerResult,&leadgermap)
if err != nil{
return "", fmt.Errorf("json unmarshal leadger map fail,err: %s",err)
}
funt := leadgermap[action.FundType].(float64)
amount := Decimal(action.ActionAmount)
if isIssue {
funt += amount
}else{
if funt < amount{
return "", fmt.Errorf("The current amount is less than the withdrawal amount and cannot be extracted ")
}
funt-= amount
}
leadgermap[action.FundType] = funt
leadgerResult,_ = json.Marshal(leadgermap)
err = stub.PutState(leadgerKey,leadgerResult)
if err!=nil{
return "", fmt.Errorf("putState %s data fail,err: %s",leadgerKey,err)
}
return "transaction successful!", nil
}
/*
*/
func normalTransfer(args []string, stub shim.ChaincodeStubInterface)error{
if len(args) != 1 {
return nil
}
tx := &CommonTx{}
err := json.Unmarshal([]byte(args[0]),tx)
if err!= nil{
fmt.Errorf("CommonTx structure json unmarshal fail,err : %s ",err)
}
sender := &TransferAccount{
tx.SenderAccountType,
tx.SenderId,
tx.SenderFunt,
}
receiver := &TransferAccount{
tx.ReceiverAccountType,
tx.ReceiverId,
tx.ReceiverFunt,
}
commonName ,err := getCertificateCommonName(stub)
if err!= nil {
return nil
}
return transfer(Decimal(tx.Amount),sender,receiver,commonName,stub)
}
/*
当增加一条交易记录的时候,我们需要根据交易记录实现,1.预付金的计算,2.计算分成,3.预付金的变化。分成的计算
*/
func merchantsale(args []string, stub shim.ChaincodeStubInterface)error{
commanName,err := getCertificateCommonName(stub)
if err!=nil{
return err
}
senderaccountType := "merchants"
receiverAccountType := "alibusi"
mer := &Merchantsale{}
err = json.Unmarshal([]byte(args[0]),mer)
if err != nil {
return fmt.Errorf("Merchantsale struct json unmarshal fail,err : %s ",err)
}
//1.计算预付金 这部分待定1698.83
var treposit float64
if mer.Nodisamount == 0 || mer.Disamount == 0{ //如果打折金额与不打折金额任一为0,则认为全部打折
treposit = Decimal(mer.Oamount * mer.Adiscounts)
}else{
treposit = Decimal(mer.Nodisamount+ mer.Disamount * mer.Adiscounts)
}
if treposit != mer.Treposit {
return fmt.Errorf("treposit calculation fail ")
}
if mer.Fee != Decimal(mer.Tamount * mer.Feerate){
return fmt.Errorf("fee calculation fail ")
}
profit := mer.Tamount - mer.Fee - treposit //计算利润
if profit < 0 {
return fmt.Errorf("profit is negative ")
}
sender := &TransferAccount{
senderaccountType,
mer.Mid,
"regular",
}
receiver := &TransferAccount{
receiverAccountType,
mer.Bid,
"abail",
}
err = transfer(treposit,sender,receiver,commanName,stub)
if err!=nil{
return nil
}
//进行分成数据
return nil
}
/*
共享惠订单交易
*/
func tickerorders(args []string, stub shim.ChaincodeStubInterface)error{
/*
由于共享惠还没有进行确定的订单交易所以这部分先进行伪代码的记录
1:计算实际支付是否正确,
2:计算手续费总和是否正确
3:计算利润
4:是否需要进行商户金额的清分(待定)
5:合作方分成
6:最终分成
*/
return nil
}
/*
实现普通的转账操作
*/
func transfer(amount float64,sender ,receiver *TransferAccount,commonName string,stub shim.ChaincodeStubInterface)error{
if amount <= 0 {
return fmt.Errorf("transfer limit must greater than 0 ")
}
senderSchema := &Schema{}
err := senderSchema.get(sender.AccountType, stub)
if err != nil {
return err
}
if ok,err := authorityCheck(senderSchema.LeadgerFields[sender.FundType].PAuth.Transfer, commonName);!ok {
return fmt.Errorf("%s field issue permission check does not match, err: %s ", sender.FundType , err)
}
senderKey := LeadgerPrefix+"_"+sender.AccountType+"_"+sender.AccountId
senderleadgermap,err := getState(senderKey,stub)
if err != nil{
return err
}
funt := senderleadgermap[sender.FundType].(float64)
if funt < amount{
return fmt.Errorf("The current amount is less than the withdrawal amount and cannot be extracted ")
}
funt-= amount
senderleadgermap[sender.FundType] = funt
err = putState(senderKey,senderleadgermap,stub)
if err != nil{
return err
}
receiverKey := LeadgerPrefix+"_"+receiver.AccountType+"_"+receiver.AccountId
receiverleadgermap,err := getState(receiverKey,stub)
if err != nil{
return err
}
rfunt := receiverleadgermap[receiver.FundType].(float64)
rfunt+= amount
receiverleadgermap[receiver.FundType] = rfunt
err = putState(receiverKey,receiverleadgermap,stub)
if err != nil{
return err
}
return nil
}
func getState(key string,stub shim.ChaincodeStubInterface)(map[string]interface{},error){
var resultmap map[string]interface{}
result, err := stub.GetState(key)
if err != nil {
return nil, fmt.Errorf("GetState %s data fail,err %s ",key,err)
}
if result == nil {
return nil,fmt.Errorf("GetState %s data is null,please check your parameters ",key)
}
err = json.Unmarshal(result,&resultmap)
if err != nil{
return nil,fmt.Errorf("json unmarshal leadger map fail,err: %s",err)
}
return resultmap,nil
}
func putState(key string,value map[string]interface{},stub shim.ChaincodeStubInterface)error{
valueByte,err := json.Marshal(value)
if err != nil{
return fmt.Errorf(" %s json marshal data fail,err: %s",key,err)
}
err = stub.PutState(key,valueByte)
if err!=nil{
return fmt.Errorf("putState %s data fail,err: %s",key,err)
}
return nil
}
func unmarshalMap(arg string)(error,map[string]interface{}){
var valueMap map[string]interface{}
err := json.Unmarshal([]byte(arg),&valueMap)
if err != nil{
return err,nil
}
return nil,valueMap
}
func getCertificateCommonName(stub shim.ChaincodeStubInterface) (string, error) {
return "Admin@org2.example.com", nil
creatorByte, _ := stub.GetCreator()
certStart := bytes.IndexAny(creatorByte, "-----BEGIN")
if certStart == -1 {
return "", fmt.Errorf("No certificate found ")
}
certText := creatorByte[certStart:]
bl, _ := pem.Decode(certText)
if bl == nil {
return "", fmt.Errorf("Could not decode the PEM structure ")
}
cert, err := x509.ParseCertificate(bl.Bytes)
if err != nil {
return "", fmt.Errorf("ParseCertificate failed")
}
return cert.Subject.CommonName, nil
}
func Decimal(value float64) float64 {
value, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", value), 64)
return value
}
func NewSchema(arg string)(*Schema,error){
schema := &Schema{
LeadgerFields:make(map[string]SchemaLeadgerParameters),
StorageFields:make(map[string]SchemaParameters),
}
var argMap map[string]interface{}
if err := json.Unmarshal([]byte(arg),&argMap);err!=nil{
return nil,err
}
if (argMap["storage_fields"] != nil || argMap["leadger_fields"] != nil)&& argMap["schema_auth"] != nil && argMap["auth"] != nil{
if err := json.Unmarshal([]byte(arg),schema);err!=nil{
return nil,err
}
//检查schema leadger字段
err := leadgerFieldsCheck(&schema.LeadgerFields)
if err!=nil{
return nil,err
}
return schema,nil
}
for k,v := range argMap{ //假设用户只传递了map类型的信息,我们则默认它全部都是存储字段
schema.StorageFields[k] = SchemaParameters{
Value:v,
PAuth:Auth{},
}
}
return schema,nil
}
func leadgerFieldsCheck(leadgerFields *map[string]SchemaLeadgerParameters)error{
for k,fields := range *leadgerFields{
if fields.FCheck == nil {
fields.FCheck = &Checks{
FType:"float64",
Must:false,
Fieldlen:1,
}
}else{
if fields.FCheck.FType != "float64"{
return fmt.Errorf("%s fields type must is float64",k)
}else if !(fields.FCheck.Fieldlen > 0) {
return fmt.Errorf("%s fields length must is greater than zero",k)
}
}
}
return nil
}
func fieldCheckout(check *Checks,val interface{})error{
fType := reflect.TypeOf(val).String()
switch check.FType {
case "string":
if fType != "string"{
return fmt.Errorf("fields type does not match the defined string type! ")
}
if check.Must && (val == ""){
return fmt.Errorf("fields can not be empty")
}
value := val.(string)
if len([]rune(value))>check.Fieldlen{
return fmt.Errorf("fields length cannot be greater than %d ",check.Fieldlen)
}
case "int","int16","int32","int64","float32","float64":
if fType != "float64"{
return fmt.Errorf("fields type does not match the defined %s type! ",check.FType )
}
value := val.(float64)
if check.Must && (value == 0){
return fmt.Errorf("fields can not be 0")
}
if check.Fieldlen !=0 && value < 0{
return fmt.Errorf("fields cannot be negative")
}
case "time.Time":
if fType != "string"{
return fmt.Errorf("fields type does not match the defined time.Time type! ")
}
dateStr := reflect.ValueOf(val).String()
if check.Must && dateStr == ""{
return fmt.Errorf("fields cannot be empty")
}
if _ ,err := time.Parse("2006-01-02 15:04:05",dateStr);err != nil{
return fmt.Errorf(err.Error())
}
//if check.Must && (dateStr == "0001-01-01 00:00:00 +0000 UTC"|| dateStr == "0001-01-01T00:00:00Z"){
// return fmt.Errorf("fields cannot be initial value")
//}
default:
fmt.Errorf("fields type no match! ")
}
return nil
}
func Constructor(capacity int) LRUCache{
lruCache := LRUCache{limit:capacity}
lruCache.HashMap = make(map[string]*Node, capacity)
return lruCache
}
func (l *LRUCache) Get(key string) []byte {
if v,ok:= l.HashMap[key];ok {
l.refreshNode(v)
return v.Value
}else {
return nil
}
}
func (l *LRUCache) Put(key string, value []byte) {
if v,ok := l.HashMap[key];!ok{
if len(l.HashMap) >= l.limit{
oldKey := l.removeNode(l.head)
delete(l.HashMap, oldKey)
}
node := Node{Key:key, Value:value}
l.addNode(&node)
l.HashMap[key] = &node
}else {
v.Value = value
l.refreshNode(v)
}
}
func (l *LRUCache) refreshNode(node *Node){
if node == l.end {
return
}
l.removeNode(node)
l.addNode(node)
}
func (l *LRUCache) removeNode(node *Node) string{
if node == l.end {
l.end = l.end.pre
l.end.next = nil
}else if node == l.head {
l.head = l.head.next
l.head.pre = nil
}else {
node.pre.next = node.next
node.next.pre = node.pre
}
return node.Key
}
func (l *LRUCache) addNode(node *Node){
if l.end != nil {
l.end.next = node
node.pre = l.end
node.next = nil
}
l.end = node
if l.head == nil {
l.head = node
}
}
func main() {
err := shim.Start(&GXHCC{})
if err != nil {
fmt.Printf("Error starting EncCC chaincode: %s", err)
}
}
package main
import (
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
"testing"
)
var (
SchemaNew = `{"leadger_fields":{"abail":{"val":"0001-01-01T00:00:00Z","auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":1584936259}},"issue":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},
"extrate":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"transfer":{"users":null,"roles":null}},
"fcheck":{"ftype":"float64","must":false,"fieldlen":1}},"sabail":{"val":"0001-01-01T00:00:00Z","auth":{"read":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"issue":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":1584936259}},"extrate":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},
"transfer":{"users":null,"roles":null}},"fcheck":null}},"storage_fields":{"common_name":{"val":"1","auth":{"read":{"users":null,"roles":null},
"write":{"users":null,"roles":null}},"fcheck":null},"alinkman":{"val":10.34,"auth":{"read":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"write":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":1584936259}}},"fcheck":{"ftype":"float64","must":true,"fieldlen":1}},"amob":{"val":"0001-01-01T00:00:00Z",
"auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"write":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}}},"fcheck":{"ftype":"time.Time","must":true,"fieldlen":0}},
"aname":{"val":"Aname","auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"write":
{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}}},"fcheck":{"ftype":"string","must":true,"fieldlen":16}},
"atype":{"val":100,"auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"write":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}}},"fcheck":{"ftype":"int","must":true,"fieldlen":1}},"backup":
{"val":{"aname":"Aname","atype":"Atype"},"auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},
"write":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}}},"fcheck":null},"id":{"val":"1","auth":{"read":
{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":null}},"schema_auth":{"read":{"users":null,"roles":null},
"write":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":0}}},"auth":{"read":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":0}},"write":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":0}}}}`
merSchema = `{"leadger_fields":{"regular":{"val":6000,"auth":{"read":{"users":null,"roles":null},"issue":{"users":null,"roles":null},"extrate":{"users":null,"roles":null},"transfer":{"users":null,
"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"rregular":{"val":6000,"auth":{"read":{"users":null,"roles":null},"issue":{"users":null,"roles":null},"extrate":{"users":null,"roles"
:null},"transfer":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}}},"storage_fields":{"common_name":{"val":"1","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":null},
"acid":{"val":3,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles"
:null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"actionid":{"val":1,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,
"fieldlen":6}},"adiscounts":{"val":"0.8","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"aid":{"val":0,"auth":{"read":
{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"are":{"val":1,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":
null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"backup":{"val":{},"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":null},"cid":{"val":0,"auth":{"read":
{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"cosperson":{"val":100,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,
"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"did":{"val":2,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,
"fieldlen":6}},"dineraprice":{"val":80,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"dinerprice":{"val":100,"auth":
{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"dinersprice":{"val":90,"auth":{"read":{"users":null,"roles":null},"write":
{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"distype":{"val":16,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":
"float64","must":false,"fieldlen":6}},"esign":{"val":"2010-12-31 15:38:54","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}}
,"fid":{"val":4,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"firrenew":{"val":"2010-01-02 15:38:54","auth":{"read":
{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"haver":{"val":1,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"id":{"val":"1","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":false,"fieldlen":6}},"indate":{"val":"2018/10/29 16:46:57","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"ischain":{"val":1,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"isset":{"val":1,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"issnp":{"val":1,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"keywords":{"val":"test","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"licence":{"val":"103451015521","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"linedate":{"val":"2010-01-02 15:38:54","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"mact":{"val":"123456","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"mactname":{"val":"联系人1","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"maddr":{"val":"测试地址1","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"marea":{"val":1,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"mbtype":{"val":1,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"mdiposit":{"val":"中国银行","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"mlinkman":{"val":"联系人1","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"mlinkmob":{"val":"18555555555","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"mname":{"val":"测试连锁店1","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"mno":{"val":"59118600000005","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"mno2":{"val":"05910005","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"msubtype":{"val":10,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"mtype":{"val":9,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"murl":{"val":"http://www.baidu.com","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"ordertel":{"val":"13444444444","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"paystatue":{"val":1,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"perquisites":{"val":3,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"persales":{"val":100,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"pname":{"val":"8820180008552970","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"ppass":{"val":"152820","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"relevel":{"val":5,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"retype":{"val":0,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"sdiscounts":{"val":"0.85","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"shophours":{"val":"24小时营业","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"sregular":{"val":6000,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"ssign":{"val":"2010-01-01 15:38:54","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"statue":{"val":0,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"supperaprice":{"val":90,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"supperprice":{"val":120,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"suppersprice":{"val":110,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"tstatue":{"val":1,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"warmline":{"val":"600","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}}},"schema_auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}}}
`
merarrary = `[{
"id": "1",
"mname": "测试连锁店1",
"maddr": "测试地址1",
"mlinkman": "联系人1",
"mlinkmob": "18555555555",
"mtype": 9,
"mact": "123456",
"mdiposit": "中国银行",
"mactname": "联系人1",
"licence": "103451015521",
"murl": "http://www.baidu.com",
"mno": "59118600000005",
"mno2": "05910005",
"indate": "2018/10/29 16:46:57",
"aid": 0,
"regular": 6000,
"adiscounts": 0.8,
"sdiscounts": 0.85,
"distype": 16,
"msubtype": 10,
"ischain": 1,
"cosperson": 100,
"statue": 0,
"retype": 0,
"did": 2,
"warmline": 600,
"cid": 0,
"sregular": 6000,
"keywords": "test",
"paystatue": 1,
"are": 1,
"marea": 1,
"actionid": 1,
"tstatue": 1,
"rregular": 6000,
"ssign": "2010-01-01 15:38:54",
"firrenew": "2010-01-02 15:38:54",
"ordertel": "13444444444",
"shophours": "24小时营业",
"persales": 100,
"linedate": "2010-01-02 15:38:54",
"issnp": 1,
"esign": "2010-12-31 15:38:54",
"fid": 4,
"acid": 3,
"pname": "8820180008552970",
"ppass": "152820",
"isset": 1,
"haver": 1,
"dinerprice": 100,
"dinersprice": 90,
"dineraprice": 80,
"supperprice": 120,
"suppersprice": 110,
"supperaprice": 90,
"common_name":"",
"perquisites": 3,
"relevel": 5,
"mbtype": 1,
"backup": {}
},{
"id": "2",
"mname": "测试连锁店1",
"maddr": "测试地址1",
"mlinkman": "联系人1",
"mlinkmob": "18555555555",
"mtype": 9,
"mact": "123456",
"mdiposit": "中国银行",
"mactname": "联系人1",
"licence": "103451015521",
"murl": "http://www.baidu.com",
"mno": "59118600000005",
"mno2": "05910005",
"indate": "2018/10/29 16:46:57",
"aid": 0,
"regular": 6000,
"adiscounts": 0.8,
"sdiscounts": 0.85,
"distype": 16,
"msubtype": 10,
"ischain": 1,
"cosperson": 100,
"statue": 0,
"retype": 0,
"did": 2,
"warmline": 600,
"cid": 0,
"sregular": 6000,
"keywords": "test",
"paystatue": 1,
"are": 1,
"marea": 1,
"actionid": 1,
"tstatue": 1,
"rregular": 6000,
"ssign": "2010-01-01 15:38:54",
"firrenew": "2010-01-02 15:38:54",
"ordertel": "13444444444",
"shophours": "24小时营业",
"persales": 100,
"linedate": "2010-01-02 15:38:54",
"issnp": 1,
"esign": "2010-12-31 15:38:54",
"fid": 4,
"acid": 3,
"pname": "8820180008552970",
"ppass": "152820",
"isset": 1,
"haver": 1,
"dinerprice": 100,
"dinersprice": 90,
"dineraprice": 80,
"supperprice": 120,
"suppersprice": 110,
"supperaprice": 90,
"common_name":"",
"perquisites": 3,
"relevel": 5,
"mbtype": 1,
"backup": {}
}]`
SchemaPutNew = `{"leadger_fields":{},"storage_fields":{"common_name":{"val":"1","auth":{"read":{"users":null,"roles":null},
"write":{"users":null,"roles":null}},"fcheck":null},"alinkman":{"val":10.34,"auth":{"read":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"write":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":1584936259}}},"fcheck":{"ftype":"float64","must":true,"fieldlen":1}},"amob":{"val":"0001-01-01T00:00:00Z",
"auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"write":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}}},"fcheck":{"ftype":"time.Time","must":true,"fieldlen":0}},
"aname":{"val":"Aname","auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"write":
{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}}},"fcheck":{"ftype":"string","must":true,"fieldlen":16}},
"atype":{"val":100,"auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"write":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}}},"fcheck":{"ftype":"int","must":true,"fieldlen":1}},"backup":
{"val":{"aname":"Aname","atype":"Atype"},"auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},
"write":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}}},"fcheck":null},"id":{"val":"1","auth":{"read":
{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":null}},"schema_auth":{"read":{"users":null,"roles":null},
"write":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":0}}},"auth":{"read":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":0}},"write":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":0}}}}`
SchemaUpdate = `{"leadger_fields":{"abail22":{"val":"0001-01-01T00:00:00Z","auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":1584936259}},"issue":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},
"extrate":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"transfer":{"users":null,"roles":null}},
"fcheck":{"ftype":"float64","must":true,"fieldlen":1}},"sabail":{"val":"0001-01-01T00:00:00Z","auth":{"read":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"issue":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":1584936259}},"extrate":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},
"transfer":{"users":null,"roles":null}},"fcheck":null}},"storage_fields":{"common_name":{"val":"1","auth":{"read":{"users":null,"roles":null},
"write":{"users":null,"roles":null}},"fcheck":null},"alinkmanNew":{"val":10.34,"auth":{"read":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"write":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":1584936259}}},"fcheck":{"ftype":"float64","must":true,"fieldlen":1}},"amob":{"val":"0001-01-01T00:00:00Z",
"auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"write":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}}},"fcheck":{"ftype":"time.Time","must":true,"fieldlen":0}},
"aname":{"val":"Aname","auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"write":
{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}}},"fcheck":{"ftype":"string","must":true,"fieldlen":6}},
"atype":{"val":100,"auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"write":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}}},"fcheck":{"ftype":"int","must":true,"fieldlen":1}},"backup":
{"val":{"aname":"Aname","atype":"Atype"},"auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},
"write":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}}},"fcheck":null},"id":{"val":"1","auth":{"read":
{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":null}},"schema_auth":{"read":{"users":null,"roles":null},
"write":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":0}}},"auth":{"read":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":0}},"write":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":0}}}}`
)
func TestGXHSchemaPut(t *testing.T){
cc := new(GXHCC)
stub := shim.NewMockStub("GXHCC",cc)
stub.MockInit("init",nil)
fmt.Println("========================================invoke schema put============================================")
responseByPutschema := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("put"),[]byte("alibusi"),[]byte(SchemaNew)})
fmt.Printf("Invoke status %d,message %s and payload %s\n",
responseByPutschema.Status,responseByPutschema.Message,string(responseByPutschema.Payload))
fmt.Println()
fmt.Println("========================================invoke schema get============================================")
responseByget := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("get"),[]byte("alibusi")})
fmt.Printf("Invoke status %d,message %s ,and payload %s \n",
responseByget.Status,responseByget.Message,string(responseByget.Payload))
fmt.Println()
fmt.Println("========================================invoke schema update============================================")
responseByupdate := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("update"),[]byte("alibusi"),[]byte(SchemaUpdate)})
fmt.Printf("Invoke status %d,message %s ,and payload %s \n",
responseByupdate.Status,responseByupdate.Message,string(responseByupdate.Payload))
fmt.Println("========================================invoke schema get============================================")
responseByget2 := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("get"),[]byte("alibusi")})
fmt.Printf("Invoke status %d,message %s ,and payload %s \n",
responseByget2.Status,responseByget2.Message,string(responseByget2.Payload))
fmt.Println()
}
func TestGXHCreateAccount(t *testing.T){
cc := new(GXHCC)
stub := shim.NewMockStub("GXHCC",cc)
stub.MockInit("init",nil)
fmt.Println()
fmt.Println("========================================invoke schema put============================================")
fmt.Println()
fmt.Println()
responseByPutschema := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("put"),[]byte("alibusi"),[]byte(SchemaNew)})
fmt.Printf("Invoke status %d,message %s and payload %s\n",
responseByPutschema.Status,responseByPutschema.Message,string(responseByPutschema.Payload))
fmt.Println()
fmt.Println("========================================invoke createAccount============================================")
fmt.Println()
fmt.Println()
responseBycreate := stub.MockInvoke("invoke1",[][]byte{[]byte("createAccount"), []byte("alibusi"),[]byte(inputarrary)})
fmt.Printf("Invoke status %d,message %s ,and payload %s \n",
responseBycreate.Status,responseBycreate.Message,string(responseBycreate.Payload))
fmt.Println()
fmt.Println()
fmt.Println("========================================invoke updateStoreData============================================")
fmt.Println()
fmt.Println()
responseByputData := stub.MockInvoke("invoke1",[][]byte{[]byte("upStoreData"), []byte("alibusi"),[]byte(inputUpdate)})
fmt.Printf("Invoke status %d,message %s ,and payload %s \n",
responseByputData.Status,responseByputData.Message,string(responseByputData.Payload))
fmt.Println()
fmt.Println()
fmt.Println("========================================invoke get============================================")
fmt.Println()
fmt.Println()
responseByget := stub.MockInvoke("invoke1",[][]byte{[]byte("get"), []byte("alibusi"),[]byte(inputUpdate)})
fmt.Printf("Invoke status %d,message %s ,and payload %s \n",
responseByget.Status,responseByget.Message,string(responseByget.Payload))
}
func TestGXHPutData(t *testing.T){
cc := new(GXHCC)
stub := shim.NewMockStub("GXHCC",cc)
stub.MockInit("init",nil)
fmt.Println()
fmt.Println("========================================invoke schema put============================================")
fmt.Println()
fmt.Println()
responseByPutschema := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("put"),[]byte("alibusi"),[]byte(SchemaPutNew)})
fmt.Printf("Invoke status %d,message %s and payload %s\n",
responseByPutschema.Status,responseByPutschema.Message,string(responseByPutschema.Payload))
fmt.Println()
fmt.Println("========================================invoke putData============================================")
fmt.Println()
fmt.Println()
responseByputData := stub.MockInvoke("invoke1",[][]byte{[]byte("putData"), []byte("alibusi"),[]byte(inputPutarray)})
fmt.Printf("Invoke status %d,message %s ,and payload %s \n",
responseByputData.Status,responseByputData.Message,string(responseByputData.Payload))
fmt.Println()
}
var (
issueTx = `{"account_type":"alibusi","account_id":"1","action_amount":1000.123,"fund_type":"abail","back_up":{"account_type":"","account_id":"","action_amount":0,"fund_type":"","back_up":null}}`
extract = `{"account_type":"alibusi","account_id":"1","action_amount":100.123,"fund_type":"abail","back_up":{"account_type":"","account_id":"","action_amount":0,"fund_type":"","back_up":null}}`
commontx = `{"sender_account":"alibusi","sender_id":"1","sender_funt":"abail","receiver_account":"alibusi","receiver_account_id":"2","receiver_funt":"abail","amount":100.123}`
merTx = `{"mid":"1","bid":"1","tamount":1805.01,"treposit":1698.83,"bereposit":6000,"afreposit":4301.17,"feerate":0.0055,"fee":9.93,"oamount":2123.54,"adiscounts":0.8,"sdiscounts":0.85,"nodisamount":0,"disamount":0,"perquisites":0}
`
)
func TestGXHIssueandExtract(t *testing.T){
cc := new(GXHCC)
stub := shim.NewMockStub("GXHCC",cc)
stub.MockInit("init",nil)
fmt.Println()
fmt.Println("========================================invoke schema put============================================")
responseByPutschema := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("put"),[]byte("alibusi"),[]byte(SchemaNew)})
if responseByPutschema.Status != 200{
t.Errorf("schema init fail,err: %s",responseByPutschema.Message)
}
fmt.Println()
responseBycreate := stub.MockInvoke("invoke1",[][]byte{[]byte("createAccount"), []byte("alibusi"),[]byte(inputarrary)})
if responseBycreate.Status != 200{
t.Errorf("createAccount init fail,err: %s",responseBycreate.Message)
}
fmt.Println()
responseByIssue := stub.MockInvoke("invoke1",[][]byte{[]byte("createTx"), []byte("issue"),[]byte(issueTx)})
fmt.Printf("Invoke status %d,message %s ,and payload %s \n",
responseByIssue.Status,responseByIssue.Message,string(responseByIssue.Payload))
fmt.Println()
responseByextract := stub.MockInvoke("invoke1",[][]byte{[]byte("createTx"), []byte("extract"),[]byte(extract)})
fmt.Printf("Invoke status %d,message %s ,and payload %s \n",
responseByextract.Status,responseByextract.Message,string(responseByextract.Payload))
fmt.Println()
fmt.Println()
responseBytx := stub.MockInvoke("invoke1",[][]byte{[]byte("createTx"), []byte("transfer"),[]byte("commontx"),[]byte(commontx)})
fmt.Printf("Invoke status %d,message %s ,and payload %s \n",
responseBytx.Status,responseBytx.Message,string(responseBytx.Payload))
fmt.Println()
responseByget := stub.MockInvoke("invoke1",[][]byte{[]byte("get"), []byte("alibusi"),[]byte(inputUpdate)})
fmt.Printf("Invoke status %d,message %s ,and payload %s \n",
responseByget.Status,responseByget.Message,string(responseByget.Payload))
responseByget2 := stub.MockInvoke("invoke1",[][]byte{[]byte("get"), []byte("alibusi"),[]byte(`{"id":"2"}`)})
fmt.Printf("Invoke status %d,message %s ,and payload %s \n",
responseByget2.Status,responseByget2.Message,string(responseByget2.Payload))
}
/*
测试商户交易
*/
func TestGXHmerTx(t *testing.T){
stub := GXHmerTxinit()
responseByPutschema := stub.MockInvoke("invoke1",[][]byte{[]byte("createTx"), []byte("transfer"),[]byte("merchants"),[]byte(merTx)})
if responseByPutschema.Status != 200{
fmt.Printf("schema init fail,err: %s",responseByPutschema.Message)
}
fmt.Println()
responseByget2 := stub.MockInvoke("invoke1",[][]byte{[]byte("get"), []byte("merchants"),[]byte(`{"id":"1"}`)})
fmt.Printf("Invoke status %d,message %s ,and payload %s \n",
responseByget2.Status,responseByget2.Message,string(responseByget2.Payload))
responseByget := stub.MockInvoke("invoke1",[][]byte{[]byte("get"), []byte("alibusi"),[]byte(`{"id":"1"}`)})
fmt.Printf("Invoke status %d,message %s ,and payload %s \n",
responseByget.Status,responseByget.Message,string(responseByget.Payload))
}
func GXHmerTxinit()*shim.MockStub{
cc := new(GXHCC)
stub := shim.NewMockStub("GXHCC",cc)
stub.MockInit("init",nil)
fmt.Println()
fmt.Println("========================================invoke schema put============================================")
responseByPutschema := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("put"),[]byte("alibusi"),[]byte(SchemaNew)})
if responseByPutschema.Status != 200{
fmt.Printf("schema init fail,err: %s",responseByPutschema.Message)
return stub
}
fmt.Println()
responseBycreate := stub.MockInvoke("invoke1",[][]byte{[]byte("createAccount"), []byte("alibusi"),[]byte(inputarrary)})
if responseBycreate.Status != 200{
fmt.Printf("createAccount init fail,err: %s",responseBycreate.Message)
return stub
}
fmt.Println()
fmt.Println()
fmt.Println("========================================invoke schema put============================================")
responseByMerschema := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("put"),[]byte("merchants"),[]byte(merSchema)})
if responseByMerschema.Status != 200{
fmt.Printf("schema init fail,err: %s",responseByMerschema.Message)
return stub
}
fmt.Println()
responseBycreateMer := stub.MockInvoke("invoke1",[][]byte{[]byte("createAccount"), []byte("merchants"),[]byte(merarrary)})
if responseBycreateMer.Status != 200{
fmt.Printf("createAccount init fail,err: %s",responseBycreateMer.Message)
return stub
}
return stub
}
\ No newline at end of file
package main
import (
"encoding/json"
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
"testing"
)
var schema = `{"fields":{"alinkman":{"val":"Alinkman","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}},"amob":{"val":"Amob","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}},"aname":{"val":"Aname","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}},"atype":{"val":"Atype","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}},"backup":{"val":{"aname":"Aname","atype":"Atype"},"auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":
{"admin":0},"roles":{"admin":1582972202}}}},"id":{"val":"1","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}}},"schema_auth":{"read":{"users":null,"roles":null},"write":{"users":{"admin":0},"roles":{"admin":0}}},"auth":{"read":{"users":
{"admin":0},"roles":{"admin":0}},"write":{"users":{"admin":0},"roles":{"admin":1582972202}}}}
`
var schema2 = `{"fields":{"alinkman":{"val":"Alinkman","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}},"amob":{"val":"Amob","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}},"aname":{"val":"Aname","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}},"atype":{"val":"Atype","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}},"backup":{"val":{"aname":"Aname","atype":"Atype"},"auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":
{"admin":0},"roles":{"admin":1582972202}}}},"id":{"val":"1","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}}},"schema_auth":{"read":{"users":null,"roles":null},"write":{"users":{"admin":0},"roles":{"admin":1582972202}}},"auth":{"read":{"users":
{"admin":0},"roles":{"admin":0}},"write":{"users":{"admin":0},"roles":{"admin":0}}}}
`
var schema3 = `{"fields":{"alinkman":{"val":"Alinkman","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}},"amob":{"val":"Amob","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}},"aname":{"val":"Aname","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}},"atype":{"val":"Atype","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}},"backup":{"val":{"aname":"Aname","atype":"Atype"},"auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":
{"admin":0},"roles":{"admin":1582972202}}}},"id":{"val":"1","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}}},"schema_auth":{"read":{"users":null,"roles":null},"write":{"users":{"admin":0},"roles":{"admin":1582972202}}},"auth":{"read":{"users":
{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":{"admin":0}}}}
`
/*
以下部分是增加权限内容的测试
*/
var (
inputUpdate = `{"id":"1","aname":"alibusi","atype":100,"alinkman":10.34,"amob":"2006-01-02 15:04:05","backup":
{"aname":"alibusi","atype":"type"}}`
inputarrary = `[{"abail":0,"sabail":0,"id":"1","aname":"alibusi","atype":100,"alinkman":10.34,"amob":"2006-01-02 15:04:05","backup":
{"aname":"alibusi","atype":"type"},"common_name":"admin"},{"abail":0,"sabail":0,"id":"2","aname":"alibusi","atype":100,"alinkman":
10.34,"amob":"2006-01-02 15:04:05","backup":{"aname":"alibusi","atype":"type"},"common_name":"admin"}]`
inputPutarray = `[{"id":"1","aname":"alibusi","atype":100,"alinkman":10.34,"amob":"2006-01-02 15:04:05","backup":{"aname":"alibusi",
"atype":"type"},"common_name":"admin"},{"id":"2","aname":"alibusi","atype":100,"alinkman":10.34,"amob":"2006-01-02 15:04:05","backup":
{"aname":"alibusi","atype":"type"},"common_name":"admin"}]`
)
func TestGXHSchemaAuth(t *testing.T){
cc := new(GXHCC)
stub := shim.NewMockStub("GXHCC",cc)
stub.MockInit("init",nil)
fmt.Println()
fmt.Println("========================================invoke schema put============================================")
fmt.Println()
fmt.Println()
responseByPutschema := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("put"),[]byte("alibusi"),[]byte(schema)})
fmt.Printf("Invoke status %d,message %s and payload %s\n",
responseByPutschema.Status,responseByPutschema.Message,string(responseByPutschema.Payload))
fmt.Println()
fmt.Println("========================================invoke schema get============================================")
fmt.Println()
fmt.Println()
responseByget := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("get"),[]byte("alibusi")})
fmt.Printf("Invoke status %d,message %s ,and payload %s \n",
responseByget.Status,responseByget.Message,string(responseByget.Payload))
fmt.Println()
fmt.Println("========================================invoke schema update============================================")
fmt.Println()
fmt.Println()
responseByupdate := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("update"),[]byte("alibusi"),[]byte(schema)})
fmt.Printf("Invoke status %d,message %s ,and payload %s \n",
responseByupdate.Status,responseByupdate.Message,string(responseByupdate.Payload))
}
/*
测试使用table 数据构建 schema
*/
func TestGXHSchemaAuthBytable(t *testing.T){
cc := new(GXHCC)
stub := shim.NewMockStub("GXHCC",cc)
stub.MockInit("init",nil)
fmt.Println()
fmt.Println("========================================invoke schema put============================================")
fmt.Println()
fmt.Println()
responseByPutschema := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("put"),[]byte("alibusi"),[]byte(inputUpdate)})
fmt.Printf("Invoke status %d,message %s and payload %s\n",
responseByPutschema.Status,responseByPutschema.Message,string(responseByPutschema.Payload))
fmt.Println()
fmt.Println("========================================invoke schema get============================================")
fmt.Println()
fmt.Println()
responseByget := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("get"),[]byte("alibusi")})
fmt.Printf("Invoke status %d,message %s ,and payload %s \n",
responseByget.Status,responseByget.Message,string(responseByget.Payload))
fmt.Println()
fmt.Println("========================================invoke schema update============================================")
fmt.Println()
fmt.Println()
responseByupdate := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("update"),[]byte("alibusi"),[]byte(inputUpdate)})
fmt.Printf("Invoke status %d,message %s ,and payload %s \n",
responseByupdate.Status,responseByupdate.Message,string(responseByupdate.Payload))
}
func TestGXHDataPutAuth(t *testing.T){
cc := new(GXHCC)
stub := shim.NewMockStub("GXHCC",cc)
stub.MockInit("init",nil)
fmt.Println()
fmt.Println("========================================invoke schema put============================================")
fmt.Println()
fmt.Println()
responseByPutschema := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("put"),[]byte("alibusi"),[]byte(schema3)})
//使用schema 数据测试过期时间err,schema right data,使用schema3 测试读取字段时的过滤
fmt.Printf("Invoke status %d,message %s and payload %s\n",
responseByPutschema.Status,responseByPutschema.Message,string(responseByPutschema.Payload))
responseByget := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("get"),[]byte("alibusi")})
fmt.Printf("Invoke status %d,message %s ,and payload %s \n",
responseByget.Status,responseByget.Message,string(responseByget.Payload))
fmt.Println()
fmt.Println("========================================invoke data put============================================")
fmt.Println()
fmt.Println()
responseByPut := stub.MockInvoke("invoke1",[][]byte{[]byte("put"), []byte("alibusi"),[]byte(inputarrary)})
fmt.Printf("Invoke status %d,message %s ,and payload %s\n",
responseByPut.Status,responseByPut.Message,string(responseByPut.Payload))
responseByget = stub.MockInvoke("invoke1",[][]byte{[]byte("get"), []byte("alibusi"),[]byte(`{"id":"1"}`)})
fmt.Printf("Invoke status %d,message %s ,and payload %s \n",
responseByget.Status,responseByget.Message,string(responseByget.Payload))
fmt.Println()
fmt.Println("========================================invoke data update============================================")
fmt.Println()
fmt.Println()
responseByUpdate := stub.MockInvoke("invoke1",[][]byte{[]byte("update"), []byte("alibusi"),[]byte(inputUpdate)})
fmt.Printf("Invoke status %d,message %s ,and payload %s\n",
responseByUpdate.Status,responseByUpdate.Message,string(responseByUpdate.Payload))
responseByget2 := stub.MockInvoke("invoke1",[][]byte{[]byte("get"), []byte("alibusi"),[]byte(`{"id":"1"}`)})
fmt.Printf("Invoke status %d,message %s ,and payload %s \n",
responseByget2.Status,responseByget2.Message,string(responseByget2.Payload))
}
var testData = `{"float64":10.33,"int":10,"string":"我中国人a!","time.Time":"2020-03-06 18:30:07.49752435 +0800 CST m=+0.000270574"}`
func TestFieldCheck(t *testing.T){
var testmap map[string]interface{}
json.Unmarshal([]byte(testData),&testmap)
intC := &Checks{
FType:"int",
Must:true,
Fieldlen:1,
}
err := fieldCheckout(intC,testmap["int"])
if err != nil{
t.Error(err)
}
floatC := &Checks{
FType:"float64",
Must:true,
Fieldlen:1,
}
err = fieldCheckout(floatC,testmap["float64"])
if err != nil{
t.Error(err)
}
stringC := &Checks{
FType:"string",
Must:true,
Fieldlen:6,
}
err = fieldCheckout(stringC,testmap["string"])
if err != nil{
t.Error(err)
}
timeC := &Checks{
FType:"time.Time",
Must:true,
Fieldlen:1,
}
err = fieldCheckout(timeC,testmap["time.Time"])
if err != nil{
t.Error(err)
}
}
var schemaCheck = `{"fields":{"alinkman":{"val":10.34,"auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":1583501961}},"write":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":1583501961}}},"fcheck":{"ftype":"float64","must":true,"fieldlen":1}},
"amob":{"val":"0001-01-01T00:00:00Z","auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":1583501961}},"write":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":
1583501961}}},"fcheck":{"ftype":"time.Time","must":true,"fieldlen":0}},"aname":{"val":"Aname","auth":{"read":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1583501961}},"write":{"users":{"Admin@org2.example.com":0},
"roles":{"Admin@org2.example.com":1583501961}}},"fcheck":{"ftype":"string","must":true,"fieldlen":16}},"atype":{"val":100,
"auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1583501961}},"write":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1583501961}}},"fcheck":{"ftype":"int",
"must":true,"fieldlen":1}},"backup":{"val":{"aname":"Aname","atype":"Atype"},"auth":{"read":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1583501961}},"write":{"users":{"Admin@org2.example.com":0},
"roles":{"Admin@org2.example.com":1583501961}}},"fcheck":null},"id":{"val":"1","auth":{"read":{"users":null,"roles":null},
"write":{"users":null,"roles":null}},"fcheck":null}},"schema_auth":{"read":{"users":null,"roles":null},"write":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1583501961}}},"auth":{"read":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":0}},"write":{"users":{"Admin@org2.example.com":0},
"roles":{"Admin@org2.example.com":0}}}}
`
var (
inputC = `{"id":"1","aname":"alibusi","atype":1000,"alinkman":1.233,
"amob":"new1234567890","backup":{"aname":"alibusi","atype":"type"}}`
inputCs = `[{
"id": "1",
"aname": "alibusi",
"atype": 102,
"alinkman": 10.34,
"amob": "0001-01-01 00:00:00 + UTC",
"backup": {
"aname": "alibusi",
"atype": "type"
}
}, {
"id": "2",
"aname": "alibusi",
"atype": 102,
"alinkman": 10.34,
"amob": "0001-01-01 00:00:00 + UTC",
"backup": {
"aname": "alibusi",
"atype": "type"
}
}]`
)
/*
本测试主要进行data put,update的测试操作,主要进行fieldcheck 的测试。
*/
func TestPut(t *testing.T){
cc := new(GXHCC)
stub := shim.NewMockStub("GXHCC",cc)
stub.MockInit("init",nil)
fmt.Println()
fmt.Println("========================================invoke schema put============================================")
fmt.Println()
fmt.Println()
responseByPutschema := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("put"),[]byte("alibusi"),[]byte(inputC)})
//使用schema 数据测试过期时间err,schema right data,使用schema3 测试读取字段时的过滤
fmt.Printf("Invoke status %d,message %s and payload %s\n",
responseByPutschema.Status,responseByPutschema.Message,string(responseByPutschema.Payload))
responseByget := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("get"),[]byte("alibusi")})
fmt.Printf("Invoke status %d,message %s ,and payload %s \n",
responseByget.Status,responseByget.Message,string(responseByget.Payload))
fmt.Println()
fmt.Println("========================================invoke data put============================================")
fmt.Println()
fmt.Println()
responseByPut := stub.MockInvoke("invoke1",[][]byte{[]byte("put"), []byte("alibusi"),[]byte(inputCs)})
fmt.Printf("Invoke status %d,message %s ,and payload %s\n",
responseByPut.Status,responseByPut.Message,string(responseByPut.Payload))
responseByget = stub.MockInvoke("invoke1",[][]byte{[]byte("get"), []byte("alibusi"),[]byte(`{"id":"1"}`)})
fmt.Printf("Invoke status %d,message %s ,and payload %s \n",
responseByget.Status,responseByget.Message,string(responseByget.Payload))
fmt.Println()
fmt.Println("========================================invoke data update============================================")
fmt.Println()
fmt.Println()
responseByUpdate := stub.MockInvoke("invoke1",[][]byte{[]byte("update"), []byte("alibusi"),[]byte(inputC)})
fmt.Printf("Invoke status %d,message %s ,and payload %s\n",
responseByUpdate.Status,responseByUpdate.Message,string(responseByUpdate.Payload))
responseByget2 := stub.MockInvoke("invoke1",[][]byte{[]byte("get"), []byte("alibusi"),[]byte(`{"id":"1"}`)})
fmt.Printf("Invoke status %d,message %s ,and payload %s \n",
responseByget2.Status,responseByget2.Message,string(responseByget2.Payload))
}
package main
import (
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
"testing"
)
func TestInvokeTable(t *testing.T){
cc := new(GXHCC)
stub := shim.NewMockStub("GXHCC",cc)
stub.MockInit("init",nil)
responseByPutschema := stub.MockInvoke("invoke1",[][]byte{[]byte("InvokeTable"), []byte("alibusi"),[]byte(inputC)})
fmt.Printf("Invoke status %d,message %s and payload %s\n",
responseByPutschema.Status,responseByPutschema.Message,string(responseByPutschema.Payload))
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment