add chincode code

parent d7ba709c
...@@ -57,7 +57,6 @@ func (t *GXHCC) Invoke(stub shim.ChaincodeStubInterface) pb.Response { ...@@ -57,7 +57,6 @@ func (t *GXHCC) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
return shim.Error(fmt.Sprintf("update function err: %s", err)) return shim.Error(fmt.Sprintf("update function err: %s", err))
} }
return shim.Success([]byte(res)) return shim.Success([]byte(res))
case "cert": case "cert":
testCertificate(stub) testCertificate(stub)
...@@ -339,13 +338,13 @@ func testCertificate(stub shim.ChaincodeStubInterface) pb.Response{ ...@@ -339,13 +338,13 @@ func testCertificate(stub shim.ChaincodeStubInterface) pb.Response{
if err != nil { if err != nil {
fmt.Errorf("ParseCertificate failed") fmt.Errorf("ParseCertificate failed")
} }
fmt.Println("cert %v ",cert) fmt.Println("cert ",cert)
result,err := json.Marshal(cert) result,err := json.Marshal(cert)
if err!=nil{ if err!=nil{
fmt.Println("Marshal err:",err) fmt.Println("Marshal err:",err)
} }
fmt.Println("cert marshal:",string(result)) fmt.Println("cert marshal:",string(result))
fmt.Println("cert Subject %v ",cert.Subject) fmt.Println("cert Subject ",cert.Subject)
uname:=cert.Subject.CommonName uname:=cert.Subject.CommonName
fmt.Println("Name:"+uname) fmt.Println("Name:"+uname)
......
...@@ -26,10 +26,11 @@ func TestGXHCC(t *testing.T) { ...@@ -26,10 +26,11 @@ func TestGXHCC(t *testing.T) {
func TestGXHSchema(t *testing.T){ func TestGXHSchema(t *testing.T){
input := `{"id":"1","aname":"alibusi","aname":"alibus","atype":"type","alinkman":"","aader":"aader", // input := `{"id":"1","aname":"alibusi","aname":"alibus","atype":"type","alinkman":"","aader":"aader",
"amob":"1234567890","backup":{"id":"1","aname":"alibusi","atype":"type","alinkman":"", //"amob":"1234567890","backup":{"id":"1","aname":"alibusi","atype":"type","alinkman":"",
"aader":"aader","amob":"1234567890"}}` //"aader":"aader","amob":"1234567890"}}`
schema := `{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"fields":{"acid":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":3},"id":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"1"},"actionid":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"adiscounts":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"0.8"},"aid":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":0},"altdate":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"2010-01-01 15:38:54"},"are":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"backup":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":{}},"cid":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":0},"contract":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"16161616032"},"cosperson":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":100},"did":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":2},"dineraprice":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":80},"dineretime":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"15:30:59"},"dinerprice":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":100},"dinersprice":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":90},"dinerstime":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"11:10:00"},"distype":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":16},"dledate":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"2010-01-01 15:38:54"},"esign":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"2010-12-31 15:38:54"},"fid":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":4},"firrenew":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"2010-01-02 15:38:54"},"haver":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"indate":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"2018/10/29 16:46:57"},"ischain":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"isset":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"issnp":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"keywords":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"test"},"lat":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"43.840345"},"licence":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"103451015521"},"linedate":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"2010-01-02 15:38:54"},"lng":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"125.28796"},"mact":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"123456"},"mactname":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"联系人1"},"maddr":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"测试地址1"},"marea":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"mbtype":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"mdiposit":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"中国银行"},"mlinkman":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"联系人1"},"mlinkmob":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"18555555555"},"mname":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"测试连锁店1"},"mno":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"59118600000005"},"mno2":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"05910005"},"msubtype":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":10},"mtype":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":9},"murl":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"http://www.baidu.com"},"ordertel":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"13444444444"},"paystatue":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"perquisites":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":3},"persales":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":100},"pname":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"8820180008552970"},"ppass":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"152820"},"regular":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":6000},"relevel":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":5},"retype":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":0},"rregular":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":6000},"sdiscounts":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"0.85"},"shophours":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"24小时营业"},"sregular":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":6000},"ssign":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"2010-01-01 15:38:54"},"statue":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":0},"supperaprice":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":90},"supperetime":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"23:59:59"},"supperprice":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":120},"suppersprice":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":110},"supperstime":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"15:31:00"},"tstatue":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"mcode":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"11201700000003"},"warmline":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"600"}},"schema_auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}}}`
inputarrary := `[{"id":"1","aname":"alibusi","atype":"type","alinkman":"", inputarrary := `[{"id":"1","aname":"alibusi","atype":"type","alinkman":"",
"aader":"aader","amob":"1234567890","backup":{"id":"1","aname":"alibusi","atype":"type", "aader":"aader","amob":"1234567890","backup":{"id":"1","aname":"alibusi","atype":"type",
"alinkman":"","aader":"aader","amob":"1234567890"}},{"id":"2","aname":"alibusi","atype":"type", "alinkman":"","aader":"aader","amob":"1234567890"}},{"id":"2","aname":"alibusi","atype":"type",
...@@ -46,7 +47,7 @@ func TestGXHSchema(t *testing.T){ ...@@ -46,7 +47,7 @@ func TestGXHSchema(t *testing.T){
fmt.Println("========================================invoke schema put============================================") fmt.Println("========================================invoke schema put============================================")
fmt.Println() fmt.Println()
fmt.Println() fmt.Println()
responseByPutschema := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("put"),[]byte("alibusi"),[]byte(input)}) responseByPutschema := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("put"),[]byte("alibusi"),[]byte(schema)})
fmt.Printf("Invoke status %d,message %s and payload %s\n", fmt.Printf("Invoke status %d,message %s and payload %s\n",
responseByPutschema.Status,responseByPutschema.Message,string(responseByPutschema.Payload)) responseByPutschema.Status,responseByPutschema.Message,string(responseByPutschema.Payload))
...@@ -54,6 +55,7 @@ func TestGXHSchema(t *testing.T){ ...@@ -54,6 +55,7 @@ func TestGXHSchema(t *testing.T){
fmt.Printf("Invoke status %d,message %s and payload %s\n", fmt.Printf("Invoke status %d,message %s and payload %s\n",
responseByGet.Status,responseByGet.Message,string(responseByGet.Payload)) responseByGet.Status,responseByGet.Message,string(responseByGet.Payload))
fmt.Println() fmt.Println()
return
fmt.Println("========================================invoke data put============================================") fmt.Println("========================================invoke data put============================================")
fmt.Println() fmt.Println()
fmt.Println() fmt.Println()
......
...@@ -125,15 +125,12 @@ func (t *GXHCC) Invoke(stub shim.ChaincodeStubInterface) pb.Response { ...@@ -125,15 +125,12 @@ func (t *GXHCC) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
return shim.Error(err.Error()) return shim.Error(err.Error())
} }
switch functionName { switch functionName {
case "authority":
case "schema": case "schema":
res, err := SchemaProcess(args, stub) res, err := SchemaProcess(args, stub)
if err != nil { if err != nil {
return shim.Error(fmt.Sprintf("SchemaProcess function err: %s", err)) return shim.Error(fmt.Sprintf("SchemaProcess function err: %s", err))
} }
return shim.Success([]byte(res)) return shim.Success([]byte(res))
case "put": case "put":
res, err := put(args, stub) res, err := put(args, stub)
if err != nil { if err != nil {
...@@ -193,12 +190,6 @@ func put(args []string, stub shim.ChaincodeStubInterface) (string, error) { ...@@ -193,12 +190,6 @@ func put(args []string, stub shim.ChaincodeStubInterface) (string, error) {
if !ok { if !ok {
return "", fmt.Errorf("The id field must exist ") return "", fmt.Errorf("The id field must exist ")
} }
//if result, err := stub.GetState(args[0] + Id.(string)); err != nil {
// return "", fmt.Errorf("get %s data happen err: ", args[0]+Id.(string))
//}
//else if result != nil {
// return "", fmt.Errorf("%s data already exist", args[0]+Id.(string))
//}
if !SchemaCheck(schema.Fields, mapres) { if !SchemaCheck(schema.Fields, mapres) {
return "", fmt.Errorf("SchemaCheck fail,args index %d string doesn't match %s format", k, args[0]) return "", fmt.Errorf("SchemaCheck fail,args index %d string doesn't match %s format", k, args[0])
} }
...@@ -209,10 +200,6 @@ func put(args []string, stub shim.ChaincodeStubInterface) (string, error) { ...@@ -209,10 +200,6 @@ func put(args []string, stub shim.ChaincodeStubInterface) (string, error) {
if err := stub.PutState(PREFIX+"_"+args[0]+"_"+Id.(string), putDate); err != nil { if err := stub.PutState(PREFIX+"_"+args[0]+"_"+Id.(string), putDate); err != nil {
return "", fmt.Errorf("PutState fail, err :%s", err) return "", fmt.Errorf("PutState fail, err :%s", err)
} }
err := tableDifferentiate(args[0],mapres,stub)
if err != nil{
return "", err
}
} }
return fmt.Sprintf("%s put data success!", args[0]), nil return fmt.Sprintf("%s put data success!", args[0]), nil
} }
...@@ -263,13 +250,11 @@ func update(args []string, stub shim.ChaincodeStubInterface) (string, error) { ...@@ -263,13 +250,11 @@ func update(args []string, stub shim.ChaincodeStubInterface) (string, error) {
if err := Deassign(Updata, allMap); err != nil { if err := Deassign(Updata, allMap); err != nil {
return "", err return "", err
} }
resultByte, _ := json.Marshal(allMap) resultByte, _ := json.Marshal(allMap)
if err := stub.PutState(PREFIX+"_"+args[0]+"_"+Id.(string), resultByte); err != nil { if err := stub.PutState(PREFIX+"_"+args[0]+"_"+Id.(string), resultByte); err != nil {
return "", fmt.Errorf("Put %s date fail, err :%s ",args[0]+"_"+Id.(string), err) return "", fmt.Errorf("Put %s date fail, err :%s ",args[0]+"_"+Id.(string), err)
} }
return fmt.Sprintf("%s update data success!", args[0]), nil return fmt.Sprintf("%s update data success!", args[0]), nil
} }
func get(args []string, stub shim.ChaincodeStubInterface) (string, error) { func get(args []string, stub shim.ChaincodeStubInterface) (string, error) {
...@@ -513,7 +498,6 @@ func (this *Schema) update(args []string, stub shim.ChaincodeStubInterface) (str ...@@ -513,7 +498,6 @@ func (this *Schema) update(args []string, stub shim.ChaincodeStubInterface) (str
func (this *Schema) get(args string, stub shim.ChaincodeStubInterface) (string, error) { func (this *Schema) get(args string, stub shim.ChaincodeStubInterface) (string, error) {
var result []byte var result []byte
if result = schemaCache.Get(args);result == nil{ if result = schemaCache.Get(args);result == nil{
fmt.Println("schemaCache.Get nil")
CompositeKey,err := stub.CreateCompositeKey(GxhSchema,[]string{args}) CompositeKey,err := stub.CreateCompositeKey(GxhSchema,[]string{args})
if err != nil{ if err != nil{
return "", fmt.Errorf("the schema %s create comosite key fail,err : %s", args,err) return "", fmt.Errorf("the schema %s create comosite key fail,err : %s", args,err)
...@@ -530,7 +514,6 @@ func (this *Schema) get(args string, stub shim.ChaincodeStubInterface) (string, ...@@ -530,7 +514,6 @@ func (this *Schema) get(args string, stub shim.ChaincodeStubInterface) (string,
func (this *Schema) getSchema(args string, stub shim.ChaincodeStubInterface)(string, error) { func (this *Schema) getSchema(args string, stub shim.ChaincodeStubInterface)(string, error) {
var result []byte var result []byte
if result = schemaCache.Get(args);result == nil{ if result = schemaCache.Get(args);result == nil{
fmt.Println("schemaCache.Get nil")
CompositeKey,err := stub.CreateCompositeKey(GxhSchema,[]string{args}) CompositeKey,err := stub.CreateCompositeKey(GxhSchema,[]string{args})
if err != nil{ if err != nil{
return "", fmt.Errorf("the schema %s create comosite key fail,err : %s", args,err) return "", fmt.Errorf("the schema %s create comosite key fail,err : %s", args,err)
...@@ -555,6 +538,7 @@ func (this *Schema) getSchema(args string, stub shim.ChaincodeStubInterface)(str ...@@ -555,6 +538,7 @@ func (this *Schema) getSchema(args string, stub shim.ChaincodeStubInterface)(str
} }
func getCertificateCommonName(stub shim.ChaincodeStubInterface) (string, error) { func getCertificateCommonName(stub shim.ChaincodeStubInterface) (string, error) {
return "Admin@org2.example.com", nil
creatorByte, _ := stub.GetCreator() creatorByte, _ := stub.GetCreator()
certStart := bytes.IndexAny(creatorByte, "-----BEGIN") certStart := bytes.IndexAny(creatorByte, "-----BEGIN")
if certStart == -1 { if certStart == -1 {
...@@ -585,19 +569,9 @@ func parsauthorityCheck(schema map[string]SchemaParameters, checkmap map[string] ...@@ -585,19 +569,9 @@ func parsauthorityCheck(schema map[string]SchemaParameters, checkmap map[string]
return false, fmt.Errorf("Update data parameter mismatch with schema structure! ") return false, fmt.Errorf("Update data parameter mismatch with schema structure! ")
} }
} }
// if !authorityCheck(schemaV.Write, commonName) {
// return false, fmt.Errorf("%s field permission check does not match", k)
// }
// else {
// if res, err := parsauthorityCheck(parameterS, parameterC, commonName); !res {
// return res, err
// }
// }
//} else {
if ok,err := authorityCheck(schemaV.PAuth.Write, commonName);!ok { 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 false, fmt.Errorf("%s field permission check does not match, err: %s ", k,err)
} }
//}
} }
} }
return true, nil return true, nil
...@@ -618,11 +592,6 @@ func dataFilter(schema map[string]SchemaParameters, checkmap map[string]interfac ...@@ -618,11 +592,6 @@ func dataFilter(schema map[string]SchemaParameters, checkmap map[string]interfac
if ok,_ := authorityCheck(schemaV.PAuth.Read, commonName);!ok { if ok,_ := authorityCheck(schemaV.PAuth.Read, commonName);!ok {
checkmap[k] = defValue checkmap[k] = defValue
} }
//else {
// if _, err := dataFilter(parameterS, parameterC, commonName); err!=nil {
// return nil, err
// }
//}
} else { } else {
if ok,_ := authorityCheck(schemaV.PAuth.Read, commonName);!ok { if ok,_ := authorityCheck(schemaV.PAuth.Read, commonName);!ok {
checkmap[k] = defValue checkmap[k] = defValue
...@@ -692,7 +661,7 @@ func fieldCheckout(check *Checks,val interface{})error{ ...@@ -692,7 +661,7 @@ func fieldCheckout(check *Checks,val interface{})error{
} }
value := val.(string) value := val.(string)
if len([]rune(value))>check.Fieldlen{ if len([]rune(value))>check.Fieldlen{
return fmt.Errorf("fields length must be greater than %d ",check.Fieldlen) return fmt.Errorf("fields length cannot be greater than %d ",check.Fieldlen)
} }
case "int","int16","int32","int64","float32","float64": case "int","int16","int32","int64","float32","float64":
if fType != "float64"{ if fType != "float64"{
...@@ -710,86 +679,92 @@ func fieldCheckout(check *Checks,val interface{})error{ ...@@ -710,86 +679,92 @@ func fieldCheckout(check *Checks,val interface{})error{
return fmt.Errorf("fields type does not match the defined time.Time type! ") return fmt.Errorf("fields type does not match the defined time.Time type! ")
} }
dateStr := reflect.ValueOf(val).String() dateStr := reflect.ValueOf(val).String()
if check.Must && (dateStr == "0001-01-01 00:00:00 +0000 UTC"|| dateStr == "0001-01-01T00:00:00Z"){ if check.Must && dateStr == ""{
return fmt.Errorf("fields cannot be initial value") return fmt.Errorf("fields cannot be empty")
}
if _ ,err := time.Parse("2006-1-02 15:04:05",dateStr);err != nil{
return fmt.Errorf(err.Error())
} }
default:
fmt.Errorf("fields type no match! ")
}
return nil
}
/* //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")
*/ //}
func tableDifferentiate(tableName string,value map[string]interface{}, stub shim.ChaincodeStubInterface)(error){
switch tableName {
case "alibusi":
return alibusiCompositeKey(tableName,value, stub)
case "alibusirecord":
//return addAlibusirecord(tableName,value, stub)
case "merchants":
//return merchantsLeadger(tableName,value, stub)
case "couincomingparts":
//return addMerchantsale(args[1:],stub)
case "merchantsale":
//return addMerchantsale(tableName,value, stub)
case "coutickets":
//return couticketsLeadger(tableName,value, stub)
case "coutcantm":
//return coutcantmLeadger(tableName,value, stub)
case "couticketcodes":
//return coupartnersLeadger(args[1:],stub)
case "coupartners":
//return coupartnersLeadger(tableName,value, stub)
case "couticketorders":
// return addCouticketorders(tableName,value,stub)
default: default:
return fmt.Errorf(fmt.Sprintf("Unsupported table name of %s", tableName)) fmt.Errorf("fields type no match! ")
} }
return nil return nil
} }
func alibusiCompositeKey(tableName string,value map[string]interface{}, stub shim.ChaincodeStubInterface)error{ ///*
valBy,_ := json.Marshal(value) // 根据参数区分不同的表,并执行不同的操作
Id := value["id"].(string) //*/
aname,ok := value["aname"].(string) //func tableDifferentiate(tableName string,value map[string]interface{}, stub shim.ChaincodeStubInterface)(error){
if !ok{ // switch tableName {
return fmt.Errorf("aname fields type not string! ") //
} // case "alibusi":
anamecomKey,err :=stub.CreateCompositeKey(tableName,[]string{aname,Id}) // return alibusiCompositeKey(tableName,value, stub)
if err!=nil{ // case "alibusirecord":
return err // //return addAlibusirecord(tableName,value, stub)
} // case "merchants":
alinkman,ok := value["alinkman"].(string) // //return merchantsLeadger(tableName,value, stub)
if !ok{ // case "couincomingparts":
return fmt.Errorf("alinkman fields type not string! ") // //return addMerchantsale(args[1:],stub)
} // case "merchantsale":
alinkmancomKey,err :=stub.CreateCompositeKey(tableName,[]string{alinkman,Id}) // //return addMerchantsale(tableName,value, stub)
if err!=nil{ // case "coutickets":
return err // //return couticketsLeadger(tableName,value, stub)
} // case "coutcantm":
amob,ok := value["amob"].(string) // //return coutcantmLeadger(tableName,value, stub)
if !ok{ // case "couticketcodes":
return fmt.Errorf("amob fields type not string! ") // //return coupartnersLeadger(args[1:],stub)
} // case "coupartners":
amobcomKey,err :=stub.CreateCompositeKey(tableName,[]string{amob,Id}) // //return coupartnersLeadger(tableName,value, stub)
if err!=nil{ // case "couticketorders":
return err // // return addCouticketorders(tableName,value,stub)
} // default:
if err := stub.PutState(anamecomKey, valBy); err != nil { // return fmt.Errorf(fmt.Sprintf("Unsupported table name of %s", tableName))
return fmt.Errorf("Put %s date fail, err :%s ",anamecomKey, err) // }
} // return nil
if err := stub.PutState(alinkmancomKey, valBy); err != nil { //}
return fmt.Errorf("Put %s date fail, err :%s ",alinkmancomKey, err) //
} //func alibusiCompositeKey(tableName string,value map[string]interface{}, stub shim.ChaincodeStubInterface)error{
if err := stub.PutState(amobcomKey, valBy); err != nil { // valBy,_ := json.Marshal(value)
return fmt.Errorf("Put %s date fail, err :%s ",amobcomKey, err) // Id := value["id"].(string)
} // aname,ok := value["aname"].(string)
return nil // if !ok{
} // return fmt.Errorf("aname fields type not string! ")
// }
// anamecomKey,err :=stub.CreateCompositeKey(tableName,[]string{aname,Id})
// if err!=nil{
// return err
// }
// alinkman,ok := value["alinkman"].(string)
// if !ok{
// return fmt.Errorf("alinkman fields type not string! ")
// }
// alinkmancomKey,err :=stub.CreateCompositeKey(tableName,[]string{alinkman,Id})
// if err!=nil{
// return err
// }
// amob,ok := value["amob"].(string)
// if !ok{
// return fmt.Errorf("amob fields type not string! ")
// }
// amobcomKey,err :=stub.CreateCompositeKey(tableName,[]string{amob,Id})
// if err!=nil{
// return err
// }
// if err := stub.PutState(anamecomKey, valBy); err != nil {
// return fmt.Errorf("Put %s date fail, err :%s ",anamecomKey, err)
// }
// if err := stub.PutState(alinkmancomKey, valBy); err != nil {
// return fmt.Errorf("Put %s date fail, err :%s ",alinkmancomKey, err)
// }
// if err := stub.PutState(amobcomKey, valBy); err != nil {
// return fmt.Errorf("Put %s date fail, err :%s ",amobcomKey, err)
// }
// return nil
//}
func Constructor(capacity int) LRUCache{ func Constructor(capacity int) LRUCache{
lruCache := LRUCache{limit:capacity} lruCache := LRUCache{limit:capacity}
......
...@@ -26,6 +26,7 @@ var schemaCheck = `{"fields":{"alinkman":{"val":10.34,"auth":{"read":{"users":{" ...@@ -26,6 +26,7 @@ var schemaCheck = `{"fields":{"alinkman":{"val":10.34,"auth":{"read":{"users":{"
"roles":{"Admin@org2.example.com":0}}}} "roles":{"Admin@org2.example.com":0}}}}
` `
var schemaupdate = `{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"fields":{"acid":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":3},"id":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"1"},"actionid":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"adiscounts":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"0.8"},"aid":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":0},"altdate":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"2010-01-01 15:38:54"},"are":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"backup":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":{}},"cid":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":0},"contract":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"16161616032"},"cosperson":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":100},"did":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":2},"dineraprice":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":80},"dineretime":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"15:30:59"},"dinerprice":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":100},"dinersprice":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":90},"dinerstime":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"11:10:00"},"distype":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":16},"dledate":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"2010-01-01 15:38:54"},"esign":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"2010-12-31 15:38:54"},"fid":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":4},"firrenew":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"2010-01-02 15:38:54"},"haver":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"indate":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"2018/10/29 16:46:57"},"ischain":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"isset":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"issnp":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"keywords":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"test"},"lat":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"43.840345"},"licence":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"103451015521"},"linedate":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"2010-01-02 15:38:54"},"lng":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"125.28796"},"mact":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"123456"},"mactname":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"联系人1"},"maddr":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"测试地址1"},"marea":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"mbtype":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"mdiposit":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"中国银行"},"mlinkman":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"联系人1"},"mlinkmob":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"18555555555"},"mname":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"测试连锁店1"},"mno":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"59118600000005"},"mno2":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"05910005"},"msubtype":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":10},"mtype":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":9},"murl":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"http://www.baidu.com"},"ordertel":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"13444444444"},"paystatue":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"perquisites":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":3},"persales":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":100},"pname":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"8820180008552970"},"ppass":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"152820"},"regular":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":6000},"relevel":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":5},"retype":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":0},"rregular":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":6000},"sdiscounts":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"0.85"},"shophours":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"24小时营业"},"sregular":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":6000},"ssign":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"2010-01-01 15:38:54"},"statue":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":0},"supperaprice":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":90},"supperetime":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"23:59:59"},"supperprice":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":120},"suppersprice":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":110},"supperstime":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"15:31:00"},"tstatue":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"mcode":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"11201700000003"},"warmline":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"600"}},"schema_auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}}}`
var schema = `{"fields":{"alinkman":{"val":"Alinkman","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles": 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}}}},"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}}}},"aname":{"val":"Aname","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
...@@ -74,7 +75,7 @@ func TestGXHSchemaAuth(t *testing.T){ ...@@ -74,7 +75,7 @@ func TestGXHSchemaAuth(t *testing.T){
fmt.Println("========================================invoke schema put============================================") fmt.Println("========================================invoke schema put============================================")
fmt.Println() fmt.Println()
fmt.Println() fmt.Println()
responseByPutschema := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("put"),[]byte("alibusi"),[]byte(schemaCheck)}) responseByPutschema := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("put"),[]byte("alibusi"),[]byte(schemaupdate)})
fmt.Printf("Invoke status %d,message %s and payload %s\n", fmt.Printf("Invoke status %d,message %s and payload %s\n",
responseByPutschema.Status,responseByPutschema.Message,string(responseByPutschema.Payload)) responseByPutschema.Status,responseByPutschema.Message,string(responseByPutschema.Payload))
fmt.Println() fmt.Println()
...@@ -88,7 +89,7 @@ func TestGXHSchemaAuth(t *testing.T){ ...@@ -88,7 +89,7 @@ func TestGXHSchemaAuth(t *testing.T){
fmt.Println("========================================invoke schema update============================================") fmt.Println("========================================invoke schema update============================================")
fmt.Println() fmt.Println()
fmt.Println() fmt.Println()
responseByupdate := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("update"),[]byte("alibusi"),[]byte(schema)}) responseByupdate := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("update"),[]byte("alibusi"),[]byte(schemaupdate)})
fmt.Printf("Invoke status %d,message %s ,and payload %s \n", fmt.Printf("Invoke status %d,message %s ,and payload %s \n",
responseByupdate.Status,responseByupdate.Message,string(responseByupdate.Payload)) responseByupdate.Status,responseByupdate.Message,string(responseByupdate.Payload))
} }
...@@ -162,7 +163,7 @@ func TestGXHDataPutAuth(t *testing.T){ ...@@ -162,7 +163,7 @@ func TestGXHDataPutAuth(t *testing.T){
responseByget2.Status,responseByget2.Message,string(responseByget2.Payload)) 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"}` var testData = `{"float64":10.33,"int":10,"string":"我中国人a!","time.Time":"2018-08-15 16:29:46"}`
func TestFieldCheck(t *testing.T){ func TestFieldCheck(t *testing.T){
var testmap map[string]interface{} var testmap map[string]interface{}
...@@ -215,7 +216,7 @@ var ( ...@@ -215,7 +216,7 @@ var (
"aname": "alibusi", "aname": "alibusi",
"atype": 102, "atype": 102,
"alinkman": 10.34, "alinkman": 10.34,
"amob": "0001-01-01 00:00:00 + UTC", "amob": "2018-10-29 16:46:57",
"backup": { "backup": {
"aname": "alibusi", "aname": "alibusi",
"atype": "type" "atype": "type"
...@@ -225,7 +226,7 @@ var ( ...@@ -225,7 +226,7 @@ var (
"aname": "alibusi", "aname": "alibusi",
"atype": 102, "atype": 102,
"alinkman": 10.34, "alinkman": 10.34,
"amob": "0001-01-01 00:00:00 + UTC", "amob": "2018-10-29 16:46:57",
"backup": { "backup": {
"aname": "alibusi", "aname": "alibusi",
"atype": "type" "atype": "type"
...@@ -243,7 +244,7 @@ func TestPut(t *testing.T){ ...@@ -243,7 +244,7 @@ func TestPut(t *testing.T){
fmt.Println("========================================invoke schema put============================================") fmt.Println("========================================invoke schema put============================================")
fmt.Println() fmt.Println()
fmt.Println() fmt.Println()
responseByPutschema := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("put"),[]byte("alibusi"),[]byte(inputC)}) responseByPutschema := stub.MockInvoke("invoke1",[][]byte{[]byte("schema"), []byte("put"),[]byte("alibusi"),[]byte(schemaCheck)})
//使用schema 数据测试过期时间err,schema right data,使用schema3 测试读取字段时的过滤 //使用schema 数据测试过期时间err,schema right data,使用schema3 测试读取字段时的过滤
fmt.Printf("Invoke status %d,message %s and payload %s\n", fmt.Printf("Invoke status %d,message %s and payload %s\n",
responseByPutschema.Status,responseByPutschema.Message,string(responseByPutschema.Payload)) responseByPutschema.Status,responseByPutschema.Message,string(responseByPutschema.Payload))
......
package main
import (
"bytes"
"crypto/x509"
"encoding/json"
"encoding/pem"
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
pb "github.com/hyperledger/fabric/protos/peer"
"reflect"
"strconv"
"time"
)
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 SchemaParameters struct {
Value interface{} `json:"val"`//默认值 这里特别说明一下如果这里是backUp 字段,我们不进行更深一步的校验,包括格式
PAuth Auth `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"`
SchemaAuth Auth `json:"schema_auth"`//schema 的写权限,主要是用在 schema update 部分
SAuth Auth `json:"auth"`
}
type AlibusiLeadger struct {
Id string `json:"id"` //机构Id
Abail float64 `abail` //剩余保证金
Amount float64 `amount` //可提取资金,在当前只包括预付金部分的增加,分成在后续部分记录
}
type MerchantsLeadger struct {
Id string `json:"id"` //机构Id
Bid string `json:"bid"`
Regular float64 `json:"regular"` //剩余预付金
Rregular float64 `json:"rregular"` //实际预付金
}
type CouticketsLeadger struct {
Id string `json:"id"` //券ID
Codenum int `json:"codenum"` //码总数
Codestork int `json:"codestork"` //码库存
}
type CoutcantmLeadger struct {
Id string `json:"d"` //可用门店Id
Tid string `json:"tid"` //券id
Codenum int `json:"codenum"` //可用码数
Resid int `json:"resid"` //剩余码数
}
type Merchantsale struct {
Mid string `json:"mid"` //商户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 Couticketorders struct {
Orderid string `json:"orderid"` //订单ID
Oamount float64`json:"oamount"` //原始金额
Pamount float64`json:"pamount"` //支付金额
Mid string `json:"mid"` //门店Id
Codenum float64`json:"codenum"` //券码数量
Adiscount float64`json:"adiscount"`//券结算折扣
Norate float64`json:"norate"` //无预付金收益率
Outfree float64`json:"outfree"` //付款方手续费
Infree float64`json:"infree"` //收款方手续费
Partnersfree float64`json:"partnersfree"` //订单合作方手续飞
Free float64`json:"free"` //总手续费
}
type Profit struct {
Id string `json:"id"` //交易ID/或者订单ID
Type int `json:"type"` //交易还是订单标识 0 表示商户交易 1表示订单交易
profit float64`json:"profit"` //利润
}
var (
defValue = "***" //查询用户权限不足的情况下默认返回值
PREFIX = "GXH"
IsUsers = false //是否启用用户权限,false 表示启用Roles
)
// Init does nothing for this cc
func (t *GXHCC) Init(stub shim.ChaincodeStubInterface) pb.Response {
return shim.Success([]byte("GXHCC init successful! "))
}
// Invoke for this chaincode exposes
func (t *GXHCC) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
// get arguments and transient
functionName, args := stub.GetFunctionAndParameters()
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 "put":
res, err := put(args, stub)
if err != nil {
return shim.Error(fmt.Sprintf("put data 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 data function err: %s", err))
}
return shim.Success([]byte(res))
case "update":
res, err := update(args, stub)
if err != nil {
return shim.Error(fmt.Sprintf("update data function err: %s", err))
}
return shim.Success([]byte(res))
case "InvokeTable":
return InvokeTable(args,stub)
default:
return shim.Error(fmt.Sprintf("Unsupported function %s", functionName))
}
return shim.Success([]byte("GXHCC invoke successful "))
}
/*
put
args 字段说明:
1:args[0]代表我们具体操作的表,
2:args[1:]后面的数据表示要记录到数据库的数据,每一个string 必须是json字符串,并且需要每一个json 字符串都必须包含id 字段
*/
func put(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{}
result, err := schema.get(args[0], stub)
if err != nil {
return "", err
}
if err := json.Unmarshal([]byte(result), &schema); err != nil {
return "", fmt.Errorf("The parameters Unmarshal to a Schema structural fail,err: %s ", 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 !SchemaCheck(schema.Fields, mapres) {
return "", fmt.Errorf("SchemaCheck fail,args index %d string doesn't match %s format", k, args[0])
}
if err := FiledsCheck(schema.Fields,mapres);err !=nil{
return "",err
}
putDate, _ := json.Marshal(mapres)
if err := stub.PutState(PREFIX+"_"+args[0]+"_"+Id.(string), putDate); err != nil {
return "", fmt.Errorf("PutState fail, err :%s", err)
}
}
return fmt.Sprintf("%s put data success!", args[0]), nil
}
/*
修改一个表的一条数据的一个或者多个字段值
*/
func update(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{}
schemaRes, err := schema.get(args[0], stub)
if err != nil {
return "", err
}
if err := json.Unmarshal([]byte(schemaRes), &schema); err != nil {
return "", fmt.Errorf("The parameters Unmarshal to a Schema structural fail,err: %s ", err)
}
var Updata map[string]interface{}
var allMap 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 ")
}
if ok ,_ := authorityCheck(schema.SAuth.Write, commonName);!ok {
if ok, err := parsauthorityCheck(schema.Fields, Updata, commonName); !ok {
return "", fmt.Errorf("authority Check err: %s", err)
}
}
if err := FiledsCheck(schema.Fields,Updata);err !=nil{
return "",err
}
result, err := stub.GetState(PREFIX+"_"+args[0]+"_"+Id.(string))
if err != nil || result == nil {
return "", fmt.Errorf("GetState %s data fail,please check your parameters ",args[0]+"_"+Id.(string))
}
if err := json.Unmarshal(result, &allMap); err != nil {
return "", fmt.Errorf("The original data Unmarshal fail err:%s ", err)
}
if err := Deassign(Updata, allMap); err != nil {
return "", err
}
resultByte, _ := json.Marshal(allMap)
if err := stub.PutState(PREFIX+"_"+args[0]+"_"+Id.(string), resultByte); err != nil {
return "", fmt.Errorf("Put %s date fail, err :%s ",args[0]+"_"+Id.(string), err)
}
return fmt.Sprintf("%s update 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{}
var mapResult map[string]interface{}
if err := json.Unmarshal([]byte(args[1]), &parameters); 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 ")
}
result, err := stub.GetState(PREFIX+"_"+args[0]+"_"+Id.(string))
if err != nil || result == nil {
return "", fmt.Errorf("get %s data fail,please check your parameters ",args[0]+"_"+Id.(string))
}
schema := &Schema{}
schemaRes, err := schema.get(args[0], stub)
if err != nil {
return "", err
}
if err := json.Unmarshal([]byte(schemaRes), &schema); err != nil {
return "", fmt.Errorf("The parameters Unmarshal to a Schema structural fail,err: %s ", err)
}
if err := json.Unmarshal(result, &mapResult); err != nil {
return "", fmt.Errorf("The original data Unmarshal fail err:%s ", err)
}
if ok,_:= authorityCheck(schema.SAuth.Read, commonName);!ok {
if filteredData, err := dataFilter(schema.Fields, 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 {
return string(result), 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
}
func SchemaCheck(schema map[string]SchemaParameters, checkmap map[string]interface{}) bool {
if len(schema) != len(checkmap) {
return false
}
for k, v := range checkmap {
if schemaV, ok := schema[k]; !ok {
return false
} else {
if parameterS, ok := schemaV.Value.(map[string]interface{}); ok {
if parameterC, ok := v.(map[string]interface{}); !ok {
return false
}else{
if !BackUpCheck(parameterS,parameterC){
return false
}
}
}
}
}
return true
}
func FiledsCheck(schema map[string]SchemaParameters, checkmap map[string]interface{}) error{
for k, v := range checkmap {
if k != "backup" && schema[k].FCheck!= nil&&schema[k].FCheck.FType != ""{
if err := fieldCheckout(schema[k].FCheck,v);err!=nil{
return fmt.Errorf("%s %s ",k,err)
}
}
}
return nil
}
func BackUpCheck(backUp map[string]interface{}, checkmap map[string]interface{}) bool {
if len(backUp) != len(checkmap) {
return false
}
for k, _ := range checkmap {
if _, ok := backUp[k]; !ok {
return false
}
}
return true
}
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]))
}
}
/*
put
args 字段说明:
1:args[0]代表我们具体操作的表,
2:args[1:]后面的数据表示要记录到数据库的数据,每一个string 必须是json字符串,并且需要每一个json 字符串都必须包含id 字段
我们可以发现json字符串都被我们解析成了map[string]interface{}类型的map,其中key代表表模板的字段,interface可以是一个结构,我们当前将他看做我们表模板字段的初始值。
*/
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.Fields["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.Fields["id"]
if !ok {
return "", fmt.Errorf("The id field must exist ")
}
if value, _ := stub.GetState(PREFIX+"_"+args[0]); value != nil {
return "", fmt.Errorf("the schema %s already exists and cannot be added", args[0])
}
putDate, _ := json.Marshal(schema) //处理重复字段
if err := stub.PutState(PREFIX+"_"+args[0], putDate); err != nil {
return "", fmt.Errorf("Schema PutState fail,err: %s ", err)
}
return fmt.Sprintf("%s schema put success!", args[0]), nil
}
/*
if update Schema 那么我们没有办法比较旧有的一个模板,
Schema 的 update,不支持部分修改,因为存在增加和删除某些字段的情况。
TODO,增加版本管理
*/
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 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.Fields["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.Fields["id"]
if !ok {
return "", fmt.Errorf("The id field must exist ")
}
result, err := stub.GetState(PREFIX+"_"+args[0])
if err != nil || result == nil {
return "", fmt.Errorf("%s schema data doesn't exist,please check your parameters ",args[0])
}
if err := json.Unmarshal([]byte(result), &schema); 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(schema.SchemaAuth.Write,commonName);!ok{
return "", fmt.Errorf("update %s schema fail,err: %s ",args[0],err)
}
if err = stub.PutState(PREFIX+"_"+args[0], []byte(args[1]));err != nil{
return "", fmt.Errorf("%s schema data PutState fail,please try again ",args[0])
}
return fmt.Sprintf("%s schema update success!", args[0]), err
}
func (this *Schema) get(args string, stub shim.ChaincodeStubInterface) (string, error) {
result, err := stub.GetState(PREFIX+"_"+args)
if err != nil || result == nil {
return "", fmt.Errorf("GetSchema %s data fail,please check your parameters:err : %s ",args,err)
}
return string(result), nil
}
func (this *Schema) getSchema(args string, stub shim.ChaincodeStubInterface)(string, error) {
result, err := stub.GetState(PREFIX+"_"+args)
if err != nil || result == nil {
return "", fmt.Errorf("GetSchema %s data fail,please check your parameters:err : %s ",args,err)
}
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 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 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 !authorityCheck(schemaV.Write, commonName) {
// return false, fmt.Errorf("%s field permission check does not match", k)
// }
// else {
// if res, err := parsauthorityCheck(parameterS, parameterC, commonName); !res {
// return res, err
// }
// }
//} else {
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 dataFilter(schema map[string]SchemaParameters, checkmap map[string]interface{}, commonName string) (map[string]interface{}, error) {
for k, v := range checkmap {
if schemaV, ok := schema[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 _, err := dataFilter(parameterS, parameterC, commonName); err!=nil {
// return nil, err
// }
//}
} else {
if ok,_ := authorityCheck(schemaV.PAuth.Read, commonName);!ok {
checkmap[k] = defValue
}
}
}
}
return checkmap, 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 NewSchema(arg string)(*Schema,error){
schema := &Schema{
Fields:make(map[string]SchemaParameters),
}
var argMap map[string]interface{}
if err := json.Unmarshal([]byte(arg),&argMap);err!=nil{
return nil,err
}
if argMap["fields"] != nil && argMap["schema_auth"] != nil && argMap["auth"] != nil{
if err := json.Unmarshal([]byte(arg),schema);err!=nil{
return nil,err
}
return schema,nil
}
for k,v := range argMap{
schema.Fields[k] = SchemaParameters{
Value:v,
PAuth:Auth{},
}
}
return schema,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 must 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 == "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 InvokeTable(args []string,stub shim.ChaincodeStubInterface) pb.Response{
var tets map[string]interface{}
err := json.Unmarshal([]byte(args[1]),&tets)
if err != nil{
return shim.Error(err.Error())
}
err = tableDifferentiate(args[0],tets,stub)
if err!=nil {
return shim.Error(err.Error())
}
return shim.Success([]byte("successful"))
}
/*
根据参数区分不同的表,并执行不同的操作
*/
func tableDifferentiate(tableName string,value map[string]interface{}, stub shim.ChaincodeStubInterface)(error){
switch tableName {
case "alibusi":
return alibusiLeadger(tableName,value, stub)
case "alibusirecord":
return addAlibusirecord(tableName,value, stub)
case "merchants":
return merchantsLeadger(tableName,value, stub)
case "couincomingparts":
//return addMerchantsale(args[1:],stub)
case "merchantsale":
return addMerchantsale(tableName,value, stub)
case "coutickets":
return couticketsLeadger(tableName,value, stub)
case "coutcantm":
return coutcantmLeadger(tableName,value, stub)
case "couticketcodes":
//return coupartnersLeadger(args[1:],stub)
case "coupartners":
return coupartnersLeadger(tableName,value, stub)
case "couticketorders":
return addCouticketorders(tableName,value,stub)
default:
return fmt.Errorf(fmt.Sprintf("Unsupported table name of %s", tableName))
}
return nil
}
/*
当增加Alibusi(机构)数据时,这里我们不支持覆盖.如果机构账本数据不存在我们新建机构账本数据。
当前账本数据只包含剩余保证金,以及后续预付金的增加。
*/
func alibusiLeadger(tableName string,value map[string]interface{}, stub shim.ChaincodeStubInterface)(error){
Id := value["id"].(string)
result,err := stub.GetState(PREFIX+"_alibusiLeadger_"+ Id)
if err != nil {
return fmt.Errorf("%s GetState data fail: err %s! ",tableName+Id,err)
}
if result !=nil{
return fmt.Errorf("%s leadger data already exist! ",tableName+Id)
}
abail,ok := value["abail"].(float64)
if !ok {
return fmt.Errorf("amount fields type not number! ")
}
amount,ok := value["amount"].(float64)
if !ok {
return fmt.Errorf("amount fields type not number! ")
}
alibusi := AlibusiLeadger{
Id:Id,
Abail:abail,
Amount:amount,
}
alibyte , _:= json.Marshal(alibusi)
if err := stub.PutState(PREFIX+"_alibusiLeadger_"+ Id,alibyte);err!=nil{
return fmt.Errorf("%s leadger data putstate fail: %s ",tableName+Id,err)
}
return nil
}
/*
机构资金表变动,会直接作用于对应的机构账单表
*/
func addAlibusirecord(tableName string,value map[string]interface{}, stub shim.ChaincodeStubInterface)error{
Id,ok := value["aid"].(string)
if !ok {
return fmt.Errorf("aid fields type not string! ")
}
result,err := stub.GetState(PREFIX+"_alibusiLeadger_"+ Id)
if err != nil {
return fmt.Errorf("%s GetState data fail: err %s! ",tableName+Id,err)
}
if result ==nil{
return fmt.Errorf("%s leadger data not exist! ",tableName+Id)
}
alibusi := &AlibusiLeadger{}
if err := json.Unmarshal(result,alibusi);err != nil{
return fmt.Errorf("json Unmarshal fail,err: %s",err)
}
action,ok := value["action"].(float64)
if !ok {
return fmt.Errorf("action fields type not number! ")
}
amount,ok := value["amount"].(float64)
if !ok {
return fmt.Errorf("amount fields type not number! ")
}
samount,ok := value["samount"].(float64)
if !ok {
return fmt.Errorf("samount fields type not number! ")
}
if action==1{
alibusi.Amount -= amount
}else{
alibusi.Amount += amount
}
if alibusi.Amount != samount{
fmt.Println("alibus amount different from alibusirecord table samount !")
}
alibyte , _:= json.Marshal(alibusi)
if err := stub.PutState(PREFIX+"_alibusiLeadger_"+ Id,alibyte);err!=nil{
return fmt.Errorf("%s leadger data putstate fail: %s ",tableName+Id,err)
}
return nil
}
/*
商户账本表,当增加一张商户表时我们需要增加一张商户账本表,主要记录商户预付金的变化
*/
func merchantsLeadger(tableName string,value map[string]interface{}, stub shim.ChaincodeStubInterface)error{
Id := value["id"].(string)
result,err := stub.GetState(PREFIX+"_merchantsLeadger_"+ Id)
if err != nil {
return fmt.Errorf("%s GetState data fail: err %s! ",tableName+Id,err)
}
if result !=nil{
return fmt.Errorf("%s leadger data already exist! ",tableName+Id)
}
regular ,ok := value["regular"].(float64)
if !ok {
fmt.Errorf("regular fields type not number! ")
}
Bid ,ok := value["bid"].(string)
if !ok {
fmt.Errorf("bid fields type not string! ")
}
rregular ,ok := value["rregular"].(float64)
if !ok {
fmt.Errorf("rregular fields type not number! ")
}
merchantsL := MerchantsLeadger{
Id:Id,
Bid:Bid,
Regular:regular,
Rregular:rregular,
}
merbyte , _:= json.Marshal(merchantsL)
if err := stub.PutState(PREFIX+"_merchantsLeadger_"+ Id,merbyte);err!=nil{
return fmt.Errorf("%s leadger data putstate fail: %s ",tableName+Id,err)
}
return nil
}
/*
当增加一条交易记录的时候,我们需要根据交易记录实现,1.预付金的计算,2.计算分成,3.预付金的变化。分成的计算
*/
func addMerchantsale(tableName string,value map[string]interface{}, stub shim.ChaincodeStubInterface)error{
Id := value["id"].(string)
result,err := stub.GetState(PREFIX+"_"+tableName+"_"+ Id)
if err != nil {
return fmt.Errorf("%s GetState data fail: err %s! ",tableName+Id,err)
}
if result !=nil{
return fmt.Errorf("%s data already exist! ",tableName+Id)
}
mer := &Merchantsale{}
valByte,_ := json.Marshal(value)
err = json.Unmarshal(valByte,mer)
if err != nil {
return fmt.Errorf("Merchantsale struct json unmarshal fail,err : %s ",err)
}
//1.计算预付金 这部分待定
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 ")
}
//减少商户剩余预付金
merL := &MerchantsLeadger{}
resMer,err := stub.GetState(PREFIX+"_merchantsLeadger_"+ mer.Mid)
if err != nil {
return fmt.Errorf("%s GetState data fail: err %s! ","_merchantsLeadger_"+Id,err)
}
if resMer == nil{
return fmt.Errorf("%s leadger data not exist! ","_merchantsLeadger_"+Id)
}
err = json.Unmarshal(resMer,merL)
if err != nil{
return fmt.Errorf("MerchantsLeadger json unmarshal err :%s",err)
}
merL.Regular -= treposit
if mer.Afreposit == merL.Regular {
merbyte , _:= json.Marshal(merL)
if err := stub.PutState(PREFIX+"_merchantsLeadger_"+ Id,merbyte);err!=nil{
return fmt.Errorf("%s leadger data putstate fail: %s ","_merchantsLeadger_"+Id,err)
}
}
// 增加机构可提取资金
aliL := &AlibusiLeadger{}
resAli,err := stub.GetState(PREFIX+"_alibusiLeadger_"+ merL.Bid)
if err != nil {
return fmt.Errorf("%s GetState data fail: err %s! ","_alibusiLeadger_"+merL.Bid,err)
}
if resAli == nil{
return fmt.Errorf("%s leadger data not exist! ","_alibusiLeadger_"+merL.Bid)
}
err = json.Unmarshal(resAli,aliL)
if err != nil{
return fmt.Errorf("AlibusiLeadger json unmarshal err :%s",err)
}
aliL.Amount += treposit
alibyte , _:= json.Marshal(aliL)
if err := stub.PutState(PREFIX+"_alibusiLeadger_"+ merL.Bid,alibyte);err!=nil{
return fmt.Errorf("%s leadger data putstate fail: %s ","_alibusiLeadger_"+merL.Bid,err)
}
//新建分成数据
err = addProfit(Id,0,profit,stub)
if err!= nil{
return fmt.Errorf("add profit data fail,err: %s",err)
}
return nil
}
/*
当增加一张新券表的时候,我们同时增长一张券码库存表,用来记录,码库存的变化。
*/
func couticketsLeadger(tableName string,value map[string]interface{}, stub shim.ChaincodeStubInterface)error{
Id := value["id"].(string)
result,err := stub.GetState(PREFIX+"_couticketsLeadger_"+ Id)
if err != nil {
return fmt.Errorf("%s GetState data fail: err %s! ",tableName+Id,err)
}
if result !=nil{
return fmt.Errorf("%s leadger data already exist! ",tableName+Id)
}
codenum,ok := value["codenum"].(float64)
if !ok {
fmt.Errorf("codenum fields type not number! ")
}
codestork,ok := value["codestork"].(float64)
if !ok {
fmt.Errorf("codestork fields type not number! ")
}
couticketeL := CouticketsLeadger{
Id:Id,
Codenum:int(codenum),
Codestork:int(codestork),
}
merbyte , _:= json.Marshal(couticketeL)
if err := stub.PutState(PREFIX+"_couticketsLeadger_"+ Id,merbyte);err!=nil{
return fmt.Errorf("%s leadger data putstate fail: %s ",tableName+Id,err)
}
return nil
}
/*
当增加券可用门店时,我们同样需要增加一张券码可用门店库存表
*/
func coutcantmLeadger(tableName string,value map[string]interface{}, stub shim.ChaincodeStubInterface)error{
MId := value["id"].(string)
TId := value["tid"].(string)
result,err := stub.GetState(PREFIX+"_coutcantmLeadger_"+TId+"_"+MId)
if err != nil {
return fmt.Errorf("%s GetState data fail: err %s! ",tableName+TId+MId,err)
}
if result !=nil{
return fmt.Errorf("%s leadger data already exist! ",tableName+TId+MId)
}
codenum,ok := value["codenum"].(float64)
if !ok {
fmt.Errorf("codenum fields type not number! ")
}
resid,ok := value["resid"].(float64)
if !ok {
fmt.Errorf("resid fields type not number! ")
}
coutcantmL := CoutcantmLeadger {
Id:MId,
Tid:TId,
Codenum:int(codenum),
Resid:int(resid),
}
conbyte , _:= json.Marshal(coutcantmL)
if err := stub.PutState(PREFIX+"_coutcantmLeadger_"+TId+"_"+MId,conbyte);err!=nil{
return fmt.Errorf("%s leadger data putstate fail: %s ",tableName+TId+MId,err)
}
return nil
}
/*
当我们增加一个合作方信息表时,我们同时需要增加一张分润记录表,记录合作方的分润情况
*/
func coupartnersLeadger(tableName string,value map[string]interface{}, stub shim.ChaincodeStubInterface)error{
Id := value["id"].(string)
result,err := stub.GetState(PREFIX+"_coupartnersLeadger_"+ Id)
if err != nil {
return fmt.Errorf("%s GetState data fail: err %s! ",tableName+Id,err)
}
if result !=nil{
return fmt.Errorf("%s leadger data already exist! ",tableName+Id)
}
//benefittype,ok := value["benefittype"].(float64)
//if !ok {
// fmt.Errorf("benefittype fields type not number! ")
//}
//benefit,ok := value["benefit"].(float64)
//if !ok {
// fmt.Errorf("benefit fields type not number! ")
//}//缺少分润金额
return nil
}
/*
增加一张订单表时,我们要做相应的工作1.检查金额。2.计算分成 3.执行码变化
*/
func addCouticketorders(tableName string,value map[string]interface{}, stub shim.ChaincodeStubInterface)error{
Id := value["id"].(string)
result,err := stub.GetState(PREFIX+"_"+tableName+"_"+ Id)
if err != nil {
return fmt.Errorf("%s GetState data fail: err %s! ",tableName+Id,err)
}
if result !=nil{
return fmt.Errorf("%s data already exist! ",tableName+Id)
}
cout := &Couticketorders{}
valByte,_ := json.Marshal(value)
err = json.Unmarshal(valByte,cout)
if err != nil {
return fmt.Errorf("Couticketorders struct json unmarshal fail,err : %s ",err)
}
//计算
return nil
}
func addProfit(id string,typ int,profit float64,stub shim.ChaincodeStubInterface)error{
result,err := stub.GetState(PREFIX+"_profit_"+ id)
if err != nil {
return fmt.Errorf("%s GetState data fail: err %s! ","profit_"+ id,err)
}
if result !=nil{
return fmt.Errorf("%s leadger data already exist! ","profit_"+ id)
}
prof := &Profit{
Id:id,
Type:typ,
profit:profit,
}
profbyte , _:= json.Marshal(prof)
if err := stub.PutState(PREFIX+"_profit_"+id,profbyte);err!=nil{
return fmt.Errorf("%s leadger data putstate fail: %s ","profit_"+ id,err)
}
return nil
}
func Decimal(value float64) float64 {
value, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", value), 64)
return value
}
func main() {
err := shim.Start(&GXHCC{})
if err != nil {
fmt.Printf("Error starting EncCC chaincode: %s", err)
}
}
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":"newtype","alinkman":"newalinkman",
"amob":"new1234567890","backup":{"aname":"alibusi","atype":"type"}}`
inputarrary = `[{"id":"1","aname":"alibusi","atype":"type","alinkman":"alinkman",
"amob":"1234567890","backup":{"aname":"alibusi","atype":"type"}},{"id":"2","aname":"alibusi","atype":"type","alinkman":"alinkman",
"amob":"1234567890","backup":{"aname":"alibusi","atype":"type"}}]`
)
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 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))
}
package main
import (
"bytes"
"crypto/x509"
"encoding/json"
"encoding/pem"
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
pb "github.com/hyperledger/fabric/protos/peer"
"time"
)
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 SchemaParameters struct {
Value interface{} `json:"val"` //默认值 这里特别说明一下如果这里是backUp 字段,我们不进行更深一步的校验,包括格式
PAuth Auth `json:"auth"`
}
type Schema struct {
Fields map[string]SchemaParameters `json:"fields"`
SchemaAuth Auth `json:"schema_auth"` //schema 的写权限,主要是用在 schema update 部分
SAuth Auth `json:"auth"`
}
var (
defValue = "***" //查询用户权限不足的情况下默认返回值
PREFIX = "GXH"
IsUsers = false //是否启用用户权限,false 表示启用Roles
)
// Init does nothing for this cc
func (t *GXHCC) Init(stub shim.ChaincodeStubInterface) pb.Response {
return shim.Success([]byte("GXHCC init successful! "))
}
// Invoke for this chaincode exposes
func (t *GXHCC) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
// get arguments and transient
functionName, args := stub.GetFunctionAndParameters()
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 "put":
res, err := put(args, stub)
if err != nil {
return shim.Error(fmt.Sprintf("put 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 "update":
res, err := update(args, stub)
if err != nil {
return shim.Error(fmt.Sprintf("update function err: %s", err))
}
return shim.Success([]byte(res))
default:
return shim.Error(fmt.Sprintf("Unsupported function %s", functionName))
}
return shim.Success([]byte("GXHCC invoke successful "))
}
/*
put
args 字段说明:
1:args[0]代表我们具体操作的表,
2:args[1:]后面的数据表示要记录到数据库的数据,每一个string 必须是json字符串,并且需要每一个json 字符串都必须包含id 字段
*/
func put(args []string, stub shim.ChaincodeStubInterface) (string, error) {
if len(args) < 2 {
return "", fmt.Errorf("Expected more than 2 parameters to function put!")
}
var PutDatas []map[string]interface{}
commonName, err := getCertificateCommonName(stub)
if err != nil {
return "", fmt.Errorf("getCertificateCommonName happen err: %s ", err)
}
schema := &Schema{}
result, err := schema.get(args[0], stub)
if err != nil {
return "", err
}
if err := json.Unmarshal([]byte(result), &schema); err != nil {
return "", fmt.Errorf("json Unmarshal schemaRes err: %s ", 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("parameters Unmarshal fail,args string not json array, err:%s", err)
}
for k, mapres := range PutDatas {
Id, ok := mapres["id"]
if !ok {
return "", fmt.Errorf("The id field must exist ")
}
//if result, err := stub.GetState(args[0] + Id.(string)); err != nil {
// return "", fmt.Errorf("get %s data happen err: ", args[0]+Id.(string))
//}
//else if result != nil {
// return "", fmt.Errorf("%s data already exist", args[0]+Id.(string))
//}
if !SchemaCheck(schema.Fields, mapres) {
return "", fmt.Errorf("SchemaCheck fail,args index %d string doesn't match %s format", k, args[0])
}
putDate, _ := json.Marshal(mapres)
if err := stub.PutState(PREFIX+"_"+args[0]+"_"+Id.(string), putDate); err != nil {
return "", fmt.Errorf("PutState fail, err :%s", err)
}
}
return fmt.Sprintf("%s put data success!", args[0]), nil
}
/*
修改一个表的一条数据的一个或者多个字段值
*/
func update(args []string, stub shim.ChaincodeStubInterface) (string, error) {
if len(args) != 2 {
return "", fmt.Errorf("Expected 2 parameters to function update! ")
}
commonName, err := getCertificateCommonName(stub)
if err != nil {
return "", fmt.Errorf("getCertificateCommonName happen err: %s ", err)
}
schema := &Schema{}
schemaRes, err := schema.get(args[0], stub)
if err != nil {
return "", err
}
if err := json.Unmarshal([]byte(schemaRes), &schema); err != nil {
return "", fmt.Errorf("json Unmarshal schemaRes err: %s ", err)
}
var Updata map[string]interface{}
var allMap map[string]interface{}
if err := json.Unmarshal([]byte(args[1]), &Updata); err != nil {
return "", fmt.Errorf("parameters Unmarshal fail,args string not json string,err: %s", err)
}
Id, ok := Updata["id"]
if !ok {
return "", fmt.Errorf("The id field must exist ")
}
if ok, _ := authorityCheck(schema.SAuth.Write, commonName); !ok {
if ok, err := parsauthorityCheck(schema.Fields, Updata, commonName); !ok {
return "", fmt.Errorf("parsauthorityCheck err: %s", err)
}
}
result, err := stub.GetState(PREFIX + "_" + args[0] + "_" + Id.(string))
if err != nil || result == nil {
return "", fmt.Errorf("GetState data fail,please check your parameters ")
}
if err := json.Unmarshal(result, &allMap); err != nil {
return "", fmt.Errorf("result parameters Unmarshal fail err:%s ", err)
}
if err := Deassign(Updata, allMap); err != nil {
return "", err
}
resultByte, _ := json.Marshal(allMap)
if err := stub.PutState(PREFIX+"_"+args[0]+"_"+Id.(string), resultByte); err != nil {
return "", fmt.Errorf("updateState date fail, err :%s ", err)
}
return fmt.Sprintf("%s update data success!", args[0]), nil
}
func get(args []string, stub shim.ChaincodeStubInterface) (string, error) {
if len(args) != 2 {
return "", fmt.Errorf("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{}
var mapResult map[string]interface{}
if err := json.Unmarshal([]byte(args[1]), &parameters); err != nil {
return "", fmt.Errorf("parameters Unmarshal fail,args string not json string,err: %s", err)
}
Id, ok := parameters["id"]
if !ok {
return "", fmt.Errorf("The id field must exist ")
}
result, err := stub.GetState(PREFIX + "_" + args[0] + "_" + Id.(string))
if err != nil || result == nil {
return "", fmt.Errorf("GetState data fail,please check your parameters ")
}
schema := &Schema{}
schemaRes, err := schema.get(args[0], stub)
if err != nil {
return "", err
}
if err := json.Unmarshal([]byte(schemaRes), &schema); err != nil {
return "", fmt.Errorf("json Unmarshal schemaRes err: %s ", err)
}
if err := json.Unmarshal(result, &mapResult); err != nil {
return "", fmt.Errorf(" Unmarshal fail,result err: %s", err)
}
if ok, _ := authorityCheck(schema.SAuth.Read, commonName); !ok {
if filteredData, err := dataFilter(schema.Fields, mapResult, commonName); err != nil {
return "", fmt.Errorf(" dataFilter fail, err: %s", err)
} else {
result, _ := json.Marshal(filteredData)
return string(result), nil
}
} else {
return string(result), 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
}
func SchemaCheck(schema map[string]SchemaParameters, checkmap map[string]interface{}) bool {
if len(schema) != len(checkmap) {
return false
}
for k, v := range checkmap {
if schemaV, ok := schema[k]; !ok {
return false
} else {
if parameterS, ok := schemaV.Value.(map[string]interface{}); ok {
if parameterC, ok := v.(map[string]interface{}); !ok {
return false
} else {
if !BackUpCheck(parameterS, parameterC) {
return false
}
}
//else {
// var backUp map[string]SchemaParameters
// backUpByte,_ := json.Marshal(parameterS)
// if err := json.Unmarshal(backUpByte,&backUp);err != nil{
// return false
// }
// if !SchemaCheck(backUp, parameterC) {
// return false
// }
//}
}
}
}
return true
}
func BackUpCheck(backUp map[string]interface{}, checkmap map[string]interface{}) bool {
if len(backUp) != len(checkmap) {
return false
}
for k := range checkmap {
if _, ok := backUp[k]; !ok {
return false
}
}
return true
}
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]))
}
}
/*
put
args 字段说明:
1:args[0]代表我们具体操作的表,
2:args[1:]后面的数据表示要记录到数据库的数据,每一个string 必须是json字符串,并且需要每一个json 字符串都必须包含id 字段
我们可以发现json字符串都被我们解析成了map[string]interface{}类型的map,其中key代表表模板的字段,interface可以是一个结构,我们当前将他看做我们表模板字段的初始值。
*/
func (this *Schema) put(args []string, stub shim.ChaincodeStubInterface) (string, error) {
if len(args) != 2 {
return "", fmt.Errorf("Expected 2 parameters to function put!")
}
var schema *Schema
var err error
if schema, err = NewSchema(args[1]); err != nil {
return "", fmt.Errorf("parameters Unmarshal fail,args string not json string,err: %s", err)
} else {
if backupValue, ok := schema.Fields["backup"]; ok {
if _, ok := backupValue.Value.(map[string]interface{}); !ok {
return "", fmt.Errorf("parameters Unmarshal fail,extra string not json string,err: %s", err)
}
//var backUp map[string]SchemaParameters
//backUpByte, _ := json.Marshal(backupValue.Value)
//if err := json.Unmarshal(backUpByte, &backUp); err != nil {
// return "", fmt.Errorf("backup value parameters struct err %s ", err)
//}
}
}
//if err := json.Unmarshal([]byte(args[1]), &schema); err != nil {
// return "", fmt.Errorf("parameters Unmarshal fail,args string not json string,err: %s", err)
//} else {
//
//}
_, ok := schema.Fields["id"]
if !ok {
return "", fmt.Errorf("The id field must exist ")
}
if value, _ := stub.GetState(PREFIX + "_" + args[0]); value != nil {
return "", fmt.Errorf("the parameter %s already exists and cannot be added", args[0])
}
putDate, _ := json.Marshal(schema) //处理重复字段
if err := stub.PutState(PREFIX+"_"+args[0], putDate); err != nil {
return "", fmt.Errorf("PutState fail,err: %s", err)
}
return fmt.Sprintf("%s schema put success!", args[0]), nil
}
/*
if update Schema 那么我们没有办法比较旧有的一个模板,
Schema 的 update,不支持部分修改,因为存在增加和删除某些字段的情况。
TODO,增加版本管理
*/
func (this *Schema) update(args []string, stub shim.ChaincodeStubInterface) (string, error) {
if len(args) != 2 {
return "", fmt.Errorf("expected 2 parameters to function put! ")
}
var schema *Schema
var err error
if schema, err = NewSchema(args[1]); err != nil {
return "", fmt.Errorf("parameters Unmarshal fail,args string not json string,err: %s", err)
} else {
if backupValue, ok := schema.Fields["backup"]; ok {
if _, ok := backupValue.Value.(map[string]interface{}); !ok {
return "", fmt.Errorf("parameters Unmarshal fail,extra string not json string,err: %s", err)
}
}
}
_, ok := schema.Fields["id"]
if !ok {
return "", fmt.Errorf("The id field must exist ")
}
result, err := stub.GetState(PREFIX + "_" + args[0])
if err != nil || result == nil {
return "", fmt.Errorf("%s schema data doesn't exist,please check your parameters ", args[0])
}
if err := json.Unmarshal([]byte(result), &schema); err != nil {
return "", fmt.Errorf("parameters Unmarshal fail, err: %s", err)
}
commonName, err := getCertificateCommonName(stub)
if err != nil {
return "", fmt.Errorf("getCertificateCommonName happen err: %s ", err)
}
if ok, err := authorityCheck(schema.SchemaAuth.Write, commonName); !ok {
return "", fmt.Errorf("update %s schema fail,err: %s ", args[0], err)
}
if err = stub.PutState(PREFIX+"_"+args[0], []byte(args[1])); err != nil {
return "", fmt.Errorf("%s schema data PutState fail,please try again ", args[0])
}
return fmt.Sprintf("%s schema update success!", args[0]), err
}
func (this *Schema) get(args string, stub shim.ChaincodeStubInterface) (string, error) {
result, err := stub.GetState(PREFIX + "_" + args)
if err != nil || result == nil {
return "", fmt.Errorf("GetSchema data fail,please check your parameters ")
}
return string(result), nil
}
func (this *Schema) getSchema(args string, stub shim.ChaincodeStubInterface) (string, error) {
result, err := stub.GetState(PREFIX + "_" + args)
if err != nil || result == nil {
return "", fmt.Errorf("GetSchema data fail,please check your parameters ")
}
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 getCertificateCommonName(stub shim.ChaincodeStubInterface) (string, error) {
return "admin", 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 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 !authorityCheck(schemaV.Write, commonName) {
// return false, fmt.Errorf("%s field permission check does not match", k)
// }
// else {
// if res, err := parsauthorityCheck(parameterS, parameterC, commonName); !res {
// return res, err
// }
// }
//} else {
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 dataFilter(schema map[string]SchemaParameters, checkmap map[string]interface{}, commonName string) (map[string]interface{}, error) {
for k, v := range checkmap {
if schemaV, ok := schema[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 _, err := dataFilter(parameterS, parameterC, commonName); err!=nil {
// return nil, err
// }
//}
} else {
if ok, _ := authorityCheck(schemaV.PAuth.Read, commonName); !ok {
checkmap[k] = defValue
}
}
}
}
return checkmap, 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 NewSchema(arg string) (*Schema, error) {
schema := &Schema{
Fields: make(map[string]SchemaParameters),
}
var argMap map[string]interface{}
if err := json.Unmarshal([]byte(arg), &argMap); err != nil {
return nil, err
}
if argMap["fields"] != nil {
if err := json.Unmarshal([]byte(arg), schema); err != nil {
return nil, err
}
return schema, nil
}
for k, v := range argMap {
schema.Fields[k] = SchemaParameters{
Value: v,
PAuth: Auth{},
}
}
return schema, nil
}
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 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 schemaupdate = `{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"fields":{"acid":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":3},"id":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"1"},"actionid":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"adiscounts":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"0.8"},"aid":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":0},"altdate":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"2010-01-01 15:38:54"},"are":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"backup":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":{}},"cid":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":0},"contract":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"16161616032"},"cosperson":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":100},"did":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":2},"dineraprice":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":80},"dineretime":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"15:30:59"},"dinerprice":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":100},"dinersprice":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":90},"dinerstime":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"11:10:00"},"distype":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":16},"dledate":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"2010-01-01 15:38:54"},"esign":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"2010-12-31 15:38:54"},"fid":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":4},"firrenew":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"2010-01-02 15:38:54"},"haver":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"indate":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"2018/10/29 16:46:57"},"ischain":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"isset":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"issnp":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"keywords":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"test"},"lat":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"43.840345"},"licence":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"103451015521"},"linedate":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"2010-01-02 15:38:54"},"lng":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"125.28796"},"mact":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"123456"},"mactname":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"联系人1"},"maddr":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"测试地址1"},"marea":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"mbtype":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"mdiposit":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"中国银行"},"mlinkman":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"联系人1"},"mlinkmob":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"18555555555"},"mname":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"测试连锁店1"},"mno":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"59118600000005"},"mno2":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"05910005"},"msubtype":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":10},"mtype":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":9},"murl":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"http://www.baidu.com"},"ordertel":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"13444444444"},"paystatue":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"perquisites":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":3},"persales":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":100},"pname":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"8820180008552970"},"ppass":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"152820"},"regular":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":6000},"relevel":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":5},"retype":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":0},"rregular":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":6000},"sdiscounts":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"0.85"},"shophours":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"24小时营业"},"sregular":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":6000},"ssign":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"2010-01-01 15:38:54"},"statue":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":0},"supperaprice":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":90},"supperetime":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"23:59:59"},"supperprice":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":120},"suppersprice":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":110},"supperstime":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"15:31:00"},"tstatue":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":1},"mcode":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"11201700000003"},"warmline":{"auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}},"val":"600"}},"schema_auth":{"read":{"roles":null,"users":null},"write":{"roles":null,"users":null}}}`
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":"newtype","alinkman":"newalinkman",
"amob":"new1234567890","backup":{"aname":"alibusi","atype":"type"}}`
inputarrary = `[{"id":"1","aname":"alibusi","atype":"type","alinkman":"alinkman",
"amob":"1234567890","backup":{"aname":"alibusi","atype":"type"}},{"id":"2","aname":"alibusi","atype":"type","alinkman":"alinkman",
"amob":"1234567890","backup":{"aname":"alibusi","atype":"type"}}]`
)
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(schemaupdate)})
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(schemaupdate)})
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"}`
//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 (
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": "2018-10-29 16:46:57",
"backup": {
"aname": "alibusi",
"atype": "type"
}
}, {
"id": "2",
"aname": "alibusi",
"atype": 102,
"alinkman": 10.34,
"amob": "2018-10-29 16:46:57",
"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(schemaCheck)})
//使用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 TestGetCommonName(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("getCertCommonName")})
fmt.Printf("Invoke status %d,message %s and payload %s\n",
responseByPutschema.Status,responseByPutschema.Message,string(responseByPutschema.Payload))
}
//7455 162316 ns/op
//5402 214421 ns/op
func BenchmarkPut(b *testing.B){
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(schemaCheck)})
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))
for i:=0;i<b.N ;i++ {
responseByPut := stub.MockInvoke("invoke1",[][]byte{[]byte("put"), []byte("alibusi"),[]byte(inputCs)})
if responseByPut.Status != 200{
fmt.Println()
fmt.Println("========================================invoke data put============================================")
fmt.Println()
fmt.Println()
fmt.Printf("Invoke status %d,message %s ,and payload %s\n",
responseByPut.Status,responseByPut.Message,string(responseByPut.Payload))
return
}
}
}
package testcc package main
import (
"encoding/json"
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
pb "github.com/hyperledger/fabric/protos/peer"
)
type TestCC struct {
}
// Init does nothing for this cc
func (t *TestCC) Init(stub shim.ChaincodeStubInterface) pb.Response {
return shim.Success([]byte("GXHCC init successful! "))
}
// Invoke for this chaincode exposes
func (t *TestCC) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
// get arguments and transient
functionName, args := stub.GetFunctionAndParameters()
switch functionName {
case "put":
res,err := put(args,stub)
if err!=nil{
return shim.Error(fmt.Sprintf("put function err: %s", err))
}
return shim.Success([]byte(res))
case "putNo":
res,err := putNo(args,stub)
if err!=nil{
return shim.Error(fmt.Sprintf("put function err: %s", err))
}
return shim.Success([]byte(res))
default:
return shim.Error(fmt.Sprintf("Unsupported function %s", functionName))
}
return shim.Success([]byte("GXHCC invoke successful "))
}
/*
put
args 字段说明:
1:args[0]代表我们具体操作的表,
2:args[1:]后面的数据表示要记录到数据库的数据,每一个string 必须是json字符串,并且需要每一个json 字符串都必须包含id 字段
*/
func put(args []string, stub shim.ChaincodeStubInterface) (string, error) {
//if len(args) < 2 {
// return "", fmt.Errorf("Expected more than 2 parameters to function put!")
//}
var Result []map[string]interface{}
if err := json.Unmarshal([]byte(args[0]), &Result); err != nil {
return "", fmt.Errorf("parameters Unmarshal fail,args string not json array, err:%s", err)
}
for _, mapres := range Result{
Id ,ok:= mapres["id"]
if !ok{
return "", fmt.Errorf("The id field must exist ")
}
tablename,ok := mapres["tablename"].(string)
if !ok{
return "", fmt.Errorf("tablename fields type not string! ")
}
putDate,_:=json.Marshal(mapres)
if err := stub.PutState(tablename+Id.(string), putDate); err != nil {
return "", fmt.Errorf("PutState fail, err :%s", err)
}
err := tableDifferentiate(tablename,mapres,stub)
if err != nil{
return "", err
}
}
return fmt.Sprintf("%s put data success!", args[0]), nil
}
/*
put
args 字段说明:
1:args[0]代表我们具体操作的表,
2:args[1:]后面的数据表示要记录到数据库的数据,每一个string 必须是json字符串,并且需要每一个json 字符串都必须包含id 字段
*/
func putNo(args []string, stub shim.ChaincodeStubInterface) (string, error) {
//if len(args) < 2 {
// return "", fmt.Errorf("Expected more than 2 parameters to function put!")
//}
var Result []map[string]interface{}
if err := json.Unmarshal([]byte(args[0]), &Result); err != nil {
return "", fmt.Errorf("parameters Unmarshal fail,args string not json array, err:%s", err)
}
for _, mapres := range Result{
Id ,ok:= mapres["id"]
if !ok{
return "", fmt.Errorf("The id field must exist ")
}
tablename,ok := mapres["tablename"].(string)
if !ok{
return "", fmt.Errorf("tablename fields type not string! ")
}
putDate,_:=json.Marshal(mapres)
if err := stub.PutState(tablename+Id.(string), putDate); err != nil {
return "", fmt.Errorf("PutState fail, err :%s", err)
}
}
return fmt.Sprintf("%s put data success!", args[0]), nil
}
/*
根据参数区分不同的表,并执行不同的操作
*/
func tableDifferentiate(tableName string,value map[string]interface{}, stub shim.ChaincodeStubInterface)(error){
switch tableName {
case "alibusi":
return addCompositeKey(tableName,value, stub)
case "alibusirecord":
//return addAlibusirecord(tableName,value, stub)
case "merchants":
//return merchantsLeadger(tableName,value, stub)
case "couincomingparts":
//return addMerchantsale(args[1:],stub)
case "merchantsale":
//return addMerchantsale(tableName,value, stub)
case "coutickets":
//return couticketsLeadger(tableName,value, stub)
case "coutcantm":
//return coutcantmLeadger(tableName,value, stub)
case "couticketcodes":
//return coupartnersLeadger(args[1:],stub)
case "coupartners":
//return coupartnersLeadger(tableName,value, stub)
case "couticketorders":
// return addCouticketorders(tableName,value,stub)
default:
return fmt.Errorf(fmt.Sprintf("Unsupported table name of %s", tableName))
}
return nil
}
func addCompositeKey(tableName string,value map[string]interface{}, stub shim.ChaincodeStubInterface)error{
valBy,_ := json.Marshal(value)
Id := value["id"].(string)
aname,ok := value["aname"].(string)
if !ok{
return fmt.Errorf("aname fields type not string! ")
}
anamecomKey,err :=stub.CreateCompositeKey(tableName,[]string{aname,Id})
if err!=nil{
return err
}
if err := stub.PutState(anamecomKey, valBy); err != nil {
return fmt.Errorf("Put %s date fail, err :%s ",anamecomKey, err)
}
return nil
}
func main() {
err := shim.Start(&TestCC{})
if err != nil {
fmt.Printf("Error starting EncCC chaincode: %s", err)
}
}
\ No newline at end of file
package main
import (
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
"testing"
)
func TestPutData(t *testing.T){
cc := new(TestCC)
stub := shim.NewMockStub("TestCC",cc)
response:= stub.MockInit("init",nil)
fmt.Println(string(response.Payload))
input := `[{"id":"1","aname":"共享惠","tablename":"alibusi"},{"id":"2","aname":"共享惠","tablename":"alibusi"}]`
responseByPut := stub.MockInvoke("invoke1",[][]byte{[]byte("put"),[]byte(input)})
fmt.Printf("Invoke status %d,message %s and payload %s\n",responseByPut.Status,responseByPut.Message,string(responseByPut.Payload))
}
func TestPutNoData(t *testing.T){
cc := new(TestCC)
stub := shim.NewMockStub("TestCC",cc)
response:= stub.MockInit("init",nil)
fmt.Println(string(response.Payload))
input := `[{"id":"1","aname":"共享惠","tablename":"alibusi"},{"id":"2","aname":"共享惠","tablename":"alibusi"}]`
responseByPut := stub.MockInvoke("invoke1",[][]byte{[]byte("putNo"),[]byte(input)})
fmt.Printf("Invoke status %d,message %s and payload %s\n",responseByPut.Status,responseByPut.Message,string(responseByPut.Payload))
}
\ No newline at end of file
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