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
711b2b26
Commit
711b2b26
authored
Dec 05, 2018
by
heyubin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add by hyb for multisig
parent
73a47016
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
134 additions
and
51 deletions
+134
-51
multisig.go
plugin/dapp/multisig/commands/multisig.go
+36
-25
action.go
plugin/dapp/multisig/executor/action.go
+27
-2
exec_test.go
plugin/dapp/multisig/executor/exec_test.go
+4
-2
query.go
plugin/dapp/multisig/executor/query.go
+11
-1
jrpc_channel_test.go
plugin/dapp/multisig/rpc/jrpc_channel_test.go
+22
-21
const.go
plugin/dapp/multisig/types/const.go
+32
-0
errors.go
plugin/dapp/multisig/types/errors.go
+2
-0
No files found.
plugin/dapp/multisig/commands/multisig.go
View file @
711b2b26
...
...
@@ -136,6 +136,12 @@ func createMultiSigAccTransfer(cmd *cobra.Command, args []string) {
execer
,
_
:=
cmd
.
Flags
()
.
GetString
(
"execer"
)
symbol
,
_
:=
cmd
.
Flags
()
.
GetString
(
"symbol"
)
err
:=
mty
.
IsAssetsInvalid
(
execer
,
symbol
)
if
err
!=
nil
{
fmt
.
Fprintln
(
os
.
Stderr
,
err
)
return
}
dailylimit
,
_
:=
cmd
.
Flags
()
.
GetFloat64
(
"daily_limit"
)
if
dailylimit
<
0
{
...
...
@@ -375,6 +381,13 @@ func createMultiSigAccDailyLimitModifyTransfer(cmd *cobra.Command, args []string
execer
,
_
:=
cmd
.
Flags
()
.
GetString
(
"execer"
)
symbol
,
_
:=
cmd
.
Flags
()
.
GetString
(
"symbol"
)
dailylimit
,
_
:=
cmd
.
Flags
()
.
GetFloat64
(
"daily_limit"
)
err
:=
mty
.
IsAssetsInvalid
(
execer
,
symbol
)
if
err
!=
nil
{
fmt
.
Fprintln
(
os
.
Stderr
,
err
)
return
}
if
dailylimit
<
0
{
fmt
.
Fprintln
(
os
.
Stderr
,
"DailyLimitLessThanZero"
)
return
...
...
@@ -475,6 +488,11 @@ func createMultiSigAccTransferIn(cmd *cobra.Command, args []string) {
note
,
_
:=
cmd
.
Flags
()
.
GetString
(
"note"
)
amount
,
_
:=
cmd
.
Flags
()
.
GetFloat64
(
"amount"
)
err
:=
mty
.
IsAssetsInvalid
(
execer
,
symbol
)
if
err
!=
nil
{
fmt
.
Fprintln
(
os
.
Stderr
,
err
)
return
}
params
:=
&
mty
.
MultiSigExecTransfer
{
Symbol
:
symbol
,
Amount
:
int64
(
math
.
Trunc
((
amount
+
0.0000001
)
*
1e4
))
*
1e4
,
...
...
@@ -529,6 +547,11 @@ func createMultiSigAccTransferOut(cmd *cobra.Command, args []string) {
note
,
_
:=
cmd
.
Flags
()
.
GetString
(
"note"
)
amount
,
_
:=
cmd
.
Flags
()
.
GetFloat64
(
"amount"
)
err
:=
mty
.
IsAssetsInvalid
(
execer
,
symbol
)
if
err
!=
nil
{
fmt
.
Fprintln
(
os
.
Stderr
,
err
)
return
}
params
:=
&
mty
.
MultiSigExecTransfer
{
Symbol
:
symbol
,
Amount
:
int64
(
math
.
Trunc
((
amount
+
0.0000001
)
*
1e4
))
*
1e4
,
...
...
@@ -882,8 +905,6 @@ func getMultiSigAccUnSpentTodayFlags(cmd *cobra.Command) {
cmd
.
Flags
()
.
StringP
(
"execer"
,
"e"
,
""
,
"assets execer name"
)
cmd
.
Flags
()
.
StringP
(
"symbol"
,
"s"
,
""
,
"assets symbol"
)
cmd
.
Flags
()
.
StringP
(
"isall"
,
"i"
,
"t"
,
"whether get all assets (0/f/false for No; 1/t/true for Yes)"
)
}
func
getMultiSigAccUnSpentToday
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
...
...
@@ -892,21 +913,18 @@ func getMultiSigAccUnSpentToday(cmd *cobra.Command, args []string) {
execer
,
_
:=
cmd
.
Flags
()
.
GetString
(
"execer"
)
symbol
,
_
:=
cmd
.
Flags
()
.
GetString
(
"symbol"
)
isall
,
_
:=
cmd
.
Flags
()
.
GetString
(
"isall"
)
isallBool
,
err
:=
strconv
.
ParseBool
(
isall
)
if
err
!=
nil
{
fmt
.
Fprintln
(
os
.
Stderr
,
err
)
return
}
isallBool
:=
true
assets
:=
&
mty
.
Assets
{}
//获取指定资产信息时,execer和symbol不能为空
if
!
isallBool
{
if
len
(
execer
)
==
0
||
len
(
symbol
)
==
0
{
fmt
.
Fprintln
(
os
.
Stderr
,
"input execer or symbol parameter invalid!"
)
if
len
(
execer
)
!=
0
&&
len
(
symbol
)
!=
0
{
err
:=
mty
.
IsAssetsInvalid
(
execer
,
symbol
)
if
err
!=
nil
{
fmt
.
Fprintln
(
os
.
Stderr
,
err
)
return
}
assets
.
Execer
=
execer
assets
.
Symbol
=
symbol
isallBool
=
false
}
req
:=
mty
.
ReqAccAssets
{
...
...
@@ -959,11 +977,7 @@ func getMultiSigAccAssetsFlags(cmd *cobra.Command) {
cmd
.
MarkFlagRequired
(
"addr"
)
cmd
.
Flags
()
.
StringP
(
"execer"
,
"e"
,
"coins"
,
"assets execer name "
)
cmd
.
Flags
()
.
StringP
(
"symbol"
,
"s"
,
"bty"
,
"assets symbol"
)
cmd
.
Flags
()
.
StringP
(
"isall"
,
"i"
,
"t"
,
"whether get all assets (0/f/false for No; 1/t/true for Yes)"
)
cmd
.
Flags
()
.
StringP
(
"symbol"
,
"s"
,
"BTY"
,
"assets symbol"
)
}
func
getMultiSigAccAssets
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
...
...
@@ -972,21 +986,18 @@ func getMultiSigAccAssets(cmd *cobra.Command, args []string) {
execer
,
_
:=
cmd
.
Flags
()
.
GetString
(
"execer"
)
symbol
,
_
:=
cmd
.
Flags
()
.
GetString
(
"symbol"
)
isall
,
_
:=
cmd
.
Flags
()
.
GetString
(
"isall"
)
isallBool
,
err
:=
strconv
.
ParseBool
(
isall
)
if
err
!=
nil
{
fmt
.
Fprintln
(
os
.
Stderr
,
err
)
return
}
isallBool
:=
true
assets
:=
&
mty
.
Assets
{}
//获取指定资产信息时,execer和symbol不能为空
if
!
isallBool
{
if
len
(
execer
)
==
0
||
len
(
symbol
)
==
0
{
fmt
.
Fprintln
(
os
.
Stderr
,
"input execer or symbol parameter invalid!"
)
if
len
(
execer
)
!=
0
&&
len
(
symbol
)
!=
0
{
err
:=
mty
.
IsAssetsInvalid
(
execer
,
symbol
)
if
err
!=
nil
{
fmt
.
Fprintln
(
os
.
Stderr
,
err
)
return
}
assets
.
Execer
=
execer
assets
.
Symbol
=
symbol
isallBool
=
false
}
req
:=
mty
.
ReqAccAssets
{
...
...
plugin/dapp/multisig/executor/action.go
View file @
711b2b26
...
...
@@ -78,8 +78,14 @@ func (a *action) MultiSigAccCreate(accountCreate *mty.MultiSigAccCreate) (*types
//获取资产的每日限额设置
if
accountCreate
.
DailyLimit
!=
nil
{
dailyLimit
.
Symbol
=
accountCreate
.
DailyLimit
.
Symbol
dailyLimit
.
Execer
=
accountCreate
.
DailyLimit
.
Execer
symbol
:=
accountCreate
.
DailyLimit
.
Symbol
execer
:=
accountCreate
.
DailyLimit
.
Execer
err
:=
mty
.
IsAssetsInvalid
(
execer
,
symbol
)
if
err
!=
nil
{
return
nil
,
err
}
dailyLimit
.
Symbol
=
symbol
dailyLimit
.
Execer
=
execer
dailyLimit
.
DailyLimit
=
accountCreate
.
DailyLimit
.
DailyLimit
dailyLimit
.
SpentToday
=
0
dailyLimit
.
LastDay
=
a
.
blocktime
//types.Now().Unix()
...
...
@@ -132,6 +138,15 @@ func (a *action) MultiSigAccOperate(AccountOperate *mty.MultiSigAccOperate) (*ty
return
nil
,
mty
.
ErrIsNotOwner
}
//dailylimit每日限额属性的修改需要校验assets资产的合法性
if
!
AccountOperate
.
OperateFlag
{
execer
:=
AccountOperate
.
DailyLimit
.
Execer
symbol
:=
AccountOperate
.
DailyLimit
.
Symbol
err
:=
mty
.
IsAssetsInvalid
(
execer
,
symbol
)
if
err
!=
nil
{
return
nil
,
err
}
}
//生成新的txid,并将此交易信息添加到Txs列表中
txId
:=
multiSigAccount
.
TxCount
newMultiSigTx
:=
&
mty
.
MultiSigTx
{}
...
...
@@ -210,6 +225,11 @@ func (a *action) MultiSigExecTransferFrom(multiSigAccTransfer *mty.MultiSigExecT
return
nil
,
mty
.
ErrIsNotOwner
}
//assete资产合法性校验
err
=
mty
.
IsAssetsInvalid
(
multiSigAccTransfer
.
Execname
,
multiSigAccTransfer
.
Symbol
)
if
err
!=
nil
{
return
nil
,
err
}
//生成新的txid,并将此交易信息添加到Txs列表中
txId
:=
multiSigAcc
.
TxCount
newMultiSigTx
:=
&
mty
.
MultiSigTx
{}
...
...
@@ -241,6 +261,11 @@ func (a *action) MultiSigExecTransferTo(execTransfer *mty.MultiSigExecTransfer)
multisiglog
.
Error
(
"MultiSigExecTransferTo"
,
"ToAddr"
,
execTransfer
.
To
)
return
nil
,
mty
.
ErrAddrNotSupport
}
//assete资产合法性校验
err
:=
mty
.
IsAssetsInvalid
(
execTransfer
.
Execname
,
execTransfer
.
Symbol
)
if
err
!=
nil
{
return
nil
,
err
}
//将指定账户上的资产从balance转账到多重签名账户的balance上
symbol
:=
getRealSymbol
(
execTransfer
.
Symbol
)
...
...
plugin/dapp/multisig/executor/exec_test.go
View file @
711b2b26
...
...
@@ -30,7 +30,7 @@ type execEnv struct {
}
var
(
Symbol
=
"
bty
"
Symbol
=
"
BTY
"
Asset
=
"coins"
PrivKeyA
=
"0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b"
// 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4
...
...
@@ -57,6 +57,8 @@ var (
func
init
()
{
commonlog
.
SetLogLevel
(
"debug"
)
types
.
AllowUserExec
=
append
(
types
.
AllowUserExec
,
[]
byte
(
"coins"
))
}
//创建一个多重签名的账户
...
...
@@ -155,7 +157,7 @@ func testMultiSigAccCreate(t *testing.T, driver drivers.Driver, env execEnv, loc
owners
=
append
(
owners
,
owmer2
)
symboldailylimit
:=
&
mty
.
SymbolDailyLimit
{
Symbol
:
"bty"
,
Symbol
:
Symbol
,
Execer
:
"coins"
,
DailyLimit
:
CoinsBtyDailylimit
,
}
...
...
plugin/dapp/multisig/executor/query.go
View file @
711b2b26
...
...
@@ -247,6 +247,12 @@ func (m *MultiSig) Query_MultiSigAccUnSpentToday(in *mty.ReqAccAssets) (types.Me
replyUnSpentAssets
.
UnSpentAssets
=
append
(
replyUnSpentAssets
.
UnSpentAssets
,
&
unSpentAssets
)
}
}
else
{
//assets资产合法性校验
err
:=
mty
.
IsAssetsInvalid
(
in
.
Assets
.
Execer
,
in
.
Assets
.
Symbol
)
if
err
!=
nil
{
return
nil
,
err
}
for
_
,
dailyLimit
:=
range
multiSigAcc
.
DailyLimits
{
var
unSpentAssets
mty
.
UnSpentAssets
...
...
@@ -310,7 +316,11 @@ func (m *MultiSig) Query_MultiSigAccAssets(in *mty.ReqAccAssets) (types.Message,
}
}
else
{
//获取账户上的指定资产数据
accAssets
:=
&
mty
.
AccAssets
{}
//assets资产合法性校验
err
:=
mty
.
IsAssetsInvalid
(
in
.
Assets
.
Execer
,
in
.
Assets
.
Symbol
)
if
err
!=
nil
{
return
nil
,
err
}
account
,
_
:=
m
.
getMultiSigAccAssets
(
in
.
MultiSigAddr
,
in
.
Assets
)
accAssets
.
Account
=
account
accAssets
.
Assets
=
in
.
Assets
...
...
plugin/dapp/multisig/rpc/jrpc_channel_test.go
View file @
711b2b26
...
...
@@ -14,6 +14,7 @@ import (
mty
"github.com/33cn/plugin/plugin/dapp/multisig/types"
"github.com/stretchr/testify/assert"
// 注册system和plugin 包
rpctypes
"github.com/33cn/chain33/rpc/types"
_
"github.com/33cn/chain33/system"
_
"github.com/33cn/plugin/plugin"
)
...
...
@@ -30,7 +31,7 @@ func TestJRPCChannel(t *testing.T) {
}()
mocker
.
Listen
()
jrpcClient
:=
mocker
.
GetJ
son
C
()
jrpcClient
:=
mocker
.
GetJ
SON
C
()
testCases
:=
[]
struct
{
fn
func
(
*
testing
.
T
,
*
jsonclient
.
JSONClient
)
error
...
...
@@ -115,50 +116,50 @@ func testCreateMultiSigAccTransferOutCmd(t *testing.T, jrpc *jsonclient.JSONClie
//get 多重签名账户信息
func
testGetMultiSigAccCountCmd
(
t
*
testing
.
T
,
jrpc
*
jsonclient
.
JSONClient
)
error
{
params
:=
types
.
Query4Cli
{
params
:=
rpctypes
.
Query4Jrpc
{
Execer
:
mty
.
MultiSigX
,
FuncName
:
"MultiSigAccCount"
,
Payload
:
types
.
ReqNil
{}
,
Payload
:
types
.
MustPBToJSON
(
&
types
.
ReqNil
{})
,
}
var
res
types
.
Int64
return
jrpc
.
Call
(
"Chain33.Query"
,
params
,
&
res
)
}
func
testGetMultiSigAccountsCmd
(
t
*
testing
.
T
,
jrpc
*
jsonclient
.
JSONClient
)
error
{
params
:=
types
.
Query4Cli
{
params
:=
rpctypes
.
Query4Jrpc
{
Execer
:
mty
.
MultiSigX
,
FuncName
:
"MultiSigAccounts"
,
Payload
:
mty
.
ReqMultiSigAccs
{}
,
Payload
:
types
.
MustPBToJSON
(
&
mty
.
ReqMultiSigAccs
{})
,
}
var
res
mty
.
ReplyMultiSigAccs
return
jrpc
.
Call
(
"Chain33.Query"
,
params
,
&
res
)
}
func
testGetMultiSigAccountInfoCmd
(
t
*
testing
.
T
,
jrpc
*
jsonclient
.
JSONClient
)
error
{
params
:=
types
.
Query4Cli
{
params
:=
rpctypes
.
Query4Jrpc
{
Execer
:
mty
.
MultiSigX
,
FuncName
:
"MultiSigAccountInfo"
,
Payload
:
mty
.
ReqMultiSigAccInfo
{}
,
Payload
:
types
.
MustPBToJSON
(
&
mty
.
ReqMultiSigAccInfo
{})
,
}
var
res
mty
.
MultiSig
return
jrpc
.
Call
(
"Chain33.Query"
,
params
,
&
res
)
}
func
testGetMultiSigAccTxCountCmd
(
t
*
testing
.
T
,
jrpc
*
jsonclient
.
JSONClient
)
error
{
params
:=
types
.
Query4Cli
{
params
:=
rpctypes
.
Query4Jrpc
{
Execer
:
mty
.
MultiSigX
,
FuncName
:
"MultiSigAccTxCount"
,
Payload
:
mty
.
ReqMultiSigAccInfo
{}
,
Payload
:
types
.
MustPBToJSON
(
&
mty
.
ReqMultiSigAccInfo
{})
,
}
var
res
mty
.
Uint64
return
jrpc
.
Call
(
"Chain33.Query"
,
params
,
&
res
)
}
func
testGetMultiSigTxidsCmd
(
t
*
testing
.
T
,
jrpc
*
jsonclient
.
JSONClient
)
error
{
params
:=
types
.
Query4Cli
{
params
:=
rpctypes
.
Query4Jrpc
{
Execer
:
mty
.
MultiSigX
,
FuncName
:
"MultiSigTxids"
,
Payload
:
mty
.
ReqMultiSigTxids
{}
,
Payload
:
types
.
MustPBToJSON
(
&
mty
.
ReqMultiSigTxids
{})
,
}
var
res
mty
.
ReplyMultiSigTxids
return
jrpc
.
Call
(
"Chain33.Query"
,
params
,
&
res
)
...
...
@@ -166,54 +167,54 @@ func testGetMultiSigTxidsCmd(t *testing.T, jrpc *jsonclient.JSONClient) error {
func
testGetMultiSigTxInfoCmd
(
t
*
testing
.
T
,
jrpc
*
jsonclient
.
JSONClient
)
error
{
var
rep
interface
{}
var
params
types
.
Query4Cli
var
params
rpctypes
.
Query4Jrpc
req
:=
&
mty
.
ReqMultiSigTxInfo
{}
params
.
Execer
=
mty
.
MultiSigX
params
.
FuncName
=
"MultiSigTxInfo"
params
.
Payload
=
req
params
.
Payload
=
types
.
MustPBToJSON
(
req
)
rep
=
&
mty
.
MultiSigTx
{}
return
jrpc
.
Call
(
"Chain33.Query"
,
params
,
rep
)
}
func
testGetGetMultiSigTxConfirmedWeightCmd
(
t
*
testing
.
T
,
jrpc
*
jsonclient
.
JSONClient
)
error
{
var
rep
interface
{}
var
params
types
.
Query4Cli
var
params
rpctypes
.
Query4Jrpc
req
:=
&
mty
.
ReqMultiSigTxInfo
{}
params
.
Execer
=
mty
.
MultiSigX
params
.
FuncName
=
"MultiSigTxConfirmedWeight"
params
.
Payload
=
req
params
.
Payload
=
types
.
MustPBToJSON
(
req
)
rep
=
&
mty
.
Uint64
{}
return
jrpc
.
Call
(
"Chain33.Query"
,
params
,
rep
)
}
func
testGetGetMultiSigAccUnSpentTodayCmd
(
t
*
testing
.
T
,
jrpc
*
jsonclient
.
JSONClient
)
error
{
var
rep
interface
{}
var
params
types
.
Query4Cli
var
params
rpctypes
.
Query4Jrpc
req
:=
&
mty
.
ReqAccAssets
{}
req
.
IsAll
=
true
params
.
Execer
=
mty
.
MultiSigX
params
.
FuncName
=
"MultiSigAccUnSpentToday"
params
.
Payload
=
req
params
.
Payload
=
types
.
MustPBToJSON
(
req
)
rep
=
&
mty
.
ReplyUnSpentAssets
{}
return
jrpc
.
Call
(
"Chain33.Query"
,
params
,
rep
)
}
func
testGetMultiSigAccAssetsCmd
(
t
*
testing
.
T
,
jrpc
*
jsonclient
.
JSONClient
)
error
{
var
rep
interface
{}
var
params
types
.
Query4Cli
var
params
rpctypes
.
Query4Jrpc
req
:=
&
mty
.
ReqAccAssets
{}
req
.
IsAll
=
true
params
.
Execer
=
mty
.
MultiSigX
params
.
FuncName
=
"MultiSigAccAssets"
params
.
Payload
=
req
params
.
Payload
=
types
.
MustPBToJSON
(
req
)
rep
=
&
mty
.
ReplyAccAssets
{}
return
jrpc
.
Call
(
"Chain33.Query"
,
params
,
rep
)
}
func
testGetMultiSigAccAllAddressCmd
(
t
*
testing
.
T
,
jrpc
*
jsonclient
.
JSONClient
)
error
{
var
rep
interface
{}
var
params
types
.
Query4Cli
var
params
rpctypes
.
Query4Jrpc
req
:=
mty
.
ReqMultiSigAccInfo
{
MultiSigAccAddr
:
"14jv8WB7CwNQSnh4qo9WDBgRPRBjM5LQo6"
,
...
...
@@ -221,7 +222,7 @@ func testGetMultiSigAccAllAddressCmd(t *testing.T, jrpc *jsonclient.JSONClient)
params
.
Execer
=
mty
.
MultiSigX
params
.
FuncName
=
"MultiSigAccAllAddress"
params
.
Payload
=
req
params
.
Payload
=
types
.
MustPBToJSON
(
&
req
)
rep
=
&
mty
.
AccAddress
{}
return
jrpc
.
Call
(
"Chain33.Query"
,
params
,
rep
)
}
plugin/dapp/multisig/types/const.go
View file @
711b2b26
...
...
@@ -4,9 +4,14 @@
package
types
import
(
"strings"
"github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/types"
)
var
multisiglog
=
log15
.
New
(
"module"
,
"execs.multisig"
)
var
(
//OwnerAdd owner操作类型
OwnerAdd
uint64
=
1
...
...
@@ -101,3 +106,30 @@ type UnSpentAssetsResult struct {
Execer
string
`json:"execer,omitempty"`
UnSpent
string
`json:"unspent,omitempty"`
}
//IsAssetsInvalid 资产的合法性检测,Symbol:必须全部大写,例如:BTY,coins.BTY。exec:必须在types.AllowUserExec中存在
func
IsAssetsInvalid
(
exec
,
symbol
string
)
error
{
//exec检测
allowExeName
:=
types
.
AllowUserExec
nameLen
:=
len
(
allowExeName
)
execValid
:=
false
for
i
:=
0
;
i
<
nameLen
;
i
++
{
if
exec
==
string
(
allowExeName
[
i
])
{
execValid
=
true
break
}
}
if
!
execValid
{
multisiglog
.
Error
(
"IsAssetsInvalid"
,
"exec"
,
exec
)
return
ErrInvalidExec
}
//Symbol检测
symbolstr
:=
strings
.
Split
(
symbol
,
"."
)[
len
(
strings
.
Split
(
symbol
,
"."
))
-
1
]
upperSymbol
:=
strings
.
ToUpper
(
symbolstr
)
if
symbolstr
!=
upperSymbol
{
multisiglog
.
Error
(
"IsAssetsInvalid"
,
"symbol"
,
symbol
)
return
ErrInvalidSymbol
}
return
nil
}
plugin/dapp/multisig/types/errors.go
View file @
711b2b26
...
...
@@ -36,4 +36,6 @@ var (
ErrOwnerLessThanTwo
=
errors
.
New
(
"ErrOwnerLessThanTwo"
)
ErrAddrNotSupport
=
errors
.
New
(
"ErrAddrNotSupport"
)
ErrMaxOwnerCount
=
errors
.
New
(
"ErrMaxOwnerCount"
)
ErrInvalidSymbol
=
errors
.
New
(
"ErrInvalidSymbol"
)
ErrInvalidExec
=
errors
.
New
(
"ErrInvalidExec"
)
)
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