Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
plugin
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
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
link33
plugin
Commits
235f4bb4
Commit
235f4bb4
authored
Mar 26, 2020
by
harrylee
Committed by
vipwzw
Apr 04, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
goimports files
parent
2f39ff09
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
243 additions
and
116 deletions
+243
-116
README.md
plugin/dapp/accountmanager/README.md
+49
-0
build.sh
plugin/dapp/accountmanager/cmd/build.sh
+0
-0
account_test.go
plugin/dapp/accountmanager/executor/account_test.go
+42
-18
accountdb.go
plugin/dapp/accountmanager/executor/accountdb.go
+9
-5
accountmanager.go
plugin/dapp/accountmanager/executor/accountmanager.go
+28
-3
tables.go
plugin/dapp/accountmanager/executor/tables.go
+2
-1
tables_test.go
plugin/dapp/accountmanager/executor/tables_test.go
+26
-26
accountmanager.proto
plugin/dapp/accountmanager/proto/accountmanager.proto
+11
-7
accountmanager.go
plugin/dapp/accountmanager/types/accountmanager.go
+4
-3
accountmanager.pb.go
plugin/dapp/accountmanager/types/accountmanager.pb.go
+72
-53
No files found.
plugin/dapp/accountmanager/README.md
View file @
235f4bb4
# accountmanager合约
## 前言
为适配央行发布的
[
金融分布式账户技术安全规范
](
http://www.cfstc.org/bzgk/gk/view/yulan.jsp?i_id=1855
)
,满足联盟链中的金融监管,账户公钥重置,黑白名单等要求,特意在chain33上面开发了
accountmanager合约
## 使用
合约按照中心化金融服务的设计,有管理员对合约下面的账户进行监管
提供如下功能:
功能|内容
----|----
账户创建|普通账户,管理员账户,其他有特殊权限的系统账户,在accountmanager合约中,accountID具有唯一性,可作为身份的标识
账户授权|普通权限在注册时即以授权,特殊权限则需要管理员进行授权
账户冻结和解冻|账户冻结由管理员发起,冻结的账户不能交易,账户下的资产将会被冻结
账户锁定和恢复|用于当私钥遗失,重置外部私钥的情况,需要有一定的锁定期限,在锁定期内不能转移账户下的资产
账户注销| 账户应设使用期限,默认五年时间,过期账户将被注销,提供已注销账户的查询接口
账户资产|账户资产可在accountmanager合约下进行正常的流转
合约接口,在线构造交易和查询接口分别复用了框架中的CreateTransaction和Query接口,详情请参考
[
CreateTransaction接口
](
https://github.com/33cn/chain33/blob/master/rpc/jrpchandler.go#L1101
)
和
[
Query接口
](
https://github.com/33cn/chain33/blob/master/rpc/jrpchandler.go#L838
)
查询方法名称|功能
-----|----
QueryAccountByID|根据账户ID查询账户信息,可用于检查账户ID是否注册
QueryAccountsByStatus|根据状态查询账户信息
QueryExpiredAccounts|查询过期时间
QueryAccountByAddr|根据用户地址查询账户信息
QueryBalanceByID|根据账户ID查询账户资产余额
可参照account_test.go中得相关测试用例,构建相关交易进行测试
## 注意事项
**表结构说明**
表名|主键|索引|用途|说明
---|---|---|---|---
account|index|accountID,addr,status|记录注册账户信息|index是复合索引由{expiretime
*
1e5+index(注册交易所在区块中的索引)}构成
**表中相关参数说明**
参数名|说明
----|----
Asset|资产名称
op|操作类型 分为supervisor op 1为冻结,2为解冻,3增加有效期,4为授权 apply op 1 撤销账户公钥重置, 2 锁定期结束后,执行重置公钥操作
status|账户状态,0 正常, 1表示冻结, 2表示锁定 3,过期注销
level|账户权限 0 普通,其他根据业务需求自定义
index|账户逾期的时间戳
*
1e5+注册交易在区块中的索引,占位15 %015d
plugin/dapp/accountmanager/cmd/build.sh
100644 → 100755
View file @
235f4bb4
File mode changed from 100644 to 100755
plugin/dapp/accountmanager/executor/account_test.go
View file @
235f4bb4
package
executor
import
(
"time"
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/client"
"github.com/33cn/chain33/common"
...
...
@@ -10,11 +12,11 @@ import (
"github.com/33cn/chain33/queue"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
"time"
"testing"
et
"github.com/33cn/plugin/plugin/dapp/accountmanager/types"
"github.com/stretchr/testify/assert"
"testing"
)
type
execEnv
struct
{
...
...
@@ -110,10 +112,13 @@ func TestAccountManager(t *testing.T) {
//注册
tx1
,
err
:=
CreateRegister
(
&
et
.
Register
{
AccountID
:
"harrylee2015"
},
PrivKeyB
)
if
err
!=
nil
{
t
.
Error
(
err
)
}
Exec_Block
(
t
,
stateDB
,
kvdb
,
env
,
tx1
)
assert
.
Equal
(
t
,
err
,
nil
)
err
=
Exec_Block
(
t
,
stateDB
,
kvdb
,
env
,
tx1
)
assert
.
Equal
(
t
,
err
,
nil
)
_
,
err
=
Exec_QueryAccountByID
(
"harrylee2015"
,
stateDB
,
kvdb
)
assert
.
Equal
(
t
,
err
,
nil
)
_
,
err
=
Exec_QueryAccountByAddr
(
Nodes
[
1
],
stateDB
,
kvdb
)
assert
.
Equal
(
t
,
err
,
nil
)
tx2
,
err
:=
CreateRegister
(
&
et
.
Register
{
AccountID
:
"harrylee2015"
},
PrivKeyC
)
err
=
Exec_Block
(
t
,
stateDB
,
kvdb
,
env
,
tx2
)
assert
.
Equal
(
t
,
err
,
et
.
ErrAccountIDExist
)
...
...
@@ -181,12 +186,31 @@ func TestAccountManager(t *testing.T) {
//过期账户查询
time
.
Sleep
(
10
*
time
.
Second
)
t
.
Log
(
time
.
Now
()
.
Unix
())
accs
,
err
:=
Exec_QueryExpiredAccounts
(
time
.
Now
()
.
Unix
(),
stateDB
,
kvdb
)
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
accs
)
accounts
,
err
=
Exec_QueryExpiredAccounts
(
time
.
Now
()
.
Unix
(),
stateDB
,
kvdb
)
assert
.
Equal
(
t
,
err
,
nil
)
assert
.
Equal
(
t
,
accounts
.
Accounts
[
0
]
.
AccountID
,
"harrylee2015"
)
//账户延期
tx10
,
_
:=
CreateSupervise
(
&
et
.
Supervise
{
AccountIDs
:
[]
string
{
"harrylee2015"
},
Op
:
et
.
AddExpire
,
},
PrivKeyA
)
err
=
Exec_Block
(
t
,
stateDB
,
kvdb
,
env
,
tx10
)
assert
.
Equal
(
t
,
err
,
nil
)
accounts
,
err
=
Exec_QueryExpiredAccounts
(
time
.
Now
()
.
Unix
(),
stateDB
,
kvdb
)
assert
.
Equal
(
t
,
err
,
nil
)
assert
.
Equal
(
t
,
len
(
accounts
.
Accounts
),
0
)
//账户授权
tx11
,
_
:=
CreateSupervise
(
&
et
.
Supervise
{
AccountIDs
:
[]
string
{
"harrylee2015"
},
Op
:
et
.
Authorize
,
Level
:
2
,
},
PrivKeyA
)
err
=
Exec_Block
(
t
,
stateDB
,
kvdb
,
env
,
tx11
)
assert
.
Equal
(
t
,
err
,
nil
)
acc
,
err
:=
Exec_QueryAccountByID
(
"harrylee2015"
,
stateDB
,
kvdb
)
assert
.
Equal
(
t
,
err
,
nil
)
assert
.
Equal
(
t
,
acc
.
Level
,
int32
(
2
))
}
func
CreateRegister
(
register
*
et
.
Register
,
privKey
string
)
(
tx
*
types
.
Transaction
,
err
error
)
{
...
...
@@ -290,6 +314,12 @@ func Exec_Block(t *testing.T, stateDB db.DB, kvdb db.KVDB, env *execEnv, txs ...
cfg
.
SetTitleOnlyForTest
(
"chain33"
)
exec
:=
newAccountmanager
()
e
:=
exec
.
(
*
accountmanager
)
q
:=
queue
.
New
(
"channel"
)
q
.
SetConfig
(
cfg
)
api
,
_
:=
client
.
New
(
q
.
Client
(),
nil
)
exec
.
SetAPI
(
api
)
exec
.
SetStateDB
(
stateDB
)
exec
.
SetLocalDB
(
kvdb
)
for
index
,
tx
:=
range
txs
{
err
:=
e
.
CheckTx
(
tx
,
index
)
if
err
!=
nil
{
...
...
@@ -297,12 +327,6 @@ func Exec_Block(t *testing.T, stateDB db.DB, kvdb db.KVDB, env *execEnv, txs ...
}
}
q
:=
queue
.
New
(
"channel"
)
q
.
SetConfig
(
cfg
)
api
,
_
:=
client
.
New
(
q
.
Client
(),
nil
)
exec
.
SetAPI
(
api
)
exec
.
SetStateDB
(
stateDB
)
exec
.
SetLocalDB
(
kvdb
)
env
.
blockHeight
=
env
.
blockHeight
+
1
env
.
blockTime
=
env
.
blockTime
+
1
env
.
difficulty
=
env
.
difficulty
+
1
...
...
plugin/dapp/accountmanager/executor/accountdb.go
View file @
235f4bb4
...
...
@@ -2,6 +2,9 @@ package executor
import
(
"fmt"
"strconv"
"time"
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/client"
dbm
"github.com/33cn/chain33/common/db"
...
...
@@ -9,8 +12,6 @@ import (
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
et
"github.com/33cn/plugin/plugin/dapp/accountmanager/types"
"strconv"
"time"
)
var
(
...
...
@@ -48,9 +49,9 @@ func NewAction(e *accountmanager, tx *types.Transaction, index int) *Action {
e
.
GetBlockTime
(),
e
.
GetHeight
(),
dapp
.
ExecAddress
(
string
(
tx
.
Execer
)),
e
.
GetLocalDB
(),
index
,
e
.
GetAPI
()}
}
//GetIndex get index 主键索引
//GetIndex get index 主键索引
,实际上是以过期时间为主键
func
(
a
*
Action
)
GetIndex
()
int64
{
return
a
.
height
*
types
.
MaxTxsPerBlock
+
int64
(
a
.
index
)
return
a
.
blocktime
*
types
.
MaxTxsPerBlock
+
int64
(
a
.
index
)
}
//GetKVSet get kv set
...
...
@@ -74,6 +75,7 @@ func (a *Action) Register(payload *et.Register) (*types.Receipt, error) {
Addr
:
a
.
fromaddr
,
PrevAddr
:
""
,
Status
:
et
.
Normal
,
Level
:
et
.
Normal
,
CreateTime
:
a
.
blocktime
,
ExpireTime
:
a
.
blocktime
+
defaultActiveTime
,
LockTime
:
0
,
...
...
@@ -237,6 +239,8 @@ func (a *Action) Supervise(payload *et.Supervise) (*types.Receipt, error) {
defaultActiveTime
:=
getConfValue
(
cfg
,
a
.
statedb
,
ConfNameActiveTime
,
DefaultActiveTime
)
accountM
.
Status
=
et
.
Normal
accountM
.
ExpireTime
=
a
.
blocktime
+
defaultActiveTime
case
et
.
Authorize
:
accountM
.
Level
=
payload
.
Level
}
re
.
Accounts
=
append
(
re
.
Accounts
,
accountM
)
}
...
...
@@ -407,7 +411,7 @@ func findAccountByID(localdb dbm.KV, accountID string) (*et.Account, error) {
//第一次查询,默认展示最新得成交记录
rows
,
err
:=
table
.
ListIndex
(
"accountID"
,
prefix
,
nil
,
1
,
et
.
ListDESC
)
if
err
!=
nil
{
elog
.
Error
(
"findAccountByID."
,
"prefix"
,
prefix
,
"err"
,
err
.
Error
())
elog
.
Debug
(
"findAccountByID."
,
"accountID"
,
accountID
,
"err"
,
err
.
Error
())
return
nil
,
err
}
for
_
,
row
:=
range
rows
{
...
...
plugin/dapp/accountmanager/executor/accountmanager.go
View file @
235f4bb4
...
...
@@ -4,7 +4,7 @@ import (
log
"github.com/33cn/chain33/common/log/log15"
drivers
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
accountmanagertypes
"github.com/33cn/plugin/plugin/dapp/accountmanager/types"
et
"github.com/33cn/plugin/plugin/dapp/accountmanager/types"
)
/*
...
...
@@ -17,7 +17,7 @@ var (
elog
=
log
.
New
(
"module"
,
"accountmanager.executor"
)
)
var
driverName
=
accountmanagertypes
.
AccountmanagerX
var
driverName
=
et
.
AccountmanagerX
// Init register dapp
func
Init
(
name
string
,
cfg
*
types
.
Chain33Config
,
sub
[]
byte
)
{
...
...
@@ -58,6 +58,31 @@ func (e *accountmanager) ExecutorOrder() int64 {
// CheckTx 实现自定义检验交易接口,供框架调用
func
(
a
*
accountmanager
)
CheckTx
(
tx
*
types
.
Transaction
,
index
int
)
error
{
// implement code
//发送交易的时候就检查payload,做严格的参数检查
var
ama
et
.
AccountmanagerAction
types
.
Decode
(
tx
.
GetPayload
(),
&
ama
)
switch
ama
.
Ty
{
case
et
.
TyRegisterAction
:
register
:=
ama
.
GetRegister
()
if
a
.
CheckAccountIDIsExist
(
register
.
GetAccountID
())
{
return
et
.
ErrAccountIDExist
}
case
et
.
TySuperviseAction
:
case
et
.
TyApplyAction
:
case
et
.
TyTransferAction
:
case
et
.
TyResetAction
:
}
return
nil
}
func
(
a
*
accountmanager
)
CheckAccountIDIsExist
(
accountID
string
)
bool
{
_
,
err
:=
findAccountByID
(
a
.
GetLocalDB
(),
accountID
)
if
err
==
types
.
ErrNotFound
{
return
false
}
return
true
}
plugin/dapp/accountmanager/executor/tables.go
View file @
235f4bb4
...
...
@@ -2,6 +2,7 @@ package executor
import
(
"fmt"
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/common/db/table"
"github.com/33cn/chain33/types"
...
...
@@ -74,7 +75,7 @@ func (m *AccountRow) Get(key string) ([]byte, error) {
}
else
if
key
==
"status"
{
return
[]
byte
(
fmt
.
Sprintf
(
"%d"
,
m
.
Status
)),
nil
}
else
if
key
==
"index"
{
return
[]
byte
(
fmt
.
Sprintf
(
"%01
8
d"
,
m
.
GetIndex
())),
nil
return
[]
byte
(
fmt
.
Sprintf
(
"%01
5
d"
,
m
.
GetIndex
())),
nil
}
else
if
key
==
"addr"
{
return
[]
byte
(
fmt
.
Sprintf
(
"%s"
,
m
.
GetAddr
())),
nil
}
...
...
plugin/dapp/accountmanager/executor/tables_test.go
View file @
235f4bb4
package
executor
import
(
"testing"
"time"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
et
"github.com/33cn/plugin/plugin/dapp/accountmanager/types"
"testing"
"time"
)
func
TestAccountTable
(
t
*
testing
.
T
)
{
_
,
_
,
kvdb
:=
util
.
CreateTestDB
()
table
:=
NewAccountTable
(
kvdb
)
now
:=
time
.
Now
()
.
Unix
()
row1
:=
&
et
.
Account
{
Index
:
now
*
int64
(
types
.
MaxTxsPerBlock
),
AccountID
:
"harry2015"
,
Status
:
1
,
ExpireTime
:
now
+
10
,
Addr
:
"xxxx"
}
row2
:=
&
et
.
Account
{
Index
:
now
*
int64
(
types
.
MaxTxsPerBlock
)
+
1
,
AccountID
:
"harry2020"
,
Status
:
1
,
ExpireTime
:
now
,
Addr
:
"xxxx"
}
table
:=
NewAccountTable
(
kvdb
)
now
:=
time
.
Now
()
.
Unix
()
row1
:=
&
et
.
Account
{
Index
:
now
*
int64
(
types
.
MaxTxsPerBlock
),
AccountID
:
"harry2015"
,
Status
:
1
,
ExpireTime
:
now
+
10
,
Addr
:
"xxxx"
}
row2
:=
&
et
.
Account
{
Index
:
now
*
int64
(
types
.
MaxTxsPerBlock
)
+
1
,
AccountID
:
"harry2020"
,
Status
:
1
,
ExpireTime
:
now
,
Addr
:
"xxxx"
}
table
.
Add
(
row1
)
table
.
Add
(
row2
)
kvs
,
err
:=
table
.
Save
()
if
err
!=
nil
{
kvs
,
err
:=
table
.
Save
()
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
kvs
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
for
_
,
kv
:=
range
kvs
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
time
.
Sleep
(
2
*
time
.
Second
)
list
,
err
:=
findAccountListByIndex
(
kvdb
,
time
.
Now
()
.
Unix
(),
""
)
if
err
!=
nil
{
time
.
Sleep
(
2
*
time
.
Second
)
list
,
err
:=
findAccountListByIndex
(
kvdb
,
time
.
Now
()
.
Unix
()
+
10
,
""
)
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
list
)
list
,
err
=
findAccountListByStatus
(
kvdb
,
et
.
Normal
,
0
,
""
)
if
err
!=
nil
{
list
,
err
=
findAccountListByStatus
(
kvdb
,
et
.
Normal
,
0
,
""
)
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
list
)
row1
.
Status
=
et
.
Frozen
err
=
table
.
Replace
(
row1
)
if
err
!=
nil
{
row1
.
Status
=
et
.
Frozen
err
=
table
.
Replace
(
row1
)
if
err
!=
nil
{
t
.
Error
(
err
)
}
kvs
,
err
=
table
.
Save
()
if
err
!=
nil
{
kvs
,
err
=
table
.
Save
()
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
kvs
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
for
_
,
kv
:=
range
kvs
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
list
,
err
=
findAccountListByStatus
(
kvdb
,
et
.
Frozen
,
0
,
""
)
if
err
!=
nil
{
list
,
err
=
findAccountListByStatus
(
kvdb
,
et
.
Frozen
,
0
,
""
)
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
list
)
}
\ No newline at end of file
}
plugin/dapp/accountmanager/proto/accountmanager.proto
View file @
235f4bb4
...
...
@@ -64,8 +64,10 @@ message Transfer {
message
Supervise
{
//账户名单
repeated
string
accountIDs
=
1
;
//操作, 1为冻结,2为解冻,3增加有效期
//操作, 1为冻结,2为解冻,3增加有效期
,4为授权
int32
op
=
2
;
//0普通,后面根据业务需要可以自定义,有管理员授予不同的权限
int32
level
=
3
;
}
message
account
{
...
...
@@ -75,16 +77,18 @@ message account{
string
addr
=
2
;
//上一次公钥地址
string
prevAddr
=
3
;
//账户状态
1 正常, 2表示冻结, 3表示锁定 4
,过期注销
//账户状态
0 正常, 1表示冻结, 2表示锁定 3
,过期注销
int32
status
=
4
;
//等级权限 0普通,后面根据业务需要可以自定义,有管理员授予不同的权限
int32
level
=
5
;
//注册时间
int64
createTime
=
5
;
int64
createTime
=
6
;
//失效时间
int64
expireTime
=
6
;
int64
expireTime
=
7
;
//锁定时间
int64
lockTime
=
7
;
//索引
int64
index
=
8
;
int64
lockTime
=
8
;
//
主键
索引
int64
index
=
9
;
}
message
AccountReceipt
{
...
...
plugin/dapp/accountmanager/types/accountmanager.go
View file @
235f4bb4
package
types
import
(
"reflect"
log
"github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/types"
"reflect"
)
/*
...
...
@@ -46,8 +47,7 @@ const (
//状态
const
(
UnknownStatus
=
int32
(
iota
)
Normal
Normal
=
int32
(
iota
)
Frozen
Locked
Expired
...
...
@@ -59,6 +59,7 @@ const (
Freeze
UnFreeze
AddExpire
Authorize
)
//apply op
...
...
plugin/dapp/accountmanager/types/accountmanager.pb.go
View file @
235f4bb4
...
...
@@ -422,8 +422,10 @@ func (m *Transfer) GetAmount() int64 {
type
Supervise
struct
{
// 账户名单
AccountIDs
[]
string
`protobuf:"bytes,1,rep,name=accountIDs" json:"accountIDs,omitempty"`
// 操作, 1为冻结,2为解冻,3增加有效期
// 操作, 1为冻结,2为解冻,3增加有效期
,4为授权
Op
int32
`protobuf:"varint,2,opt,name=op" json:"op,omitempty"`
// 0普通,后面根据业务需要可以自定义,有管理员授予不同的权限
Level
int32
`protobuf:"varint,3,opt,name=level" json:"level,omitempty"`
}
func
(
m
*
Supervise
)
Reset
()
{
*
m
=
Supervise
{}
}
...
...
@@ -445,6 +447,13 @@ func (m *Supervise) GetOp() int32 {
return
0
}
func
(
m
*
Supervise
)
GetLevel
()
int32
{
if
m
!=
nil
{
return
m
.
Level
}
return
0
}
type
Account
struct
{
// 账户名称
AccountID
string
`protobuf:"bytes,1,opt,name=accountID" json:"accountID,omitempty"`
...
...
@@ -452,16 +461,18 @@ type Account struct {
Addr
string
`protobuf:"bytes,2,opt,name=addr" json:"addr,omitempty"`
// 上一次公钥地址
PrevAddr
string
`protobuf:"bytes,3,opt,name=prevAddr" json:"prevAddr,omitempty"`
// 账户状态
1 正常, 2表示冻结, 3表示锁定 4
,过期注销
// 账户状态
0 正常, 1表示冻结, 2表示锁定 3
,过期注销
Status
int32
`protobuf:"varint,4,opt,name=status" json:"status,omitempty"`
// 等级权限 0普通,后面根据业务需要可以自定义,有管理员授予不同的权限
Level
int32
`protobuf:"varint,5,opt,name=level" json:"level,omitempty"`
// 注册时间
CreateTime
int64
`protobuf:"varint,
5
,opt,name=createTime" json:"createTime,omitempty"`
CreateTime
int64
`protobuf:"varint,
6
,opt,name=createTime" json:"createTime,omitempty"`
// 失效时间
ExpireTime
int64
`protobuf:"varint,
6
,opt,name=expireTime" json:"expireTime,omitempty"`
ExpireTime
int64
`protobuf:"varint,
7
,opt,name=expireTime" json:"expireTime,omitempty"`
// 锁定时间
LockTime
int64
`protobuf:"varint,
7
,opt,name=lockTime" json:"lockTime,omitempty"`
// 索引
Index
int64
`protobuf:"varint,
8
,opt,name=index" json:"index,omitempty"`
LockTime
int64
`protobuf:"varint,
8
,opt,name=lockTime" json:"lockTime,omitempty"`
//
主键
索引
Index
int64
`protobuf:"varint,
9
,opt,name=index" json:"index,omitempty"`
}
func
(
m
*
Account
)
Reset
()
{
*
m
=
Account
{}
}
...
...
@@ -497,6 +508,13 @@ func (m *Account) GetStatus() int32 {
return
0
}
func
(
m
*
Account
)
GetLevel
()
int32
{
if
m
!=
nil
{
return
m
.
Level
}
return
0
}
func
(
m
*
Account
)
GetCreateTime
()
int64
{
if
m
!=
nil
{
return
m
.
CreateTime
...
...
@@ -843,50 +861,51 @@ var _Accountmanager_serviceDesc = grpc.ServiceDesc{
func
init
()
{
proto
.
RegisterFile
(
"accountmanager.proto"
,
fileDescriptor0
)
}
var
fileDescriptor0
=
[]
byte
{
// 719 bytes of a gzipped FileDescriptorProto
0x1f
,
0x8b
,
0x08
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x02
,
0xff
,
0x94
,
0x55
,
0xcf
,
0x6a
,
0x1b
,
0x3f
,
0x10
,
0xce
,
0x7a
,
0xb3
,
0xb6
,
0x77
,
0xf2
,
0xfb
,
0x39
,
0x46
,
0xb8
,
0x61
,
0x29
,
0xa5
,
0x18
,
0x91
,
0x83
,
0x29
,
0x6d
,
0x08
,
0x29
,
0xa5
,
0xd0
,
0xf4
,
0x62
,
0x93
,
0x96
,
0x84
,
0xf6
,
0x52
,
0xc5
,
0xe7
,
0x82
,
0xb2
,
0x56
,
0xc2
,
0x52
,
0xdb
,
0xbb
,
0x68
,
0x65
,
0x93
,
0xed
,
0x0b
,
0xf4
,
0xd6
,
0x53
,
0x5f
,
0xb0
,
0x6f
,
0x52
,
0x34
,
0x92
,
0xf6
,
0x5f
,
0x9a
,
0x86
,
0x9c
,
0xbc
,
0xf3
,
0x7d
,
0x9f
,
0x66
,
0x46
,
0x33
,
0xa3
,
0x31
,
0x8c
,
0x78
,
0x1c
,
0xa7
,
0x9b
,
0xb5
,
0x5a
,
0xf1
,
0x35
,
0xbf
,
0x11
,
0xf2
,
0x28
,
0x93
,
0xa9
,
0x4a
,
0x49
,
0xa0
,
0x8a
,
0x4c
,
0xe4
,
0x74
,
0x08
,
0x83
,
0x69
,
0x83
,
0xa6
,
0xbf
,
0x3a
,
0x30
,
0x6a
,
0x42
,
0xd3
,
0x58
,
0x25
,
0xe9
,
0x9a
,
0xbc
,
0x82
,
0xbe
,
0x14
,
0x37
,
0x49
,
0xae
,
0x84
,
0x8c
,
0xbc
,
0xb1
,
0x37
,
0xd9
,
0x3b
,
0xd9
,
0x3f
,
0x42
,
0x27
,
0x47
,
0xcc
,
0xc2
,
0xe7
,
0x3b
,
0xac
,
0x94
,
0x18
,
0x79
,
0x2e
,
0xd4
,
0x27
,
0x51
,
0x44
,
0x9d
,
0x96
,
0xdc
,
0xc0
,
0x46
,
0x6e
,
0xbe
,
0xb5
,
0x5c
,
0x49
,
0xbe
,
0xce
,
0xaf
,
0x85
,
0x8c
,
0xfc
,
0x86
,
0x7c
,
0x6e
,
0x61
,
0x2d
,
0x77
,
0x12
,
0x72
,
0x0c
,
0x61
,
0xbe
,
0xc9
,
0x84
,
0xdc
,
0x26
,
0xb9
,
0x88
,
0x76
,
0x51
,
0x3f
,
0xb4
,
0xfa
,
0x4b
,
0x87
,
0x9f
,
0xef
,
0xb0
,
0x4a
,
0x44
,
0x0e
,
0x21
,
0xe0
,
0x59
,
0xb6
,
0x2c
,
0xa2
,
0x00
,
0xd5
,
0xff
,
0x59
,
0xf5
,
0x54
,
0x63
,
0xe7
,
0x3b
,
0xcc
,
0x90
,
0x64
,
0x00
,
0x1d
,
0x55
,
0x44
,
0xdd
,
0xb1
,
0x37
,
0x09
,
0x58
,
0x47
,
0x15
,
0xb3
,
0x1e
,
0x04
,
0x5b
,
0xbe
,
0xdc
,
0x08
,
0x3a
,
0x81
,
0xbe
,
0xbb
,
0x26
,
0x79
,
0x06
,
0xa1
,
0xad
,
0xe9
,
0xc5
,
0x19
,
0x96
,
0x22
,
0x64
,
0x15
,
0x40
,
0xdf
,
0x6b
,
0xa5
,
0xbd
,
0xd5
,
0x3f
,
0x95
,
0x84
,
0xc0
,
0x2e
,
0x5f
,
0x2c
,
0x24
,
0x96
,
0x27
,
0x64
,
0xf8
,
0x4d
,
0xdf
,
0x40
,
0x80
,
0x29
,
0x3d
,
0x70
,
0x74
,
0x00
,
0x9d
,
0x34
,
0xc3
,
0x83
,
0x01
,
0xeb
,
0xa4
,
0x19
,
0x7d
,
0x0b
,
0x01
,
0xcf
,
0x73
,
0xa1
,
0xc8
,
0x01
,
0x74
,
0xc5
,
0xad
,
0x88
,
0x6d
,
0x8f
,
0x42
,
0x66
,
0x2d
,
0x8d
,
0xe7
,
0xc5
,
0xea
,
0x2a
,
0x5d
,
0xda
,
0x68
,
0xd6
,
0xa2
,
0x3f
,
0x3d
,
0xe8
,
0xbb
,
0x0a
,
0x13
,
0x0a
,
0xc1
,
0x54
,
0x7b
,
0xb1
,
0xfd
,
0x75
,
0x35
,
0x42
,
0xcf
,
0xcc
,
0x50
,
0xe4
,
0x10
,
0xfe
,
0xbf
,
0x96
,
0xe9
,
0x6a
,
0x5a
,
0xe6
,
0x66
,
0xfc
,
0x35
,
0x41
,
0x32
,
0x86
,
0x3d
,
0x95
,
0x56
,
0x1a
,
0x1f
,
0x35
,
0x75
,
0x48
,
0x27
,
0xc4
,
0x57
,
0xfa
,
0x1b
,
0xdb
,
0xe7
,
0x33
,
0x6b
,
0xd1
,
0x53
,
0x08
,
0xcb
,
0x0e
,
0x92
,
0xe7
,
0x00
,
0xe5
,
0x9d
,
0xf3
,
0xc8
,
0x1b
,
0xfb
,
0x93
,
0x90
,
0xd5
,
0x90
,
0x3b
,
0x65
,
0xf8
,
0xed
,
0x41
,
0xcf
,
0xd2
,
0x8f
,
0xaf
,
0x3d
,
0x79
,
0x0a
,
0xfd
,
0x4c
,
0x8a
,
0xed
,
0x54
,
0xe3
,
0x26
,
0xe3
,
0xd2
,
0xc6
,
0xfa
,
0x29
,
0xae
,
0x36
,
0x39
,
0xa6
,
0x1b
,
0x30
,
0x6b
,
0xe9
,
0x0c
,
0x63
,
0x29
,
0xb8
,
0x12
,
0xf3
,
0x64
,
0x25
,
0x70
,
0xb6
,
0x7c
,
0x56
,
0x43
,
0x34
,
0x2f
,
0x6e
,
0xb3
,
0x44
,
0x1a
,
0xbe
,
0x6b
,
0xf8
,
0x0a
,
0xd1
,
0x31
,
0x97
,
0x69
,
0xfc
,
0x0d
,
0xd9
,
0x1e
,
0xb2
,
0xa5
,
0x4d
,
0x46
,
0x10
,
0x24
,
0xeb
,
0x85
,
0xb8
,
0x8d
,
0xfa
,
0x48
,
0x18
,
0x83
,
0xbe
,
0x2b
,
0x9f
,
0x2c
,
0x13
,
0xb1
,
0x48
,
0x32
,
0x45
,
0x26
,
0xe5
,
0xa5
,
0x6d
,
0xe3
,
0x06
,
0xae
,
0x71
,
0x56
,
0xe7
,
0x68
,
0xfa
,
0x15
,
0x86
,
0x4c
,
0x64
,
0xcb
,
0xc2
,
0x3a
,
0xf8
,
0x9c
,
0xe4
,
0x8a
,
0xbc
,
0x80
,
0xbe
,
0xa5
,
0x4d
,
0x85
,
0xef
,
0x1e
,
0x2f
,
0x79
,
0x7d
,
0x9b
,
0x4c
,
0x26
,
0x2b
,
0x2e
,
0x0b
,
0xf7
,
0xac
,
0x43
,
0x56
,
0x43
,
0xe8
,
0x0f
,
0x0f
,
0xf6
,
0xdd
,
0x34
,
0xb9
,
0xec
,
0x8e
,
0x61
,
0xef
,
0x63
,
0x35
,
0x1b
,
0xf7
,
0x64
,
0x58
,
0x97
,
0x90
,
0x97
,
0x10
,
0xce
,
0xdd
,
0xa4
,
0xd8
,
0xdd
,
0xd1
,
0xd6
,
0x57
,
0x82
,
0xaa
,
0x4a
,
0x7e
,
0xbd
,
0x4a
,
0x0b
,
0x18
,
0x96
,
0x63
,
0xe4
,
0x32
,
0x79
,
0xcc
,
0x4d
,
0x5b
,
0x93
,
0x75
,
0x4f
,
0x94
,
0x2d
,
0x8c
,
0xbe
,
0x6c
,
0x84
,
0x2c
,
0x3e
,
0x60
,
0x43
,
0x17
,
0xd3
,
0xbf
,
0xd7
,
0xc9
,
0x6b
,
0xd7
,
0x49
,
0x3f
,
0x0f
,
0x33
,
0x03
,
0x0b
,
0x6c
,
0x7c
,
0x07
,
0x7d
,
0xd6
,
0x21
,
0x3d
,
0xbd
,
0x8b
,
0x44
,
0x0a
,
0x5c
,
0xbd
,
0x18
,
0x33
,
0x60
,
0x15
,
0x40
,
0x57
,
0xf0
,
0x04
,
0xe3
,
0xba
,
0x80
,
0xb3
,
0xe2
,
0xd2
,
0x8c
,
0x63
,
0x35
,
0xa6
,
0x5e
,
0x7b
,
0x4c
,
0x6b
,
0x09
,
0xf9
,
0x77
,
0x12
,
0x6a
,
0x84
,
0x0b
,
0xda
,
0xe1
,
0x8e
,
0x61
,
0x58
,
0x0f
,
0x37
,
0x2b
,
0x2e
,
0xce
,
0x1e
,
0x58
,
0x82
,
0x13
,
0x20
,
0xcd
,
0x13
,
0xf8
,
0x88
,
0xdc
,
0xa3
,
0xf3
,
0x6a
,
0x0b
,
0x6f
,
0x6e
,
0x7d
,
0xcf
,
0xf8
,
0x92
,
0xaf
,
0x63
,
0xf1
,
0xb0
,
0x6f
,
0xbd
,
0xa5
,
0x70
,
0x23
,
0xd9
,
0xd1
,
0x68
,
0x6d
,
0x29
,
0xfc
,
0xa1
,
0xa7
,
0xd0
,
0xbb
,
0x32
,
0x0e
,
0x49
,
0x54
,
0x7e
,
0xa2
,
0x2b
,
0x9f
,
0x95
,
0xcc
,
0x01
,
0x74
,
0xaf
,
0x65
,
0xfa
,
0x5d
,
0xac
,
0x6d
,
0x03
,
0xac
,
0x75
,
0x32
,
0x84
,
0x41
,
0xf3
,
0x3f
,
0xf3
,
0xaa
,
0x8b
,
0x7f
,
0x9a
,
0xaf
,
0xff
,
0x04
,
0x00
,
0x00
,
0xff
,
0xff
,
0x71
,
0xbc
,
0x47
,
0xe4
,
0x4c
,
0x07
,
0x00
,
0x00
,
// 731 bytes of a gzipped FileDescriptorProto
0x1f
,
0x8b
,
0x08
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x02
,
0xff
,
0x94
,
0x55
,
0x4d
,
0x6b
,
0xdb
,
0x4c
,
0x10
,
0x8e
,
0xac
,
0xc8
,
0xb6
,
0x26
,
0xef
,
0xeb
,
0x98
,
0xc5
,
0x0d
,
0xa2
,
0x94
,
0x62
,
0x96
,
0x1c
,
0x4c
,
0x69
,
0x43
,
0x48
,
0x29
,
0x85
,
0xb6
,
0x17
,
0x9b
,
0xb4
,
0x24
,
0xb4
,
0x97
,
0x6c
,
0x7c
,
0x2e
,
0x28
,
0xf2
,
0x24
,
0x88
,
0xca
,
0x96
,
0x58
,
0xad
,
0x4d
,
0xd4
,
0x3f
,
0xd0
,
0x5b
,
0x4f
,
0xfd
,
0xaf
,
0xbd
,
0x96
,
0x9d
,
0x5d
,
0x7d
,
0x39
,
0x69
,
0x43
,
0x4e
,
0xda
,
0x79
,
0xe6
,
0xd9
,
0xf9
,
0xde
,
0x11
,
0x8c
,
0xc2
,
0x28
,
0x4a
,
0xd7
,
0x2b
,
0xb5
,
0x0c
,
0x57
,
0xe1
,
0x0d
,
0xca
,
0xa3
,
0x4c
,
0xa6
,
0x2a
,
0x65
,
0x9e
,
0x2a
,
0x32
,
0xcc
,
0xf9
,
0x10
,
0x06
,
0xd3
,
0x96
,
0x9a
,
0xff
,
0xea
,
0xc0
,
0xa8
,
0x0d
,
0x4d
,
0x23
,
0x15
,
0xa7
,
0x2b
,
0xf6
,
0x0a
,
0xfa
,
0x12
,
0x6f
,
0xe2
,
0x5c
,
0xa1
,
0x0c
,
0x9c
,
0xb1
,
0x33
,
0xd9
,
0x3b
,
0xd9
,
0x3f
,
0x22
,
0x23
,
0x47
,
0xc2
,
0xc2
,
0x67
,
0x3b
,
0xa2
,
0xa2
,
0x18
,
0x7a
,
0x8e
,
0xea
,
0x33
,
0x16
,
0x41
,
0x67
,
0x8b
,
0x6e
,
0x60
,
0x43
,
0x37
,
0x67
,
0x4d
,
0x57
,
0x32
,
0x5c
,
0xe5
,
0xd7
,
0x28
,
0x03
,
0xb7
,
0x45
,
0x9f
,
0x5b
,
0x58
,
0xd3
,
0x4b
,
0x0a
,
0x3b
,
0x06
,
0x3f
,
0x5f
,
0x67
,
0x28
,
0x37
,
0x71
,
0x8e
,
0xc1
,
0x2e
,
0xf1
,
0x87
,
0x96
,
0x7f
,
0x59
,
0xe2
,
0x67
,
0x3b
,
0xa2
,
0x26
,
0xb1
,
0x43
,
0xf0
,
0xc2
,
0x2c
,
0x4b
,
0x8a
,
0xc0
,
0x23
,
0xf6
,
0x7f
,
0x96
,
0x3d
,
0xd5
,
0xd8
,
0xd9
,
0x8e
,
0x30
,
0x4a
,
0x36
,
0x80
,
0x8e
,
0x2a
,
0x82
,
0xee
,
0xd8
,
0x99
,
0x78
,
0xa2
,
0xa3
,
0x8a
,
0x59
,
0x0f
,
0xbc
,
0x4d
,
0x98
,
0xac
,
0x91
,
0x4f
,
0xa0
,
0x5f
,
0xa6
,
0xc9
,
0x9e
,
0x81
,
0x6f
,
0x6b
,
0x7a
,
0x7e
,
0x4a
,
0xa5
,
0xf0
,
0x45
,
0x0d
,
0xf0
,
0x0f
,
0x9a
,
0x69
,
0xb3
,
0xfa
,
0x27
,
0x93
,
0x31
,
0xd8
,
0x0d
,
0x17
,
0x0b
,
0x49
,
0xe5
,
0xf1
,
0x05
,
0x9d
,
0xf9
,
0x1b
,
0xf0
,
0x28
,
0xa4
,
0x07
,
0xae
,
0x0e
,
0xa0
,
0x93
,
0x66
,
0x74
,
0xd1
,
0x13
,
0x9d
,
0x34
,
0xe3
,
0x6f
,
0xc1
,
0x0b
,
0xf3
,
0x1c
,
0x15
,
0x3b
,
0x80
,
0x2e
,
0xde
,
0x62
,
0x64
,
0x7b
,
0xe4
,
0x0b
,
0x2b
,
0x69
,
0x3c
,
0x2f
,
0x96
,
0x57
,
0x69
,
0x62
,
0xbd
,
0x59
,
0x89
,
0xff
,
0x74
,
0xa0
,
0x5f
,
0x56
,
0x98
,
0x71
,
0xf0
,
0xa6
,
0xda
,
0x8a
,
0xed
,
0x6f
,
0x59
,
0x23
,
0xb2
,
0x2c
,
0x8c
,
0x8a
,
0x1d
,
0xc2
,
0xff
,
0xd7
,
0x32
,
0x5d
,
0x4e
,
0xab
,
0xd8
,
0x8c
,
0xbd
,
0x36
,
0xc8
,
0xc6
,
0xb0
,
0xa7
,
0xd2
,
0x9a
,
0xe3
,
0x12
,
0xa7
,
0x09
,
0xe9
,
0x80
,
0xc2
,
0xa5
,
0x3e
,
0x53
,
0xfb
,
0x5c
,
0x61
,
0x25
,
0x7e
,
0x01
,
0x7e
,
0xd5
,
0x41
,
0xf6
,
0x1c
,
0xa0
,
0xca
,
0x39
,
0x0f
,
0x9c
,
0xb1
,
0x3b
,
0xf1
,
0x45
,
0x03
,
0xd9
,
0x2e
,
0x03
,
0x1b
,
0x81
,
0x97
,
0xe0
,
0x06
,
0x13
,
0x72
,
0xe8
,
0x09
,
0x23
,
0xf0
,
0xdf
,
0x0e
,
0xf4
,
0xec
,
0xa5
,
0xc7
,
0x77
,
0x84
,
0x3d
,
0x85
,
0x7e
,
0x26
,
0x71
,
0x33
,
0xd5
,
0xb8
,
0xc9
,
0xa3
,
0x92
,
0xa9
,
0xaa
,
0x2a
,
0x54
,
0xeb
,
0x9c
,
0x92
,
0xf0
,
0x84
,
0x95
,
0xea
,
0x38
,
0xbc
,
0x46
,
0x1c
,
0x3a
,
0x9b
,
0x48
,
0x62
,
0xa8
,
0x70
,
0x1e
,
0x2f
,
0x91
,
0x86
,
0xcc
,
0x15
,
0x0d
,
0x44
,
0xeb
,
0xf1
,
0x36
,
0x8b
,
0xa5
,
0xd1
,
0xf7
,
0x8c
,
0xbe
,
0x46
,
0x74
,
0x24
,
0x49
,
0x1a
,
0x7d
,
0x23
,
0x6d
,
0x9f
,
0xb4
,
0x95
,
0xac
,
0x3d
,
0xc6
,
0xab
,
0x05
,
0xde
,
0x06
,
0x3e
,
0x29
,
0x8c
,
0xc0
,
0xdf
,
0x55
,
0xcf
,
0x5b
,
0x60
,
0x84
,
0x71
,
0xa6
,
0xd8
,
0xa4
,
0x2a
,
0x85
,
0x6d
,
0xf2
,
0xa0
,
0x6c
,
0xb2
,
0xe5
,
0x95
,
0x6a
,
0xfe
,
0x15
,
0x86
,
0x02
,
0xb3
,
0xa4
,
0xb0
,
0x06
,
0xbe
,
0xc4
,
0xb9
,
0x62
,
0x2f
,
0xa0
,
0x6f
,
0xd5
,
0xa6
,
0x1b
,
0x77
,
0xaf
,
0x57
,
0x7a
,
0x9d
,
0x4d
,
0x26
,
0xe3
,
0x65
,
0x28
,
0x8b
,
0x72
,
0x05
,
0xf8
,
0xa2
,
0x81
,
0xf0
,
0x1f
,
0x0e
,
0xec
,
0x97
,
0x93
,
0x57
,
0x46
,
0x77
,
0x0c
,
0x7b
,
0x9f
,
0xea
,
0x39
,
0xfa
,
0x4b
,
0x84
,
0x4d
,
0x0a
,
0x7b
,
0x09
,
0xfe
,
0xbc
,
0x9c
,
0x2a
,
0xbb
,
0x67
,
0xb6
,
0xf9
,
0x35
,
0xa1
,
0xae
,
0x92
,
0xdb
,
0xac
,
0xd2
,
0x02
,
0x86
,
0xd5
,
0xc8
,
0x95
,
0x91
,
0x3c
,
0x26
,
0xd3
,
0x7b
,
0xa6
,
0xf0
,
0x1e
,
0x2f
,
0x1b
,
0x18
,
0x5d
,
0xac
,
0x51
,
0x16
,
0x1f
,
0xa9
,
0xa1
,
0x8b
,
0xe9
,
0xfd
,
0x75
,
0x72
,
0xb6
,
0xeb
,
0xa4
,
0x9f
,
0x92
,
0x99
,
0x81
,
0x05
,
0x35
,
0xbe
,
0x43
,
0x36
,
0x9b
,
0x90
,
0x9e
,
0xe9
,
0x45
,
0x2c
,
0x91
,
0xd6
,
0xb4
,
0x9d
,
0xfc
,
0x1a
,
0xe0
,
0x4b
,
0x78
,
0x42
,
0x7e
,
0x4b
,
0x87
,
0xb3
,
0xe2
,
0xd2
,
0x0c
,
0x69
,
0x3d
,
0xbc
,
0x4e
,
0x6b
,
0x78
,
0xdb
,
0x01
,
0xb9
,
0x77
,
0x02
,
0x6a
,
0xb9
,
0xf3
,
0xb6
,
0xdd
,
0x1d
,
0xc3
,
0xb0
,
0xe9
,
0x6e
,
0x56
,
0x9c
,
0x9f
,
0x3e
,
0xb0
,
0x30
,
0x27
,
0xc0
,
0xda
,
0x37
,
0xe8
,
0x69
,
0x95
,
0x4f
,
0xd1
,
0x69
,
0x2c
,
0xc7
,
0xb9
,
0xb5
,
0x3d
,
0x0b
,
0x93
,
0x70
,
0x15
,
0xe1
,
0xc3
,
0xb6
,
0xf5
,
0x46
,
0xa3
,
0xed
,
0x65
,
0x47
,
0x63
,
0x6b
,
0xa3
,
0xd1
,
0x87
,
0xbf
,
0x87
,
0xde
,
0x95
,
0x31
,
0xc8
,
0x82
,
0xea
,
0x48
,
0xa6
,
0x5c
,
0x51
,
0x69
,
0x0e
,
0xa0
,
0x7b
,
0x2d
,
0xd3
,
0xef
,
0xb8
,
0xb2
,
0x0d
,
0xb0
,
0xd2
,
0xc9
,
0x10
,
0x06
,
0xed
,
0xff
,
0xeb
,
0x55
,
0x97
,
0x7e
,
0xb0
,
0xaf
,
0xff
,
0x04
,
0x00
,
0x00
,
0xff
,
0xff
,
0x84
,
0x94
,
0xab
,
0xf2
,
0x78
,
0x07
,
0x00
,
0x00
,
}
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