Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
chaincode
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
袁邓@五瓣科技
chaincode
Commits
d7ba709c
Commit
d7ba709c
authored
Apr 07, 2020
by
刘星星@五瓣科技
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
4.7 commit
parent
46b87768
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
3862 additions
and
670 deletions
+3862
-670
gongxianghui.go
src/github.com/gongxianghui2.0/gongxianghui.go
+1075
-645
gongxianghui2.0_test.go
src/github.com/gongxianghui2.0/gongxianghui2.0_test.go
+51
-23
gongxianghui_test.go
src/github.com/gongxianghui2.0/gongxianghui_test.go
+46
-2
dataobject.go
src/github.com/gongxianghui_framework/dataobject.go
+306
-0
gongxianghui.go
src/github.com/gongxianghui_framework/gongxianghui.go
+741
-0
gongxianghui2.0_test.go
...github.com/gongxianghui_framework/gongxianghui2.0_test.go
+427
-0
gongxianghui_test.go
src/github.com/gongxianghui_framework/gongxianghui_test.go
+327
-0
gongxinghuileadger_test.go
...hub.com/gongxianghui_framework/gongxinghuileadger_test.go
+18
-0
leadger.go
src/github.com/gongxianghui_framework/leadger.go
+545
-0
schema.go
src/github.com/gongxianghui_framework/schema.go
+326
-0
No files found.
src/github.com/gongxianghui2.0/gongxianghui.go
View file @
d7ba709c
...
...
@@ -4,8 +4,8 @@ import (
"bytes"
"crypto/x509"
"encoding/json"
"math/big"
"reflect"
"sync"
"time"
//"encoding/json"
...
...
@@ -19,35 +19,31 @@ import (
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"`
//字段的写权限
Write
AuthGroup
`json:"write"`
//字段的写权限
}
type
LeadgerAuth
struct
{
type
LeadgerAuth
struct
{
// 账本数据除了读权限外
Read
AuthGroup
`json:"read"`
// 字段的读权限,“”,不存在权限,
// Write AuthGroup `json:"write"`//字段的写权限 如果是账本数据
Issue
AuthGroup
`json:"issue"`
//账本数据的发行权限
Extract
AuthGroup
`json:"extrate"`
//账本数据的提取权限
Transfer
AuthGroup
`json:"transfer"`
// 账本数据的转账权限,默认是只有账户的所属者
Issue
AuthGroup
`json:"issue"`
//账本数据的发行权限,
Extract
AuthGroup
`json:"extrate"`
//账本数据的提取权限,
Transfer
AuthGroup
`json:"transfer"`
// 账本数据的转账权限,
}
type
SchemaParameters
struct
{
Value
interface
{}
`json:"val"`
//默认值 这里特别说明一下如果这里是backUp 字段,我们不进行更深一步的校验,包括格式
Value
interface
{}
`json:"val"`
//默认值 这里特别说明一下如果这里是backUp 字段,我们不进行更深一步的校验,包括格式
PAuth
Auth
`json:"auth"`
FCheck
*
Checks
`json:"fcheck"`
}
type
SchemaLeadgerParameters
struct
{
Value
interface
{}
`json:"val"`
//默认值 这里特别说明一下如果这里是backUp 字段,我们不进行更深一步的校验,包括格式
Value
interface
{}
`json:"val"`
//默认值 这里特别说明一下如果这里是backUp 字段,我们不进行更深一步的校验,包括格式
PAuth
LeadgerAuth
`json:"auth"`
FCheck
*
Checks
`json:"fcheck"`
}
...
...
@@ -58,36 +54,33 @@ type Checks struct {
Fieldlen
int
`json:"fieldlen"`
//字段长度(如果字段类型是string,表示字段长度,如果是数值类型用0,1表示数据正负)
}
type
Schema
struct
{
//Fields map[string]SchemaParameters `json:"fields"`
LeadgerFields
map
[
string
]
SchemaLeadgerParameters
`json:"leadger_fields"`
//账本字段
StorageFields
map
[
string
]
SchemaParameters
`json:"storage_fields"`
//存证字段
SchemaAuth
Auth
`json:"schema_auth"`
//schema 的写权限,主要是用在 schema update 部分
SAuth
Auth
`json:"auth"`
SchemaAuth
Auth
`json:"schema_auth"`
//schema 的写权限,主要是用在 schema update 部分
SAuth
Auth
`json:"auth"`
//数据总的读权限
}
type
Action
struct
{
AccountType
string
`json:"account_type"`
//账户类型
AccountType
string
`json:"account_type"`
//账户类型
AccountId
string
`json:"account_id"`
//账户Id
ActionAmount
float64
`json:"action_amount"`
//这次的动作金额
ActionAmount
string
`json:"action_amount"`
//这次的动作金额
FundType
string
`json:"fund_type"`
//资金类型
BackUp
interface
{}
`json:"back_up"`
//备注信息
BackUp
interface
{}
`json:"back_up"`
//备注信息
}
type
TransferAccount
struct
{
AccountType
string
`json:"account_type"`
//账户类型
AccountType
string
`json:"account_type"`
//账户类型
AccountId
string
`json:"account_id"`
//账户Id
FundType
string
`json:"fund_type"`
//资金类型
}
type
Node
struct
{
Key
string
Value
[]
byte
Value
*
Schema
pre
*
Node
next
*
Node
}
type
LRUCache
struct
{
limit
int
HashMap
map
[
string
]
*
Node
...
...
@@ -95,28 +88,40 @@ type LRUCache struct {
end
*
Node
}
type
Merchantsale
struct
{
Mid
string
`json:"mid"`
//商户Id
Bid
string
`json:"bid"`
// 分支机构id,也是一笔交易的接受者
Tamount
float64
`json:"tamount"`
//交易金额
Treposit
float64
`json:"treposit"`
//扣除预付金
Bereposit
float64
`json:"bereposit"`
//扣除前预付金
Afreposit
float64
`json:"afreposit"`
//扣除后预付金
Tamount
string
`json:"tamount"`
//交易金额
Treposit
string
`json:"treposit"`
//扣除预付金
Bereposit
string
`json:"bereposit"`
//扣除前预付金
Afreposit
string
`json:"afreposit"`
//扣除后预付金
Feerate
float64
`json:"feerate"`
// 手续费扣率
F
ee
float64
`json:"fee"`
// 手续费
Oamount
float64
`json:"oamount"`
// 原始交易金额
F
ree
string
`json:"free"`
// 手续费
Oamount
string
`json:"oamount"`
// 原始交易金额
Adiscounts
float64
`json:"adiscounts"`
//代理结算折扣
Sdiscounts
float64
`json:"sdiscounts"`
//消费折扣
Nodisamount
float64
`json:"nodisamount"`
//不打折金额
Disamount
float64
`json:"disamount"`
//打折金额
Perquisites
float64
`json:"perquisites"`
//额外收益
Nodisamount
string
`json:"nodisamount"`
//不打折金额
Disamount
string
`json:"disamount"`
//打折金额
Perquisites
string
`json:"perquisites"`
//额外收益
}
type
OrderTx
struct
{
Oamount
string
`json:"oamount"`
// 原始交易金额
Pamount
string
`json:"pamount"`
// 支付金额
Odesc
*
OrderDescribe
`json:"odesc"`
//订单描述
Mid
string
`json:"mid"`
//商户Id
Norate
float64
`json:"norate"`
//无预付金收益率
Outfree
string
`json:"outfree"`
//付款方手续费
Infree
string
`json:"infree"`
//收款方手续费
Partnersfree
string
`json:"partnersfree"`
//订单合作方手续费
Free
string
`json:"free"`
// 手续费
Pid
string
`json:"pid"`
//合作方Id
}
type
Merchant
struct
{
Id
string
`json:"id"`
type
OrderDescribe
struct
{
Codes
[]
string
`json:"codes"`
//码
TicketType
int
`json:"ticket_type"`
//券类型,折扣券只能使用一次
Tid
string
`json:"tid"`
//券Id
}
type
CommonTx
struct
{
...
...
@@ -124,36 +129,37 @@ type CommonTx struct {
SenderId
string
`json:"sender_id"`
SenderFunt
string
`json:"sender_funt"`
ReceiverAccountType
string
`json:"receiver_account"`
ReceiverId
string
`json:"receiver_account
_id"`
ReceiverId
string
`json:"receiver
_id"`
ReceiverFunt
string
`json:"receiver_funt"`
Amount
float64
`json:"amount"`
Amount
string
`json:"amount"`
}
type
transferTypes
func
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
error
// 声明了一个函数类型
type
transferTypes
func
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
error
// 声明了一个函数类型
type
putDataFilter
func
(
putDatas
[]
map
[
string
]
interface
{},
name
,
tableName
string
,
schema
*
Schema
,
stub
shim
.
ChaincodeStubInterface
)
(
string
,
error
)
// 声明了一个函数类型,这个函数类型主要是用于putdata 数据过滤使用
var
(
defValue
=
"***"
//查询用户权限不足的情况下默认返回值
PREFIX
=
"GXH"
StoragePrefix
=
"SGXH"
LeadgerPrefix
=
"LGXH"
IsUsers
=
true
//是否启用用户权限,false 表示启用Roles
GxhSchema
=
"gxhSchema"
//schema 存储前缀,为了实现复合主键使用。
InitSchemaLength
=
12
//初始化时
schema 的长度
InitSchemaLength
=
12
//缓存的
schema 的长度
schemaCache
=
Constructor
(
InitSchemaLength
)
once
=
sync
.
Once
{}
updateTime
=
int64
(
60
*
60
*
12
)
//schema 更新时间间隔,默认是12小时
lastTime
=
int64
(
0
)
transferType
=
initTransfer
()
PutDataFilter
=
initPutData
()
)
// Init does nothing for this cc
func
(
t
*
GXHCC
)
Init
(
stub
shim
.
ChaincodeStubInterface
)
pb
.
Response
{
return
shim
.
Success
([]
byte
(
"
GXHCC
init successful! "
))
return
shim
.
Success
([]
byte
(
"
gxhcc
init successful! "
))
}
/*
初始化我们要使用的交易
类型
初始化我们要使用的交易
执行方法
*/
func
initTransfer
()
map
[
string
]
transferTypes
{
func
initTransfer
()
map
[
string
]
transferTypes
{
transferType
:=
make
(
map
[
string
]
transferTypes
)
transferType
[
"merchants"
]
=
merchantsale
transferType
[
"tickerorders"
]
=
tickerorders
...
...
@@ -161,42 +167,67 @@ func initTransfer()map[string]transferTypes{
return
transferType
}
func
initSchema
(
stub
shim
.
ChaincodeStubInterface
)
error
{
var
errinfo
error
once
.
Do
(
func
(){
schemaIterator
,
err
:=
stub
.
GetStateByPartialCompositeKey
(
GxhSchema
,
nil
)
func
initPutData
()
map
[
string
]
putDataFilter
{
filter
:=
make
(
map
[
string
]
putDataFilter
)
filter
[
"couticketcodes"
]
=
codeFilter
filter
[
"commonput"
]
=
commanFilter
filter
[
"coutcantm"
]
=
ticketMerFilter
return
filter
}
/*
处理缓存内容的方法,
*/
func
initSchema
(
stub
shim
.
ChaincodeStubInterface
)
error
{
timeStamp
,
err
:=
stub
.
GetTxTimestamp
()
if
err
!=
nil
{
errinfo
=
err
return
return
err
}
else
if
timeStamp
.
GetSeconds
()
<
lastTime
+
updateTime
{
return
nil
}
var
values
map
[
string
]
*
Schema
values
=
make
(
map
[
string
]
*
Schema
)
schemaIterator
,
err
:=
stub
.
GetStateByPartialCompositeKey
(
GxhSchema
,
nil
)
if
err
!=
nil
{
return
err
}
defer
schemaIterator
.
Close
()
index
:=
1
for
schemaIterator
.
HasNext
()
{
querykv
,
err
:=
schemaIterator
.
Next
()
for
schemaIterator
.
HasNext
()
{
querykv
,
err
:=
schemaIterator
.
Next
()
if
err
!=
nil
{
errinfo
=
err
return
return
err
}
fmt
.
Println
(
"add cache key:"
,
querykv
.
Key
)
_
,
compisiteKeys
,
err
:=
stub
.
SplitCompositeKey
(
querykv
.
Key
)
if
err
!=
nil
{
errinfo
=
err
return
fmt
.
Println
(
"add cache key:"
,
querykv
.
Key
)
_
,
compisiteKeys
,
err
:=
stub
.
SplitCompositeKey
(
querykv
.
Key
)
if
err
!=
nil
{
return
err
}
scema
:=
&
Schema
{}
err
=
json
.
Unmarshal
(
querykv
.
Value
,
scema
)
if
err
!=
nil
{
fmt
.
Sprintf
(
"json unmarshal %s schema fail,err: %s
\n
"
,
querykv
.
Key
,
err
)
}
schemaCache
.
Put
(
compisiteKeys
[
0
],
querykv
.
Value
)
fmt
.
Println
(
"add cache key:"
,
querykv
.
Key
)
if
schemaCache
.
Get
(
compisiteKeys
[
0
])
!=
nil
{
schemaCache
.
Put
(
compisiteKeys
[
0
],
scema
)
fmt
.
Println
(
"add cache key:"
,
querykv
.
Key
)
index
++
if
index
>
InitSchemaLength
{
fmt
.
Println
(
"cache data length :"
,
len
(
schemaCache
.
HashMap
))
return
fmt
.
Println
(
"cache data length :"
,
len
(
schemaCache
.
HashMap
))
return
nil
}
}
else
{
values
[
compisiteKeys
[
0
]]
=
scema
}
fmt
.
Println
(
"cache data length :"
,
len
(
schemaCache
.
HashMap
))
return
})
if
errinfo
!=
nil
{
return
errinfo
}
for
len
(
schemaCache
.
HashMap
)
<
InitSchemaLength
{
for
k
,
v
:=
range
values
{
schemaCache
.
Put
(
k
,
v
)
}
}
fmt
.
Println
(
"cache data length :"
,
len
(
schemaCache
.
HashMap
))
lastTime
=
timeStamp
.
GetSeconds
()
//设置最新修改时间
return
nil
}
...
...
@@ -204,70 +235,52 @@ func initSchema(stub shim.ChaincodeStubInterface)error{
func
(
t
*
GXHCC
)
Invoke
(
stub
shim
.
ChaincodeStubInterface
)
pb
.
Response
{
// get arguments and transient
functionName
,
args
:=
stub
.
GetFunctionAndParameters
()
err
:=
initSchema
(
stub
)
if
err
!=
nil
{
var
err
error
err
=
initSchema
(
stub
)
if
err
!=
nil
{
return
shim
.
Error
(
err
.
Error
())
}
var
res
string
switch
functionName
{
case
"authority"
:
case
"schema"
:
res
,
err
:=
SchemaProcess
(
args
,
stub
)
if
err
!=
nil
{
return
shim
.
Error
(
fmt
.
Sprintf
(
"SchemaProcess function err: %s"
,
err
))
res
,
err
=
SchemaProcess
(
args
,
stub
)
if
err
!=
nil
{
return
shim
.
Error
(
fmt
.
Sprintf
(
"schema process function err: %s"
,
err
))
}
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
"putData"
:
res
,
err
:=
putData
(
args
,
stub
)
if
err
!=
nil
{
return
shim
.
Error
(
fmt
.
Sprintf
(
"putData function err: %s"
,
err
))
case
"update"
:
res
,
err
=
updateStoreData
(
args
,
stub
)
if
err
!=
nil
{
return
shim
.
Error
(
fmt
.
Sprintf
(
"up store data function err: %s"
,
err
))
}
return
shim
.
Success
([]
byte
(
res
))
case
"get"
:
res
,
err
:=
get
(
args
,
stub
)
if
err
!=
nil
{
res
,
err
=
get
(
args
,
stub
)
if
err
!=
nil
{
return
shim
.
Error
(
fmt
.
Sprintf
(
"get function err: %s"
,
err
))
}
return
shim
.
Success
([]
byte
(
res
))
case
"upStoreData"
:
//
res
,
err
:=
updateStoreData
(
args
,
stub
)
if
err
!=
nil
{
return
shim
.
Error
(
fmt
.
Sprintf
(
"upStoreData function err: %s"
,
err
))
}
return
shim
.
Success
([]
byte
(
res
))
case
"createAccount"
:
res
,
err
:=
createAccount
(
args
,
stub
)
if
err
!=
nil
{
return
shim
.
Error
(
fmt
.
Sprintf
(
"createAccount function err: %s"
,
err
))
}
return
shim
.
Success
([]
byte
(
res
))
case
"createTx"
:
res
,
err
:=
transactionProcess
(
args
,
stub
)
if
err
!=
nil
{
return
shim
.
Error
(
fmt
.
Sprintf
(
"transaction
P
rocess function err: %s"
,
err
))
res
,
err
=
transactionProcess
(
args
,
stub
)
if
err
!=
nil
{
return
shim
.
Error
(
fmt
.
Sprintf
(
"transaction
p
rocess function err: %s"
,
err
))
}
return
shim
.
Success
([]
byte
(
res
))
case
"getCertCommonName"
:
name
,
err
:
=
getCertificateCommonName
(
stub
)
if
err
!=
nil
{
return
shim
.
Error
(
fmt
.
Sprintf
(
"get certificate
CommonName fail,err: %s"
,
err
))
res
,
err
=
getCertificateCommonName
(
stub
)
if
err
!=
nil
{
return
shim
.
Error
(
fmt
.
Sprintf
(
"get certificate
common_name fail,err: %s"
,
err
))
}
re
turn
shim
.
Success
([]
byte
(
"current user certificate commonname :"
+
name
))
re
s
=
"current user certificate common_name is:"
+
res
default
:
return
shim
.
Error
(
fmt
.
Sprintf
(
"Unsupported function %s"
,
functionName
))
}
return
shim
.
Success
([]
byte
(
"
GXHCC invoke successful "
))
return
shim
.
Success
([]
byte
(
"
gxhcc invoke successful:"
+
res
))
}
/*
根据账户类型创建账本账户,由于我们这里有存储数据与账本数据两种,所以我们还需要在schema 部分标识不同的数据类型。
伪代码:
1:检查当前用户是否具有账户的总写(创建)权限
2:检查账户必备的属性,如Id,账户名,账户所属者,对应的是证书commonName
2:根据schema 标注的金额(账本)字段,和存证字段,分别进行数据的putState存储工作。其中在存证数据的Id 字段是标示字段。
3:完成账户创建工作
*/
func
createAccount
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
(
string
,
error
){
func
put
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
(
string
,
error
)
{
if
len
(
args
)
<
2
{
return
""
,
fmt
.
Errorf
(
"put data operation expected more than 2 parameters! "
)
}
...
...
@@ -277,16 +290,32 @@ func createAccount(args []string, stub shim.ChaincodeStubInterface) (string, err
return
""
,
fmt
.
Errorf
(
"getCertificateCommonName happen err: %s "
,
err
)
}
schema
:=
&
Schema
{}
err
=
schema
.
get
(
args
[
0
],
stub
)
err
,
schema
=
schema
.
get
(
args
[
0
],
stub
)
if
err
!=
nil
{
return
""
,
err
}
if
ok
,
err
:=
authorityCheck
(
schema
.
SAuth
.
Write
,
commonName
);
!
ok
{
return
""
,
fmt
.
Errorf
(
"write %s table fail,err: %s "
,
args
[
0
],
err
)
if
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
)
return
""
,
fmt
.
Errorf
(
"%s table parameters Unmarshal fail,put string not json array, err:%s"
,
args
[
0
],
err
)
}
if
len
(
schema
.
LeadgerFields
)
!=
0
{
return
createAccount
(
args
[
0
],
PutDatas
,
schema
,
stub
)
}
else
{
return
putData
(
args
[
0
],
PutDatas
,
commonName
,
schema
,
stub
)
}
}
/*
根据账户类型创建账本账户,由于我们这里有存储数据与账本数据两种,所以我们还需要在schema 部分标识不同的数据类型。
伪代码:
1:检查当前用户是否具有账户的总写(创建)权限
2:检查账户必备的属性,如Id,账户名,账户所属者,对应的是证书commonName
2:根据schema 标注的金额(账本)字段,和存证字段,分别进行数据的putState存储工作。其中在存证数据的Id 字段是标示字段。
3:完成账户创建工作
*/
func
createAccount
(
tablename
string
,
PutDatas
[]
map
[
string
]
interface
{},
schema
*
Schema
,
stub
shim
.
ChaincodeStubInterface
)
(
string
,
error
)
{
for
k
,
mapres
:=
range
PutDatas
{
Id
,
ok
:=
mapres
[
"id"
]
if
!
ok
{
...
...
@@ -296,34 +325,66 @@ func createAccount(args []string, stub shim.ChaincodeStubInterface) (string, err
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"The common_name field must exist "
)
}
err
=
SchemaCheck
(
schema
,
mapres
)
err
:
=
SchemaCheck
(
schema
,
mapres
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"args index %d string, %s schema cheack fail,err : %s "
,
k
,
args
[
0
],
err
)
return
""
,
fmt
.
Errorf
(
"args index %d string, %s schema cheack fail,err : %s "
,
k
,
tablename
,
err
)
}
if
err
:=
FiledsCheck
(
schema
,
mapres
);
err
!=
nil
{
return
""
,
err
if
err
:=
FiledsCheck
(
schema
,
mapres
);
err
!=
nil
{
return
""
,
err
}
storagemap
,
leadgermap
:=
separateFields
(
schema
,
mapres
,[]
string
{
"id"
,
"common_name"
})
storagemap
,
leadgermap
:=
separateFields
(
schema
,
mapres
,
[]
string
{
"id"
,
"common_name"
})
storageDate
,
_
:=
json
.
Marshal
(
storagemap
)
leadgerDate
,
_
:=
json
.
Marshal
(
leadgermap
)
key
:=
StoragePrefix
+
"_"
+
args
[
0
]
+
"_"
+
Id
.
(
string
)
getResult
,
err
:=
stub
.
GetState
(
key
)
key
:=
StoragePrefix
+
"_"
+
tablename
+
"_"
+
Id
.
(
string
)
getResult
,
err
:=
stub
.
GetState
(
key
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"GetState %s data fail,please check your parameters "
,
key
)
return
""
,
fmt
.
Errorf
(
"GetState %s data fail,please check your parameters "
,
key
)
}
if
getResult
!=
nil
{
return
""
,
fmt
.
Errorf
(
"%s data already exists and cannot be added"
,
key
)
if
getResult
!=
nil
{
return
""
,
fmt
.
Errorf
(
"%s data already exists and cannot be added"
,
key
)
}
if
err
:=
stub
.
PutState
(
key
,
storageDate
);
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"PutState fail, err :%s"
,
err
)
}
if
err
:=
stub
.
PutState
(
LeadgerPrefix
+
"_"
+
args
[
0
]
+
"_"
+
Id
.
(
string
),
leadgerDate
);
err
!=
nil
{
if
err
:=
stub
.
PutState
(
LeadgerPrefix
+
"_"
+
tablename
+
"_"
+
Id
.
(
string
),
leadgerDate
);
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"PutState fail, err :%s"
,
err
)
}
}
return
fmt
.
Sprintf
(
"create %s account success!"
,
args
[
0
]
),
nil
return
fmt
.
Sprintf
(
"create %s account success!"
,
tablename
),
nil
}
///*
// 存储数据,某些不产生账本数据的数据使用这个接口来存储。例如码数据,进件表数据
//
//*/
//func putData(args []string, stub shim.ChaincodeStubInterface) (string, error) {
// if len(args) < 2 {
// return "", fmt.Errorf("put data operation expected more than 2 parameters! ")
// }
// var PutDatas []map[string]interface{}
// commonName, err := getCertificateCommonName(stub)
// if err != nil {
// return "", fmt.Errorf("getCertificateCommonName happen err: %s ", err)
// }
// schema := &Schema{}
// err, schema = schema.get(args[0], stub)
// if err != nil {
// return "", err
// }
// if ok, err := authorityCheck(schema.SAuth.Write, commonName, ""); !ok {
// return "", fmt.Errorf("write %s table fail,err: %s ", args[0], err)
// }
// if err := json.Unmarshal([]byte(args[1]), &PutDatas); err != nil {
// return "", fmt.Errorf("%s table parameters Unmarshal fail,put string not json array, err:%s", args[0], err)
// }
// //存储过滤器
// _, err = filterByput(args[0], PutDatas, commonName, schema, stub)
// if err != nil {
// return "", err
// }
//
// return fmt.Sprintf("%s put data success!", args[0]), nil
//}
/*
修改一个账户的存储数据,修改规则由Schema 控制,有些特殊数据在账本数据也使用,所以无法修改
...
...
@@ -337,13 +398,13 @@ func updateStoreData(args []string, stub shim.ChaincodeStubInterface) (string, e
return
""
,
fmt
.
Errorf
(
"getCertificateCommonName happen err: %s "
,
err
)
}
schema
:=
&
Schema
{}
err
=
schema
.
get
(
args
[
0
],
stub
)
err
,
schema
=
schema
.
get
(
args
[
0
],
stub
)
if
err
!=
nil
{
return
""
,
err
}
var
Updata
map
[
string
]
interface
{}
if
err
:=
json
.
Unmarshal
([]
byte
(
args
[
1
]),
&
Updata
);
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"%s table parameters Unmarshal fail,err: %s"
,
args
[
0
],
err
)
return
""
,
fmt
.
Errorf
(
"%s table parameters Unmarshal fail,err: %s"
,
args
[
0
],
err
)
}
Id
,
ok
:=
Updata
[
"id"
]
if
!
ok
{
...
...
@@ -353,16 +414,16 @@ func updateStoreData(args []string, stub shim.ChaincodeStubInterface) (string, e
if
ok
{
return
""
,
fmt
.
Errorf
(
"The common_name field cannot update "
)
}
if
ok
,
_
:=
authorityCheck
(
schema
.
SAuth
.
Write
,
commonName
);
!
ok
{
if
ok
,
_
:=
authorityCheck
(
schema
.
SAuth
.
Write
,
commonName
,
""
);
!
ok
{
if
ok
,
err
:=
parsauthorityCheck
(
schema
.
StorageFields
,
Updata
,
commonName
);
!
ok
{
return
""
,
fmt
.
Errorf
(
"authority Check err: %s"
,
err
)
}
}
if
err
:=
FiledsCheck
(
schema
,
Updata
);
err
!=
nil
{
return
""
,
err
if
err
:=
FiledsCheck
(
schema
,
Updata
);
err
!=
nil
{
return
""
,
err
}
key
:=
StoragePrefix
+
"_"
+
args
[
0
]
+
"_"
+
Id
.
(
string
)
allMap
,
err
:=
getState
(
key
,
stub
)
key
:=
StoragePrefix
+
"_"
+
args
[
0
]
+
"_"
+
Id
.
(
string
)
allMap
,
err
:=
getState
(
key
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
...
...
@@ -370,61 +431,13 @@ func updateStoreData(args []string, stub shim.ChaincodeStubInterface) (string, e
if
err
:=
Deassign
(
Updata
,
allMap
);
err
!=
nil
{
return
""
,
err
}
err
=
putState
(
key
,
allMap
,
stub
)
err
=
putState
(
key
,
allMap
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
return
fmt
.
Sprintf
(
"%s update data success!"
,
args
[
0
]),
nil
}
/*
存储数据,某些不产生账本数据的数据使用这个接口来存储。例如码数据,进件表数据
允许覆盖
*/
func
putData
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
(
string
,
error
)
{
if
len
(
args
)
<
2
{
return
""
,
fmt
.
Errorf
(
"put data operation expected more than 2 parameters! "
)
}
var
PutDatas
[]
map
[
string
]
interface
{}
commonName
,
err
:=
getCertificateCommonName
(
stub
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"getCertificateCommonName happen err: %s "
,
err
)
}
schema
:=
&
Schema
{}
err
=
schema
.
get
(
args
[
0
],
stub
)
if
err
!=
nil
{
return
""
,
err
}
if
ok
,
err
:=
authorityCheck
(
schema
.
SAuth
.
Write
,
commonName
);
!
ok
{
return
""
,
fmt
.
Errorf
(
"write %s table fail,err: %s "
,
args
[
0
],
err
)
}
if
err
:=
json
.
Unmarshal
([]
byte
(
args
[
1
]),
&
PutDatas
);
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"%s table parameters Unmarshal fail,put string not json array, err:%s"
,
args
[
0
],
err
)
}
for
k
,
mapres
:=
range
PutDatas
{
Id
,
ok
:=
mapres
[
"id"
]
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"The id field must exist "
)
}
if
len
(
schema
.
LeadgerFields
)
!=
0
{
return
""
,
fmt
.
Errorf
(
"%s schema exist leadger fields,cannot putData"
,
args
[
0
])
}
err
=
SchemaCheck
(
schema
,
mapres
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"args index %d string, %s schema cheack fail,err : %s "
,
k
,
args
[
0
],
err
)
}
if
err
:=
FiledsCheck
(
schema
,
mapres
);
err
!=
nil
{
return
""
,
err
}
key
:=
StoragePrefix
+
"_"
+
args
[
0
]
+
"_"
+
Id
.
(
string
)
err
=
putState
(
key
,
mapres
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
}
return
fmt
.
Sprintf
(
"%s put data success!"
,
args
[
0
]),
nil
}
/*
查询数据,如果存在账本数据,与存证数据,则进行数据拼接,然后返回。
*/
...
...
@@ -446,18 +459,18 @@ func get(args []string, stub shim.ChaincodeStubInterface) (string, error) {
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"The id field must exist "
)
}
storageKey
:=
StoragePrefix
+
"_"
+
args
[
0
]
+
"_"
+
Id
.
(
string
)
mapResult
,
err
:=
getState
(
storageKey
,
stub
)
storageKey
:=
StoragePrefix
+
"_"
+
args
[
0
]
+
"_"
+
Id
.
(
string
)
mapResult
,
err
:=
getState
(
storageKey
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
leadgerKey
:=
LeadgerPrefix
+
"_"
+
args
[
0
]
+
"_"
+
Id
.
(
string
)
leadgerKey
:=
LeadgerPrefix
+
"_"
+
args
[
0
]
+
"_"
+
Id
.
(
string
)
leadgerResult
,
err
:=
stub
.
GetState
(
leadgerKey
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"get %s data fail,please check your parameters "
,
leadgerKey
)
return
""
,
fmt
.
Errorf
(
"get %s data fail,please check your parameters "
,
leadgerKey
)
}
schema
:=
&
Schema
{}
err
=
schema
.
get
(
args
[
0
],
stub
)
err
,
schema
=
schema
.
get
(
args
[
0
],
stub
)
if
err
!=
nil
{
return
""
,
err
}
...
...
@@ -466,8 +479,12 @@ func get(args []string, stub shim.ChaincodeStubInterface) (string, error) {
return
""
,
fmt
.
Errorf
(
"The leadger original data Unmarshal fail err:%s "
,
err
)
}
}
if
ok
,
_
:=
authorityCheck
(
schema
.
SAuth
.
Read
,
commonName
);
!
ok
{
if
filteredData
,
err
:=
dataFilter
(
schema
,
mapResult
,
commonName
);
err
!=
nil
{
onwer
,
ok
:=
mapResult
[
"common_name"
]
.
(
string
)
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"common_name fields resolution failed "
)
}
if
ok
,
_
:=
authorityCheck
(
schema
.
SAuth
.
Read
,
commonName
,
""
);
!
ok
{
if
filteredData
,
err
:=
dataFilter
(
schema
,
mapResult
,
commonName
,
onwer
);
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"get data authority filter fail, err: %s"
,
err
)
}
else
{
result
,
_
:=
json
.
Marshal
(
filteredData
)
...
...
@@ -480,127 +497,6 @@ func get(args []string, stub shim.ChaincodeStubInterface) (string, error) {
}
}
func
SchemaCheck
(
schema
*
Schema
,
checkmap
map
[
string
]
interface
{})
error
{
if
len
(
schema
.
StorageFields
)
+
len
(
schema
.
LeadgerFields
)
!=
len
(
checkmap
)
{
return
fmt
.
Errorf
(
"The input field length is less than the schema field length ! "
)
}
for
k
,
v
:=
range
schema
.
StorageFields
{
if
schemaV
,
ok
:=
checkmap
[
k
];
!
ok
{
return
fmt
.
Errorf
(
"There is no input storage field %s "
,
k
)
}
else
{
if
parameterS
,
ok
:=
v
.
Value
.
(
map
[
string
]
interface
{});
ok
{
if
parameterC
,
ok
:=
schemaV
.
(
map
[
string
]
interface
{});
!
ok
{
return
fmt
.
Errorf
(
"The input field %s does not match the output field format "
,
k
)
}
else
{
err
:=
BackUpCheck
(
parameterS
,
parameterC
)
if
err
!=
nil
{
return
err
}
}
}
}
}
for
k
,
_
:=
range
schema
.
LeadgerFields
{
if
_
,
ok
:=
checkmap
[
k
];
!
ok
{
return
fmt
.
Errorf
(
"There is no input leadger field %s "
,
k
)
}
}
return
nil
}
func
FiledsCheck
(
schema
*
Schema
,
checkmap
map
[
string
]
interface
{})
error
{
for
k
,
schemaV
:=
range
schema
.
StorageFields
{
if
k
!=
"backup"
&&
schemaV
.
FCheck
!=
nil
&&
schemaV
.
FCheck
.
FType
!=
""
&&
checkmap
[
k
]
!=
nil
{
if
err
:=
fieldCheckout
(
schemaV
.
FCheck
,
checkmap
[
k
]);
err
!=
nil
{
return
fmt
.
Errorf
(
"%s %s "
,
k
,
err
)
}
}
}
for
k
,
schemaV
:=
range
schema
.
LeadgerFields
{
if
schemaV
.
FCheck
!=
nil
&&
schemaV
.
FCheck
.
FType
!=
""
&&
checkmap
[
k
]
!=
nil
{
if
err
:=
fieldCheckout
(
schemaV
.
FCheck
,
checkmap
[
k
]);
err
!=
nil
{
return
fmt
.
Errorf
(
"%s %s "
,
k
,
err
)
}
}
}
return
nil
}
func
BackUpCheck
(
backUp
map
[
string
]
interface
{},
checkmap
map
[
string
]
interface
{})
error
{
if
len
(
backUp
)
!=
len
(
checkmap
)
{
return
fmt
.
Errorf
(
"The input backup field length is less than the schema backup field length ! "
)
}
for
k
,
_
:=
range
checkmap
{
if
_
,
ok
:=
backUp
[
k
];
!
ok
{
return
fmt
.
Errorf
(
"There is no input backup field %s "
,
k
)
}
}
return
nil
}
/*
将字段根据账本数据,与存储数据分开
leadgers:参数表示我们需要在账本数据包含的字段,这些字段不属于账本数据。
*/
func
separateFields
(
schema
*
Schema
,
checkmap
map
[
string
]
interface
{},
leadgers
[]
string
)(
storagemap
,
leadgermap
map
[
string
]
interface
{}){
storagemap
=
make
(
map
[
string
]
interface
{})
leadgermap
=
make
(
map
[
string
]
interface
{})
for
k
,
_
:=
range
schema
.
LeadgerFields
{
leadgermap
[
k
]
=
checkmap
[
k
]
}
for
_
,
v
:=
range
leadgers
{
leadgermap
[
v
]
=
checkmap
[
v
]
}
for
k
,
_
:=
range
schema
.
StorageFields
{
storagemap
[
k
]
=
checkmap
[
k
]
}
return
}
/*
根据权限拼装数据,进行数据过滤
*/
func
dataFilter
(
schema
*
Schema
,
checkmap
map
[
string
]
interface
{},
commonName
string
)
(
map
[
string
]
interface
{},
error
)
{
for
k
,
schemaV
:=
range
schema
.
StorageFields
{
if
v
,
ok
:=
checkmap
[
k
];
!
ok
{
return
nil
,
fmt
.
Errorf
(
"Update data parameter mismatch with schema structure! "
)
}
else
{
if
_
,
ok
:=
schemaV
.
Value
.
(
map
[
string
]
SchemaParameters
);
ok
{
if
_
,
ok
:=
v
.
(
map
[
string
]
interface
{});
!
ok
{
return
nil
,
fmt
.
Errorf
(
"Update data parameter mismatch with schema structure! "
)
}
if
ok
,
_
:=
authorityCheck
(
schemaV
.
PAuth
.
Read
,
commonName
);
!
ok
{
checkmap
[
k
]
=
defValue
}
}
else
{
if
ok
,
_
:=
authorityCheck
(
schemaV
.
PAuth
.
Read
,
commonName
);
!
ok
{
checkmap
[
k
]
=
defValue
}
}
}
}
for
k
,
schemaV
:=
range
schema
.
LeadgerFields
{
if
v
,
ok
:=
checkmap
[
k
];
!
ok
{
return
nil
,
fmt
.
Errorf
(
"Update data parameter mismatch with schema structure! "
)
}
else
{
if
_
,
ok
:=
schemaV
.
Value
.
(
map
[
string
]
SchemaLeadgerParameters
);
ok
{
if
_
,
ok
:=
v
.
(
map
[
string
]
interface
{});
!
ok
{
return
nil
,
fmt
.
Errorf
(
"Update data parameter mismatch with schema structure! "
)
}
if
ok
,
_
:=
authorityCheck
(
schemaV
.
PAuth
.
Read
,
commonName
);
!
ok
{
checkmap
[
k
]
=
defValue
}
}
else
{
if
ok
,
_
:=
authorityCheck
(
schemaV
.
PAuth
.
Read
,
commonName
);
!
ok
{
checkmap
[
k
]
=
defValue
}
}
}
}
return
checkmap
,
nil
}
func
SchemaProcess
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
(
string
,
error
)
{
if
len
(
args
)
<
2
{
return
""
,
fmt
.
Errorf
(
"Expect features with 2 or more parameters to play! "
)
...
...
@@ -628,17 +524,18 @@ func transactionProcess(args []string, stub shim.ChaincodeStubInterface) (string
switch
args
[
0
]
{
case
"issue"
:
//进行账户金额发行(无中生有)
return
funtOperation
(
args
[
1
:
],
stub
,
true
)
return
funtOperation
(
args
[
1
:
],
stub
,
true
)
case
"extract"
:
//提取账户金额(直接减去)
return
funtOperation
(
args
[
1
:
],
stub
,
false
)
return
funtOperation
(
args
[
1
:
],
stub
,
false
)
case
"transfer"
:
// 一笔普通转账
return
transferTx
(
args
[
1
:
],
stub
)
return
transferTx
(
args
[
1
:
],
stub
)
default
:
return
""
,
fmt
.
Errorf
(
fmt
.
Sprintf
(
"Unsupported schema function of %s"
,
args
[
0
]))
}
return
""
,
nil
}
/*
put
args 字段说明:
...
...
@@ -655,11 +552,11 @@ func (this *Schema) put(args []string, stub shim.ChaincodeStubInterface) (string
}
var
schema
*
Schema
var
err
error
if
schema
,
err
=
NewSchema
(
args
[
1
]);
err
!=
nil
{
if
schema
,
err
=
NewSchema
(
args
[
1
]);
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"The parameters Unmarshal to a Schema structural fail,err: %s "
,
err
)
}
else
{
}
else
{
if
backupValue
,
ok
:=
schema
.
StorageFields
[
"backup"
];
ok
{
if
_
,
ok
:=
backupValue
.
Value
.
(
map
[
string
]
interface
{});
!
ok
{
if
_
,
ok
:=
backupValue
.
Value
.
(
map
[
string
]
interface
{});
!
ok
{
return
""
,
fmt
.
Errorf
(
"backup parameters Unmarshal fail,it not json string,err: %s"
,
err
)
}
}
...
...
@@ -673,22 +570,20 @@ func (this *Schema) put(args []string, stub shim.ChaincodeStubInterface) (string
return
""
,
fmt
.
Errorf
(
"The common_name field must exist "
)
}
CompositeKey
,
err
:=
stub
.
CreateCompositeKey
(
GxhSchema
,
[]
string
{
args
[
0
]})
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"the schema %s create comosite key fail,err : %s"
,
args
[
0
],
err
)
CompositeKey
,
err
:=
stub
.
CreateCompositeKey
(
GxhSchema
,
[]
string
{
args
[
0
]})
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"the schema %s create comosite key fail,err : %s"
,
args
[
0
],
err
)
}
if
schemaCache
.
Get
(
args
[
0
])
!=
nil
{
fmt
.
Println
(
"schemaCache.Get err"
)
return
""
,
fmt
.
Errorf
(
"the schema %s already exists and cannot be added"
,
args
[
0
])
}
else
if
value
,
_
:=
stub
.
GetState
(
CompositeKey
);
value
!=
nil
{
fmt
.
Println
(
"GetState.Get err"
)
}
else
if
value
,
_
:=
stub
.
GetState
(
CompositeKey
);
value
!=
nil
{
return
""
,
fmt
.
Errorf
(
"the schema %s already exists and cannot be added"
,
args
[
0
])
}
putDate
,
_
:=
json
.
Marshal
(
schema
)
//处理重复字段
if
err
:=
stub
.
PutState
(
CompositeKey
,
putDate
);
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"Schema PutState fail,err: %s "
,
err
)
}
schemaCache
.
Put
(
args
[
0
],
putDate
)
schemaCache
.
Put
(
args
[
0
],
schema
)
return
fmt
.
Sprintf
(
"%s schema put success!"
,
args
[
0
]),
nil
}
...
...
@@ -702,13 +597,13 @@ func (this *Schema) update(args []string, stub shim.ChaincodeStubInterface) (str
return
""
,
fmt
.
Errorf
(
"Schema update operation expected 2 parameters! "
)
}
var
schema
*
Schema
var
schemaOld
*
Schema
schemaOld
:=
&
Schema
{}
var
err
error
if
schema
,
err
=
NewSchema
(
args
[
1
]);
err
!=
nil
{
if
schema
,
err
=
NewSchema
(
args
[
1
]);
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"The parameters Unmarshal to a Schema structural fail,err: %s "
,
err
)
}
else
{
}
else
{
if
backupValue
,
ok
:=
schema
.
StorageFields
[
"backup"
];
ok
{
if
_
,
ok
:=
backupValue
.
Value
.
(
map
[
string
]
interface
{});
!
ok
{
if
_
,
ok
:=
backupValue
.
Value
.
(
map
[
string
]
interface
{});
!
ok
{
return
""
,
fmt
.
Errorf
(
"backup parameters Unmarshal fail,it not json string,err: %s"
,
err
)
}
}
...
...
@@ -721,120 +616,381 @@ func (this *Schema) update(args []string, stub shim.ChaincodeStubInterface) (str
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"The common_name field must exist "
)
}
CompositeKey
,
err
:=
stub
.
CreateCompositeKey
(
GxhSchema
,[]
string
{
args
[
0
]})
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"the schema %s create comosite key fail,err : %s"
,
args
[
0
],
err
)
}
var
result
[]
byte
if
result
=
schemaCache
.
Get
(
args
[
0
]);
result
==
nil
{
fmt
.
Println
(
"schemaCache.Get nil"
)
result
,
err
:=
stub
.
GetState
(
CompositeKey
)
if
err
!=
nil
||
result
==
nil
{
return
""
,
fmt
.
Errorf
(
"%s schema data doesn't exist,please check your parameters "
,
args
[
0
])
}
CompositeKey
,
err
:=
stub
.
CreateCompositeKey
(
GxhSchema
,
[]
string
{
args
[
0
]})
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"the schema %s create comosite key fail,err : %s"
,
args
[
0
],
err
)
}
if
err
:=
json
.
Unmarshal
(
result
,
&
schemaOld
);
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"The parameters Unmarshal to a Schema structural fail, err: %s "
,
err
)
err
,
schemaOld
=
schemaOld
.
get
(
args
[
0
],
stub
)
if
err
!=
nil
{
return
""
,
err
}
//if err := json.Unmarshal(result, &schemaOld); err != nil {
// return "", fmt.Errorf("The parameters Unmarshal to a Schema structural fail, err: %s ", err)
//}
commonName
,
err
:=
getCertificateCommonName
(
stub
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"getCertificateCommonName happen err: %s "
,
err
)
}
if
ok
,
err
:=
authorityCheck
(
schemaOld
.
SchemaAuth
.
Write
,
commonName
);
!
ok
{
return
""
,
fmt
.
Errorf
(
"update %s schema fail,err: %s "
,
args
[
0
],
err
)
if
ok
,
err
:=
authorityCheck
(
schemaOld
.
SchemaAuth
.
Write
,
commonName
,
""
);
!
ok
{
return
""
,
fmt
.
Errorf
(
"update %s schema fail,err: %s "
,
args
[
0
],
err
)
}
schema
.
LeadgerFields
=
schemaOld
.
LeadgerFields
updateData
,
_
:=
json
.
Marshal
(
schema
)
if
err
=
stub
.
PutState
(
CompositeKey
,
updateData
);
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"%s schema data PutState fail,please try again "
,
args
[
0
])
updateData
,
_
:=
json
.
Marshal
(
schema
)
if
err
=
stub
.
PutState
(
CompositeKey
,
updateData
);
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"%s schema data PutState fail,please try again "
,
args
[
0
])
}
schemaCache
.
Put
(
args
[
0
],
updateData
)
return
fmt
.
Sprintf
(
"%s schema update success!"
,
args
[
0
]),
err
}
func
(
this
*
Schema
)
get
(
args
string
,
stub
shim
.
ChaincodeStubInterface
)
error
{
func
(
this
*
Schema
)
get
(
args
string
,
stub
shim
.
ChaincodeStubInterface
)
(
error
,
*
Schema
)
{
schema
:=
&
Schema
{}
var
result
[]
byte
if
result
=
schemaCache
.
Get
(
args
);
result
==
nil
{
CompositeKey
,
err
:=
stub
.
CreateCompositeKey
(
GxhSchema
,
[]
string
{
args
})
if
err
!=
nil
{
return
fmt
.
Errorf
(
"the schema %s create comosite key fail,err : %s"
,
args
,
err
)
if
schema
=
schemaCache
.
Get
(
args
);
schema
==
nil
{
CompositeKey
,
err
:=
stub
.
CreateCompositeKey
(
GxhSchema
,
[]
string
{
args
})
if
err
!=
nil
{
return
fmt
.
Errorf
(
"the schema %s create comosite key fail,err : %s"
,
args
,
err
),
nil
}
result
,
err
=
stub
.
GetState
(
CompositeKey
)
if
err
!=
nil
||
result
==
nil
{
return
fmt
.
Errorf
(
"%s schema data doesn't exist,please check your parameters "
,
args
)
return
fmt
.
Errorf
(
"%s schema data doesn't exist,please check your parameters "
,
args
),
nil
}
schemaCache
.
Put
(
args
,
result
)
if
err
:=
json
.
Unmarshal
(
result
,
schema
);
err
!=
nil
{
return
fmt
.
Errorf
(
"SchemaData Unmarshal fail, err: %s"
,
err
),
nil
}
return
json
.
Unmarshal
(
result
,
this
)
schemaCache
.
Put
(
args
,
schema
)
}
return
nil
,
schema
}
func
(
this
*
Schema
)
getSchema
(
args
string
,
stub
shim
.
ChaincodeStubInterface
)(
string
,
error
)
{
func
(
this
*
Schema
)
getSchema
(
args
string
,
stub
shim
.
ChaincodeStubInterface
)
(
string
,
error
)
{
schema
:=
&
Schema
{}
var
result
[]
byte
if
result
=
schemaCache
.
Get
(
args
);
result
==
nil
{
CompositeKey
,
err
:=
stub
.
CreateCompositeKey
(
GxhSchema
,
[]
string
{
args
})
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"the schema %s create comosite key fail,err : %s"
,
args
,
err
)
if
schema
=
schemaCache
.
Get
(
args
);
schema
==
nil
{
CompositeKey
,
err
:=
stub
.
CreateCompositeKey
(
GxhSchema
,
[]
string
{
args
})
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"the schema %s create comosite key fail,err : %s"
,
args
,
err
)
}
result
,
err
=
stub
.
GetState
(
CompositeKey
)
result
,
err
:
=
stub
.
GetState
(
CompositeKey
)
if
err
!=
nil
||
result
==
nil
{
return
""
,
fmt
.
Errorf
(
"%s schema data doesn't exist,please check your parameters "
,
args
)
return
""
,
fmt
.
Errorf
(
"%s schema data doesn't exist,please check your parameters "
,
args
)
}
schemaCache
.
Put
(
args
,
result
)
}
if
err
:=
json
.
Unmarshal
(
result
,
this
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
result
,
schema
);
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"SchemaData Unmarshal fail, err: %s"
,
err
)
}
schemaCache
.
Put
(
args
,
schema
)
}
else
{
result
,
_
=
json
.
Marshal
(
schema
)
}
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
)
if
ok
,
err
:=
authorityCheck
(
this
.
SchemaAuth
.
Read
,
commonName
,
""
);
!
ok
{
return
""
,
fmt
.
Errorf
(
"get %s schema fail,err: %s"
,
args
,
err
)
}
return
string
(
result
),
nil
}
func
transferTx
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)(
string
,
error
)
{
func
transferTx
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
(
string
,
error
)
{
txFunc
:=
transferType
[
args
[
0
]]
if
txFunc
==
nil
{
if
txFunc
==
nil
{
return
""
,
fmt
.
Errorf
(
"No matching transfer operation method was found ! "
)
}
err
:=
txFunc
(
args
[
1
:
],
stub
)
err
:=
txFunc
(
args
[
1
:
],
stub
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"%s transfer operation fail,err:%s "
,
args
[
0
],
err
)
return
""
,
fmt
.
Errorf
(
"%s transfer operation fail,err:%s "
,
args
[
0
],
err
)
}
return
""
,
nil
}
func
authorityCheck
(
authority
AuthGroup
,
commonName
string
)
(
bool
,
error
)
{
var
auths
map
[
string
]
int64
if
IsUsers
{
auths
=
authority
.
Users
}
else
{
auths
=
authority
.
Roles
}
if
len
(
auths
)
==
0
{
return
true
,
nil
}
for
k
,
v
:=
range
auths
{
if
k
==
commonName
{
if
v
==
0
||
v
>
time
.
Now
()
.
Unix
(){
return
true
,
nil
}
else
{
return
false
,
fmt
.
Errorf
(
"%s user permission period "
,
commonName
)
}
/*
有些特殊的putdata 数据是存在过滤条件的,此方法就是进行过滤
*/
func
putData
(
filterName
string
,
putDatas
[]
map
[
string
]
interface
{},
commonName
string
,
schema
*
Schema
,
stub
shim
.
ChaincodeStubInterface
)
(
string
,
error
)
{
filterFunc
:=
PutDataFilter
[
filterName
]
if
filterFunc
==
nil
{
return
""
,
fmt
.
Errorf
(
"No matching filter operation method was found ! "
)
}
str
,
err
:=
filterFunc
(
putDatas
,
commonName
,
filterName
,
schema
,
stub
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"%s filter operation fail,err:%s "
,
filterName
,
err
)
}
return
false
,
fmt
.
Errorf
(
"%s user does not have permission"
,
commonName
)
return
str
,
nil
}
/*
检查一组参数的权限是否匹配
在共享惠项目中当用户上传码数据时,存在对发行总数控制的要求。
*/
func
parsauthorityCheck
(
schema
map
[
string
]
SchemaParameters
,
checkmap
map
[
string
]
interface
{},
commonName
string
)
(
bool
,
error
)
{
func
codeFilter
(
putDatas
[]
map
[
string
]
interface
{},
commonName
,
tableName
string
,
schema
*
Schema
,
stub
shim
.
ChaincodeStubInterface
)
(
string
,
error
)
{
sum
:=
len
(
putDatas
)
if
sum
==
0
{
return
""
,
fmt
.
Errorf
(
"put length cannot zero! "
)
}
tid
,
ok
:=
putDatas
[
0
][
"tid"
]
.
(
string
)
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"tid fields type must string! "
)
}
dependData
:=
"coutickets"
Stkey
:=
StoragePrefix
+
"_"
+
dependData
+
"_"
+
tid
tmap
,
err
:=
getState
(
Stkey
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
count
,
ok
:=
tmap
[
"surplusCount"
]
.
(
float64
)
//剩余可发行数
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"surplusCount fields type must float64! "
)
}
count
-=
float64
(
sum
)
if
count
>=
0
{
tmap
[
"surplusCount"
]
=
count
}
else
{
return
""
,
fmt
.
Errorf
(
"The number of issues exceeds the total number of issues! "
)
}
err
=
putState
(
Stkey
,
tmap
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
for
k
,
mapres
:=
range
putDatas
{
Id
,
ok
:=
mapres
[
"id"
]
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"The id field must exist "
)
}
_
,
ok
=
mapres
[
"common_name"
]
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"The common_name field must exist "
)
}
err
=
SchemaCheck
(
schema
,
mapres
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"args index %d string, %s schema cheack fail,err : %s "
,
k
,
tableName
,
err
)
}
if
err
:=
FiledsCheck
(
schema
,
mapres
);
err
!=
nil
{
return
""
,
err
}
key
:=
StoragePrefix
+
"_"
+
tableName
+
"_"
+
Id
.
(
string
)
_
,
err
:=
getState
(
key
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
err
=
putState
(
key
,
mapres
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
}
return
fmt
.
Sprintf
(
"%s data save success!"
,
tableName
),
nil
}
func
commanFilter
(
putDatas
[]
map
[
string
]
interface
{},
commonName
,
tableName
string
,
schema
*
Schema
,
stub
shim
.
ChaincodeStubInterface
)
(
string
,
error
)
{
for
k
,
mapres
:=
range
putDatas
{
Id
,
ok
:=
mapres
[
"id"
]
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"The id field must exist "
)
}
_
,
ok
=
mapres
[
"common_name"
]
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"The common_name field must exist "
)
}
err
:=
SchemaCheck
(
schema
,
mapres
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"args index %d string, %s schema cheack fail,err : %s "
,
k
,
tableName
,
err
)
}
if
err
:=
FiledsCheck
(
schema
,
mapres
);
err
!=
nil
{
return
""
,
err
}
key
:=
StoragePrefix
+
"_"
+
tableName
+
"_"
+
Id
.
(
string
)
err
=
putState
(
key
,
mapres
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
}
return
fmt
.
Sprintf
(
"%s data save success!"
,
tableName
),
nil
}
/*
券可用门店过滤表
*/
func
ticketMerFilter
(
putDatas
[]
map
[
string
]
interface
{},
commonName
,
tableName
string
,
schema
*
Schema
,
stub
shim
.
ChaincodeStubInterface
)
(
string
,
error
)
{
for
k
,
mapres
:=
range
putDatas
{
mid
,
ok
:=
mapres
[
"mid"
]
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"The mid field must exist "
)
}
tid
,
ok
:=
mapres
[
"tid"
]
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"The tid field must exist "
)
}
_
,
ok
=
mapres
[
"common_name"
]
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"The common_name field must exist "
)
}
if
len
(
schema
.
LeadgerFields
)
!=
0
{
return
""
,
fmt
.
Errorf
(
"%s schema exist leadger fields,cannot putData"
,
tableName
)
}
err
:=
SchemaCheck
(
schema
,
mapres
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"args index %d string, %s schema cheack fail,err : %s "
,
k
,
tableName
,
err
)
}
if
err
:=
FiledsCheck
(
schema
,
mapres
);
err
!=
nil
{
return
""
,
err
}
key
:=
StoragePrefix
+
"_"
+
tableName
+
"_"
+
mid
.
(
string
)
+
"_"
+
tid
.
(
string
)
err
=
putState
(
key
,
mapres
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
}
return
""
,
nil
}
func
SchemaCheck
(
schema
*
Schema
,
checkmap
map
[
string
]
interface
{})
error
{
if
len
(
schema
.
StorageFields
)
+
len
(
schema
.
LeadgerFields
)
!=
len
(
checkmap
)
{
return
fmt
.
Errorf
(
"The input field length is less than the schema field length ! "
)
}
for
k
,
v
:=
range
schema
.
StorageFields
{
if
schemaV
,
ok
:=
checkmap
[
k
];
!
ok
{
return
fmt
.
Errorf
(
"There is no input storage field %s "
,
k
)
}
else
{
if
parameterS
,
ok
:=
v
.
Value
.
(
map
[
string
]
interface
{});
ok
{
if
parameterC
,
ok
:=
schemaV
.
(
map
[
string
]
interface
{});
!
ok
{
return
fmt
.
Errorf
(
"The input field %s does not match the output field format "
,
k
)
}
else
{
err
:=
BackUpCheck
(
parameterS
,
parameterC
)
if
err
!=
nil
{
return
err
}
}
}
}
}
for
k
,
_
:=
range
schema
.
LeadgerFields
{
if
_
,
ok
:=
checkmap
[
k
];
!
ok
{
return
fmt
.
Errorf
(
"There is no input leadger field %s "
,
k
)
}
}
return
nil
}
func
FiledsCheck
(
schema
*
Schema
,
checkmap
map
[
string
]
interface
{})
error
{
for
k
,
schemaV
:=
range
schema
.
StorageFields
{
if
k
!=
"backup"
&&
schemaV
.
FCheck
!=
nil
&&
schemaV
.
FCheck
.
FType
!=
""
&&
checkmap
[
k
]
!=
nil
{
if
err
:=
fieldCheckout
(
schemaV
.
FCheck
,
checkmap
[
k
]);
err
!=
nil
{
return
fmt
.
Errorf
(
"%s %s "
,
k
,
err
)
}
}
}
for
k
,
schemaV
:=
range
schema
.
LeadgerFields
{
if
schemaV
.
FCheck
!=
nil
&&
schemaV
.
FCheck
.
FType
!=
""
&&
checkmap
[
k
]
!=
nil
{
if
err
:=
fieldCheckout
(
schemaV
.
FCheck
,
checkmap
[
k
]);
err
!=
nil
{
return
fmt
.
Errorf
(
"%s %s "
,
k
,
err
)
}
}
}
return
nil
}
func
BackUpCheck
(
backUp
map
[
string
]
interface
{},
checkmap
map
[
string
]
interface
{})
error
{
if
len
(
backUp
)
!=
len
(
checkmap
)
{
return
fmt
.
Errorf
(
"The input backup field length is less than the schema backup field length ! "
)
}
for
k
,
_
:=
range
checkmap
{
if
_
,
ok
:=
backUp
[
k
];
!
ok
{
return
fmt
.
Errorf
(
"There is no input backup field %s "
,
k
)
}
}
return
nil
}
/*
将字段根据账本数据,与存储数据分开
leadgers:参数表示我们需要在账本数据包含的字段,这些字段不属于账本数据。
*/
func
separateFields
(
schema
*
Schema
,
checkmap
map
[
string
]
interface
{},
leadgers
[]
string
)
(
storagemap
,
leadgermap
map
[
string
]
interface
{})
{
storagemap
=
make
(
map
[
string
]
interface
{})
leadgermap
=
make
(
map
[
string
]
interface
{})
for
k
,
_
:=
range
schema
.
LeadgerFields
{
leadgermap
[
k
]
=
checkmap
[
k
]
}
for
_
,
v
:=
range
leadgers
{
leadgermap
[
v
]
=
checkmap
[
v
]
}
for
k
,
_
:=
range
schema
.
StorageFields
{
storagemap
[
k
]
=
checkmap
[
k
]
}
return
}
/*
根据权限拼装数据,进行数据过滤
*/
func
dataFilter
(
schema
*
Schema
,
checkmap
map
[
string
]
interface
{},
commonName
,
onwer
string
)
(
map
[
string
]
interface
{},
error
)
{
for
k
,
schemaV
:=
range
schema
.
StorageFields
{
if
v
,
ok
:=
checkmap
[
k
];
!
ok
{
return
nil
,
fmt
.
Errorf
(
"Update data parameter mismatch with schema structure! "
)
}
else
{
if
_
,
ok
:=
schemaV
.
Value
.
(
map
[
string
]
SchemaParameters
);
ok
{
if
_
,
ok
:=
v
.
(
map
[
string
]
interface
{});
!
ok
{
return
nil
,
fmt
.
Errorf
(
"Update data parameter mismatch with schema structure! "
)
}
if
ok
,
_
:=
authorityCheck
(
schemaV
.
PAuth
.
Read
,
commonName
,
onwer
);
!
ok
{
checkmap
[
k
]
=
defValue
}
}
else
{
if
ok
,
_
:=
authorityCheck
(
schemaV
.
PAuth
.
Read
,
commonName
,
onwer
);
!
ok
{
checkmap
[
k
]
=
defValue
}
}
}
}
for
k
,
schemaV
:=
range
schema
.
LeadgerFields
{
if
v
,
ok
:=
checkmap
[
k
];
!
ok
{
return
nil
,
fmt
.
Errorf
(
"Update data parameter mismatch with schema structure! "
)
}
else
{
if
_
,
ok
:=
schemaV
.
Value
.
(
map
[
string
]
SchemaLeadgerParameters
);
ok
{
if
_
,
ok
:=
v
.
(
map
[
string
]
interface
{});
!
ok
{
return
nil
,
fmt
.
Errorf
(
"Update data parameter mismatch with schema structure! "
)
}
if
ok
,
_
:=
authorityCheck
(
schemaV
.
PAuth
.
Read
,
commonName
,
onwer
);
!
ok
{
checkmap
[
k
]
=
defValue
}
}
else
{
if
ok
,
_
:=
authorityCheck
(
schemaV
.
PAuth
.
Read
,
commonName
,
onwer
);
!
ok
{
checkmap
[
k
]
=
defValue
}
}
}
}
return
checkmap
,
nil
}
func
authorityCheck
(
authority
AuthGroup
,
commonName
,
owner
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
||
(
k
==
"owner"
&&
commonName
==
owner
)
{
if
v
==
0
||
v
>
time
.
Now
()
.
Unix
()
{
return
true
,
nil
}
else
{
return
false
,
fmt
.
Errorf
(
"%s user permission period "
,
commonName
)
}
}
}
return
false
,
fmt
.
Errorf
(
"%s user does not have permission"
,
commonName
)
}
/*
检查一组参数的权限是否匹配
*/
func
parsauthorityCheck
(
schema
map
[
string
]
SchemaParameters
,
checkmap
map
[
string
]
interface
{},
commonName
string
)
(
bool
,
error
)
{
for
k
,
v
:=
range
checkmap
{
if
schemaV
,
ok
:=
schema
[
k
];
!
ok
{
return
false
,
fmt
.
Errorf
(
"Update data parameter mismatch with schema structure! "
)
...
...
@@ -844,8 +1000,8 @@ func parsauthorityCheck(schema map[string]SchemaParameters, checkmap map[string]
return
false
,
fmt
.
Errorf
(
"Update data parameter mismatch with schema structure! "
)
}
}
if
ok
,
err
:=
authorityCheck
(
schemaV
.
PAuth
.
Write
,
commonName
);
!
ok
{
return
false
,
fmt
.
Errorf
(
"%s field permission check does not match, err: %s "
,
k
,
err
)
if
ok
,
err
:=
authorityCheck
(
schemaV
.
PAuth
.
Write
,
commonName
,
""
);
!
ok
{
return
false
,
fmt
.
Errorf
(
"%s field permission check does not match, err: %s "
,
k
,
err
)
}
}
}
...
...
@@ -877,14 +1033,12 @@ func Deassign(upMap, result map[string]interface{}) error {
return
nil
}
/*
账户金额发现,核心是在对应的schema 找到有发行的权利。
1:金额字段也就是(账本字段数据)都有发行标示
2:发行交易可以存在多个字段,但只要保证我们要求的字段存在就可以。账户类型,Id,发行金额(大于0)
*/
func
funtOperation
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
,
isIssue
bool
)
(
string
,
error
)
{
func
funtOperation
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
,
isIssue
bool
)
(
string
,
error
)
{
if
len
(
args
)
!=
1
{
return
""
,
fmt
.
Errorf
(
"issue or extract operation expected 1 parameters ! "
)
}
...
...
@@ -893,68 +1047,69 @@ func funtOperation(args []string, stub shim.ChaincodeStubInterface,isIssue bool)
return
""
,
fmt
.
Errorf
(
"getCertificateCommonName happen err: %s "
,
err
)
}
action
:=
&
Action
{}
err
=
json
.
Unmarshal
([]
byte
(
args
[
0
]),
action
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"json unmarshal Action structure fail,err: %s"
,
err
)
err
=
json
.
Unmarshal
([]
byte
(
args
[
0
]),
action
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"json unmarshal Action structure fail,err: %s"
,
err
)
}
schema
:=
&
Schema
{}
err
=
schema
.
get
(
action
.
AccountType
,
stub
)
err
,
schema
=
schema
.
get
(
action
.
AccountType
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
if
isIssue
{
if
ok
,
err
:=
authorityCheck
(
schema
.
LeadgerFields
[
action
.
FundType
]
.
PAuth
.
Issue
,
commonName
);
!
ok
{
return
""
,
fmt
.
Errorf
(
"%s field issue permission check does not match, err: %s "
,
action
.
FundType
,
err
)
leadgerKey
:=
LeadgerPrefix
+
"_"
+
action
.
AccountType
+
"_"
+
action
.
AccountId
leadgermap
,
err
:=
getState
(
leadgerKey
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
}
else
{
if
ok
,
err
:=
authorityCheck
(
schema
.
LeadgerFields
[
action
.
FundType
]
.
PAuth
.
Extract
,
commonName
);
!
ok
{
return
""
,
fmt
.
Errorf
(
"%s field extract permission check does not match, err: %s "
,
action
.
FundType
,
err
)
onwer
,
ok
:=
leadgermap
[
"common_name"
]
.
(
string
)
if
isIssue
{
if
ok
,
err
:=
authorityCheck
(
schema
.
LeadgerFields
[
action
.
FundType
]
.
PAuth
.
Issue
,
commonName
,
onwer
);
!
ok
{
return
""
,
fmt
.
Errorf
(
"%s field issue permission check does not match, err: %s "
,
action
.
FundType
,
err
)
}
}
else
{
if
ok
,
err
:=
authorityCheck
(
schema
.
LeadgerFields
[
action
.
FundType
]
.
PAuth
.
Extract
,
commonName
,
onwer
);
!
ok
{
return
""
,
fmt
.
Errorf
(
"%s field extract permission check does not match, err: %s "
,
action
.
FundType
,
err
)
}
leadgerKey
:=
LeadgerPrefix
+
"_"
+
action
.
AccountType
+
"_"
+
action
.
AccountId
leadgerResult
,
err
:=
stub
.
GetState
(
leadgerKey
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"GetState %s data fail,err %s "
,
leadgerKey
,
err
)
}
if
leadgerResult
==
nil
{
return
""
,
fmt
.
Errorf
(
"GetState %s data is null,please check your parameters "
,
leadgerKey
)
funt
,
ok
:=
leadgermap
[
action
.
FundType
]
.
(
string
)
funtAmount
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
funt
,
10
)
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"%s parameter resolution to big.int failed "
,
action
.
FundType
)
}
var
leadgermap
map
[
string
]
interface
{}
err
=
json
.
Unmarshal
(
leadgerResult
,
&
leadgermap
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"json unmarshal leadger map fail,err: %s"
,
err
)
actionAmount
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
action
.
ActionAmount
,
10
)
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"action_amount parameter resolution to big.int failed "
)
}
funt
:=
leadgermap
[
action
.
FundType
]
.
(
float64
)
amount
:=
Decimal
(
action
.
ActionAmount
)
sum
:=
new
(
big
.
Int
)
if
isIssue
{
funt
+=
amount
}
else
{
if
funt
<
amount
{
sum
=
sum
.
Add
(
funtAmount
,
actionAmount
)
}
else
{
if
funt
Amount
.
Cmp
(
actionAmount
)
==
-
1
{
return
""
,
fmt
.
Errorf
(
"The current amount is less than the withdrawal amount and cannot be extracted "
)
}
funt
-=
amount
sum
=
sum
.
Sub
(
funtAmount
,
actionAmount
)
}
leadgermap
[
action
.
FundType
]
=
funt
leadgerResult
,
_
=
json
.
Marshal
(
leadgermap
)
err
=
stub
.
PutState
(
leadgerKey
,
leadgerResult
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"putState %s data fail,err: %s"
,
leadgerKey
,
err
)
leadgermap
[
action
.
FundType
]
=
sum
.
String
()
leadgerResult
,
_
:=
json
.
Marshal
(
leadgermap
)
err
=
stub
.
PutState
(
leadgerKey
,
leadgerResult
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"putState %s data fail,err: %s"
,
leadgerKey
,
err
)
}
return
"transaction successful!"
,
nil
}
/*
*/
func
normalTransfer
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
error
{
*/
func
normalTransfer
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
error
{
if
len
(
args
)
!=
1
{
return
nil
}
tx
:=
&
CommonTx
{}
err
:=
json
.
Unmarshal
([]
byte
(
args
[
0
]),
tx
)
if
err
!=
nil
{
fmt
.
Errorf
(
"CommonTx structure json unmarshal fail,err : %s "
,
err
)
err
:=
json
.
Unmarshal
([]
byte
(
args
[
0
]),
tx
)
if
err
!=
nil
{
fmt
.
Errorf
(
"CommonTx structure json unmarshal fail,err : %s "
,
err
)
}
sender
:=
&
TransferAccount
{
tx
.
SenderAccountType
,
...
...
@@ -966,47 +1121,32 @@ func normalTransfer(args []string, stub shim.ChaincodeStubInterface)error{
tx
.
ReceiverId
,
tx
.
ReceiverFunt
,
}
commonName
,
err
:=
getCertificateCommonName
(
stub
)
if
err
!=
nil
{
commonName
,
err
:=
getCertificateCommonName
(
stub
)
if
err
!=
nil
{
return
nil
}
return
transfer
(
Decimal
(
tx
.
Amount
),
sender
,
receiver
,
commonName
,
stub
)
amount
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
tx
.
Amount
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"amount parameter resolution to big.int failed "
)
}
return
transfer
(
amount
,
sender
,
receiver
,
commonName
,
stub
)
}
/*
当增加一条交易记录的时候,我们需要根据交易记录实现,1.预付金的计算,2.计算分成,3.预付金的变化。分成的计算
当增加一条交易记录的时候,我们需要根据交易记录实现,
1.预付金的计算,2.计算分成,3.预付金的变化。分成的计算
*/
func
merchantsale
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
error
{
commanName
,
err
:=
getCertificateCommonName
(
stub
)
if
err
!=
nil
{
func
merchantsale
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
error
{
commanName
,
err
:=
getCertificateCommonName
(
stub
)
if
err
!=
nil
{
return
err
}
senderaccountType
:=
"merchants"
receiverAccountType
:=
"alibusi"
mer
:=
&
Merchantsale
{}
err
=
json
.
Unmarshal
([]
byte
(
args
[
0
]),
mer
)
err
=
json
.
Unmarshal
([]
byte
(
args
[
0
]),
mer
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"Merchantsale struct json unmarshal fail,err : %s "
,
err
)
}
//1.计算预付金 这部分待定1698.83
var
treposit
float64
if
mer
.
Nodisamount
==
0
||
mer
.
Disamount
==
0
{
//如果打折金额与不打折金额任一为0,则认为全部打折
treposit
=
Decimal
(
mer
.
Oamount
*
mer
.
Adiscounts
)
}
else
{
treposit
=
Decimal
(
mer
.
Nodisamount
+
mer
.
Disamount
*
mer
.
Adiscounts
)
}
if
treposit
!=
mer
.
Treposit
{
return
fmt
.
Errorf
(
"treposit calculation fail "
)
}
if
mer
.
Fee
!=
Decimal
(
mer
.
Tamount
*
mer
.
Feerate
){
return
fmt
.
Errorf
(
"fee calculation fail "
)
}
profit
:=
mer
.
Tamount
-
mer
.
Fee
-
treposit
//计算利润
if
profit
<
0
{
return
fmt
.
Errorf
(
"profit is negative "
)
return
fmt
.
Errorf
(
"Merchantsale struct json unmarshal fail,err : %s "
,
err
)
}
sender
:=
&
TransferAccount
{
senderaccountType
,
...
...
@@ -1018,117 +1158,389 @@ func merchantsale(args []string, stub shim.ChaincodeStubInterface)error{
mer
.
Bid
,
"abail"
,
}
err
=
transfer
(
treposit
,
sender
,
receiver
,
commanName
,
stub
)
if
err
!=
nil
{
return
nil
rtreposit
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
mer
.
Treposit
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"Treposit parameter resolution to big.int failed "
)
}
//errinfo := make(chan error)
err
=
transfer
(
rtreposit
,
sender
,
receiver
,
commanName
,
stub
)
if
err
!=
nil
{
return
err
}
//1.计算预付金 这部分待定
treposit
:=
new
(
big
.
Int
)
nodisamount
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
mer
.
Nodisamount
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"Nodisamount parameter resolution to big.int failed "
)
}
disamount
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
mer
.
Disamount
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"Disamount parameter resolution to big.int failed "
)
}
oamount
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
mer
.
Oamount
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"Oamount parameter resolution to big.int failed "
)
}
if
nodisamount
.
Cmp
(
big
.
NewInt
(
0
))
==
0
||
disamount
.
Cmp
(
big
.
NewInt
(
0
))
==
0
{
//如果打折金额与不打折金额任一为0,则认为全部打折
treposit
,
err
=
dividecalc
(
oamount
,
mer
.
Adiscounts
)
if
err
!=
nil
{
return
err
}
}
else
{
distre
,
err
:=
dividecalc
(
disamount
,
mer
.
Adiscounts
)
//计算打折部分的金额
if
err
!=
nil
{
return
err
}
treposit
=
new
(
big
.
Int
)
.
Add
(
nodisamount
,
distre
)
}
//进行分成数据
if
treposit
.
Cmp
(
rtreposit
)
!=
0
{
return
fmt
.
Errorf
(
"treposit calculation fail "
)
}
return
nil
rfee
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
mer
.
Free
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"Fee parameter resolution to big.int failed "
)
}
tamount
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
mer
.
Tamount
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"Tamount parameter resolution to big.int failed "
)
}
fee
,
err
:=
dividecalc
(
tamount
,
mer
.
Feerate
)
if
err
!=
nil
{
return
err
}
if
fee
.
Cmp
(
rfee
)
!=
0
{
return
fmt
.
Errorf
(
"fee calculation fail "
)
}
profit
:=
new
(
big
.
Int
)
.
Sub
(
tamount
,
new
(
big
.
Int
)
.
Add
(
rfee
,
rtreposit
))
//计算分成
if
profit
.
Cmp
(
big
.
NewInt
(
0
))
==
-
1
{
return
fmt
.
Errorf
(
"profit is negative "
)
}
//进行分成数据
err
=
dividesTransaction
(
mer
.
Mid
,
treposit
,
stub
)
if
err
!=
nil
{
return
err
}
return
err
}
/*
共享惠订单交易
*/
func
tickerorders
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
error
{
func
tickerorders
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
error
{
/*
由于共享惠还没有进行确定的订单交易所以这部分先进行伪代码的记录
1:计算实际支付是否正确,
2:计算手续费总和是否正确
3:计算利润
4:是否需要进行商户金额的清分(待定)
4:是否需要进行商户金额的清分(待定)//待办
5:合作方分成
6:最终分成
*/
//commanName, err := getCertificateCommonName(stub)
//if err != nil {
// return err
//}
ticketcanName
:=
"coutcantm"
ticketName
:=
"coutickets"
codeName
:=
"couticketcodes"
oTx
:=
&
OrderTx
{}
err
:=
json
.
Unmarshal
([]
byte
(
args
[
0
]),
oTx
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"OrderTx struct json unmarshal fail,err : %s "
,
err
)
}
tickMerKey
:=
StoragePrefix
+
"_"
+
ticketcanName
+
"_"
+
oTx
.
Mid
+
"_"
+
oTx
.
Odesc
.
Tid
//券可用门店key
tickM
,
err
:=
getState
(
tickMerKey
,
stub
)
if
err
!=
nil
{
return
err
}
tickKey
:=
StoragePrefix
+
"_"
+
ticketName
+
"_"
+
oTx
.
Odesc
.
Tid
//券key
tick
,
err
:=
getState
(
tickKey
,
stub
)
if
err
!=
nil
{
return
err
}
resid
,
_
:=
tickM
[
"resid"
]
.
(
float64
)
//剩余可用码数
discount
,
_
:=
tick
[
"discount"
]
.
(
float64
)
//得到券面值
fieldkeys
:=
[]
string
{
"status"
}
// 码状态
var
checkvalue
,
upvalue
[]
interface
{}
if
resid
==
0
{
return
fmt
.
Errorf
(
"The current merchant has been unable to use the %s ticket "
,
oTx
.
Odesc
.
Tid
)
}
oamount
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
oTx
.
Oamount
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"Oamount parameter resolution to big.int failed "
)
}
pamount
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
oTx
.
Pamount
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"Pamount parameter resolution to big.int failed "
)
}
outfree
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
oTx
.
Outfree
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"Outfree parameter resolution to big.int failed "
)
}
infree
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
oTx
.
Infree
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"Infree parameter resolution to big.int failed "
)
}
partnersfree
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
oTx
.
Partnersfree
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"Partnersfree parameter resolution to big.int failed "
)
}
free
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
oTx
.
Free
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"Free parameter resolution to big.int failed "
)
}
if
oTx
.
Odesc
.
TicketType
==
1
{
//如果是折扣券则只能使用一张券
if
len
(
oTx
.
Odesc
.
Codes
)
>
1
{
return
fmt
.
Errorf
(
"Only one coupon can be used "
)
}
codeKey
:=
StoragePrefix
+
"_"
+
codeName
+
"_"
+
oTx
.
Odesc
.
Codes
[
0
]
checkvalue
[
0
]
=
float64
(
1
)
upvalue
[
0
]
=
float64
(
2
)
_
,
err
=
checkandUpdate
(
codeKey
,
fieldkeys
,
checkvalue
,
upvalue
,
stub
)
if
err
!=
nil
{
return
err
}
camount
,
_
:=
dividecalc
(
oamount
,
discount
)
if
camount
.
Cmp
(
pamount
)
!=
0
{
return
fmt
.
Errorf
(
"pamount calculation fail "
)
}
}
else
{
for
i
,
v
:=
range
oTx
.
Odesc
.
Codes
{
codeKey
:=
StoragePrefix
+
"_"
+
codeName
+
"_"
+
v
checkvalue
[
i
]
=
float64
(
1
)
upvalue
[
i
]
=
float64
(
2
)
_
,
err
=
checkandUpdate
(
codeKey
,
fieldkeys
,
checkvalue
,
upvalue
,
stub
)
if
err
!=
nil
{
return
err
}
}
length
:=
int64
(
len
(
oTx
.
Odesc
.
Codes
))
disint
:=
int64
(
discount
)
//将discount 转化为整数
camount
:=
new
(
big
.
Int
)
.
Sub
(
oamount
,
big
.
NewInt
(
disint
*
length
))
if
camount
.
Cmp
(
pamount
)
!=
0
{
return
fmt
.
Errorf
(
"pamount calculation fail "
)
}
}
cfree
:=
new
(
big
.
Int
)
.
Add
(
new
(
big
.
Int
)
.
Add
(
outfree
,
infree
),
partnersfree
)
if
free
.
Cmp
(
cfree
)
!=
0
{
return
fmt
.
Errorf
(
"free calculation fail "
)
}
income
:=
new
(
big
.
Int
)
.
Sub
(
pamount
,
free
)
treposit
,
err
:=
dividecalc
(
income
,
oTx
.
Norate
)
if
err
!=
nil
{
return
err
}
receiver
:=
&
TransferAccount
{
AccountType
:
"coupartners"
,
AccountId
:
oTx
.
Pid
,
FundType
:
"benefit"
,
}
err
=
transfer
(
partnersfree
,
nil
,
receiver
,
""
,
stub
)
if
err
!=
nil
{
return
err
}
//netincome := new(big.Int).Sub(income,treposit)
err
=
dividesTransaction
(
oTx
.
Mid
,
treposit
,
stub
)
if
err
!=
nil
{
return
err
}
return
nil
}
/*
根据商户Id,进行分成交易
*/
func
dividesTransaction
(
mid
string
,
treposit
*
big
.
Int
,
stub
shim
.
ChaincodeStubInterface
)
error
{
merkey
:=
StoragePrefix
+
"_"
+
"merchants"
+
"_"
+
mid
mermap
,
err
:=
getState
(
merkey
,
stub
)
if
err
!=
nil
{
return
err
}
aid
,
ok
:=
mermap
[
"aid"
]
.
(
string
)
//得到代理商Id
if
!
ok
{
return
fmt
.
Errorf
(
"aid parameter resolution to string failed "
)
}
bid
,
ok
:=
mermap
[
"bid"
]
.
(
string
)
//得到分支机构Id
if
!
ok
{
return
fmt
.
Errorf
(
"Free parameter resolution to string failed "
)
}
acid
,
ok
:=
mermap
[
"acid"
]
.
(
string
)
//得到加盟商Id
if
!
ok
{
return
fmt
.
Errorf
(
"Free parameter resolution to string failed "
)
}
fid
,
ok
:=
mermap
[
"fid"
]
.
(
string
)
//得到保理
if
!
ok
{
return
fmt
.
Errorf
(
"Free parameter resolution to string failed "
)
}
asdiscounts
,
err
:=
divide
(
aid
,
treposit
,
stub
)
if
err
!=
nil
{
return
err
}
bsdiscounts
,
err
:=
divide
(
bid
,
treposit
,
stub
)
if
err
!=
nil
{
return
err
}
acsdiscounts
,
err
:=
divide
(
acid
,
treposit
,
stub
)
if
err
!=
nil
{
return
err
}
fsdiscounts
,
err
:=
divide
(
fid
,
treposit
,
stub
)
if
err
!=
nil
{
return
err
}
if
asdiscounts
+
bsdiscounts
+
acsdiscounts
+
fsdiscounts
>
1
{
return
fmt
.
Errorf
(
"The divide proportion must not exceed 1 "
)
}
return
nil
}
func
divide
(
id
string
,
treposit
*
big
.
Int
,
stub
shim
.
ChaincodeStubInterface
)(
float64
,
error
){
akey
:=
StoragePrefix
+
"_"
+
"alibusi"
+
"_"
+
id
amap
,
err
:=
getState
(
akey
,
stub
)
if
err
!=
nil
{
return
0
,
err
}
sdiscounts
,
ok
:=
amap
[
"sdiscounts"
]
.
(
float64
)
if
!
ok
{
return
0
,
fmt
.
Errorf
(
"sdiscounts parameter resolution to float64 failed "
)
}
adivide
,
err
:=
dividecalc
(
treposit
,
sdiscounts
)
if
err
!=
nil
{
return
0
,
err
}
areceiver
:=
&
TransferAccount
{
AccountType
:
"alibusi"
,
AccountId
:
id
,
FundType
:
"amount"
,
}
return
sdiscounts
,
transfer
(
adivide
,
nil
,
areceiver
,
""
,
stub
)
}
/*
特别说明interface 不能是引用类型
*/
func
checkandUpdate
(
key
string
,
fieldkeys
[]
string
,
checkvalue
,
upvalue
[]
interface
{},
stub
shim
.
ChaincodeStubInterface
)(
map
[
string
]
interface
{},
error
){
valueMap
,
err
:=
getState
(
key
,
stub
)
if
err
!=
nil
{
return
nil
,
err
}
for
i
,
fk
:=
range
fieldkeys
{
if
!
reflect
.
DeepEqual
(
valueMap
[
fk
],
checkvalue
[
i
])
{
return
nil
,
fmt
.
Errorf
(
"%s not the expected field value"
,
fk
)
}
else
{
valueMap
[
fk
]
=
upvalue
[
i
]
}
}
value
,
err
:=
json
.
Marshal
(
valueMap
)
if
err
!=
nil
{
return
nil
,
err
}
err
=
stub
.
PutState
(
key
,
value
)
if
err
!=
nil
{
return
nil
,
err
}
return
valueMap
,
nil
}
/*
实现普通的转账操作
*/
func
transfer
(
amount
float64
,
sender
,
receiver
*
TransferAccount
,
commonName
string
,
stub
shim
.
ChaincodeStubInterface
)
error
{
if
amount
<=
0
{
return
fmt
.
Errorf
(
"transfer limit must greater than 0 "
)
func
transfer
(
amount
*
big
.
Int
,
sender
,
receiver
*
TransferAccount
,
commonName
string
,
stub
shim
.
ChaincodeStubInterface
)
error
{
var
err
error
if
amount
.
Cmp
(
big
.
NewInt
(
0
))
==
-
1
{
err
=
fmt
.
Errorf
(
"transfer limit must greater than 0 "
)
return
err
}
if
sender
!=
nil
{
senderSchema
:=
&
Schema
{}
err
:=
senderSchema
.
get
(
sender
.
AccountType
,
stub
)
err
,
senderSchema
=
senderSchema
.
get
(
sender
.
AccountType
,
stub
)
if
err
!=
nil
{
return
err
}
senderKey
:=
LeadgerPrefix
+
"_"
+
sender
.
AccountType
+
"_"
+
sender
.
AccountId
senderleadgermap
,
err
:=
getState
(
senderKey
,
stub
)
if
err
!=
nil
{
return
err
}
if
ok
,
err
:=
authorityCheck
(
senderSchema
.
LeadgerFields
[
sender
.
FundType
]
.
PAuth
.
Transfer
,
commonName
);
!
ok
{
return
fmt
.
Errorf
(
"%s field issue permission check does not match, err: %s "
,
sender
.
FundType
,
err
)
onwer
,
ok
:=
senderleadgermap
[
"common_name"
]
.
(
string
)
if
ok
,
err
:=
authorityCheck
(
senderSchema
.
LeadgerFields
[
sender
.
FundType
]
.
PAuth
.
Transfer
,
commonName
,
onwer
);
!
ok
{
err
=
fmt
.
Errorf
(
"%s field issue permission check does not match, err: %s "
,
sender
.
FundType
,
err
)
return
err
}
senderKey
:=
LeadgerPrefix
+
"_"
+
sender
.
AccountType
+
"_"
+
sender
.
AccountId
senderleadgermap
,
err
:=
getState
(
senderKey
,
stub
)
if
err
!=
nil
{
fundstr
:=
senderleadgermap
[
sender
.
FundType
]
.
(
string
)
fund
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
fundstr
,
10
)
if
!
ok
{
err
=
fmt
.
Errorf
(
"%s parameter resolution to big.int failed "
,
sender
.
FundType
)
return
err
}
funt
:=
senderleadgermap
[
sender
.
FundType
]
.
(
float64
)
if
funt
<
amount
{
return
fmt
.
Errorf
(
"The current amount is less than the withdrawal amount and cannot be extracted "
)
if
fund
.
Cmp
(
amount
)
==
-
1
{
err
=
fmt
.
Errorf
(
"The current amount is less than the withdrawal amount and cannot be extracted "
)
return
err
}
fun
t
-=
amount
senderleadgermap
[
sender
.
FundType
]
=
funt
fun
d
.
Sub
(
fund
,
amount
)
senderleadgermap
[
sender
.
FundType
]
=
fund
.
String
()
err
=
putState
(
senderKey
,
senderleadgermap
,
stub
)
if
err
!=
nil
{
err
=
putState
(
senderKey
,
senderleadgermap
,
stub
)
if
err
!=
nil
{
return
err
}
receiverKey
:=
LeadgerPrefix
+
"_"
+
receiver
.
AccountType
+
"_"
+
receiver
.
AccountId
receiverleadgermap
,
err
:=
getState
(
receiverKey
,
stub
)
if
err
!=
nil
{
}
if
receiver
!=
nil
{
receiverKey
:=
LeadgerPrefix
+
"_"
+
receiver
.
AccountType
+
"_"
+
receiver
.
AccountId
receiverleadgermap
,
err
:=
getState
(
receiverKey
,
stub
)
if
err
!=
nil
{
return
err
}
rfundstr
:=
receiverleadgermap
[
receiver
.
FundType
]
.
(
string
)
rfund
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
rfundstr
,
10
)
if
!
ok
{
err
=
fmt
.
Errorf
(
"%s parameter resolution to big.int failed "
,
receiver
.
FundType
)
return
err
}
rfunt
:=
receiverleadgermap
[
receiver
.
FundType
]
.
(
float64
)
rfunt
+=
amount
receiverleadgermap
[
receiver
.
FundType
]
=
rfunt
rfund
.
Add
(
rfund
,
amount
)
receiverleadgermap
[
receiver
.
FundType
]
=
rfund
.
String
()
err
=
putState
(
receiverKey
,
receiverleadgermap
,
stub
)
if
err
!=
nil
{
err
=
putState
(
receiverKey
,
receiverleadgermap
,
stub
)
if
err
!=
nil
{
return
err
}
}
return
nil
}
func
getState
(
key
string
,
stub
shim
.
ChaincodeStubInterface
)(
map
[
string
]
interface
{},
error
){
func
getState
(
key
string
,
stub
shim
.
ChaincodeStubInterface
)
(
map
[
string
]
interface
{},
error
)
{
var
resultmap
map
[
string
]
interface
{}
result
,
err
:=
stub
.
GetState
(
key
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"GetState %s data fail,err %s "
,
key
,
err
)
return
nil
,
fmt
.
Errorf
(
"GetState %s data fail,err %s "
,
key
,
err
)
}
if
result
==
nil
{
return
nil
,
fmt
.
Errorf
(
"GetState %s data is null,please check your parameters "
,
key
)
return
nil
,
fmt
.
Errorf
(
"GetState %s data is null,please check your parameters "
,
key
)
}
err
=
json
.
Unmarshal
(
result
,
&
resultmap
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"json unmarshal leadger map fail,err: %s"
,
err
)
err
=
json
.
Unmarshal
(
result
,
&
resultmap
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"json unmarshal leadger map fail,err: %s"
,
err
)
}
return
resultmap
,
nil
return
resultmap
,
nil
}
func
putState
(
key
string
,
value
map
[
string
]
interface
{},
stub
shim
.
ChaincodeStubInterface
)
error
{
valueByte
,
err
:=
json
.
Marshal
(
value
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
" %s json marshal data fail,err: %s"
,
key
,
err
)
func
putState
(
key
string
,
value
map
[
string
]
interface
{},
stub
shim
.
ChaincodeStubInterface
)
error
{
valueByte
,
err
:=
json
.
Marshal
(
value
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
" %s json marshal data fail,err: %s"
,
key
,
err
)
}
err
=
stub
.
PutState
(
key
,
valueByte
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"putState %s data fail,err: %s"
,
key
,
err
)
err
=
stub
.
PutState
(
key
,
valueByte
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"putState %s data fail,err: %s"
,
key
,
err
)
}
return
nil
}
func
unmarshalMap
(
arg
string
)(
error
,
map
[
string
]
interface
{}){
var
valueMap
map
[
string
]
interface
{}
err
:=
json
.
Unmarshal
([]
byte
(
arg
),
&
valueMap
)
if
err
!=
nil
{
return
err
,
nil
}
return
nil
,
valueMap
}
func
getCertificateCommonName
(
stub
shim
.
ChaincodeStubInterface
)
(
string
,
error
)
{
return
"Admin@org2.example.com"
,
nil
creatorByte
,
_
:=
stub
.
GetCreator
()
...
...
@@ -1153,133 +1565,146 @@ func Decimal(value float64) float64 {
return
value
}
func
NewSchema
(
arg
string
)
(
*
Schema
,
error
)
{
func
NewSchema
(
arg
string
)
(
*
Schema
,
error
)
{
schema
:=
&
Schema
{
LeadgerFields
:
make
(
map
[
string
]
SchemaLeadgerParameters
),
StorageFields
:
make
(
map
[
string
]
SchemaParameters
),
LeadgerFields
:
make
(
map
[
string
]
SchemaLeadgerParameters
),
StorageFields
:
make
(
map
[
string
]
SchemaParameters
),
}
var
argMap
map
[
string
]
interface
{}
if
err
:=
json
.
Unmarshal
([]
byte
(
arg
),
&
argMap
);
err
!=
nil
{
return
nil
,
err
if
err
:=
json
.
Unmarshal
([]
byte
(
arg
),
&
argMap
);
err
!=
nil
{
return
nil
,
err
}
if
(
argMap
[
"storage_fields"
]
!=
nil
||
argMap
[
"leadger_fields"
]
!=
nil
)
&&
argMap
[
"schema_auth"
]
!=
nil
&&
argMap
[
"auth"
]
!=
nil
{
if
err
:=
json
.
Unmarshal
([]
byte
(
arg
),
schema
);
err
!=
nil
{
return
nil
,
err
if
(
argMap
[
"storage_fields"
]
!=
nil
||
argMap
[
"leadger_fields"
]
!=
nil
)
&&
argMap
[
"schema_auth"
]
!=
nil
&&
argMap
[
"auth"
]
!=
nil
{
if
err
:=
json
.
Unmarshal
([]
byte
(
arg
),
schema
);
err
!=
nil
{
return
nil
,
err
}
//检查schema leadger字段
err
:=
leadgerFieldsCheck
(
&
schema
.
LeadgerFields
)
if
err
!=
nil
{
return
nil
,
err
if
err
!=
nil
{
return
nil
,
err
}
return
schema
,
nil
return
schema
,
nil
}
for
k
,
v
:=
range
argMap
{
//假设用户只传递了map类型的信息,我们则默认它全部都是存储字段
for
k
,
v
:=
range
argMap
{
//假设用户只传递了map类型的信息,我们则默认它全部都是存储字段
schema
.
StorageFields
[
k
]
=
SchemaParameters
{
Value
:
v
,
PAuth
:
Auth
{},
Value
:
v
,
PAuth
:
Auth
{},
}
}
return
schema
,
nil
return
schema
,
nil
}
func
leadgerFieldsCheck
(
leadgerFields
*
map
[
string
]
SchemaLeadgerParameters
)
error
{
for
k
,
fields
:=
range
*
leadgerFields
{
func
leadgerFieldsCheck
(
leadgerFields
*
map
[
string
]
SchemaLeadgerParameters
)
error
{
for
k
,
fields
:=
range
*
leadgerFields
{
if
fields
.
FCheck
==
nil
{
fields
.
FCheck
=
&
Checks
{
FType
:
"float64
"
,
Must
:
false
,
Fieldlen
:
1
,
FType
:
"big.int
"
,
Must
:
false
,
Fieldlen
:
1
,
}
}
else
{
if
fields
.
FCheck
.
FType
!=
"
float64"
{
return
fmt
.
Errorf
(
"%s fields type must is
float64"
,
k
)
}
else
if
!
(
fields
.
FCheck
.
Fieldlen
>
0
)
{
return
fmt
.
Errorf
(
"%s fields length must is greater than zero"
,
k
)
}
else
{
if
fields
.
FCheck
.
FType
!=
"
big.int"
{
return
fmt
.
Errorf
(
"%s fields type must is
big.int"
,
k
)
}
else
if
!
(
fields
.
FCheck
.
Fieldlen
>
0
)
{
return
fmt
.
Errorf
(
"%s fields length must is greater than zero"
,
k
)
}
}
if
len
(
fields
.
PAuth
.
Extract
.
Roles
)
==
0
&&
len
(
fields
.
PAuth
.
Extract
.
Users
)
==
0
{
}
}
return
nil
}
func
fieldCheckout
(
check
*
Checks
,
val
interface
{})
error
{
func
fieldCheckout
(
check
*
Checks
,
val
interface
{})
error
{
fType
:=
reflect
.
TypeOf
(
val
)
.
String
()
switch
check
.
FType
{
case
"string"
:
if
fType
!=
"string"
{
if
fType
!=
"string"
{
return
fmt
.
Errorf
(
"fields type does not match the defined string type! "
)
}
if
check
.
Must
&&
(
val
==
""
){
if
check
.
Must
&&
(
val
==
""
)
{
return
fmt
.
Errorf
(
"fields can not be empty"
)
}
value
:=
val
.
(
string
)
if
len
([]
rune
(
value
))
>
check
.
Fieldlen
{
return
fmt
.
Errorf
(
"fields length cannot be greater than %d "
,
check
.
Fieldlen
)
if
len
([]
rune
(
value
))
>
check
.
Fieldlen
{
return
fmt
.
Errorf
(
"fields length cannot be greater than %d "
,
check
.
Fieldlen
)
}
case
"int"
,
"int16"
,
"int32"
,
"int64"
,
"float32"
,
"float64"
:
if
fType
!=
"float64"
{
return
fmt
.
Errorf
(
"fields type does not match the defined %s type! "
,
check
.
FType
)
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
){
if
check
.
Must
&&
(
value
==
0
)
{
return
fmt
.
Errorf
(
"fields can not be 0"
)
}
if
check
.
Fieldlen
!=
0
&&
value
<
0
{
if
check
.
Fieldlen
!=
0
&&
value
<
0
{
return
fmt
.
Errorf
(
"fields cannot be negative"
)
}
case
"time.Time"
:
if
fType
!=
"string"
{
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
==
""
{
if
check
.
Must
&&
dateStr
==
""
{
return
fmt
.
Errorf
(
"fields cannot be empty"
)
}
if
_
,
err
:=
time
.
Parse
(
"2006-01-02 15:04:05"
,
dateStr
);
err
!=
nil
{
if
_
,
err
:=
time
.
Parse
(
"2006-01-02 15:04:05"
,
dateStr
);
err
!=
nil
{
return
fmt
.
Errorf
(
err
.
Error
())
}
//if check.Must && (dateStr == "0001-01-01 00:00:00 +0000 UTC"|| dateStr == "0001-01-01T00:00:00Z"){
// return fmt.Errorf("fields cannot be initial value")
//}
case
"big.int"
:
if
fType
!=
"string"
{
return
fmt
.
Errorf
(
"fields type does not match the defined big.int type! "
)
}
number
:=
new
(
big
.
Int
)
dateStr
:=
reflect
.
ValueOf
(
val
)
.
String
()
_
,
ok
:=
number
.
SetString
(
dateStr
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"parameter resolution failed "
)
}
default
:
fmt
.
Errorf
(
"fields type no match! "
)
}
return
nil
}
func
Constructor
(
capacity
int
)
LRUCache
{
lruCache
:=
LRUCache
{
limit
:
capacity
}
func
Constructor
(
capacity
int
)
LRUCache
{
lruCache
:=
LRUCache
{
limit
:
capacity
}
lruCache
.
HashMap
=
make
(
map
[
string
]
*
Node
,
capacity
)
return
lruCache
}
func
(
l
*
LRUCache
)
Get
(
key
string
)
[]
byte
{
if
v
,
ok
:=
l
.
HashMap
[
key
];
ok
{
func
(
l
*
LRUCache
)
Get
(
key
string
)
*
Schema
{
if
v
,
ok
:=
l
.
HashMap
[
key
];
ok
{
l
.
refreshNode
(
v
)
return
v
.
Value
}
else
{
}
else
{
return
nil
}
}
func
(
l
*
LRUCache
)
Put
(
key
string
,
value
[]
byte
)
{
if
v
,
ok
:=
l
.
HashMap
[
key
];
!
ok
{
if
len
(
l
.
HashMap
)
>=
l
.
limit
{
func
(
l
*
LRUCache
)
Put
(
key
string
,
value
*
Schema
)
error
{
if
v
,
ok
:=
l
.
HashMap
[
key
];
!
ok
{
if
len
(
l
.
HashMap
)
>=
l
.
limit
{
oldKey
:=
l
.
removeNode
(
l
.
head
)
delete
(
l
.
HashMap
,
oldKey
)
}
node
:=
Node
{
Key
:
key
,
Value
:
value
}
node
:=
Node
{
Key
:
key
,
Value
:
value
}
l
.
addNode
(
&
node
)
l
.
HashMap
[
key
]
=
&
node
}
else
{
}
else
{
v
.
Value
=
value
l
.
refreshNode
(
v
)
}
return
nil
}
func
(
l
*
LRUCache
)
refreshNode
(
node
*
Node
){
func
(
l
*
LRUCache
)
refreshNode
(
node
*
Node
)
{
if
node
==
l
.
end
{
return
}
...
...
@@ -1287,21 +1712,21 @@ func (l *LRUCache) refreshNode(node *Node){
l
.
addNode
(
node
)
}
func
(
l
*
LRUCache
)
removeNode
(
node
*
Node
)
string
{
func
(
l
*
LRUCache
)
removeNode
(
node
*
Node
)
string
{
if
node
==
l
.
end
{
l
.
end
=
l
.
end
.
pre
l
.
end
.
next
=
nil
}
else
if
node
==
l
.
head
{
}
else
if
node
==
l
.
head
{
l
.
head
=
l
.
head
.
next
l
.
head
.
pre
=
nil
}
else
{
}
else
{
node
.
pre
.
next
=
node
.
next
node
.
next
.
pre
=
node
.
pre
}
return
node
.
Key
}
func
(
l
*
LRUCache
)
addNode
(
node
*
Node
){
func
(
l
*
LRUCache
)
addNode
(
node
*
Node
)
{
if
l
.
end
!=
nil
{
l
.
end
.
next
=
node
node
.
pre
=
l
.
end
...
...
@@ -1313,7 +1738,12 @@ func (l *LRUCache) addNode(node *Node){
}
}
func
dividecalc
(
bint
*
big
.
Int
,
divide
float64
)
(
*
big
.
Int
,
error
)
{
divide
*=
1000000
value
:=
new
(
big
.
Int
)
.
Mul
(
bint
,
big
.
NewInt
(
int64
(
divide
)))
value
.
Div
(
value
,
big
.
NewInt
(
1000000
))
return
value
,
nil
}
func
main
()
{
err
:=
shim
.
Start
(
&
GXHCC
{})
...
...
src/github.com/gongxianghui2.0/gongxianghui2.0_test.go
View file @
d7ba709c
package
main
import
(
"encoding/json"
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
"reflect"
"testing"
)
...
...
@@ -10,7 +12,7 @@ var (
SchemaNew
=
`{"leadger_fields":{"abail":{"val":"0001-01-01T00:00:00Z","auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":1584936259}},"issue":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},
"extrate":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"transfer":{"users":null,"roles":null}},
"fcheck":{"ftype":"
float64
","must":false,"fieldlen":1}},"sabail":{"val":"0001-01-01T00:00:00Z","auth":{"read":{"users":
"fcheck":{"ftype":"
big.int
","must":false,"fieldlen":1}},"sabail":{"val":"0001-01-01T00:00:00Z","auth":{"read":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"issue":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":1584936259}},"extrate":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},
"transfer":{"users":null,"roles":null}},"fcheck":null}},"storage_fields":{"common_name":{"val":"1","auth":{"read":{"users":null,"roles":null},
...
...
@@ -30,8 +32,8 @@ var (
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":0}},"write":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":0}}}}`
merSchema
=
`{"leadger_fields":{"regular":{"val":6000,"auth":{"read":{"users":null,"roles":null},"issue":{"users":null,"roles":null},"extrate":{"users":null,"roles":null},"transfer":{"users":null,
"roles":null}},"fcheck":{"ftype":"
float64
","must":false,"fieldlen":6}},"rregular":{"val":6000,"auth":{"read":{"users":null,"roles":null},"issue":{"users":null,"roles":null},"extrate":{"users":null,"roles"
:null},"transfer":{"users":null,"roles":null}},"fcheck":{"ftype":"
float64
","must":false,"fieldlen":6}}},"storage_fields":{"common_name":{"val":"1","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":null},
"roles":null}},"fcheck":{"ftype":"
big.int
","must":false,"fieldlen":6}},"rregular":{"val":6000,"auth":{"read":{"users":null,"roles":null},"issue":{"users":null,"roles":null},"extrate":{"users":null,"roles"
:null},"transfer":{"users":null,"roles":null}},"fcheck":{"ftype":"
big.int
","must":false,"fieldlen":6}}},"storage_fields":{"common_name":{"val":"1","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":null},
"acid":{"val":3,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles"
:null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"actionid":{"val":1,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,
"fieldlen":6}},"adiscounts":{"val":"0.8","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"aid":{"val":0,"auth":{"read":
...
...
@@ -62,7 +64,7 @@ null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"backup":{"val":{
"mno2": "05910005",
"indate": "2018/10/29 16:46:57",
"aid": 0,
"regular":
6000
,
"regular":
"60000000"
,
"adiscounts": 0.8,
"sdiscounts": 0.85,
"distype": 16,
...
...
@@ -74,14 +76,14 @@ null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"backup":{"val":{
"did": 2,
"warmline": 600,
"cid": 0,
"sregular": 6000,
"sregular": 6000
0000
,
"keywords": "test",
"paystatue": 1,
"are": 1,
"marea": 1,
"actionid": 1,
"tstatue": 1,
"rregular":
6000
,
"rregular":
"60000000"
,
"ssign": "2010-01-01 15:38:54",
"firrenew": "2010-01-02 15:38:54",
"ordertel": "13444444444",
...
...
@@ -125,7 +127,7 @@ null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"backup":{"val":{
"mno2": "05910005",
"indate": "2018/10/29 16:46:57",
"aid": 0,
"regular":
6000
,
"regular":
"60000000"
,
"adiscounts": 0.8,
"sdiscounts": 0.85,
"distype": 16,
...
...
@@ -144,7 +146,7 @@ null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"backup":{"val":{
"marea": 1,
"actionid": 1,
"tstatue": 1,
"rregular":
6000
,
"rregular":
"60000000"
,
"ssign": "2010-01-01 15:38:54",
"firrenew": "2010-01-02 15:38:54",
"ordertel": "13444444444",
...
...
@@ -190,10 +192,10 @@ null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"backup":{"val":{
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":0}},"write":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":0}}}}`
SchemaUpdate
=
`{"leadger_fields":{"abail22":{"val":"0
001-01-01T00:00:00Z
","auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":
SchemaUpdate
=
`{"leadger_fields":{"abail22":{"val":"0","auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":1584936259}},"issue":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},
"extrate":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"transfer":{"users":null,"roles":null}},
"fcheck":{"ftype":"
float64
","must":true,"fieldlen":1}},"sabail":{"val":"0001-01-01T00:00:00Z","auth":{"read":{"users":
"fcheck":{"ftype":"
big.int
","must":true,"fieldlen":1}},"sabail":{"val":"0001-01-01T00:00:00Z","auth":{"read":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"issue":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":1584936259}},"extrate":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},
"transfer":{"users":null,"roles":null}},"fcheck":null}},"storage_fields":{"common_name":{"val":"1","auth":{"read":{"users":null,"roles":null},
...
...
@@ -301,10 +303,10 @@ func TestGXHPutData(t *testing.T){
}
var
(
issueTx
=
`{"account_type":"alibusi","account_id":"1","action_amount":
1000.123
,"fund_type":"abail","back_up":{"account_type":"","account_id":"","action_amount":0,"fund_type":"","back_up":null}}`
extract
=
`{"account_type":"alibusi","account_id":"1","action_amount":
100.123
,"fund_type":"abail","back_up":{"account_type":"","account_id":"","action_amount":0,"fund_type":"","back_up":null}}`
commontx
=
`{"sender_account":"alibusi","sender_id":"1","sender_funt":"abail","receiver_account":"alibusi","receiver_account_id":"2","receiver_funt":"abail","amount":
100.123
}`
merTx
=
`{"mid":"1","bid":"1","tamount":
1805.01,"treposit":1698.83,"bereposit":6000,"afreposit":4301.17,"feerate":0.0055,"fee":9.93,"oamount":2123.54,"adiscounts":0.8,"sdiscounts":0.85,"nodisamount":0,"disamount":0,"perquisites":0
}
issueTx
=
`{"account_type":"alibusi","account_id":"1","action_amount":
"1230"
,"fund_type":"abail","back_up":{"account_type":"","account_id":"","action_amount":0,"fund_type":"","back_up":null}}`
extract
=
`{"account_type":"alibusi","account_id":"1","action_amount":
"123"
,"fund_type":"abail","back_up":{"account_type":"","account_id":"","action_amount":0,"fund_type":"","back_up":null}}`
commontx
=
`{"sender_account":"alibusi","sender_id":"1","sender_funt":"abail","receiver_account":"alibusi","receiver_account_id":"2","receiver_funt":"abail","amount":
"223"
}`
merTx
=
`{"mid":"1","bid":"1","tamount":
"18050100","treposit":"16988320","bereposit":"60000000","afreposit":"43011700","feerate":0.0055,"fee":"99275","oamount":"21235400","adiscounts":0.8,"sdiscounts":0.85,"nodisamount":"0","disamount":"0","perquisites":"0"
}
`
)
...
...
@@ -337,7 +339,7 @@ func TestGXHIssueandExtract(t *testing.T){
fmt
.
Printf
(
"Invoke status %d,message %s ,and payload %s
\n
"
,
responseBytx
.
Status
,
responseBytx
.
Message
,
string
(
responseBytx
.
Payload
))
fmt
.
Println
()
responseByget
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"get"
),
[]
byte
(
"alibusi"
),[]
byte
(
inputUpdate
)})
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
))
responseByget2
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"get"
),
[]
byte
(
"alibusi"
),[]
byte
(
`{"id":"2"}`
)})
...
...
@@ -348,13 +350,13 @@ func TestGXHIssueandExtract(t *testing.T){
/*
测试商户交易
*/
//736288 590270 620798
func
TestGXHmerTx
(
t
*
testing
.
T
){
stub
:=
GXHmerTxinit
()
responseByPutschema
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"createTx"
),
[]
byte
(
"transfer"
),[]
byte
(
"merchants"
),[]
byte
(
merTx
)})
if
responseByPutschema
.
Status
!=
200
{
fmt
.
Printf
(
"schema init fail,err: %s"
,
responseByPutschema
.
Message
)
}
fmt
.
Println
()
responseByget2
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"get"
),
[]
byte
(
"merchants"
),[]
byte
(
`{"id":"1"}`
)})
fmt
.
Printf
(
"Invoke status %d,message %s ,and payload %s
\n
"
,
responseByget2
.
Status
,
responseByget2
.
Message
,
string
(
responseByget2
.
Payload
))
...
...
@@ -363,6 +365,8 @@ func TestGXHmerTx(t *testing.T){
responseByget
.
Status
,
responseByget
.
Message
,
string
(
responseByget
.
Payload
))
}
func
GXHmerTxinit
()
*
shim
.
MockStub
{
cc
:=
new
(
GXHCC
)
stub
:=
shim
.
NewMockStub
(
"GXHCC"
,
cc
)
...
...
@@ -371,13 +375,13 @@ func GXHmerTxinit()*shim.MockStub{
fmt
.
Println
(
"========================================invoke schema put============================================"
)
responseByPutschema
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"schema"
),
[]
byte
(
"put"
),[]
byte
(
"alibusi"
),[]
byte
(
SchemaNew
)})
if
responseByPutschema
.
Status
!=
200
{
fmt
.
Printf
(
"schema
init
fail,err: %s"
,
responseByPutschema
.
Message
)
fmt
.
Printf
(
"schema
put alibusi
fail,err: %s"
,
responseByPutschema
.
Message
)
return
stub
}
fmt
.
Println
()
responseBycreate
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"createAccount"
),
[]
byte
(
"alibusi"
),[]
byte
(
inputarrary
)})
if
responseBycreate
.
Status
!=
200
{
fmt
.
Printf
(
"createAccount
init
fail,err: %s"
,
responseBycreate
.
Message
)
fmt
.
Printf
(
"createAccount
alibusi
fail,err: %s"
,
responseBycreate
.
Message
)
return
stub
}
fmt
.
Println
()
...
...
@@ -385,15 +389,39 @@ func GXHmerTxinit()*shim.MockStub{
fmt
.
Println
(
"========================================invoke schema put============================================"
)
responseByMerschema
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"schema"
),
[]
byte
(
"put"
),[]
byte
(
"merchants"
),[]
byte
(
merSchema
)})
if
responseByMerschema
.
Status
!=
200
{
fmt
.
Printf
(
"schema
init
fail,err: %s"
,
responseByMerschema
.
Message
)
fmt
.
Printf
(
"schema
put merchants
fail,err: %s"
,
responseByMerschema
.
Message
)
return
stub
}
fmt
.
Println
()
responseBycreateMer
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"createAccount"
),
[]
byte
(
"merchants"
),[]
byte
(
merarrary
)})
if
responseBycreateMer
.
Status
!=
200
{
fmt
.
Printf
(
"createAccount
init
fail,err: %s"
,
responseBycreateMer
.
Message
)
fmt
.
Printf
(
"createAccount
merchants
fail,err: %s"
,
responseBycreateMer
.
Message
)
return
stub
}
return
stub
}
func
TestDeassign
(
t
*
testing
.
T
)
{
var
m
map
[
string
]
interface
{}
err
:=
json
.
Unmarshal
([]
byte
(
commontx
),
&
m
)
if
err
!=
nil
{
t
.
Errorf
(
err
.
Error
())
}
onwer
,
_
:=
m
[
"sender_account"
]
.
(
float64
)
//fmt.Println(ok)
fmt
.
Println
(
onwer
==
0
)
}
//5958 5242 5600 5909
func
BenchmarkBackUpCheck
(
b
*
testing
.
B
)
{
var
m
map
[
string
]
interface
{}
err
:=
json
.
Unmarshal
([]
byte
(
commontx
),
&
m
)
if
err
!=
nil
{
fmt
.
Println
(
err
.
Error
())
return
}
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
fmt
.
Println
(
reflect
.
DeepEqual
(
m
[
"sender_account"
]
,
m
[
"receiver_account"
]))
}
}
src/github.com/gongxianghui2.0/gongxianghui_test.go
View file @
d7ba709c
...
...
@@ -4,6 +4,8 @@ import (
"encoding/json"
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
"math/big"
"strings"
"testing"
)
...
...
@@ -44,8 +46,8 @@ var (
inputUpdate
=
`{"id":"1","aname":"alibusi","atype":100,"alinkman":10.34,"amob":"2006-01-02 15:04:05","backup":
{"aname":"alibusi","atype":"type"}}`
inputarrary
=
`[{"abail":
0,"sabail":0
,"id":"1","aname":"alibusi","atype":100,"alinkman":10.34,"amob":"2006-01-02 15:04:05","backup":
{"aname":"alibusi","atype":"type"},"common_name":"admin"},{"abail":
0,"sabail":0
,"id":"2","aname":"alibusi","atype":100,"alinkman":
inputarrary
=
`[{"abail":
"0","sabail":"0"
,"id":"1","aname":"alibusi","atype":100,"alinkman":10.34,"amob":"2006-01-02 15:04:05","backup":
{"aname":"alibusi","atype":"type"},"common_name":"admin"},{"abail":
"0","sabail":"0"
,"id":"2","aname":"alibusi","atype":100,"alinkman":
10.34,"amob":"2006-01-02 15:04:05","backup":{"aname":"alibusi","atype":"type"},"common_name":"admin"}]`
inputPutarray
=
`[{"id":"1","aname":"alibusi","atype":100,"alinkman":10.34,"amob":"2006-01-02 15:04:05","backup":{"aname":"alibusi",
"atype":"type"},"common_name":"admin"},{"id":"2","aname":"alibusi","atype":100,"alinkman":10.34,"amob":"2006-01-02 15:04:05","backup":
...
...
@@ -276,3 +278,45 @@ func TestPut(t *testing.T){
}
func
TestDivide
(
t
*
testing
.
T
){
testInt
:=
big
.
NewInt
(
23456789000000
)
i
,
err
:=
dividecalc
(
testInt
,
float64
(
0.0056
))
if
err
!=
nil
{
t
.
Error
(
err
.
Error
())
}
fmt
.
Println
(
i
)
}
//经过测试发现使用big.int 比直接使用float64 会有2500多倍的性能损失
func
BenchmarkDivide
(
b
*
testing
.
B
)
{
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
//testInt := big.NewInt(23456789)
//i := dividecalctest(testInt,float64(0.0056))
//if err!=nil{
// fmt.Println("happen err",err)
// return
//}
}
//for i:= 0 ;i < b.N ; i++ {
// a := float64(23456789)
// _ , err := testfunc(a,float64(0.0056))
// if err!=nil{
// fmt.Println("happen err",err)
// return
// }
// //fmt.Println(c)
//}
}
func
testfunc
(
a
,
b
float64
)(
float64
,
error
){
str
:=
fmt
.
Sprintf
(
"%v"
,
b
)
strs
:=
strings
.
Split
(
str
,
"."
)
if
len
(
strs
[
1
])
>
6
{
return
0
,
fmt
.
Errorf
(
"divide can only exist to six decimal places "
)
}
//var mul int64
//length := len(strs[1])
// pow(10,int64(length))
return
a
*
b
,
nil
}
src/github.com/gongxianghui_framework/dataobject.go
0 → 100644
View file @
d7ba709c
package
main
import
(
"encoding/json"
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
)
func
put
(
tablename
string
,
PutDatas
[]
map
[
string
]
interface
{},
stub
shim
.
ChaincodeStubInterface
)
(
string
,
error
)
{
commonName
,
err
:=
getCertificateCommonName
(
stub
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"getCertificateCommonName happen err: %s "
,
err
)
}
schema
:=
&
Schema
{}
schema
,
err
=
getSchema
(
tablename
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
if
err
:=
schema
.
AllWriteCheck
(
commonName
,
""
);
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"write %s table fail,err: %s "
,
tablename
,
err
)
}
if
len
(
schema
.
LeadgerFields
)
!=
0
{
return
createAccount
(
tablename
,
PutDatas
,
schema
,
stub
)
}
else
{
return
putData
(
tablename
,
PutDatas
,
commonName
,
schema
,
stub
)
}
}
/*
根据账户类型创建账本账户,由于我们这里有存储数据与账本数据两种,所以我们还需要在schema 部分标识不同的数据类型。
伪代码:
1:检查当前用户是否具有账户的总写(创建)权限
2:检查账户必备的属性,如Id,账户名,账户所属者,对应的是证书commonName
2:根据schema 标注的金额(账本)字段,和存证字段,分别进行数据的putState存储工作。其中在存证数据的Id 字段是标示字段。
3:完成账户创建工作
*/
func
createAccount
(
tablename
string
,
PutDatas
[]
map
[
string
]
interface
{},
schema
*
Schema
,
stub
shim
.
ChaincodeStubInterface
)
(
string
,
error
)
{
for
k
,
mapres
:=
range
PutDatas
{
Id
,
ok
:=
mapres
[
"id"
]
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"The id field must exist "
)
}
_
,
ok
=
mapres
[
"common_name"
]
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"The common_name field must exist "
)
}
err
:=
schema
.
FieldsCheck
(
mapres
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"args index %d string, %s schema cheack fail,err : %s "
,
k
,
tablename
,
err
)
}
storagemap
,
leadgermap
:=
separateFields
(
schema
,
mapres
,
[]
string
{
"id"
,
"common_name"
})
key
:=
StoragePrefix
+
"_"
+
tablename
+
"_"
+
Id
.
(
string
)
getResult
,
err
:=
getState
(
key
,
stub
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"GetState %s data fail,please check your parameters "
,
key
)
}
if
getResult
!=
nil
{
return
""
,
fmt
.
Errorf
(
"%s data already exists and cannot be added"
,
key
)
}
if
err
:=
putState
(
key
,
storagemap
,
stub
);
err
!=
nil
{
return
""
,
err
}
if
err
:=
putState
(
LeadgerPrefix
+
"_"
+
tablename
+
"_"
+
Id
.
(
string
),
leadgermap
,
stub
);
err
!=
nil
{
return
""
,
err
}
}
return
fmt
.
Sprintf
(
"create %s account success!"
,
tablename
),
nil
}
/*
修改一个账户的存储数据,修改规则由Schema 控制,有些特殊数据在账本数据也使用,所以无法修改
*/
func
updateStoreData
(
tablename
string
,
updata
map
[
string
]
interface
{},
stub
shim
.
ChaincodeStubInterface
)
(
string
,
error
)
{
commonName
,
err
:=
getCertificateCommonName
(
stub
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"getCertificateCommonName happen err: %s "
,
err
)
}
schema
:=
&
Schema
{}
schema
,
err
=
getSchema
(
tablename
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
Id
,
ok
:=
updata
[
"id"
]
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"The id field must exist "
)
}
_
,
ok
=
updata
[
"common_name"
]
if
ok
{
return
""
,
fmt
.
Errorf
(
"The common_name field cannot update "
)
}
key
:=
StoragePrefix
+
"_"
+
tablename
+
"_"
+
Id
.
(
string
)
allMap
,
err
:=
getState
(
key
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
owner
,
ok
:=
allMap
[
"common_name"
]
.
(
string
)
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"common_name fields resolution failed "
)
}
schema
.
AllWriteCheck
(
commonName
,
owner
)
if
err
!=
nil
{
err
:=
schema
.
DataWriteCheck
(
updata
,
commonName
,
owner
)
if
err
!=
nil
{
return
""
,
err
}
}
if
err
:=
schema
.
FieldsFormatCheck
(
updata
);
err
!=
nil
{
return
""
,
err
}
if
err
:=
Deassign
(
updata
,
allMap
);
err
!=
nil
{
return
""
,
err
}
err
=
putState
(
key
,
allMap
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
return
fmt
.
Sprintf
(
"%s update data success!"
,
tablename
),
nil
}
/*
查询数据,如果存在账本数据,与存证数据,则进行数据拼接,然后返回。
*/
func
get
(
tablename
string
,
parameters
map
[
string
]
interface
{},
stub
shim
.
ChaincodeStubInterface
)
(
string
,
error
)
{
commonName
,
err
:=
getCertificateCommonName
(
stub
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"getCertificateCommonName happen err: %s "
,
err
)
}
Id
,
ok
:=
parameters
[
"id"
]
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"The id field must exist "
)
}
storageKey
:=
StoragePrefix
+
"_"
+
tablename
+
"_"
+
Id
.
(
string
)
mapResult
,
err
:=
getState
(
storageKey
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
leadgerKey
:=
LeadgerPrefix
+
"_"
+
tablename
+
"_"
+
Id
.
(
string
)
leadgerResult
,
err
:=
stub
.
GetState
(
leadgerKey
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"get %s data fail,please check your parameters "
,
leadgerKey
)
}
schema
:=
&
Schema
{}
schema
,
err
=
getSchema
(
tablename
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
if
leadgerResult
!=
nil
{
if
err
:=
json
.
Unmarshal
(
leadgerResult
,
&
mapResult
);
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"The leadger original data Unmarshal fail err:%s "
,
err
)
}
}
onwer
,
ok
:=
mapResult
[
"common_name"
]
.
(
string
)
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"common_name fields resolution failed "
)
}
if
err
:=
schema
.
AllReadCheck
(
commonName
,
onwer
);
err
!=
nil
{
if
filteredData
,
err
:=
schema
.
ReadFiler
(
mapResult
,
commonName
,
onwer
);
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"get data authority filter fail, err: %s"
,
err
)
}
else
{
result
,
_
:=
json
.
Marshal
(
filteredData
)
return
string
(
result
),
nil
}
}
else
{
result
,
_
:=
json
.
Marshal
(
mapResult
)
return
string
(
result
),
nil
}
}
/*
有些特殊的putdata 数据是存在过滤条件的,此方法就是进行过滤
*/
func
putData
(
filterName
string
,
putDatas
[]
map
[
string
]
interface
{},
commonName
string
,
schema
*
Schema
,
stub
shim
.
ChaincodeStubInterface
)
(
string
,
error
)
{
filterFunc
:=
PutDataFilter
[
filterName
]
if
filterFunc
==
nil
{
return
""
,
fmt
.
Errorf
(
"No matching filter operation method was found ! "
)
}
str
,
err
:=
filterFunc
(
putDatas
,
commonName
,
filterName
,
schema
,
stub
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"%s filter operation fail,err:%s "
,
filterName
,
err
)
}
return
str
,
nil
}
/*
在共享惠项目中当用户上传码数据时,存在对发行总数控制的要求。
*/
func
codeFilter
(
putDatas
[]
map
[
string
]
interface
{},
commonName
,
tableName
string
,
schema
*
Schema
,
stub
shim
.
ChaincodeStubInterface
)
(
string
,
error
)
{
sum
:=
len
(
putDatas
)
if
sum
==
0
{
return
""
,
fmt
.
Errorf
(
"put length cannot zero! "
)
}
tid
,
ok
:=
putDatas
[
0
][
"tid"
]
.
(
string
)
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"tid fields type must string! "
)
}
dependData
:=
"coutickets"
Stkey
:=
StoragePrefix
+
"_"
+
dependData
+
"_"
+
tid
tmap
,
err
:=
getState
(
Stkey
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
count
,
ok
:=
tmap
[
"surplusCount"
]
.
(
float64
)
//剩余可发行数
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"surplusCount fields type must float64! "
)
}
count
-=
float64
(
sum
)
if
count
>=
0
{
tmap
[
"surplusCount"
]
=
count
}
else
{
return
""
,
fmt
.
Errorf
(
"The number of issues exceeds the total number of issues! "
)
}
err
=
putState
(
Stkey
,
tmap
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
for
k
,
mapres
:=
range
putDatas
{
Id
,
ok
:=
mapres
[
"id"
]
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"The id field must exist "
)
}
_
,
ok
=
mapres
[
"common_name"
]
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"The common_name field must exist "
)
}
err
=
schema
.
FieldsCheck
(
mapres
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"args index %d string, %s schema cheack fail,err : %s "
,
k
,
tableName
,
err
)
}
key
:=
StoragePrefix
+
"_"
+
tableName
+
"_"
+
Id
.
(
string
)
_
,
err
:=
getState
(
key
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
err
=
putState
(
key
,
mapres
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
}
return
fmt
.
Sprintf
(
"%s data save success!"
,
tableName
),
nil
}
func
commanFilter
(
putDatas
[]
map
[
string
]
interface
{},
commonName
,
tableName
string
,
schema
*
Schema
,
stub
shim
.
ChaincodeStubInterface
)
(
string
,
error
)
{
for
k
,
mapres
:=
range
putDatas
{
Id
,
ok
:=
mapres
[
"id"
]
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"The id field must exist "
)
}
_
,
ok
=
mapres
[
"common_name"
]
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"The common_name field must exist "
)
}
err
:=
schema
.
FieldsFormatCheck
(
mapres
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"args index %d string, %s schema cheack fail,err : %s "
,
k
,
tableName
,
err
)
}
key
:=
StoragePrefix
+
"_"
+
tableName
+
"_"
+
Id
.
(
string
)
err
=
putState
(
key
,
mapres
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
}
return
fmt
.
Sprintf
(
"%s data save success!"
,
tableName
),
nil
}
/*
券可用门店过滤表
*/
func
ticketMerFilter
(
putDatas
[]
map
[
string
]
interface
{},
commonName
,
tableName
string
,
schema
*
Schema
,
stub
shim
.
ChaincodeStubInterface
)
(
string
,
error
)
{
for
k
,
mapres
:=
range
putDatas
{
mid
,
ok
:=
mapres
[
"mid"
]
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"The mid field must exist "
)
}
tid
,
ok
:=
mapres
[
"tid"
]
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"The tid field must exist "
)
}
_
,
ok
=
mapres
[
"common_name"
]
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"The common_name field must exist "
)
}
err
:=
schema
.
FieldsFormatCheck
(
mapres
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"args index %d string, %s schema cheack fail,err : %s "
,
k
,
tableName
,
err
)
}
key
:=
StoragePrefix
+
"_"
+
tableName
+
"_"
+
mid
.
(
string
)
+
"_"
+
tid
.
(
string
)
err
=
putState
(
key
,
mapres
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
}
return
""
,
nil
}
\ No newline at end of file
src/github.com/gongxianghui_framework/gongxianghui.go
0 → 100644
View file @
d7ba709c
package
main
import
(
"bytes"
"crypto/x509"
"encoding/json"
"math/big"
"encoding/pem"
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
pb
"github.com/hyperledger/fabric/protos/peer"
"strconv"
"strings"
)
type
GXHCC
struct
{
}
type
AuthGroup
struct
{
Users
map
[
string
]
int64
`json:"users"`
//用户组权限,默认使用用户组。我们使用形如:“User1”:timestamp. key 表示用户或者角色,value 表示有效时间。我们使用格林威治时间时间戳
Roles
map
[
string
]
int64
`json:"roles"`
//角色组权限,
}
type
Auth
struct
{
Read
AuthGroup
`json:"read"`
// 字段的读权限,“”,不存在权限,
Write
AuthGroup
`json:"write"`
//字段的写权限
}
type
LeadgerAuth
struct
{
// 账本数据除了读权限外
Read
AuthGroup
`json:"read"`
// 字段的读权限,“”,不存在权限,
Issue
AuthGroup
`json:"issue"`
//账本数据的发行权限,
Extract
AuthGroup
`json:"extrate"`
//账本数据的提取权限,
Transfer
AuthGroup
`json:"transfer"`
// 账本数据的转账权限,
}
type
SchemaParameters
struct
{
Value
interface
{}
`json:"val"`
//默认值 这里特别说明一下如果这里是backUp 字段,我们不进行更深一步的校验,包括格式
PAuth
Auth
`json:"auth"`
FCheck
*
Checks
`json:"fcheck"`
}
type
SchemaLeadgerParameters
struct
{
Value
interface
{}
`json:"val"`
//默认值 这里特别说明一下如果这里是backUp 字段,我们不进行更深一步的校验,包括格式
PAuth
LeadgerAuth
`json:"auth"`
FCheck
*
Checks
`json:"fcheck"`
}
type
Checks
struct
{
FType
string
`json:"ftype"`
//字段类型
Must
bool
`json:"must"`
//是否必填
Fieldlen
int
`json:"fieldlen"`
//字段长度(如果字段类型是string,表示字段长度,如果是数值类型用0,1表示数据正负)
}
type
Schema
struct
{
LeadgerFields
map
[
string
]
SchemaLeadgerParameters
`json:"leadger_fields"`
//账本字段
StorageFields
map
[
string
]
SchemaParameters
`json:"storage_fields"`
//存证字段
SchemaAuth
Auth
`json:"schema_auth"`
//schema 的写权限,主要是用在 schema update 部分
SAuth
Auth
`json:"auth"`
//数据总的读权限
}
type
Action
struct
{
AccountType
string
`json:"account_type"`
//账户类型
AccountId
string
`json:"account_id"`
//账户Id
ActionAmount
string
`json:"action_amount"`
//这次的动作金额
FundType
string
`json:"fund_type"`
//资金类型
BackUp
interface
{}
`json:"back_up"`
//备注信息
}
type
TransferAccount
struct
{
AccountType
string
`json:"account_type"`
//账户类型
AccountId
string
`json:"account_id"`
//账户Id
FundType
string
`json:"fund_type"`
//资金类型
}
type
Node
struct
{
Key
string
Value
*
Schema
pre
*
Node
next
*
Node
}
type
LRUCache
struct
{
limit
int
HashMap
map
[
string
]
*
Node
head
*
Node
end
*
Node
}
type
Merchantsale
struct
{
Mid
string
`json:"mid"`
//商户Id
Bid
string
`json:"bid"`
// 分支机构id,也是一笔交易的接受者
Tamount
string
`json:"tamount"`
//交易金额
Treposit
string
`json:"treposit"`
//扣除预付金
Bereposit
string
`json:"bereposit"`
//扣除前预付金
Afreposit
string
`json:"afreposit"`
//扣除后预付金
Feerate
float64
`json:"feerate"`
// 手续费扣率
Free
string
`json:"free"`
// 手续费
Oamount
string
`json:"oamount"`
// 原始交易金额
Adiscounts
float64
`json:"adiscounts"`
//代理结算折扣
Sdiscounts
float64
`json:"sdiscounts"`
//消费折扣
Nodisamount
string
`json:"nodisamount"`
//不打折金额
Disamount
string
`json:"disamount"`
//打折金额
Perquisites
string
`json:"perquisites"`
//额外收益
}
type
OrderTx
struct
{
Oamount
string
`json:"oamount"`
// 原始交易金额
Pamount
string
`json:"pamount"`
// 支付金额
Odesc
*
OrderDescribe
`json:"odesc"`
//订单描述
Mid
string
`json:"mid"`
//商户Id
Norate
float64
`json:"norate"`
//无预付金收益率
Outfree
string
`json:"outfree"`
//付款方手续费
Infree
string
`json:"infree"`
//收款方手续费
Partnersfree
string
`json:"partnersfree"`
//订单合作方手续费
Free
string
`json:"free"`
// 手续费
Pid
string
`json:"pid"`
//合作方Id
}
type
OrderDescribe
struct
{
Codes
[]
string
`json:"codes"`
//码
TicketType
int
`json:"ticket_type"`
//券类型,折扣券只能使用一次
Tid
string
`json:"tid"`
//券Id
}
type
CommonTx
struct
{
SenderAccountType
string
`json:"sender_account"`
SenderId
string
`json:"sender_id"`
SenderFunt
string
`json:"sender_funt"`
ReceiverAccountType
string
`json:"receiver_account"`
ReceiverId
string
`json:"receiver_id"`
ReceiverFunt
string
`json:"receiver_funt"`
Amount
string
`json:"amount"`
}
type
transferTypes
func
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
error
// 声明了一个函数类型
type
putDataFilter
func
(
putDatas
[]
map
[
string
]
interface
{},
name
,
tableName
string
,
schema
*
Schema
,
stub
shim
.
ChaincodeStubInterface
)
(
string
,
error
)
// 声明了一个函数类型,这个函数类型主要是用于putdata 数据过滤使用
var
(
defValue
=
"***"
//查询用户权限不足的情况下默认返回值
StoragePrefix
=
"SGXH"
LeadgerPrefix
=
"LGXH"
IsUsers
=
true
//是否启用用户权限,false 表示启用Roles
GxhSchema
=
"gxhSchema"
//schema 存储前缀,为了实现复合主键使用。
InitSchemaLength
=
12
//缓存的 schema 的长度
schemaCache
=
Constructor
(
InitSchemaLength
)
updateTime
=
int64
(
60
*
60
*
12
)
//schema 更新时间间隔,默认是12小时
lastTime
=
int64
(
0
)
transferType
=
initTransfer
()
PutDataFilter
=
initPutData
()
)
// Init does nothing for this cc
func
(
t
*
GXHCC
)
Init
(
stub
shim
.
ChaincodeStubInterface
)
pb
.
Response
{
return
shim
.
Success
([]
byte
(
"gxhcc init successful! "
))
}
/*
初始化我们要使用的交易执行方法
*/
func
initTransfer
()
map
[
string
]
transferTypes
{
transferType
:=
make
(
map
[
string
]
transferTypes
)
transferType
[
"merchants"
]
=
merchantsale
transferType
[
"tickerorders"
]
=
tickerorders
transferType
[
"commontx"
]
=
normalTransfer
return
transferType
}
func
initPutData
()
map
[
string
]
putDataFilter
{
filter
:=
make
(
map
[
string
]
putDataFilter
)
filter
[
"couticketcodes"
]
=
codeFilter
filter
[
"commonput"
]
=
commanFilter
filter
[
"coutcantm"
]
=
ticketMerFilter
return
filter
}
/*
处理缓存内容的方法,
*/
func
initSchema
(
stub
shim
.
ChaincodeStubInterface
)
error
{
timeStamp
,
err
:=
stub
.
GetTxTimestamp
()
if
err
!=
nil
{
return
err
}
else
if
timeStamp
.
GetSeconds
()
<
lastTime
+
updateTime
{
return
nil
}
var
values
map
[
string
]
*
Schema
values
=
make
(
map
[
string
]
*
Schema
)
schemaIterator
,
err
:=
stub
.
GetStateByPartialCompositeKey
(
GxhSchema
,
nil
)
if
err
!=
nil
{
return
err
}
defer
schemaIterator
.
Close
()
index
:=
1
for
schemaIterator
.
HasNext
()
{
querykv
,
err
:=
schemaIterator
.
Next
()
if
err
!=
nil
{
return
err
}
fmt
.
Println
(
"add cache key:"
,
querykv
.
Key
)
_
,
compisiteKeys
,
err
:=
stub
.
SplitCompositeKey
(
querykv
.
Key
)
if
err
!=
nil
{
return
err
}
scema
:=
&
Schema
{}
err
=
json
.
Unmarshal
(
querykv
.
Value
,
scema
)
if
err
!=
nil
{
fmt
.
Sprintf
(
"json unmarshal %s schema fail,err: %s
\n
"
,
querykv
.
Key
,
err
)
}
if
schemaCache
.
Get
(
compisiteKeys
[
0
])
!=
nil
{
schemaCache
.
Put
(
compisiteKeys
[
0
],
scema
)
fmt
.
Println
(
"add cache key:"
,
querykv
.
Key
)
index
++
if
index
>
InitSchemaLength
{
fmt
.
Println
(
"cache data length :"
,
len
(
schemaCache
.
HashMap
))
return
nil
}
}
else
{
values
[
compisiteKeys
[
0
]]
=
scema
}
}
for
len
(
schemaCache
.
HashMap
)
<
InitSchemaLength
{
for
k
,
v
:=
range
values
{
schemaCache
.
Put
(
k
,
v
)
}
}
fmt
.
Println
(
"cache data length :"
,
len
(
schemaCache
.
HashMap
))
lastTime
=
timeStamp
.
GetSeconds
()
//设置最新修改时间
return
nil
}
// Invoke for this chaincode exposes
func
(
t
*
GXHCC
)
Invoke
(
stub
shim
.
ChaincodeStubInterface
)
pb
.
Response
{
// get arguments and transient
functionName
,
args
:=
stub
.
GetFunctionAndParameters
()
var
err
error
err
=
initSchema
(
stub
)
if
err
!=
nil
{
return
shim
.
Error
(
err
.
Error
())
}
paths
:=
splitPath
(
functionName
)
return
Router
(
paths
,
args
,
stub
)
}
func
Router
(
paths
,
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
pb
.
Response
{
switch
paths
[
0
]
{
case
"schema"
:
return
SchemaProcess
(
paths
,
args
,
stub
)
case
"put"
:
return
putApi
(
args
,
stub
)
case
"update"
:
return
updateApi
(
args
,
stub
)
case
"get"
:
return
getApi
(
args
,
stub
)
case
"createTx"
:
return
transactionProcess
(
paths
,
args
,
stub
)
case
"getCertCommonName"
:
return
getCertNameApi
(
stub
)
default
:
return
shim
.
Error
(
fmt
.
Sprintf
(
"Unsupported function %s"
,
paths
[
0
]))
}
}
func
putApi
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
pb
.
Response
{
if
len
(
args
)
<
2
{
return
shim
.
Error
(
"put data operation expected more than 2 parameters! "
)
}
var
PutDatas
[]
map
[
string
]
interface
{}
err
:=
json
.
Unmarshal
([]
byte
(
args
[
1
]),
&
PutDatas
)
if
err
!=
nil
{
return
shim
.
Error
(
fmt
.
Sprintf
(
"%s table parameters Unmarshal fail,put string not json array, err:%s"
,
args
[
0
],
err
))
}
res
,
err
:=
put
(
args
[
0
],
PutDatas
,
stub
)
if
err
!=
nil
{
return
shim
.
Error
(
fmt
.
Sprintf
(
"put function err: %s"
,
err
))
}
return
shim
.
Success
([]
byte
(
"gxhcc invoke successful:"
+
res
))
}
func
updateApi
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
pb
.
Response
{
if
len
(
args
)
!=
2
{
return
shim
.
Error
(
"update data operation expected 2 parameters! "
)
}
var
datas
map
[
string
]
interface
{}
if
err
:=
json
.
Unmarshal
([]
byte
(
args
[
1
]),
&
datas
);
err
!=
nil
{
return
shim
.
Error
(
fmt
.
Sprintf
(
"%s table parameters Unmarshal fail,put string not json array, err:%s"
,
args
[
0
],
err
))
}
res
,
err
:=
updateStoreData
(
args
[
0
],
datas
,
stub
)
if
err
!=
nil
{
return
shim
.
Error
(
fmt
.
Sprintf
(
"put function err: %s"
,
err
))
}
return
shim
.
Success
([]
byte
(
"gxhcc invoke successful:"
+
res
))
}
func
getApi
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
pb
.
Response
{
if
len
(
args
)
!=
2
{
return
shim
.
Error
(
"get data operation expected 2 parameters to function get!"
)
}
var
datas
map
[
string
]
interface
{}
if
err
:=
json
.
Unmarshal
([]
byte
(
args
[
1
]),
&
datas
);
err
!=
nil
{
return
shim
.
Error
(
fmt
.
Sprintf
(
"%s table parameters Unmarshal fail,put string not json array, err:%s"
,
args
[
0
],
err
))
}
res
,
err
:=
get
(
args
[
0
],
datas
,
stub
)
if
err
!=
nil
{
return
shim
.
Error
(
fmt
.
Sprintf
(
"put function err: %s"
,
err
))
}
return
shim
.
Success
([]
byte
(
res
))
}
func
getCertNameApi
(
stub
shim
.
ChaincodeStubInterface
)
pb
.
Response
{
res
,
err
:=
getCertificateCommonName
(
stub
)
if
err
!=
nil
{
return
shim
.
Error
(
fmt
.
Sprintf
(
"get certificate common_name fail,err: %s"
,
err
))
}
return
shim
.
Success
([]
byte
(
"current user certificate common_name is:"
+
res
))
}
func
SchemaProcess
(
paths
,
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
pb
.
Response
{
switch
paths
[
0
]
{
case
"put"
:
return
schemaPutApi
(
args
,
stub
)
case
"update"
:
return
schemaUpdateApi
(
args
,
stub
)
case
"get"
:
return
schemaGetApi
(
args
,
stub
)
default
:
return
shim
.
Error
(
fmt
.
Sprintf
(
"Unsupported schema function of %s"
,
paths
[
0
]))
}
}
/*
put
args 字段说明:
1:args[0]代表我们具体操作的表,
2:args[1:]后面的数据表示要记录到数据库的数据,每一个string 必须是json字符串,并且需要每一个json 字符串都必须包含id 字段
我们可以发现json字符串都被我们解析成了map[string]interface{}类型的map,其中key代表表模板的字段,interface可以是一个结构,我们当前将他看做我们表模板字段的初始值。
伪代码:
1:在创建schema data 时,我们必须检查金额字段的类型必须是float64,并且不能为负数。
*/
func
schemaPutApi
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
pb
.
Response
{
if
len
(
args
)
!=
2
{
return
shim
.
Error
(
"Schema put operation expected 2 parameters!"
)
}
schema
,
err
:=
NewSchema
(
args
[
1
])
if
err
!=
nil
{
return
shim
.
Error
(
"The parameters Unmarshal to a Schema structural fail,err: "
+
err
.
Error
())
}
result
,
err
:=
schemaPut
(
args
[
0
],
schema
,
stub
)
if
err
!=
nil
{
return
shim
.
Error
(
err
.
Error
())
}
return
shim
.
Success
([]
byte
(
result
))
}
func
schemaUpdateApi
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
pb
.
Response
{
if
len
(
args
)
!=
2
{
return
shim
.
Error
(
"Schema update operation expected 2 parameters!"
)
}
schema
,
err
:=
NewSchema
(
args
[
1
])
if
err
!=
nil
{
return
shim
.
Error
(
"The parameters Unmarshal to a Schema structural fail,err: "
+
err
.
Error
())
}
result
,
err
:=
schemaUpdate
(
args
[
0
],
schema
,
stub
)
if
err
!=
nil
{
return
shim
.
Error
(
err
.
Error
())
}
return
shim
.
Success
([]
byte
(
result
))
}
func
schemaGetApi
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
pb
.
Response
{
if
len
(
args
)
!=
1
{
return
shim
.
Error
(
"Schema get operation expected 1 parameters!"
)
}
result
,
err
:=
schemaGet
(
args
[
0
],
stub
)
if
err
!=
nil
{
return
shim
.
Error
(
err
.
Error
())
}
return
shim
.
Success
([]
byte
(
result
))
}
func
schemaPut
(
schemaName
string
,
schema
*
Schema
,
stub
shim
.
ChaincodeStubInterface
)
(
string
,
error
)
{
_
,
ok
:=
schema
.
StorageFields
[
"id"
]
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"The id field must exist "
)
}
_
,
ok
=
schema
.
StorageFields
[
"common_name"
]
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"The common_name field must exist "
)
}
CompositeKey
,
err
:=
stub
.
CreateCompositeKey
(
GxhSchema
,
[]
string
{
schemaName
})
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"the schema %s create comosite key fail,err : %s"
,
schemaName
,
err
)
}
if
schemaCache
.
Get
(
schemaName
)
!=
nil
{
return
""
,
fmt
.
Errorf
(
"the schema %s already exists and cannot be added"
,
schemaName
)
}
else
if
value
,
_
:=
getBytes
(
CompositeKey
,
stub
);
value
!=
nil
{
return
""
,
fmt
.
Errorf
(
"the schema %s already exists and cannot be added"
,
schemaName
)
}
err
=
putState
(
CompositeKey
,
schema
,
stub
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"Schema PutState fail,err: %s "
,
err
)
}
//schemaCache.Put(args[0], schema)
return
fmt
.
Sprintf
(
"%s schema put success!"
,
schemaName
),
nil
}
/*
if update Schema 那么我们没有办法比较旧有的一个模板,
Schema 的 update,不支持部分修改,因为存在增加和删除某些字段的情况。
初版暂时只允许修改存储数据,金额字段暂时不允许修改
*/
func
schemaUpdate
(
schemaName
string
,
schema
*
Schema
,
stub
shim
.
ChaincodeStubInterface
)
(
string
,
error
)
{
schemaOld
:=
&
Schema
{}
var
err
error
_
,
ok
:=
schema
.
StorageFields
[
"id"
]
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"The id field must exist "
)
}
_
,
ok
=
schema
.
StorageFields
[
"common_name"
]
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"The common_name field must exist "
)
}
CompositeKey
,
err
:=
stub
.
CreateCompositeKey
(
GxhSchema
,
[]
string
{
schemaName
})
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"the schema %s create comosite key fail,err : %s"
,
schemaName
,
err
)
}
schemaOld
,
err
=
getSchema
(
schemaName
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
commonName
,
err
:=
getCertificateCommonName
(
stub
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"getCertificateCommonName happen err: %s "
,
err
)
}
if
err
:=
schema
.
WriteCheck
(
commonName
,
""
);
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"update %s schema fail,err: %s "
,
schemaName
,
err
)
}
schema
.
LeadgerFields
=
schemaOld
.
LeadgerFields
err
=
putState
(
CompositeKey
,
schema
,
stub
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"%s schema data PutState fail,please try again "
,
schemaName
)
}
return
fmt
.
Sprintf
(
"%s schema update success!"
,
schemaName
),
err
}
func
getSchema
(
name
string
,
stub
shim
.
ChaincodeStubInterface
)
(
*
Schema
,
error
)
{
schema
:=
&
Schema
{}
if
schema
=
schemaCache
.
Get
(
name
);
schema
==
nil
{
CompositeKey
,
err
:=
stub
.
CreateCompositeKey
(
GxhSchema
,
[]
string
{
name
})
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"the schema %s create comosite key fail,err : %s"
,
name
,
err
)
}
ok
,
err
:=
getObject
(
CompositeKey
,
schema
,
stub
)
if
!
ok
{
return
nil
,
fmt
.
Errorf
(
"%s schema data doesn't exist,please check your parameters "
,
name
)
}
schemaCache
.
Put
(
name
,
schema
)
}
return
schema
,
nil
}
func
schemaGet
(
args
string
,
stub
shim
.
ChaincodeStubInterface
)
(
string
,
error
)
{
schema
:=
&
Schema
{}
var
result
[]
byte
if
schema
=
schemaCache
.
Get
(
args
);
schema
==
nil
{
CompositeKey
,
err
:=
stub
.
CreateCompositeKey
(
GxhSchema
,
[]
string
{
args
})
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"the schema %s create comosite key fail,err : %s"
,
args
,
err
)
}
bool
,
err
:=
getObject
(
CompositeKey
,
schema
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
if
!
bool
{
return
""
,
fmt
.
Errorf
(
"%s schema data doesn't exist,please check your parameters "
,
args
)
}
schemaCache
.
Put
(
args
,
schema
)
}
commonName
,
err
:=
getCertificateCommonName
(
stub
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"getCertificateCommonName happen err: %s "
,
err
)
}
err
=
schema
.
WriteCheck
(
commonName
,
""
)
if
err
!=
nil
{
return
""
,
err
}
result
,
_
=
json
.
Marshal
(
schema
)
return
string
(
result
),
nil
}
/*
将字段根据账本数据,与存储数据分开
leadgers:参数表示我们需要在账本数据包含的字段,这些字段不属于账本数据。
*/
func
separateFields
(
schema
*
Schema
,
checkmap
map
[
string
]
interface
{},
leadgers
[]
string
)
(
storagemap
,
leadgermap
map
[
string
]
interface
{})
{
storagemap
=
make
(
map
[
string
]
interface
{})
leadgermap
=
make
(
map
[
string
]
interface
{})
for
k
,
_
:=
range
schema
.
LeadgerFields
{
leadgermap
[
k
]
=
checkmap
[
k
]
}
for
_
,
v
:=
range
leadgers
{
leadgermap
[
v
]
=
checkmap
[
v
]
}
for
k
,
_
:=
range
schema
.
StorageFields
{
storagemap
[
k
]
=
checkmap
[
k
]
}
return
}
/*
重新赋值,并检查相应的格式是否正确
*/
func
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
getMap
(
key
string
,
stub
shim
.
ChaincodeStubInterface
)
(
map
[
string
]
interface
{},
error
)
{
var
resultmap
map
[
string
]
interface
{}
result
,
err
:=
stub
.
GetState
(
key
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"GetState %s data fail,err %s "
,
key
,
err
)
}
if
result
==
nil
{
return
nil
,
nil
}
err
=
json
.
Unmarshal
(
result
,
&
resultmap
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"json unmarshal leadger map fail,err: %s"
,
err
)
}
return
resultmap
,
nil
}
func
getState
(
key
string
,
stub
shim
.
ChaincodeStubInterface
)
(
map
[
string
]
interface
{},
error
)
{
var
resultmap
map
[
string
]
interface
{}
result
,
err
:=
stub
.
GetState
(
key
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"GetState %s data fail,err %s "
,
key
,
err
)
}
if
result
==
nil
{
return
nil
,
nil
}
err
=
json
.
Unmarshal
(
result
,
&
resultmap
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"json unmarshal leadger map fail,err: %s"
,
err
)
}
return
resultmap
,
nil
}
func
getObject
(
key
string
,
value
interface
{},
stub
shim
.
ChaincodeStubInterface
)(
bool
,
error
){
result
,
err
:=
stub
.
GetState
(
key
)
if
err
!=
nil
{
return
false
,
fmt
.
Errorf
(
"GetState %s data fail,err %s "
,
key
,
err
)
}
if
result
==
nil
{
return
false
,
nil
}
err
=
json
.
Unmarshal
(
result
,
value
)
if
err
!=
nil
{
return
false
,
fmt
.
Errorf
(
"json unmarshal leadger map fail,err: %s"
,
err
)
}
return
true
,
nil
}
func
getBytes
(
key
string
,
stub
shim
.
ChaincodeStubInterface
)
([]
byte
,
error
)
{
result
,
err
:=
stub
.
GetState
(
key
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"GetState %s data fail,err %s "
,
key
,
err
)
}
return
result
,
nil
}
/*
不要进行[]byte 的marshal,
*/
func
putState
(
key
string
,
value
interface
{},
stub
shim
.
ChaincodeStubInterface
)
error
{
valueByte
,
err
:=
json
.
Marshal
(
value
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
" %s json marshal data fail,err: %s"
,
key
,
err
)
}
err
=
stub
.
PutState
(
key
,
valueByte
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"putState %s data fail,err: %s"
,
key
,
err
)
}
return
nil
}
/*
不要进行[]byte 的marshal,
*/
func
putStateByte
(
key
string
,
value
[]
byte
,
stub
shim
.
ChaincodeStubInterface
)
error
{
err
:=
stub
.
PutState
(
key
,
value
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"putState %s data fail,err: %s"
,
key
,
err
)
}
return
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
Decimal
(
value
float64
)
float64
{
value
,
_
=
strconv
.
ParseFloat
(
fmt
.
Sprintf
(
"%.2f"
,
value
),
64
)
return
value
}
func
Constructor
(
capacity
int
)
LRUCache
{
lruCache
:=
LRUCache
{
limit
:
capacity
}
lruCache
.
HashMap
=
make
(
map
[
string
]
*
Node
,
capacity
)
return
lruCache
}
func
(
l
*
LRUCache
)
Get
(
key
string
)
*
Schema
{
if
v
,
ok
:=
l
.
HashMap
[
key
];
ok
{
l
.
refreshNode
(
v
)
return
v
.
Value
}
else
{
return
nil
}
}
func
(
l
*
LRUCache
)
Put
(
key
string
,
value
*
Schema
)
error
{
if
v
,
ok
:=
l
.
HashMap
[
key
];
!
ok
{
if
len
(
l
.
HashMap
)
>=
l
.
limit
{
oldKey
:=
l
.
removeNode
(
l
.
head
)
delete
(
l
.
HashMap
,
oldKey
)
}
node
:=
Node
{
Key
:
key
,
Value
:
value
}
l
.
addNode
(
&
node
)
l
.
HashMap
[
key
]
=
&
node
}
else
{
v
.
Value
=
value
l
.
refreshNode
(
v
)
}
return
nil
}
func
(
l
*
LRUCache
)
refreshNode
(
node
*
Node
)
{
if
node
==
l
.
end
{
return
}
l
.
removeNode
(
node
)
l
.
addNode
(
node
)
}
func
(
l
*
LRUCache
)
removeNode
(
node
*
Node
)
string
{
if
node
==
l
.
end
{
l
.
end
=
l
.
end
.
pre
l
.
end
.
next
=
nil
}
else
if
node
==
l
.
head
{
l
.
head
=
l
.
head
.
next
l
.
head
.
pre
=
nil
}
else
{
node
.
pre
.
next
=
node
.
next
node
.
next
.
pre
=
node
.
pre
}
return
node
.
Key
}
func
(
l
*
LRUCache
)
addNode
(
node
*
Node
)
{
if
l
.
end
!=
nil
{
l
.
end
.
next
=
node
node
.
pre
=
l
.
end
node
.
next
=
nil
}
l
.
end
=
node
if
l
.
head
==
nil
{
l
.
head
=
node
}
}
func
dividecalc
(
bint
*
big
.
Int
,
divide
float64
)
(
*
big
.
Int
,
error
)
{
divide
*=
1000000
value
:=
new
(
big
.
Int
)
.
Mul
(
bint
,
big
.
NewInt
(
int64
(
divide
)))
value
.
Div
(
value
,
big
.
NewInt
(
1000000
))
return
value
,
nil
}
// "/" -> []
// "/admin" -> ["admin"]
// "/admin/" -> ["admin"]
// "/admin/users" -> ["admin", "users"]
func
splitPath
(
key
string
)
[]
string
{
key
=
strings
.
Trim
(
key
,
"/ "
)
if
key
==
""
{
return
[]
string
{}
}
return
strings
.
Split
(
key
,
"/"
)
}
func
main
()
{
err
:=
shim
.
Start
(
&
GXHCC
{})
if
err
!=
nil
{
fmt
.
Printf
(
"Error starting EncCC chaincode: %s"
,
err
)
}
}
src/github.com/gongxianghui_framework/gongxianghui2.0_test.go
0 → 100644
View file @
d7ba709c
package
main
import
(
"encoding/json"
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
"reflect"
"testing"
)
var
(
SchemaNew
=
`{"leadger_fields":{"abail":{"val":"0001-01-01T00:00:00Z","auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":1584936259}},"issue":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},
"extrate":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"transfer":{"users":null,"roles":null}},
"fcheck":{"ftype":"big.int","must":false,"fieldlen":1}},"sabail":{"val":"0001-01-01T00:00:00Z","auth":{"read":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"issue":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":1584936259}},"extrate":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},
"transfer":{"users":null,"roles":null}},"fcheck":null}},"storage_fields":{"common_name":{"val":"1","auth":{"read":{"users":null,"roles":null},
"write":{"users":null,"roles":null}},"fcheck":null},"alinkman":{"val":10.34,"auth":{"read":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"write":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":1584936259}}},"fcheck":{"ftype":"float64","must":true,"fieldlen":1}},"amob":{"val":"0001-01-01T00:00:00Z",
"auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"write":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}}},"fcheck":{"ftype":"time.Time","must":true,"fieldlen":0}},
"aname":{"val":"Aname","auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"write":
{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}}},"fcheck":{"ftype":"string","must":true,"fieldlen":16}},
"atype":{"val":100,"auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"write":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}}},"fcheck":{"ftype":"int","must":true,"fieldlen":1}},"backup":
{"val":{"aname":"Aname","atype":"Atype"},"auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},
"write":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}}},"fcheck":null},"id":{"val":"1","auth":{"read":
{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":null}},"schema_auth":{"read":{"users":null,"roles":null},
"write":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":0}}},"auth":{"read":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":0}},"write":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":0}}}}`
merSchema
=
`{"leadger_fields":{"regular":{"val":6000,"auth":{"read":{"users":null,"roles":null},"issue":{"users":null,"roles":null},"extrate":{"users":null,"roles":null},"transfer":{"users":null,
"roles":null}},"fcheck":{"ftype":"big.int","must":false,"fieldlen":6}},"rregular":{"val":6000,"auth":{"read":{"users":null,"roles":null},"issue":{"users":null,"roles":null},"extrate":{"users":null,"roles"
:null},"transfer":{"users":null,"roles":null}},"fcheck":{"ftype":"big.int","must":false,"fieldlen":6}}},"storage_fields":{"common_name":{"val":"1","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":null},
"acid":{"val":3,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles"
:null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"actionid":{"val":1,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,
"fieldlen":6}},"adiscounts":{"val":"0.8","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"aid":{"val":0,"auth":{"read":
{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"are":{"val":1,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":
null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"backup":{"val":{},"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":null},"cid":{"val":0,"auth":{"read":
{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"cosperson":{"val":100,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,
"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"did":{"val":2,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,
"fieldlen":6}},"dineraprice":{"val":80,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"dinerprice":{"val":100,"auth":
{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"dinersprice":{"val":90,"auth":{"read":{"users":null,"roles":null},"write":
{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"distype":{"val":16,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":
"float64","must":false,"fieldlen":6}},"esign":{"val":"2010-12-31 15:38:54","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}}
,"fid":{"val":4,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"firrenew":{"val":"2010-01-02 15:38:54","auth":{"read":
{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"haver":{"val":1,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"id":{"val":"1","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":false,"fieldlen":6}},"indate":{"val":"2018/10/29 16:46:57","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"ischain":{"val":1,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"isset":{"val":1,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"issnp":{"val":1,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"keywords":{"val":"test","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"licence":{"val":"103451015521","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"linedate":{"val":"2010-01-02 15:38:54","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"mact":{"val":"123456","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"mactname":{"val":"联系人1","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"maddr":{"val":"测试地址1","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"marea":{"val":1,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"mbtype":{"val":1,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"mdiposit":{"val":"中国银行","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"mlinkman":{"val":"联系人1","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"mlinkmob":{"val":"18555555555","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"mname":{"val":"测试连锁店1","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"mno":{"val":"59118600000005","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"mno2":{"val":"05910005","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"msubtype":{"val":10,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"mtype":{"val":9,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"murl":{"val":"http://www.baidu.com","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"ordertel":{"val":"13444444444","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"paystatue":{"val":1,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"perquisites":{"val":3,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"persales":{"val":100,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"pname":{"val":"8820180008552970","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"ppass":{"val":"152820","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"relevel":{"val":5,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"retype":{"val":0,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"sdiscounts":{"val":"0.85","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"shophours":{"val":"24小时营业","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"sregular":{"val":6000,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"ssign":{"val":"2010-01-01 15:38:54","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"string","must":true,"fieldlen":160}},"statue":{"val":0,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"supperaprice":{"val":90,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"supperprice":{"val":120,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"suppersprice":{"val":110,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"tstatue":{"val":1,"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}},"warmline":{"val":"600","auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":{"ftype":"float64","must":false,"fieldlen":6}}},"schema_auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}},"auth":{"read":{"users":null,"roles":null},"write":{"users":null,"roles":null}}}
`
merarrary
=
`[{
"id": "1",
"mname": "测试连锁店1",
"maddr": "测试地址1",
"mlinkman": "联系人1",
"mlinkmob": "18555555555",
"mtype": 9,
"mact": "123456",
"mdiposit": "中国银行",
"mactname": "联系人1",
"licence": "103451015521",
"murl": "http://www.baidu.com",
"mno": "59118600000005",
"mno2": "05910005",
"indate": "2018/10/29 16:46:57",
"aid": 0,
"regular": "60000000",
"adiscounts": 0.8,
"sdiscounts": 0.85,
"distype": 16,
"msubtype": 10,
"ischain": 1,
"cosperson": 100,
"statue": 0,
"retype": 0,
"did": 2,
"warmline": 600,
"cid": 0,
"sregular": 60000000,
"keywords": "test",
"paystatue": 1,
"are": 1,
"marea": 1,
"actionid": 1,
"tstatue": 1,
"rregular": "60000000",
"ssign": "2010-01-01 15:38:54",
"firrenew": "2010-01-02 15:38:54",
"ordertel": "13444444444",
"shophours": "24小时营业",
"persales": 100,
"linedate": "2010-01-02 15:38:54",
"issnp": 1,
"esign": "2010-12-31 15:38:54",
"fid": 4,
"acid": 3,
"pname": "8820180008552970",
"ppass": "152820",
"isset": 1,
"haver": 1,
"dinerprice": 100,
"dinersprice": 90,
"dineraprice": 80,
"supperprice": 120,
"suppersprice": 110,
"supperaprice": 90,
"common_name":"",
"perquisites": 3,
"relevel": 5,
"mbtype": 1,
"backup": {}
},{
"id": "2",
"mname": "测试连锁店1",
"maddr": "测试地址1",
"mlinkman": "联系人1",
"mlinkmob": "18555555555",
"mtype": 9,
"mact": "123456",
"mdiposit": "中国银行",
"mactname": "联系人1",
"licence": "103451015521",
"murl": "http://www.baidu.com",
"mno": "59118600000005",
"mno2": "05910005",
"indate": "2018/10/29 16:46:57",
"aid": 0,
"regular": "60000000",
"adiscounts": 0.8,
"sdiscounts": 0.85,
"distype": 16,
"msubtype": 10,
"ischain": 1,
"cosperson": 100,
"statue": 0,
"retype": 0,
"did": 2,
"warmline": 600,
"cid": 0,
"sregular": 6000,
"keywords": "test",
"paystatue": 1,
"are": 1,
"marea": 1,
"actionid": 1,
"tstatue": 1,
"rregular": "60000000",
"ssign": "2010-01-01 15:38:54",
"firrenew": "2010-01-02 15:38:54",
"ordertel": "13444444444",
"shophours": "24小时营业",
"persales": 100,
"linedate": "2010-01-02 15:38:54",
"issnp": 1,
"esign": "2010-12-31 15:38:54",
"fid": 4,
"acid": 3,
"pname": "8820180008552970",
"ppass": "152820",
"isset": 1,
"haver": 1,
"dinerprice": 100,
"dinersprice": 90,
"dineraprice": 80,
"supperprice": 120,
"suppersprice": 110,
"supperaprice": 90,
"common_name":"",
"perquisites": 3,
"relevel": 5,
"mbtype": 1,
"backup": {}
}]`
SchemaPutNew
=
`{"leadger_fields":{},"storage_fields":{"common_name":{"val":"1","auth":{"read":{"users":null,"roles":null},
"write":{"users":null,"roles":null}},"fcheck":null},"alinkman":{"val":10.34,"auth":{"read":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"write":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":1584936259}}},"fcheck":{"ftype":"float64","must":true,"fieldlen":1}},"amob":{"val":"0001-01-01T00:00:00Z",
"auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"write":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}}},"fcheck":{"ftype":"time.Time","must":true,"fieldlen":0}},
"aname":{"val":"Aname","auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"write":
{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}}},"fcheck":{"ftype":"string","must":true,"fieldlen":16}},
"atype":{"val":100,"auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"write":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}}},"fcheck":{"ftype":"int","must":true,"fieldlen":1}},"backup":
{"val":{"aname":"Aname","atype":"Atype"},"auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},
"write":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}}},"fcheck":null},"id":{"val":"1","auth":{"read":
{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":null}},"schema_auth":{"read":{"users":null,"roles":null},
"write":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":0}}},"auth":{"read":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":0}},"write":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":0}}}}`
SchemaUpdate
=
`{"leadger_fields":{"abail22":{"val":"0","auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":1584936259}},"issue":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},
"extrate":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"transfer":{"users":null,"roles":null}},
"fcheck":{"ftype":"big.int","must":true,"fieldlen":1}},"sabail":{"val":"0001-01-01T00:00:00Z","auth":{"read":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"issue":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":1584936259}},"extrate":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},
"transfer":{"users":null,"roles":null}},"fcheck":null}},"storage_fields":{"common_name":{"val":"1","auth":{"read":{"users":null,"roles":null},
"write":{"users":null,"roles":null}},"fcheck":null},"alinkmanNew":{"val":10.34,"auth":{"read":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"write":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":1584936259}}},"fcheck":{"ftype":"float64","must":true,"fieldlen":1}},"amob":{"val":"0001-01-01T00:00:00Z",
"auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"write":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}}},"fcheck":{"ftype":"time.Time","must":true,"fieldlen":0}},
"aname":{"val":"Aname","auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"write":
{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}}},"fcheck":{"ftype":"string","must":true,"fieldlen":6}},
"atype":{"val":100,"auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},"write":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}}},"fcheck":{"ftype":"int","must":true,"fieldlen":1}},"backup":
{"val":{"aname":"Aname","atype":"Atype"},"auth":{"read":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}},
"write":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":1584936259}}},"fcheck":null},"id":{"val":"1","auth":{"read":
{"users":null,"roles":null},"write":{"users":null,"roles":null}},"fcheck":null}},"schema_auth":{"read":{"users":null,"roles":null},
"write":{"users":{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":0}}},"auth":{"read":{"users":
{"Admin@org2.example.com":0},"roles":{"Admin@org2.example.com":0}},"write":{"users":{"Admin@org2.example.com":0},"roles":
{"Admin@org2.example.com":0}}}}`
)
func
TestGXHSchemaPut
(
t
*
testing
.
T
){
cc
:=
new
(
GXHCC
)
stub
:=
shim
.
NewMockStub
(
"GXHCC"
,
cc
)
stub
.
MockInit
(
"init"
,
nil
)
fmt
.
Println
(
"========================================invoke schema put============================================"
)
responseByPutschema
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"schema"
),
[]
byte
(
"put"
),[]
byte
(
"alibusi"
),[]
byte
(
SchemaNew
)})
fmt
.
Printf
(
"Invoke status %d,message %s and payload %s
\n
"
,
responseByPutschema
.
Status
,
responseByPutschema
.
Message
,
string
(
responseByPutschema
.
Payload
))
fmt
.
Println
()
fmt
.
Println
(
"========================================invoke schema get============================================"
)
responseByget
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"schema"
),
[]
byte
(
"get"
),[]
byte
(
"alibusi"
)})
fmt
.
Printf
(
"Invoke status %d,message %s ,and payload %s
\n
"
,
responseByget
.
Status
,
responseByget
.
Message
,
string
(
responseByget
.
Payload
))
fmt
.
Println
()
fmt
.
Println
(
"========================================invoke schema update============================================"
)
responseByupdate
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"schema"
),
[]
byte
(
"update"
),[]
byte
(
"alibusi"
),[]
byte
(
SchemaUpdate
)})
fmt
.
Printf
(
"Invoke status %d,message %s ,and payload %s
\n
"
,
responseByupdate
.
Status
,
responseByupdate
.
Message
,
string
(
responseByupdate
.
Payload
))
fmt
.
Println
(
"========================================invoke schema get============================================"
)
responseByget2
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"schema"
),
[]
byte
(
"get"
),[]
byte
(
"alibusi"
)})
fmt
.
Printf
(
"Invoke status %d,message %s ,and payload %s
\n
"
,
responseByget2
.
Status
,
responseByget2
.
Message
,
string
(
responseByget2
.
Payload
))
fmt
.
Println
()
}
func
TestGXHCreateAccount
(
t
*
testing
.
T
){
cc
:=
new
(
GXHCC
)
stub
:=
shim
.
NewMockStub
(
"GXHCC"
,
cc
)
stub
.
MockInit
(
"init"
,
nil
)
fmt
.
Println
()
fmt
.
Println
(
"========================================invoke schema put============================================"
)
fmt
.
Println
()
fmt
.
Println
()
responseByPutschema
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"schema"
),
[]
byte
(
"put"
),[]
byte
(
"alibusi"
),[]
byte
(
SchemaNew
)})
fmt
.
Printf
(
"Invoke status %d,message %s and payload %s
\n
"
,
responseByPutschema
.
Status
,
responseByPutschema
.
Message
,
string
(
responseByPutschema
.
Payload
))
fmt
.
Println
()
fmt
.
Println
(
"========================================invoke createAccount============================================"
)
fmt
.
Println
()
fmt
.
Println
()
responseBycreate
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"createAccount"
),
[]
byte
(
"alibusi"
),[]
byte
(
inputarrary
)})
fmt
.
Printf
(
"Invoke status %d,message %s ,and payload %s
\n
"
,
responseBycreate
.
Status
,
responseBycreate
.
Message
,
string
(
responseBycreate
.
Payload
))
fmt
.
Println
()
fmt
.
Println
()
fmt
.
Println
(
"========================================invoke updateStoreData============================================"
)
fmt
.
Println
()
fmt
.
Println
()
responseByputData
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"upStoreData"
),
[]
byte
(
"alibusi"
),[]
byte
(
inputUpdate
)})
fmt
.
Printf
(
"Invoke status %d,message %s ,and payload %s
\n
"
,
responseByputData
.
Status
,
responseByputData
.
Message
,
string
(
responseByputData
.
Payload
))
fmt
.
Println
()
fmt
.
Println
()
fmt
.
Println
(
"========================================invoke get============================================"
)
fmt
.
Println
()
fmt
.
Println
()
responseByget
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"get"
),
[]
byte
(
"alibusi"
),[]
byte
(
inputUpdate
)})
fmt
.
Printf
(
"Invoke status %d,message %s ,and payload %s
\n
"
,
responseByget
.
Status
,
responseByget
.
Message
,
string
(
responseByget
.
Payload
))
}
func
TestGXHPutData
(
t
*
testing
.
T
){
cc
:=
new
(
GXHCC
)
stub
:=
shim
.
NewMockStub
(
"GXHCC"
,
cc
)
stub
.
MockInit
(
"init"
,
nil
)
fmt
.
Println
()
fmt
.
Println
(
"========================================invoke schema put============================================"
)
fmt
.
Println
()
fmt
.
Println
()
responseByPutschema
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"schema"
),
[]
byte
(
"put"
),[]
byte
(
"alibusi"
),[]
byte
(
SchemaPutNew
)})
fmt
.
Printf
(
"Invoke status %d,message %s and payload %s
\n
"
,
responseByPutschema
.
Status
,
responseByPutschema
.
Message
,
string
(
responseByPutschema
.
Payload
))
fmt
.
Println
()
fmt
.
Println
(
"========================================invoke putData============================================"
)
fmt
.
Println
()
fmt
.
Println
()
responseByputData
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"putData"
),
[]
byte
(
"alibusi"
),[]
byte
(
inputPutarray
)})
fmt
.
Printf
(
"Invoke status %d,message %s ,and payload %s
\n
"
,
responseByputData
.
Status
,
responseByputData
.
Message
,
string
(
responseByputData
.
Payload
))
fmt
.
Println
()
}
var
(
issueTx
=
`{"account_type":"alibusi","account_id":"1","action_amount":"1230","fund_type":"abail","back_up":{"account_type":"","account_id":"","action_amount":0,"fund_type":"","back_up":null}}`
extract
=
`{"account_type":"alibusi","account_id":"1","action_amount":"123","fund_type":"abail","back_up":{"account_type":"","account_id":"","action_amount":0,"fund_type":"","back_up":null}}`
commontx
=
`{"sender_account":"alibusi","sender_id":"1","sender_funt":"abail","receiver_account":"alibusi","receiver_account_id":"2","receiver_funt":"abail","amount":"223"}`
merTx
=
`{"mid":"1","bid":"1","tamount":"18050100","treposit":"16988320","bereposit":"60000000","afreposit":"43011700","feerate":0.0055,"fee":"99275","oamount":"21235400","adiscounts":0.8,"sdiscounts":0.85,"nodisamount":"0","disamount":"0","perquisites":"0"}
`
)
func
TestGXHIssueandExtract
(
t
*
testing
.
T
){
cc
:=
new
(
GXHCC
)
stub
:=
shim
.
NewMockStub
(
"GXHCC"
,
cc
)
stub
.
MockInit
(
"init"
,
nil
)
fmt
.
Println
()
fmt
.
Println
(
"========================================invoke schema put============================================"
)
responseByPutschema
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"schema"
),
[]
byte
(
"put"
),[]
byte
(
"alibusi"
),[]
byte
(
SchemaNew
)})
if
responseByPutschema
.
Status
!=
200
{
t
.
Errorf
(
"schema init fail,err: %s"
,
responseByPutschema
.
Message
)
}
fmt
.
Println
()
responseBycreate
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"createAccount"
),
[]
byte
(
"alibusi"
),[]
byte
(
inputarrary
)})
if
responseBycreate
.
Status
!=
200
{
t
.
Errorf
(
"createAccount init fail,err: %s"
,
responseBycreate
.
Message
)
}
fmt
.
Println
()
responseByIssue
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"createTx"
),
[]
byte
(
"issue"
),[]
byte
(
issueTx
)})
fmt
.
Printf
(
"Invoke status %d,message %s ,and payload %s
\n
"
,
responseByIssue
.
Status
,
responseByIssue
.
Message
,
string
(
responseByIssue
.
Payload
))
fmt
.
Println
()
responseByextract
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"createTx"
),
[]
byte
(
"extract"
),[]
byte
(
extract
)})
fmt
.
Printf
(
"Invoke status %d,message %s ,and payload %s
\n
"
,
responseByextract
.
Status
,
responseByextract
.
Message
,
string
(
responseByextract
.
Payload
))
fmt
.
Println
()
fmt
.
Println
()
responseBytx
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"createTx"
),
[]
byte
(
"transfer"
),[]
byte
(
"commontx"
),[]
byte
(
commontx
)})
fmt
.
Printf
(
"Invoke status %d,message %s ,and payload %s
\n
"
,
responseBytx
.
Status
,
responseBytx
.
Message
,
string
(
responseBytx
.
Payload
))
fmt
.
Println
()
responseByget
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"get"
),
[]
byte
(
"alibusi"
),[]
byte
(
`{"id":"1"}`
)})
fmt
.
Printf
(
"Invoke status %d,message %s ,and payload %s
\n
"
,
responseByget
.
Status
,
responseByget
.
Message
,
string
(
responseByget
.
Payload
))
responseByget2
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"get"
),
[]
byte
(
"alibusi"
),[]
byte
(
`{"id":"2"}`
)})
fmt
.
Printf
(
"Invoke status %d,message %s ,and payload %s
\n
"
,
responseByget2
.
Status
,
responseByget2
.
Message
,
string
(
responseByget2
.
Payload
))
}
/*
测试商户交易
*/
//736288 590270 620798
func
TestGXHmerTx
(
t
*
testing
.
T
){
stub
:=
GXHmerTxinit
()
responseByPutschema
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"createTx"
),
[]
byte
(
"transfer"
),[]
byte
(
"merchants"
),[]
byte
(
merTx
)})
if
responseByPutschema
.
Status
!=
200
{
fmt
.
Printf
(
"schema init fail,err: %s"
,
responseByPutschema
.
Message
)
}
responseByget2
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"get"
),
[]
byte
(
"merchants"
),[]
byte
(
`{"id":"1"}`
)})
fmt
.
Printf
(
"Invoke status %d,message %s ,and payload %s
\n
"
,
responseByget2
.
Status
,
responseByget2
.
Message
,
string
(
responseByget2
.
Payload
))
responseByget
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"get"
),
[]
byte
(
"alibusi"
),[]
byte
(
`{"id":"1"}`
)})
fmt
.
Printf
(
"Invoke status %d,message %s ,and payload %s
\n
"
,
responseByget
.
Status
,
responseByget
.
Message
,
string
(
responseByget
.
Payload
))
}
func
GXHmerTxinit
()
*
shim
.
MockStub
{
cc
:=
new
(
GXHCC
)
stub
:=
shim
.
NewMockStub
(
"GXHCC"
,
cc
)
stub
.
MockInit
(
"init"
,
nil
)
fmt
.
Println
()
fmt
.
Println
(
"========================================invoke schema put============================================"
)
responseByPutschema
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"schema"
),
[]
byte
(
"put"
),[]
byte
(
"alibusi"
),[]
byte
(
SchemaNew
)})
if
responseByPutschema
.
Status
!=
200
{
fmt
.
Printf
(
"schema put alibusi fail,err: %s"
,
responseByPutschema
.
Message
)
return
stub
}
responseBycreate
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"createAccount"
),
[]
byte
(
"alibusi"
),[]
byte
(
inputarrary
)})
if
responseBycreate
.
Status
!=
200
{
fmt
.
Printf
(
"createAccount alibusi fail,err: %s"
,
responseBycreate
.
Message
)
return
stub
}
fmt
.
Println
()
fmt
.
Println
()
fmt
.
Println
(
"========================================invoke schema put============================================"
)
responseByMerschema
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"schema"
),
[]
byte
(
"put"
),[]
byte
(
"merchants"
),[]
byte
(
merSchema
)})
if
responseByMerschema
.
Status
!=
200
{
fmt
.
Printf
(
"schema put merchants fail,err: %s"
,
responseByMerschema
.
Message
)
return
stub
}
responseBycreateMer
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"createAccount"
),
[]
byte
(
"merchants"
),[]
byte
(
merarrary
)})
if
responseBycreateMer
.
Status
!=
200
{
fmt
.
Printf
(
"createAccount merchants fail,err: %s"
,
responseBycreateMer
.
Message
)
return
stub
}
return
stub
}
func
TestDeassign
(
t
*
testing
.
T
)
{
var
m
map
[
string
]
interface
{}
err
:=
json
.
Unmarshal
([]
byte
(
commontx
),
&
m
)
if
err
!=
nil
{
t
.
Errorf
(
err
.
Error
())
}
onwer
,
_
:=
m
[
"sender_account"
]
.
(
float64
)
//fmt.Println(ok)
fmt
.
Println
(
onwer
==
0
)
}
//5958 5242 5600 5909
func
BenchmarkBackUpCheck
(
b
*
testing
.
B
)
{
var
m
map
[
string
]
interface
{}
err
:=
json
.
Unmarshal
([]
byte
(
commontx
),
&
m
)
if
err
!=
nil
{
fmt
.
Println
(
err
.
Error
())
return
}
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
fmt
.
Println
(
reflect
.
DeepEqual
(
m
[
"sender_account"
]
,
m
[
"receiver_account"
]))
}
}
src/github.com/gongxianghui_framework/gongxianghui_test.go
0 → 100644
View file @
d7ba709c
package
main
import
(
"encoding/json"
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
"math/big"
"strings"
"testing"
)
var
schema
=
`{"fields":{"alinkman":{"val":"Alinkman","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}},"amob":{"val":"Amob","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}},"aname":{"val":"Aname","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}},"atype":{"val":"Atype","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}},"backup":{"val":{"aname":"Aname","atype":"Atype"},"auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":
{"admin":0},"roles":{"admin":1582972202}}}},"id":{"val":"1","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}}},"schema_auth":{"read":{"users":null,"roles":null},"write":{"users":{"admin":0},"roles":{"admin":0}}},"auth":{"read":{"users":
{"admin":0},"roles":{"admin":0}},"write":{"users":{"admin":0},"roles":{"admin":1582972202}}}}
`
var
schema2
=
`{"fields":{"alinkman":{"val":"Alinkman","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}},"amob":{"val":"Amob","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}},"aname":{"val":"Aname","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}},"atype":{"val":"Atype","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}},"backup":{"val":{"aname":"Aname","atype":"Atype"},"auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":
{"admin":0},"roles":{"admin":1582972202}}}},"id":{"val":"1","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}}},"schema_auth":{"read":{"users":null,"roles":null},"write":{"users":{"admin":0},"roles":{"admin":1582972202}}},"auth":{"read":{"users":
{"admin":0},"roles":{"admin":0}},"write":{"users":{"admin":0},"roles":{"admin":0}}}}
`
var
schema3
=
`{"fields":{"alinkman":{"val":"Alinkman","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}},"amob":{"val":"Amob","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}},"aname":{"val":"Aname","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}},"atype":{"val":"Atype","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}},"backup":{"val":{"aname":"Aname","atype":"Atype"},"auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":
{"admin":0},"roles":{"admin":1582972202}}}},"id":{"val":"1","auth":{"read":{"users":{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":
{"admin":1582972202}}}}},"schema_auth":{"read":{"users":null,"roles":null},"write":{"users":{"admin":0},"roles":{"admin":1582972202}}},"auth":{"read":{"users":
{"admin":0},"roles":{"admin":1582972202}},"write":{"users":{"admin":0},"roles":{"admin":0}}}}
`
/*
以下部分是增加权限内容的测试
*/
var
(
inputUpdate
=
`{"id":"1","aname":"alibusi","atype":100,"alinkman":10.34,"amob":"2006-01-02 15:04:05","backup":
{"aname":"alibusi","atype":"type"}}`
inputarrary
=
`[{"abail":"0","sabail":"0","id":"1","aname":"alibusi","atype":100,"alinkman":10.34,"amob":"2006-01-02 15:04:05","backup":
{"aname":"alibusi","atype":"type"},"common_name":"admin"},{"abail":"0","sabail":"0","id":"2","aname":"alibusi","atype":100,"alinkman":
10.34,"amob":"2006-01-02 15:04:05","backup":{"aname":"alibusi","atype":"type"},"common_name":"admin"}]`
inputPutarray
=
`[{"id":"1","aname":"alibusi","atype":100,"alinkman":10.34,"amob":"2006-01-02 15:04:05","backup":{"aname":"alibusi",
"atype":"type"},"common_name":"admin"},{"id":"2","aname":"alibusi","atype":100,"alinkman":10.34,"amob":"2006-01-02 15:04:05","backup":
{"aname":"alibusi","atype":"type"},"common_name":"admin"}]`
)
func
TestGXHSchemaAuth
(
t
*
testing
.
T
){
cc
:=
new
(
GXHCC
)
stub
:=
shim
.
NewMockStub
(
"GXHCC"
,
cc
)
stub
.
MockInit
(
"init"
,
nil
)
fmt
.
Println
()
fmt
.
Println
(
"========================================invoke schema put============================================"
)
fmt
.
Println
()
fmt
.
Println
()
responseByPutschema
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"schema"
),
[]
byte
(
"put"
),[]
byte
(
"alibusi"
),[]
byte
(
schema
)})
fmt
.
Printf
(
"Invoke status %d,message %s and payload %s
\n
"
,
responseByPutschema
.
Status
,
responseByPutschema
.
Message
,
string
(
responseByPutschema
.
Payload
))
fmt
.
Println
()
fmt
.
Println
(
"========================================invoke schema get============================================"
)
fmt
.
Println
()
fmt
.
Println
()
responseByget
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"schema"
),
[]
byte
(
"get"
),[]
byte
(
"alibusi"
)})
fmt
.
Printf
(
"Invoke status %d,message %s ,and payload %s
\n
"
,
responseByget
.
Status
,
responseByget
.
Message
,
string
(
responseByget
.
Payload
))
fmt
.
Println
()
fmt
.
Println
(
"========================================invoke schema update============================================"
)
fmt
.
Println
()
fmt
.
Println
()
responseByupdate
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"schema"
),
[]
byte
(
"update"
),[]
byte
(
"alibusi"
),[]
byte
(
schema
)})
fmt
.
Printf
(
"Invoke status %d,message %s ,and payload %s
\n
"
,
responseByupdate
.
Status
,
responseByupdate
.
Message
,
string
(
responseByupdate
.
Payload
))
}
/*
测试使用table 数据构建 schema
*/
func
TestGXHSchemaAuthBytable
(
t
*
testing
.
T
){
cc
:=
new
(
GXHCC
)
stub
:=
shim
.
NewMockStub
(
"GXHCC"
,
cc
)
stub
.
MockInit
(
"init"
,
nil
)
fmt
.
Println
()
fmt
.
Println
(
"========================================invoke schema put============================================"
)
fmt
.
Println
()
fmt
.
Println
()
responseByPutschema
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"schema"
),
[]
byte
(
"put"
),[]
byte
(
"alibusi"
),[]
byte
(
inputUpdate
)})
fmt
.
Printf
(
"Invoke status %d,message %s and payload %s
\n
"
,
responseByPutschema
.
Status
,
responseByPutschema
.
Message
,
string
(
responseByPutschema
.
Payload
))
fmt
.
Println
()
fmt
.
Println
(
"========================================invoke schema get============================================"
)
fmt
.
Println
()
fmt
.
Println
()
responseByget
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"schema"
),
[]
byte
(
"get"
),[]
byte
(
"alibusi"
)})
fmt
.
Printf
(
"Invoke status %d,message %s ,and payload %s
\n
"
,
responseByget
.
Status
,
responseByget
.
Message
,
string
(
responseByget
.
Payload
))
fmt
.
Println
()
fmt
.
Println
(
"========================================invoke schema update============================================"
)
fmt
.
Println
()
fmt
.
Println
()
responseByupdate
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"schema"
),
[]
byte
(
"update"
),[]
byte
(
"alibusi"
),[]
byte
(
inputUpdate
)})
fmt
.
Printf
(
"Invoke status %d,message %s ,and payload %s
\n
"
,
responseByupdate
.
Status
,
responseByupdate
.
Message
,
string
(
responseByupdate
.
Payload
))
}
func
TestGXHDataPutAuth
(
t
*
testing
.
T
){
cc
:=
new
(
GXHCC
)
stub
:=
shim
.
NewMockStub
(
"GXHCC"
,
cc
)
stub
.
MockInit
(
"init"
,
nil
)
fmt
.
Println
()
fmt
.
Println
(
"========================================invoke schema put============================================"
)
fmt
.
Println
()
fmt
.
Println
()
responseByPutschema
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"schema"
),
[]
byte
(
"put"
),[]
byte
(
"alibusi"
),[]
byte
(
schema3
)})
//使用schema 数据测试过期时间err,schema right data,使用schema3 测试读取字段时的过滤
fmt
.
Printf
(
"Invoke status %d,message %s and payload %s
\n
"
,
responseByPutschema
.
Status
,
responseByPutschema
.
Message
,
string
(
responseByPutschema
.
Payload
))
responseByget
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"schema"
),
[]
byte
(
"get"
),[]
byte
(
"alibusi"
)})
fmt
.
Printf
(
"Invoke status %d,message %s ,and payload %s
\n
"
,
responseByget
.
Status
,
responseByget
.
Message
,
string
(
responseByget
.
Payload
))
fmt
.
Println
()
fmt
.
Println
(
"========================================invoke data put============================================"
)
fmt
.
Println
()
fmt
.
Println
()
responseByPut
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"put"
),
[]
byte
(
"alibusi"
),[]
byte
(
inputarrary
)})
fmt
.
Printf
(
"Invoke status %d,message %s ,and payload %s
\n
"
,
responseByPut
.
Status
,
responseByPut
.
Message
,
string
(
responseByPut
.
Payload
))
responseByget
=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"get"
),
[]
byte
(
"alibusi"
),[]
byte
(
`{"id":"1"}`
)})
fmt
.
Printf
(
"Invoke status %d,message %s ,and payload %s
\n
"
,
responseByget
.
Status
,
responseByget
.
Message
,
string
(
responseByget
.
Payload
))
fmt
.
Println
()
fmt
.
Println
(
"========================================invoke data update============================================"
)
fmt
.
Println
()
fmt
.
Println
()
responseByUpdate
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"update"
),
[]
byte
(
"alibusi"
),[]
byte
(
inputUpdate
)})
fmt
.
Printf
(
"Invoke status %d,message %s ,and payload %s
\n
"
,
responseByUpdate
.
Status
,
responseByUpdate
.
Message
,
string
(
responseByUpdate
.
Payload
))
responseByget2
:=
stub
.
MockInvoke
(
"invoke1"
,[][]
byte
{[]
byte
(
"get"
),
[]
byte
(
"alibusi"
),[]
byte
(
`{"id":"1"}`
)})
fmt
.
Printf
(
"Invoke status %d,message %s ,and payload %s
\n
"
,
responseByget2
.
Status
,
responseByget2
.
Message
,
string
(
responseByget2
.
Payload
))
}
var
testData
=
`{"float64":10.33,"int":10,"string":"我中国人a!","time.Time":"2020-03-06 18:30:07.49752435 +0800 CST m=+0.000270574","struct":{}}`
func
TestFieldCheck
(
t
*
testing
.
T
){
var
testmap
map
[
string
]
interface
{}
json
.
Unmarshal
([]
byte
(
testData
),
&
testmap
)
err
:=
fieldCheckout
(
nil
,
testmap
[
"struct"
])
if
err
!=
nil
{
t
.
Error
(
err
)
}
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
))
}
func
TestDivide
(
t
*
testing
.
T
){
testInt
:=
big
.
NewInt
(
23456789000000
)
i
,
err
:=
dividecalc
(
testInt
,
float64
(
0.0056
))
if
err
!=
nil
{
t
.
Error
(
err
.
Error
())
}
fmt
.
Println
(
i
)
}
//经过测试发现使用big.int 比直接使用float64 会有2500多倍的性能损失
func
BenchmarkDivide
(
b
*
testing
.
B
)
{
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
//testInt := big.NewInt(23456789)
//i := dividecalctest(testInt,float64(0.0056))
//if err!=nil{
// fmt.Println("happen err",err)
// return
//}
}
//for i:= 0 ;i < b.N ; i++ {
// a := float64(23456789)
// _ , err := testfunc(a,float64(0.0056))
// if err!=nil{
// fmt.Println("happen err",err)
// return
// }
// //fmt.Println(c)
//}
}
func
testfunc
(
a
,
b
float64
)(
float64
,
error
){
str
:=
fmt
.
Sprintf
(
"%v"
,
b
)
strs
:=
strings
.
Split
(
str
,
"."
)
if
len
(
strs
[
1
])
>
6
{
return
0
,
fmt
.
Errorf
(
"divide can only exist to six decimal places "
)
}
//var mul int64
//length := len(strs[1])
// pow(10,int64(length))
return
a
*
b
,
nil
}
src/github.com/gongxianghui_framework/gongxinghuileadger_test.go
0 → 100644
View file @
d7ba709c
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
))
}
src/github.com/gongxianghui_framework/leadger.go
0 → 100644
View file @
d7ba709c
package
main
import
(
"encoding/json"
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
pb
"github.com/hyperledger/fabric/protos/peer"
"math/big"
"reflect"
)
func
transactionProcess
(
paths
,
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
pb
.
Response
{
switch
paths
[
0
]
{
case
"issue"
:
//进行账户金额发行(无中生有)
return
issueApi
(
args
,
stub
)
case
"extract"
:
//提取账户金额(直接减去)
return
extractApi
(
args
,
stub
)
case
"transfer"
:
// 一笔普通转账
return
transferApi
(
args
,
stub
)
default
:
return
shim
.
Error
(
fmt
.
Sprintf
(
"Unsupported schema function of %s"
,
paths
[
0
]))
}
}
func
issueApi
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
pb
.
Response
{
if
len
(
args
)
!=
1
{
return
shim
.
Error
(
"issue operation expected 1 parameters ! "
)
}
action
:=
&
Action
{}
err
:=
json
.
Unmarshal
([]
byte
(
args
[
0
]),
action
)
if
err
!=
nil
{
return
shim
.
Error
(
fmt
.
Sprintf
(
"json unmarshal Action structure fail,err: %s"
,
err
))
}
res
,
err
:=
funtOperation
(
action
,
stub
,
true
)
if
err
!=
nil
{
return
shim
.
Error
(
fmt
.
Sprintf
(
"issue operation err: %s"
,
err
))
}
return
shim
.
Success
([]
byte
(
"extract "
+
res
))
}
func
extractApi
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
pb
.
Response
{
if
len
(
args
)
!=
1
{
return
shim
.
Error
(
"extract operation expected 1 parameters ! "
)
}
action
:=
&
Action
{}
err
:=
json
.
Unmarshal
([]
byte
(
args
[
0
]),
action
)
if
err
!=
nil
{
return
shim
.
Error
(
fmt
.
Sprintf
(
"json unmarshal Action structure fail,err: %s"
,
err
))
}
res
,
err
:=
funtOperation
(
action
,
stub
,
false
)
if
err
!=
nil
{
return
shim
.
Error
(
fmt
.
Sprintf
(
"extract operation err: %s"
,
err
))
}
return
shim
.
Success
([]
byte
(
"extract "
+
res
))
}
func
transferApi
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
pb
.
Response
{
txFunc
:=
transferType
[
args
[
0
]]
if
txFunc
==
nil
{
return
shim
.
Error
(
fmt
.
Sprintf
(
"No matching transfer operation method was found ! "
))
}
err
:=
txFunc
(
args
[
1
:
],
stub
)
if
err
!=
nil
{
return
shim
.
Error
(
fmt
.
Sprintf
(
"%s transfer operation fail,err:%s "
,
args
[
0
],
err
))
}
return
pb
.
Response
{}
}
/*
账户金额发现,核心是在对应的schema 找到有发行的权利。
1:金额字段也就是(账本字段数据)都有发行标示
2:发行交易可以存在多个字段,但只要保证我们要求的字段存在就可以。账户类型,Id,发行金额(大于0)
*/
func
funtOperation
(
action
*
Action
,
stub
shim
.
ChaincodeStubInterface
,
isIssue
bool
)
(
string
,
error
)
{
commonName
,
err
:=
getCertificateCommonName
(
stub
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"getCertificateCommonName happen err: %s "
,
err
)
}
schema
:=
&
Schema
{}
schema
,
err
=
getSchema
(
action
.
AccountType
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
leadgerKey
:=
LeadgerPrefix
+
"_"
+
action
.
AccountType
+
"_"
+
action
.
AccountId
leadgermap
,
err
:=
getState
(
leadgerKey
,
stub
)
if
err
!=
nil
{
return
""
,
err
}
onwer
,
ok
:=
leadgermap
[
"common_name"
]
.
(
string
)
if
isIssue
{
err
:=
schema
.
AuthorityCheck
(
schema
.
LeadgerFields
[
action
.
FundType
]
.
PAuth
.
Issue
,
commonName
,
onwer
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"%s field issue permission check does not match, err: %s "
,
action
.
FundType
,
err
)
}
}
else
{
err
:=
schema
.
AuthorityCheck
(
schema
.
LeadgerFields
[
action
.
FundType
]
.
PAuth
.
Extract
,
commonName
,
onwer
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"%s field extract permission check does not match, err: %s "
,
action
.
FundType
,
err
)
}
}
funt
,
ok
:=
leadgermap
[
action
.
FundType
]
.
(
string
)
funtAmount
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
funt
,
10
)
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"%s parameter resolution to big.int failed "
,
action
.
FundType
)
}
actionAmount
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
action
.
ActionAmount
,
10
)
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"action_amount parameter resolution to big.int failed "
)
}
sum
:=
new
(
big
.
Int
)
if
isIssue
{
sum
=
sum
.
Add
(
funtAmount
,
actionAmount
)
}
else
{
if
funtAmount
.
Cmp
(
actionAmount
)
==
-
1
{
return
""
,
fmt
.
Errorf
(
"The current amount is less than the withdrawal amount and cannot be extracted "
)
}
sum
=
sum
.
Sub
(
funtAmount
,
actionAmount
)
}
leadgermap
[
action
.
FundType
]
=
sum
.
String
()
leadgerResult
,
_
:=
json
.
Marshal
(
leadgermap
)
err
=
stub
.
PutState
(
leadgerKey
,
leadgerResult
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"putState %s data fail,err: %s"
,
leadgerKey
,
err
)
}
return
"transaction successful!"
,
nil
}
/*
*/
func
normalTransfer
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
error
{
if
len
(
args
)
!=
1
{
return
nil
}
tx
:=
&
CommonTx
{}
err
:=
json
.
Unmarshal
([]
byte
(
args
[
0
]),
tx
)
if
err
!=
nil
{
fmt
.
Errorf
(
"CommonTx structure json unmarshal fail,err : %s "
,
err
)
}
sender
:=
&
TransferAccount
{
tx
.
SenderAccountType
,
tx
.
SenderId
,
tx
.
SenderFunt
,
}
receiver
:=
&
TransferAccount
{
tx
.
ReceiverAccountType
,
tx
.
ReceiverId
,
tx
.
ReceiverFunt
,
}
commonName
,
err
:=
getCertificateCommonName
(
stub
)
if
err
!=
nil
{
return
nil
}
amount
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
tx
.
Amount
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"amount parameter resolution to big.int failed "
)
}
return
transfer
(
amount
,
sender
,
receiver
,
commonName
,
stub
)
}
/*
当增加一条交易记录的时候,我们需要根据交易记录实现,
1.预付金的计算,2.计算分成,3.预付金的变化。分成的计算
*/
func
merchantsale
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
error
{
commanName
,
err
:=
getCertificateCommonName
(
stub
)
if
err
!=
nil
{
return
err
}
senderaccountType
:=
"merchants"
receiverAccountType
:=
"alibusi"
mer
:=
&
Merchantsale
{}
err
=
json
.
Unmarshal
([]
byte
(
args
[
0
]),
mer
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"Merchantsale struct json unmarshal fail,err : %s "
,
err
)
}
sender
:=
&
TransferAccount
{
senderaccountType
,
mer
.
Mid
,
"regular"
,
}
receiver
:=
&
TransferAccount
{
receiverAccountType
,
mer
.
Bid
,
"abail"
,
}
rtreposit
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
mer
.
Treposit
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"Treposit parameter resolution to big.int failed "
)
}
//errinfo := make(chan error)
err
=
transfer
(
rtreposit
,
sender
,
receiver
,
commanName
,
stub
)
if
err
!=
nil
{
return
err
}
//1.计算预付金 这部分待定
treposit
:=
new
(
big
.
Int
)
nodisamount
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
mer
.
Nodisamount
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"Nodisamount parameter resolution to big.int failed "
)
}
disamount
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
mer
.
Disamount
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"Disamount parameter resolution to big.int failed "
)
}
oamount
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
mer
.
Oamount
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"Oamount parameter resolution to big.int failed "
)
}
if
nodisamount
.
Cmp
(
big
.
NewInt
(
0
))
==
0
||
disamount
.
Cmp
(
big
.
NewInt
(
0
))
==
0
{
//如果打折金额与不打折金额任一为0,则认为全部打折
treposit
,
err
=
dividecalc
(
oamount
,
mer
.
Adiscounts
)
if
err
!=
nil
{
return
err
}
}
else
{
distre
,
err
:=
dividecalc
(
disamount
,
mer
.
Adiscounts
)
//计算打折部分的金额
if
err
!=
nil
{
return
err
}
treposit
=
new
(
big
.
Int
)
.
Add
(
nodisamount
,
distre
)
}
if
treposit
.
Cmp
(
rtreposit
)
!=
0
{
return
fmt
.
Errorf
(
"treposit calculation fail "
)
}
rfee
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
mer
.
Free
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"Fee parameter resolution to big.int failed "
)
}
tamount
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
mer
.
Tamount
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"Tamount parameter resolution to big.int failed "
)
}
fee
,
err
:=
dividecalc
(
tamount
,
mer
.
Feerate
)
if
err
!=
nil
{
return
err
}
if
fee
.
Cmp
(
rfee
)
!=
0
{
return
fmt
.
Errorf
(
"fee calculation fail "
)
}
profit
:=
new
(
big
.
Int
)
.
Sub
(
tamount
,
new
(
big
.
Int
)
.
Add
(
rfee
,
rtreposit
))
//计算分成
if
profit
.
Cmp
(
big
.
NewInt
(
0
))
==
-
1
{
return
fmt
.
Errorf
(
"profit is negative "
)
}
//进行分成数据
err
=
dividesTransaction
(
mer
.
Mid
,
treposit
,
stub
)
if
err
!=
nil
{
return
err
}
return
err
}
/*
共享惠订单交易
*/
func
tickerorders
(
args
[]
string
,
stub
shim
.
ChaincodeStubInterface
)
error
{
/*
由于共享惠还没有进行确定的订单交易所以这部分先进行伪代码的记录
1:计算实际支付是否正确,
2:计算手续费总和是否正确
3:计算利润
4:是否需要进行商户金额的清分(待定)//待办
5:合作方分成
6:最终分成
*/
//commanName, err := getCertificateCommonName(stub)
//if err != nil {
// return err
//}
ticketcanName
:=
"coutcantm"
ticketName
:=
"coutickets"
codeName
:=
"couticketcodes"
oTx
:=
&
OrderTx
{}
err
:=
json
.
Unmarshal
([]
byte
(
args
[
0
]),
oTx
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"OrderTx struct json unmarshal fail,err : %s "
,
err
)
}
tickMerKey
:=
StoragePrefix
+
"_"
+
ticketcanName
+
"_"
+
oTx
.
Mid
+
"_"
+
oTx
.
Odesc
.
Tid
//券可用门店key
tickM
,
err
:=
getState
(
tickMerKey
,
stub
)
if
err
!=
nil
{
return
err
}
tickKey
:=
StoragePrefix
+
"_"
+
ticketName
+
"_"
+
oTx
.
Odesc
.
Tid
//券key
tick
,
err
:=
getState
(
tickKey
,
stub
)
if
err
!=
nil
{
return
err
}
resid
,
_
:=
tickM
[
"resid"
]
.
(
float64
)
//剩余可用码数
discount
,
_
:=
tick
[
"discount"
]
.
(
float64
)
//得到券面值
fieldkeys
:=
[]
string
{
"status"
}
// 码状态
var
checkvalue
,
upvalue
[]
interface
{}
if
resid
==
0
{
return
fmt
.
Errorf
(
"The current merchant has been unable to use the %s ticket "
,
oTx
.
Odesc
.
Tid
)
}
oamount
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
oTx
.
Oamount
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"Oamount parameter resolution to big.int failed "
)
}
pamount
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
oTx
.
Pamount
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"Pamount parameter resolution to big.int failed "
)
}
outfree
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
oTx
.
Outfree
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"Outfree parameter resolution to big.int failed "
)
}
infree
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
oTx
.
Infree
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"Infree parameter resolution to big.int failed "
)
}
partnersfree
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
oTx
.
Partnersfree
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"Partnersfree parameter resolution to big.int failed "
)
}
free
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
oTx
.
Free
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"Free parameter resolution to big.int failed "
)
}
if
oTx
.
Odesc
.
TicketType
==
1
{
//如果是折扣券则只能使用一张券
if
len
(
oTx
.
Odesc
.
Codes
)
>
1
{
return
fmt
.
Errorf
(
"Only one coupon can be used "
)
}
codeKey
:=
StoragePrefix
+
"_"
+
codeName
+
"_"
+
oTx
.
Odesc
.
Codes
[
0
]
checkvalue
[
0
]
=
float64
(
1
)
upvalue
[
0
]
=
float64
(
2
)
_
,
err
=
checkandUpdate
(
codeKey
,
fieldkeys
,
checkvalue
,
upvalue
,
stub
)
if
err
!=
nil
{
return
err
}
camount
,
_
:=
dividecalc
(
oamount
,
discount
)
if
camount
.
Cmp
(
pamount
)
!=
0
{
return
fmt
.
Errorf
(
"pamount calculation fail "
)
}
}
else
{
for
i
,
v
:=
range
oTx
.
Odesc
.
Codes
{
codeKey
:=
StoragePrefix
+
"_"
+
codeName
+
"_"
+
v
checkvalue
[
i
]
=
float64
(
1
)
upvalue
[
i
]
=
float64
(
2
)
_
,
err
=
checkandUpdate
(
codeKey
,
fieldkeys
,
checkvalue
,
upvalue
,
stub
)
if
err
!=
nil
{
return
err
}
}
length
:=
int64
(
len
(
oTx
.
Odesc
.
Codes
))
disint
:=
int64
(
discount
)
//将discount 转化为整数
camount
:=
new
(
big
.
Int
)
.
Sub
(
oamount
,
big
.
NewInt
(
disint
*
length
))
if
camount
.
Cmp
(
pamount
)
!=
0
{
return
fmt
.
Errorf
(
"pamount calculation fail "
)
}
}
cfree
:=
new
(
big
.
Int
)
.
Add
(
new
(
big
.
Int
)
.
Add
(
outfree
,
infree
),
partnersfree
)
if
free
.
Cmp
(
cfree
)
!=
0
{
return
fmt
.
Errorf
(
"free calculation fail "
)
}
income
:=
new
(
big
.
Int
)
.
Sub
(
pamount
,
free
)
treposit
,
err
:=
dividecalc
(
income
,
oTx
.
Norate
)
if
err
!=
nil
{
return
err
}
receiver
:=
&
TransferAccount
{
AccountType
:
"coupartners"
,
AccountId
:
oTx
.
Pid
,
FundType
:
"benefit"
,
}
err
=
transfer
(
partnersfree
,
nil
,
receiver
,
""
,
stub
)
if
err
!=
nil
{
return
err
}
//netincome := new(big.Int).Sub(income,treposit)
err
=
dividesTransaction
(
oTx
.
Mid
,
treposit
,
stub
)
if
err
!=
nil
{
return
err
}
return
nil
}
/*
根据商户Id,进行分成交易
*/
func
dividesTransaction
(
mid
string
,
treposit
*
big
.
Int
,
stub
shim
.
ChaincodeStubInterface
)
error
{
merkey
:=
StoragePrefix
+
"_"
+
"merchants"
+
"_"
+
mid
mermap
,
err
:=
getState
(
merkey
,
stub
)
if
err
!=
nil
{
return
err
}
aid
,
ok
:=
mermap
[
"aid"
]
.
(
string
)
//得到代理商Id
if
!
ok
{
return
fmt
.
Errorf
(
"aid parameter resolution to string failed "
)
}
bid
,
ok
:=
mermap
[
"bid"
]
.
(
string
)
//得到分支机构Id
if
!
ok
{
return
fmt
.
Errorf
(
"Free parameter resolution to string failed "
)
}
acid
,
ok
:=
mermap
[
"acid"
]
.
(
string
)
//得到加盟商Id
if
!
ok
{
return
fmt
.
Errorf
(
"Free parameter resolution to string failed "
)
}
fid
,
ok
:=
mermap
[
"fid"
]
.
(
string
)
//得到保理
if
!
ok
{
return
fmt
.
Errorf
(
"Free parameter resolution to string failed "
)
}
asdiscounts
,
err
:=
divide
(
aid
,
treposit
,
stub
)
if
err
!=
nil
{
return
err
}
bsdiscounts
,
err
:=
divide
(
bid
,
treposit
,
stub
)
if
err
!=
nil
{
return
err
}
acsdiscounts
,
err
:=
divide
(
acid
,
treposit
,
stub
)
if
err
!=
nil
{
return
err
}
fsdiscounts
,
err
:=
divide
(
fid
,
treposit
,
stub
)
if
err
!=
nil
{
return
err
}
if
asdiscounts
+
bsdiscounts
+
acsdiscounts
+
fsdiscounts
>
1
{
return
fmt
.
Errorf
(
"The divide proportion must not exceed 1 "
)
}
return
nil
}
func
divide
(
id
string
,
treposit
*
big
.
Int
,
stub
shim
.
ChaincodeStubInterface
)
(
float64
,
error
)
{
akey
:=
StoragePrefix
+
"_"
+
"alibusi"
+
"_"
+
id
amap
,
err
:=
getState
(
akey
,
stub
)
if
err
!=
nil
{
return
0
,
err
}
sdiscounts
,
ok
:=
amap
[
"sdiscounts"
]
.
(
float64
)
if
!
ok
{
return
0
,
fmt
.
Errorf
(
"sdiscounts parameter resolution to float64 failed "
)
}
adivide
,
err
:=
dividecalc
(
treposit
,
sdiscounts
)
if
err
!=
nil
{
return
0
,
err
}
areceiver
:=
&
TransferAccount
{
AccountType
:
"alibusi"
,
AccountId
:
id
,
FundType
:
"amount"
,
}
return
sdiscounts
,
transfer
(
adivide
,
nil
,
areceiver
,
""
,
stub
)
}
/*
特别说明interface 不能是引用类型
*/
func
checkandUpdate
(
key
string
,
fieldkeys
[]
string
,
checkvalue
,
upvalue
[]
interface
{},
stub
shim
.
ChaincodeStubInterface
)
(
map
[
string
]
interface
{},
error
)
{
valueMap
,
err
:=
getState
(
key
,
stub
)
if
err
!=
nil
{
return
nil
,
err
}
for
i
,
fk
:=
range
fieldkeys
{
if
!
reflect
.
DeepEqual
(
valueMap
[
fk
],
checkvalue
[
i
])
{
return
nil
,
fmt
.
Errorf
(
"%s not the expected field value"
,
fk
)
}
else
{
valueMap
[
fk
]
=
upvalue
[
i
]
}
}
value
,
err
:=
json
.
Marshal
(
valueMap
)
if
err
!=
nil
{
return
nil
,
err
}
err
=
stub
.
PutState
(
key
,
value
)
if
err
!=
nil
{
return
nil
,
err
}
return
valueMap
,
nil
}
/*
实现普通的转账操作
*/
func
transfer
(
amount
*
big
.
Int
,
sender
,
receiver
*
TransferAccount
,
commonName
string
,
stub
shim
.
ChaincodeStubInterface
)
error
{
var
err
error
if
amount
.
Cmp
(
big
.
NewInt
(
0
))
==
-
1
{
err
=
fmt
.
Errorf
(
"transfer limit must greater than 0 "
)
return
err
}
if
sender
!=
nil
{
senderSchema
:=
&
Schema
{}
senderSchema
,
err
=
getSchema
(
sender
.
AccountType
,
stub
)
if
err
!=
nil
{
return
err
}
senderKey
:=
LeadgerPrefix
+
"_"
+
sender
.
AccountType
+
"_"
+
sender
.
AccountId
senderleadgermap
,
err
:=
getState
(
senderKey
,
stub
)
if
err
!=
nil
{
return
err
}
onwer
,
ok
:=
senderleadgermap
[
"common_name"
]
.
(
string
)
err
=
senderSchema
.
AuthorityCheck
(
senderSchema
.
LeadgerFields
[
sender
.
FundType
]
.
PAuth
.
Transfer
,
commonName
,
onwer
)
if
err
!=
nil
{
err
=
fmt
.
Errorf
(
"%s field issue permission check does not match, err: %s "
,
sender
.
FundType
,
err
)
return
err
}
fundstr
:=
senderleadgermap
[
sender
.
FundType
]
.
(
string
)
fund
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
fundstr
,
10
)
if
!
ok
{
err
=
fmt
.
Errorf
(
"%s parameter resolution to big.int failed "
,
sender
.
FundType
)
return
err
}
if
fund
.
Cmp
(
amount
)
==
-
1
{
err
=
fmt
.
Errorf
(
"The current amount is less than the withdrawal amount and cannot be extracted "
)
return
err
}
fund
.
Sub
(
fund
,
amount
)
senderleadgermap
[
sender
.
FundType
]
=
fund
.
String
()
err
=
putState
(
senderKey
,
senderleadgermap
,
stub
)
if
err
!=
nil
{
return
err
}
}
if
receiver
!=
nil
{
receiverKey
:=
LeadgerPrefix
+
"_"
+
receiver
.
AccountType
+
"_"
+
receiver
.
AccountId
receiverleadgermap
,
err
:=
getState
(
receiverKey
,
stub
)
if
err
!=
nil
{
return
err
}
rfundstr
:=
receiverleadgermap
[
receiver
.
FundType
]
.
(
string
)
rfund
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
rfundstr
,
10
)
if
!
ok
{
err
=
fmt
.
Errorf
(
"%s parameter resolution to big.int failed "
,
receiver
.
FundType
)
return
err
}
rfund
.
Add
(
rfund
,
amount
)
receiverleadgermap
[
receiver
.
FundType
]
=
rfund
.
String
()
err
=
putState
(
receiverKey
,
receiverleadgermap
,
stub
)
if
err
!=
nil
{
return
err
}
}
return
nil
}
src/github.com/gongxianghui_framework/schema.go
0 → 100644
View file @
d7ba709c
package
main
import
(
"encoding/json"
"fmt"
"math/big"
"reflect"
"time"
)
func
NewSchema
(
arg
string
)
(
*
Schema
,
error
)
{
schema
:=
&
Schema
{
LeadgerFields
:
make
(
map
[
string
]
SchemaLeadgerParameters
),
StorageFields
:
make
(
map
[
string
]
SchemaParameters
),
}
var
argMap
map
[
string
]
interface
{}
if
err
:=
json
.
Unmarshal
([]
byte
(
arg
),
&
argMap
);
err
!=
nil
{
return
nil
,
err
}
if
(
argMap
[
"storage_fields"
]
!=
nil
||
argMap
[
"leadger_fields"
]
!=
nil
)
&&
argMap
[
"schema_auth"
]
!=
nil
&&
argMap
[
"auth"
]
!=
nil
{
if
err
:=
json
.
Unmarshal
([]
byte
(
arg
),
schema
);
err
!=
nil
{
return
nil
,
err
}
//检查schema leadger字段
err
:=
leadgerFieldsCheck
(
&
schema
.
LeadgerFields
)
if
err
!=
nil
{
return
nil
,
err
}
return
schema
,
nil
}
for
k
,
v
:=
range
argMap
{
//假设用户只传递了map类型的信息,我们则默认它全部都是存储字段
schema
.
StorageFields
[
k
]
=
SchemaParameters
{
Value
:
v
,
PAuth
:
Auth
{},
}
}
return
schema
,
nil
}
func
leadgerFieldsCheck
(
leadgerFields
*
map
[
string
]
SchemaLeadgerParameters
)
error
{
for
k
,
fields
:=
range
*
leadgerFields
{
if
fields
.
FCheck
==
nil
{
fields
.
FCheck
=
&
Checks
{
FType
:
"big.int"
,
Must
:
false
,
Fieldlen
:
1
,
}
}
else
{
if
fields
.
FCheck
.
FType
!=
"big.int"
{
return
fmt
.
Errorf
(
"%s fields type must is big.int"
,
k
)
}
else
if
!
(
fields
.
FCheck
.
Fieldlen
>
0
)
{
return
fmt
.
Errorf
(
"%s fields length must is greater than zero"
,
k
)
}
}
if
len
(
fields
.
PAuth
.
Extract
.
Roles
)
==
0
&&
len
(
fields
.
PAuth
.
Extract
.
Users
)
==
0
{
}
}
return
nil
}
/*
schema 权限检查,权限组是否满足权限
*/
func
(
schema
*
Schema
)
AuthorityCheck
(
authority
AuthGroup
,
name
,
owner
string
)
error
{
var
auths
map
[
string
]
int64
if
IsUsers
{
auths
=
authority
.
Users
}
else
{
auths
=
authority
.
Roles
}
if
len
(
auths
)
==
0
{
return
nil
}
for
k
,
v
:=
range
auths
{
if
k
==
name
||
(
k
==
"owner"
&&
name
==
owner
)
{
if
v
==
0
||
v
>
time
.
Now
()
.
Unix
()
{
return
nil
}
else
{
return
fmt
.
Errorf
(
"%s user permission period "
,
name
)
}
}
}
return
fmt
.
Errorf
(
"%s user does not have permission"
,
name
)
}
/*
schema 写权限检查,权限组是否满足权限
*/
func
(
schema
*
Schema
)
WriteCheck
(
name
,
owner
string
)
error
{
return
schema
.
AuthorityCheck
(
schema
.
SchemaAuth
.
Write
,
name
,
owner
)
}
/*
schema 对应数据总写权限检查,权限组是否满足权限
*/
func
(
schema
*
Schema
)
AllWriteCheck
(
name
,
owner
string
)
error
{
return
schema
.
AuthorityCheck
(
schema
.
SAuth
.
Write
,
name
,
owner
)
}
/*
数据的写权限检查
*/
func
(
schema
*
Schema
)
DataWriteCheck
(
checks
map
[
string
]
interface
{},
commonName
,
owner
string
)
error
{
//if err := schema.WriteCheck(commonName,owner) ; err != nil{
// return nil
//}
for
k
,
_
:=
range
checks
{
if
schemaV
,
ok
:=
schema
.
StorageFields
[
k
];
!
ok
{
return
fmt
.
Errorf
(
"inexistence %s field! "
,
k
)
}
else
{
if
err
:=
schema
.
AuthorityCheck
(
schemaV
.
PAuth
.
Write
,
commonName
,
owner
);
err
!=
nil
{
return
fmt
.
Errorf
(
"%s field authority check fail, %s "
,
k
,
err
)
}
}
}
return
nil
}
/*
schema 读权限检查,权限组是否满足权限
*/
func
(
schema
*
Schema
)
ReadCheck
(
name
,
owner
string
)
error
{
return
schema
.
AuthorityCheck
(
schema
.
SchemaAuth
.
Read
,
name
,
owner
)
}
/*
schema 对应数据总读权限检查,权限组是否满足权限
*/
func
(
schema
*
Schema
)
AllReadCheck
(
name
,
owner
string
)
error
{
return
schema
.
AuthorityCheck
(
schema
.
SAuth
.
Read
,
name
,
owner
)
}
/*
schema 读过滤
*/
func
(
schema
*
Schema
)
ReadFiler
(
checks
map
[
string
]
interface
{},
commonName
,
owner
string
)
(
map
[
string
]
interface
{},
error
)
{
//if err := schema.ReadCheck(commonName,owner) ; err != nil{
// return checks, nil
//}
for
k
,
schemaV
:=
range
schema
.
StorageFields
{
if
err
:=
schema
.
AuthorityCheck
(
schemaV
.
PAuth
.
Read
,
commonName
,
owner
);
err
!=
nil
{
checks
[
k
]
=
defValue
}
}
for
k
,
schemaV
:=
range
schema
.
LeadgerFields
{
if
err
:=
schema
.
AuthorityCheck
(
schemaV
.
PAuth
.
Read
,
commonName
,
owner
);
err
!=
nil
{
checks
[
k
]
=
defValue
}
}
return
checks
,
nil
}
func
(
schema
*
Schema
)
DataReadCheck
(
checks
map
[
string
]
interface
{},
commonName
,
owner
string
)
error
{
//if err := schema.WriteCheck(commonName,owner) ; err != nil{
// return nil
//}
for
k
,
_
:=
range
checks
{
if
schemaV
,
ok
:=
schema
.
StorageFields
[
k
];
!
ok
{
return
fmt
.
Errorf
(
"inexistence %s field! "
,
k
)
}
else
{
if
err
:=
schema
.
AuthorityCheck
(
schemaV
.
PAuth
.
Read
,
commonName
,
owner
);
err
!=
nil
{
return
fmt
.
Errorf
(
"%s field authority check fail, %s "
,
k
,
err
)
}
}
}
return
nil
}
/*
进行Schema 字段的格式匹配
*/
func
(
schema
*
Schema
)
SchemaMatched
(
checks
map
[
string
]
interface
{})
error
{
if
len
(
schema
.
StorageFields
)
+
len
(
schema
.
LeadgerFields
)
!=
len
(
checks
)
{
return
fmt
.
Errorf
(
"field length is less than the schema field length ! "
)
}
for
k
,
v
:=
range
schema
.
StorageFields
{
if
schemaV
,
ok
:=
checks
[
k
];
!
ok
{
return
fmt
.
Errorf
(
"There is no input storage field %s "
,
k
)
}
else
{
if
parameterS
,
ok
:=
v
.
Value
.
(
map
[
string
]
interface
{});
ok
{
if
parameterC
,
ok
:=
schemaV
.
(
map
[
string
]
interface
{});
!
ok
{
return
fmt
.
Errorf
(
"The input field %s does not match the output field format "
,
k
)
}
else
{
err
:=
backUpCheck
(
parameterS
,
parameterC
)
if
err
!=
nil
{
return
err
}
}
}
}
}
for
k
,
_
:=
range
schema
.
LeadgerFields
{
if
_
,
ok
:=
checks
[
k
];
!
ok
{
return
fmt
.
Errorf
(
"There is no input leadger field %s "
,
k
)
}
}
return
nil
}
func
backUpCheck
(
backUp
map
[
string
]
interface
{},
checkmap
map
[
string
]
interface
{})
error
{
if
len
(
backUp
)
!=
len
(
checkmap
)
{
return
fmt
.
Errorf
(
"The input backup field length is less than the schema backup field length ! "
)
}
for
k
,
_
:=
range
checkmap
{
if
_
,
ok
:=
backUp
[
k
];
!
ok
{
return
fmt
.
Errorf
(
"There is no input backup field %s "
,
k
)
}
}
return
nil
}
func
(
schema
*
Schema
)
FieldsCheck
(
checks
map
[
string
]
interface
{})
error
{
for
k
,
schemaV
:=
range
schema
.
StorageFields
{
if
_
,
ok
:=
checks
[
k
];
!
ok
{
return
fmt
.
Errorf
(
"There is no input storage field %s "
,
k
)
}
if
schemaV
.
FCheck
!=
nil
&&
schemaV
.
FCheck
.
FType
!=
""
{
if
err
:=
schema
.
fieldCheckout
(
schemaV
.
FCheck
,
checks
[
k
]);
err
!=
nil
{
return
fmt
.
Errorf
(
"%s field check err:%s "
,
k
,
err
)
}
}
}
for
k
,
schemaV
:=
range
schema
.
LeadgerFields
{
if
_
,
ok
:=
checks
[
k
];
!
ok
{
return
fmt
.
Errorf
(
"There is no input storage field %s "
,
k
)
}
if
schemaV
.
FCheck
!=
nil
&&
schemaV
.
FCheck
.
FType
!=
""
{
if
err
:=
schema
.
fieldCheckout
(
schemaV
.
FCheck
,
checks
[
k
]);
err
!=
nil
{
return
fmt
.
Errorf
(
"%s field check err:%s "
,
k
,
err
)
}
}
}
return
nil
}
func
(
schema
*
Schema
)
FieldsFormatCheck
(
checks
map
[
string
]
interface
{})
error
{
for
k
,
_
:=
range
checks
{
fcheck
:=
&
Checks
{}
sfield
,
ok
:=
schema
.
StorageFields
[
k
]
if
ok
{
fcheck
=
sfield
.
FCheck
}
else
{
lfield
,
ok
:=
schema
.
LeadgerFields
[
k
]
if
!
ok
{
return
fmt
.
Errorf
(
"%s field check inexistence in schema"
,
k
,
)
}
fcheck
=
lfield
.
FCheck
}
if
fcheck
!=
nil
&&
fcheck
.
FType
!=
""
&&
checks
[
k
]
!=
nil
{
if
err
:=
schema
.
fieldCheckout
(
fcheck
,
checks
[
k
]);
err
!=
nil
{
return
fmt
.
Errorf
(
"%s field check err:%s "
,
k
,
err
)
}
}
}
return
nil
}
func
(
schema
*
Schema
)
fieldCheckout
(
check
*
Checks
,
val
interface
{})
error
{
fType
:=
reflect
.
TypeOf
(
val
)
.
String
()
switch
check
.
FType
{
case
"string"
:
if
fType
!=
"string"
{
return
fmt
.
Errorf
(
"fields type does not match the defined string type! "
)
}
if
check
.
Must
&&
(
val
==
""
)
{
return
fmt
.
Errorf
(
"fields can not be empty"
)
}
value
:=
val
.
(
string
)
if
len
([]
rune
(
value
))
>
check
.
Fieldlen
{
return
fmt
.
Errorf
(
"fields length cannot be greater than %d "
,
check
.
Fieldlen
)
}
case
"int"
,
"int16"
,
"int32"
,
"int64"
,
"float32"
,
"float64"
:
if
fType
!=
"float64"
{
return
fmt
.
Errorf
(
"fields type does not match the defined %s type! "
,
check
.
FType
)
}
value
:=
val
.
(
float64
)
if
check
.
Must
&&
(
value
==
0
)
{
return
fmt
.
Errorf
(
"fields can not be 0"
)
}
if
check
.
Fieldlen
!=
0
&&
value
<
0
{
return
fmt
.
Errorf
(
"fields cannot be negative"
)
}
case
"time.Time"
:
if
fType
!=
"string"
{
return
fmt
.
Errorf
(
"fields type does not match the defined time.Time type! "
)
}
dateStr
:=
reflect
.
ValueOf
(
val
)
.
String
()
if
check
.
Must
&&
dateStr
==
""
{
return
fmt
.
Errorf
(
"fields cannot be empty"
)
}
if
_
,
err
:=
time
.
Parse
(
"2006-01-02 15:04:05"
,
dateStr
);
err
!=
nil
{
return
fmt
.
Errorf
(
err
.
Error
())
}
//if check.Must && (dateStr == "0001-01-01 00:00:00 +0000 UTC"|| dateStr == "0001-01-01T00:00:00Z"){
// return fmt.Errorf("fields cannot be initial value")
//}
case
"big.int"
:
if
fType
!=
"string"
{
return
fmt
.
Errorf
(
"fields type does not match the defined big.int type! "
)
}
number
:=
new
(
big
.
Int
)
dateStr
:=
reflect
.
ValueOf
(
val
)
.
String
()
_
,
ok
:=
number
.
SetString
(
dateStr
,
10
)
if
!
ok
{
return
fmt
.
Errorf
(
"parameter resolution failed "
)
}
case
"object"
,
"struct"
:
if
fType
!=
"map[string]interface {}"
{
return
fmt
.
Errorf
(
"fields type does not match the defined big.int type! "
)
}
default
:
fmt
.
Errorf
(
"fields type no match! "
)
}
return
nil
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment