4.7 commit

parent 46b87768
......@@ -4,6 +4,8 @@ import (
"encoding/json"
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
"math/big"
"strings"
"testing"
)
......@@ -44,8 +46,8 @@ 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":
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":
......@@ -276,3 +278,45 @@ func TestPut(t *testing.T){
}
func TestDivide(t *testing.T){
testInt := big.NewInt(23456789000000)
i , err := dividecalc(testInt,float64(0.0056))
if err!=nil{
t.Error(err.Error())
}
fmt.Println(i)
}
//经过测试发现使用big.int 比直接使用float64 会有2500多倍的性能损失
func BenchmarkDivide(b *testing.B) {
for i:= 0 ;i < b.N ; i++ {
//testInt := big.NewInt(23456789)
//i := dividecalctest(testInt,float64(0.0056))
//if err!=nil{
// fmt.Println("happen err",err)
// return
//}
}
//for i:= 0 ;i < b.N ; i++ {
// a := float64(23456789)
// _ , err := testfunc(a,float64(0.0056))
// if err!=nil{
// fmt.Println("happen err",err)
// return
// }
// //fmt.Println(c)
//}
}
func testfunc(a,b float64)(float64,error){
str := fmt.Sprintf("%v", b)
strs := strings.Split(str, ".")
if len(strs[1]) > 6 {
return 0, fmt.Errorf("divide can only exist to six decimal places ")
}
//var mul int64
//length := len(strs[1])
// pow(10,int64(length))
return a*b,nil
}
package main
import (
"encoding/json"
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
)
func put(tablename string,PutDatas []map[string]interface{}, stub shim.ChaincodeStubInterface) (string, error) {
commonName, err := getCertificateCommonName(stub)
if err != nil {
return "", fmt.Errorf("getCertificateCommonName happen err: %s ", err)
}
schema := &Schema{}
schema ,err = getSchema(tablename, stub)
if err != nil {
return "", err
}
if err := schema.AllWriteCheck( commonName, ""); err != nil {
return "", fmt.Errorf("write %s table fail,err: %s ", tablename, err)
}
if len(schema.LeadgerFields) != 0 {
return createAccount(tablename,PutDatas,schema,stub)
}else{
return putData(tablename, PutDatas, commonName, schema, stub)
}
}
/*
根据账户类型创建账本账户,由于我们这里有存储数据与账本数据两种,所以我们还需要在schema 部分标识不同的数据类型。
伪代码:
1:检查当前用户是否具有账户的总写(创建)权限
2:检查账户必备的属性,如Id,账户名,账户所属者,对应的是证书commonName
2:根据schema 标注的金额(账本)字段,和存证字段,分别进行数据的putState存储工作。其中在存证数据的Id 字段是标示字段。
3:完成账户创建工作
*/
func createAccount(tablename string,PutDatas []map[string]interface{},schema *Schema, stub shim.ChaincodeStubInterface) (string, error) {
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 := schema.FieldsCheck(mapres)
if err != nil {
return "", fmt.Errorf("args index %d string, %s schema cheack fail,err : %s ", k, tablename, err)
}
storagemap, leadgermap := separateFields(schema, mapres, []string{"id", "common_name"})
key := StoragePrefix + "_" + tablename + "_" + Id.(string)
getResult, err := getState(key,stub)
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 := putState(key, storagemap,stub); err != nil {
return "", err
}
if err := putState(LeadgerPrefix+"_"+tablename+"_"+Id.(string), leadgermap,stub); err != nil {
return "", err
}
}
return fmt.Sprintf("create %s account success!", tablename), nil
}
/*
修改一个账户的存储数据,修改规则由Schema 控制,有些特殊数据在账本数据也使用,所以无法修改
*/
func updateStoreData(tablename string,updata map[string]interface{}, stub shim.ChaincodeStubInterface) (string, error) {
commonName, err := getCertificateCommonName(stub)
if err != nil {
return "", fmt.Errorf("getCertificateCommonName happen err: %s ", err)
}
schema := &Schema{}
schema ,err = getSchema(tablename, stub)
if err != nil {
return "", 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 ")
}
key := StoragePrefix + "_" + tablename + "_" + Id.(string)
allMap, err := getState(key, stub)
if err != nil {
return "", err
}
owner, ok := allMap["common_name"].(string)
if !ok {
return "", fmt.Errorf("common_name fields resolution failed ")
}
schema.AllWriteCheck(commonName, owner)
if err != nil{
err := schema.DataWriteCheck( updata, commonName,owner)
if err !=nil{
return "", err
}
}
if err := schema.FieldsFormatCheck(updata); 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!",tablename), nil
}
/*
查询数据,如果存在账本数据,与存证数据,则进行数据拼接,然后返回。
*/
func get(tablename string,parameters map[string]interface{}, stub shim.ChaincodeStubInterface) (string, error) {
commonName, err := getCertificateCommonName(stub)
if err != nil {
return "", fmt.Errorf("getCertificateCommonName happen err: %s ", err)
}
Id, ok := parameters["id"]
if !ok {
return "", fmt.Errorf("The id field must exist ")
}
storageKey := StoragePrefix + "_" + tablename + "_" + Id.(string)
mapResult, err := getState(storageKey, stub)
if err != nil {
return "", err
}
leadgerKey := LeadgerPrefix + "_" + tablename + "_" + Id.(string)
leadgerResult, err := stub.GetState(leadgerKey)
if err != nil {
return "", fmt.Errorf("get %s data fail,please check your parameters ", leadgerKey)
}
schema := &Schema{}
schema ,err = getSchema(tablename, 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)
}
}
onwer, ok := mapResult["common_name"].(string)
if !ok {
return "", fmt.Errorf("common_name fields resolution failed ")
}
if err := schema.AllReadCheck( commonName, onwer); err != nil {
if filteredData, err := schema.ReadFiler( mapResult, commonName, onwer); 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
}
}
/*
有些特殊的putdata 数据是存在过滤条件的,此方法就是进行过滤
*/
func putData(filterName string, putDatas []map[string]interface{}, commonName string, schema *Schema, stub shim.ChaincodeStubInterface) (string, error) {
filterFunc := PutDataFilter[filterName]
if filterFunc == nil {
return "", fmt.Errorf("No matching filter operation method was found ! ")
}
str, err := filterFunc(putDatas, commonName, filterName, schema, stub)
if err != nil {
return "", fmt.Errorf("%s filter operation fail,err:%s ", filterName, err)
}
return str, nil
}
/*
在共享惠项目中当用户上传码数据时,存在对发行总数控制的要求。
*/
func codeFilter(putDatas []map[string]interface{}, commonName, tableName string, schema *Schema, stub shim.ChaincodeStubInterface) (string, error) {
sum := len(putDatas)
if sum == 0 {
return "", fmt.Errorf("put length cannot zero! ")
}
tid, ok := putDatas[0]["tid"].(string)
if !ok {
return "", fmt.Errorf("tid fields type must string! ")
}
dependData := "coutickets"
Stkey := StoragePrefix + "_" + dependData + "_" + tid
tmap, err := getState(Stkey, stub)
if err != nil {
return "", err
}
count, ok := tmap["surplusCount"].(float64) //剩余可发行数
if !ok {
return "", fmt.Errorf("surplusCount fields type must float64! ")
}
count -= float64(sum)
if count >= 0 {
tmap["surplusCount"] = count
} else {
return "", fmt.Errorf("The number of issues exceeds the total number of issues! ")
}
err = putState(Stkey, tmap, stub)
if err != nil {
return "", 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 = schema.FieldsCheck(mapres)
if err != nil {
return "", fmt.Errorf("args index %d string, %s schema cheack fail,err : %s ", k, tableName, err)
}
key := StoragePrefix + "_" + tableName + "_" + Id.(string)
_, err := getState(key, stub)
if err != nil {
return "", err
}
err = putState(key, mapres, stub)
if err != nil {
return "", err
}
}
return fmt.Sprintf("%s data save success!", tableName), nil
}
func commanFilter(putDatas []map[string]interface{}, commonName, tableName string, schema *Schema, stub shim.ChaincodeStubInterface) (string, error) {
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 := schema.FieldsFormatCheck(mapres)
if err!= nil{
return "", fmt.Errorf("args index %d string, %s schema cheack fail,err : %s ", k, tableName, err)
}
key := StoragePrefix + "_" + tableName + "_" + Id.(string)
err = putState(key, mapres, stub)
if err != nil {
return "", err
}
}
return fmt.Sprintf("%s data save success!", tableName), nil
}
/*
券可用门店过滤表
*/
func ticketMerFilter(putDatas []map[string]interface{}, commonName, tableName string, schema *Schema, stub shim.ChaincodeStubInterface) (string, error) {
for k, mapres := range putDatas {
mid, ok := mapres["mid"]
if !ok {
return "", fmt.Errorf("The mid field must exist ")
}
tid, ok := mapres["tid"]
if !ok {
return "", fmt.Errorf("The tid field must exist ")
}
_, ok = mapres["common_name"]
if !ok {
return "", fmt.Errorf("The common_name field must exist ")
}
err := schema.FieldsFormatCheck(mapres)
if err!= nil{
return "", fmt.Errorf("args index %d string, %s schema cheack fail,err : %s ", k, tableName, err)
}
key := StoragePrefix + "_" + tableName + "_" + mid.(string) + "_" + tid.(string)
err = putState(key, mapres, stub)
if err != nil {
return "", err
}
}
return "", nil
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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))
}
This diff is collapsed.
This diff is collapsed.
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