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
5226c257
Commit
5226c257
authored
Dec 30, 2020
by
jiangpeng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add dapp vote
parent
2983a997
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
1766 additions
and
0 deletions
+1766
-0
go.sum
go.sum
+0
-0
init.go
plugin/dapp/init/init.go
+1
-0
Makefile
plugin/dapp/vote/cmd/Makefile
+2
-0
build.sh
plugin/dapp/vote/cmd/build.sh
+11
-0
commands.go
plugin/dapp/vote/commands/commands.go
+75
-0
createtx.go
plugin/dapp/vote/commands/createtx.go
+197
-0
query.go
plugin/dapp/vote/commands/query.go
+154
-0
action.go
plugin/dapp/vote/executor/action.go
+156
-0
checktx.go
plugin/dapp/vote/executor/checktx.go
+161
-0
errors.go
plugin/dapp/vote/executor/errors.go
+24
-0
exec.go
plugin/dapp/vote/executor/exec.go
+31
-0
exec_del_local.go
plugin/dapp/vote/executor/exec_del_local.go
+20
-0
exec_local.go
plugin/dapp/vote/executor/exec_local.go
+211
-0
key.go
plugin/dapp/vote/executor/key.go
+19
-0
query.go
plugin/dapp/vote/executor/query.go
+152
-0
table.go
plugin/dapp/vote/executor/table.go
+132
-0
util.go
plugin/dapp/vote/executor/util.go
+78
-0
vote.go
plugin/dapp/vote/executor/vote.go
+52
-0
plugin.go
plugin/dapp/vote/plugin.go
+23
-0
Makefile
plugin/dapp/vote/proto/Makefile
+2
-0
create_protobuf.sh
plugin/dapp/vote/proto/create_protobuf.sh
+4
-0
vote.proto
plugin/dapp/vote/proto/vote.proto
+117
-0
rpc.go
plugin/dapp/vote/rpc/rpc.go
+7
-0
types.go
plugin/dapp/vote/rpc/types.go
+31
-0
vote.go
plugin/dapp/vote/types/vote.go
+106
-0
vote.pb.go
plugin/dapp/vote/types/vote.pb.go
+0
-0
No files found.
go.sum
View file @
5226c257
This diff is collapsed.
Click to expand it.
plugin/dapp/init/init.go
View file @
5226c257
...
...
@@ -30,6 +30,7 @@ import (
_
"github.com/33cn/plugin/plugin/dapp/trade"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/unfreeze"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/valnode"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/vote"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/wasm"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/x2ethereum"
//auto gen
)
plugin/dapp/vote/cmd/Makefile
0 → 100644
View file @
5226c257
all
:
bash build.sh
$(OUT)
$(FLAG)
plugin/dapp/vote/cmd/build.sh
0 → 100644
View file @
5226c257
#!/bin/bash
# 官方ci集成脚本
strpwd
=
$(
pwd
)
strcmd
=
${
strpwd
##*dapp/
}
strapp
=
${
strcmd
%/cmd*
}
OUT_DIR
=
"
${
1
}
/
$strapp
"
#FLAG=$2
mkdir
-p
"
${
OUT_DIR
}
"
cp
./build/
*
"
${
OUT_DIR
}
"
plugin/dapp/vote/commands/commands.go
0 → 100644
View file @
5226c257
/*Package commands implement dapp client commands*/
package
commands
import
(
jsonrpc
"github.com/33cn/chain33/rpc/jsonclient"
rpctypes
"github.com/33cn/chain33/rpc/types"
"github.com/33cn/chain33/types"
vty
"github.com/33cn/plugin/plugin/dapp/vote/types"
"github.com/spf13/cobra"
)
/*
* 实现合约对应客户端
*/
// Cmd vote client command
func
Cmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"vote"
,
Short
:
"vote command"
,
Args
:
cobra
.
MinimumNArgs
(
1
),
}
cmd
.
AddCommand
(
//create tx
createGroupCMD
(),
updateMemberCMD
(),
createVoteCMD
(),
commitVoteCMD
(),
//query rpc
groupInfoCMD
(),
voteInfoCMD
(),
memberInfoCMD
(),
listGroupCMD
(),
listVoteCMD
(),
listMemberCMD
(),
)
return
cmd
}
func
markRequired
(
cmd
*
cobra
.
Command
,
params
...
string
)
{
for
_
,
param
:=
range
params
{
_
=
cmd
.
MarkFlagRequired
(
param
)
}
}
func
sendCreateTxRPC
(
cmd
*
cobra
.
Command
,
actionName
string
,
req
types
.
Message
)
{
title
,
_
:=
cmd
.
Flags
()
.
GetString
(
"title"
)
cfg
:=
types
.
GetCliSysParam
(
title
)
rpcAddr
,
_
:=
cmd
.
Flags
()
.
GetString
(
"rpc_laddr"
)
payLoad
:=
types
.
MustPBToJSON
(
req
)
pm
:=
&
rpctypes
.
CreateTxIn
{
Execer
:
cfg
.
ExecName
(
vty
.
VoteX
),
ActionName
:
actionName
,
Payload
:
payLoad
,
}
var
res
string
ctx
:=
jsonrpc
.
NewRPCCtx
(
rpcAddr
,
"Chain33.CreateTransaction"
,
pm
,
&
res
)
ctx
.
RunWithoutMarshal
()
}
func
sendQueryRPC
(
cmd
*
cobra
.
Command
,
funcName
string
,
req
,
reply
types
.
Message
)
{
title
,
_
:=
cmd
.
Flags
()
.
GetString
(
"title"
)
cfg
:=
types
.
GetCliSysParam
(
title
)
rpcAddr
,
_
:=
cmd
.
Flags
()
.
GetString
(
"rpc_laddr"
)
payLoad
:=
types
.
MustPBToJSON
(
req
)
query
:=
&
rpctypes
.
Query4Jrpc
{
Execer
:
cfg
.
ExecName
(
vty
.
VoteX
),
FuncName
:
funcName
,
Payload
:
payLoad
,
}
ctx
:=
jsonrpc
.
NewRPCCtx
(
rpcAddr
,
"Chain33.Query"
,
query
,
reply
)
ctx
.
Run
()
}
plugin/dapp/vote/commands/createtx.go
0 → 100644
View file @
5226c257
package
commands
import
(
"fmt"
"os"
"github.com/33cn/chain33/types"
vty
"github.com/33cn/plugin/plugin/dapp/vote/types"
"github.com/spf13/cobra"
)
func
createGroupCMD
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"createGroup"
,
Short
:
"create tx(create vote group)"
,
Run
:
createGroup
,
Example
:
"createGroup -n=group1 -a=admin1 -m=member1 -m=member2"
,
}
createGroupFlags
(
cmd
)
return
cmd
}
func
createGroupFlags
(
cmd
*
cobra
.
Command
)
{
cmd
.
Flags
()
.
StringP
(
"name"
,
"n"
,
""
,
"group name"
)
cmd
.
Flags
()
.
StringArrayP
(
"admins"
,
"a"
,
nil
,
"group admin address array"
)
cmd
.
Flags
()
.
StringArrayP
(
"members"
,
"m"
,
nil
,
"group member address array"
)
cmd
.
Flags
()
.
UintSliceP
(
"weights"
,
"w"
,
nil
,
"member vote weight array"
)
markRequired
(
cmd
,
"name"
)
}
func
createGroup
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
name
,
_
:=
cmd
.
Flags
()
.
GetString
(
"name"
)
admins
,
_
:=
cmd
.
Flags
()
.
GetStringArray
(
"admins"
)
memberAddrs
,
_
:=
cmd
.
Flags
()
.
GetStringArray
(
"members"
)
weights
,
_
:=
cmd
.
Flags
()
.
GetUintSlice
(
"weights"
)
if
name
==
""
{
fmt
.
Fprintf
(
os
.
Stderr
,
"ErrNilGroupName"
)
}
if
len
(
weights
)
==
0
{
weights
=
make
([]
uint
,
len
(
memberAddrs
))
}
if
len
(
weights
)
!=
len
(
memberAddrs
)
{
fmt
.
Fprintf
(
os
.
Stderr
,
"member address array length should equal with vote weight array length"
)
}
members
:=
make
([]
*
vty
.
GroupMember
,
0
)
for
i
,
addr
:=
range
memberAddrs
{
members
=
append
(
members
,
&
vty
.
GroupMember
{
Addr
:
addr
,
VoteWeight
:
uint32
(
weights
[
i
])})
}
params
:=
&
vty
.
CreateGroup
{
Name
:
name
,
Admins
:
admins
,
Members
:
members
,
}
sendCreateTxRPC
(
cmd
,
vty
.
NameCreateGroupAction
,
params
)
}
func
updateMemberCMD
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"updateMember"
,
Short
:
"create tx(update group members)"
,
Run
:
updateMember
,
Example
:
"updateMember -g=id -a=addMember1 -a=addMember2 -r=removeMember1 ..."
,
}
updateMemberFlags
(
cmd
)
return
cmd
}
func
updateMemberFlags
(
cmd
*
cobra
.
Command
)
{
cmd
.
Flags
()
.
StringP
(
"groupID"
,
"g"
,
""
,
"group id"
)
cmd
.
Flags
()
.
StringArrayP
(
"addMembers"
,
"a"
,
nil
,
"group member address array for adding"
)
cmd
.
Flags
()
.
UintSliceP
(
"weights"
,
"w"
,
nil
,
"member vote weight array for adding"
)
cmd
.
Flags
()
.
StringArrayP
(
"removeMembers"
,
"r"
,
nil
,
"group member address array for removing"
)
markRequired
(
cmd
,
"groupID"
)
}
func
updateMember
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
groupID
,
_
:=
cmd
.
Flags
()
.
GetString
(
"groupID"
)
addAddrs
,
_
:=
cmd
.
Flags
()
.
GetStringArray
(
"addMembers"
)
weights
,
_
:=
cmd
.
Flags
()
.
GetUintSlice
(
"weights"
)
removeAddrs
,
_
:=
cmd
.
Flags
()
.
GetStringArray
(
"removeMembers"
)
if
groupID
==
""
{
fmt
.
Fprintf
(
os
.
Stderr
,
"ErrNilGroupID"
)
}
if
len
(
weights
)
==
0
{
weights
=
make
([]
uint
,
len
(
addAddrs
))
}
if
len
(
weights
)
!=
len
(
addAddrs
)
{
fmt
.
Fprintf
(
os
.
Stderr
,
"member address array length should equal with vote weight array length"
)
}
addMembers
:=
make
([]
*
vty
.
GroupMember
,
0
)
for
i
,
addr
:=
range
addAddrs
{
addMembers
=
append
(
addMembers
,
&
vty
.
GroupMember
{
Addr
:
addr
,
VoteWeight
:
uint32
(
weights
[
i
])})
}
params
:=
&
vty
.
UpdateMember
{
GroupID
:
groupID
,
RemoveMemberAddrs
:
removeAddrs
,
AddMembers
:
addMembers
,
}
sendCreateTxRPC
(
cmd
,
vty
.
NameUpdateMemberAction
,
params
)
}
func
createVoteCMD
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"createVote"
,
Short
:
"create tx(create vote)"
,
Run
:
createVote
,
}
createVoteFlags
(
cmd
)
return
cmd
}
func
createVoteFlags
(
cmd
*
cobra
.
Command
)
{
cmd
.
Flags
()
.
StringP
(
"name"
,
"n"
,
""
,
"vote name"
)
cmd
.
Flags
()
.
StringArrayP
(
"groupIDs"
,
"g"
,
nil
,
"related group id array"
)
cmd
.
Flags
()
.
StringArrayP
(
"options"
,
"o"
,
nil
,
"vote option array"
)
cmd
.
Flags
()
.
Int64P
(
"beginTime"
,
"b"
,
0
,
"vote begin unix timestamp, default set now time"
)
cmd
.
Flags
()
.
Int64P
(
"endTime"
,
"e"
,
0
,
"vote end unix timestamp, default set beginTime + 300 seconds"
)
markRequired
(
cmd
,
"name"
,
"groupIDs"
,
"options"
)
}
func
createVote
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
name
,
_
:=
cmd
.
Flags
()
.
GetString
(
"name"
)
groupIDs
,
_
:=
cmd
.
Flags
()
.
GetStringArray
(
"groupIDs"
)
options
,
_
:=
cmd
.
Flags
()
.
GetStringArray
(
"options"
)
beginTime
,
_
:=
cmd
.
Flags
()
.
GetInt64
(
"beginTime"
)
endTime
,
_
:=
cmd
.
Flags
()
.
GetInt64
(
"endTime"
)
if
name
==
""
{
fmt
.
Fprintf
(
os
.
Stderr
,
"ErrNilVoteName"
)
}
if
len
(
groupIDs
)
==
0
{
fmt
.
Fprintf
(
os
.
Stderr
,
"ErrNilGroupIDs"
)
}
if
len
(
options
)
==
0
{
fmt
.
Fprintf
(
os
.
Stderr
,
"ErrNilOptions"
)
}
if
beginTime
==
0
{
beginTime
=
types
.
Now
()
.
Unix
()
}
if
endTime
==
0
{
endTime
=
beginTime
+
300
}
params
:=
&
vty
.
CreateVote
{
Name
:
name
,
VoteGroups
:
groupIDs
,
VoteOptions
:
options
,
BeginTimestamp
:
beginTime
,
EndTimestamp
:
endTime
,
}
sendCreateTxRPC
(
cmd
,
vty
.
NameCreateVoteAction
,
params
)
}
func
commitVoteCMD
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"commitVote"
,
Short
:
"create tx(commit vote)"
,
Run
:
commitVote
,
}
commitVoteFlags
(
cmd
)
return
cmd
}
func
commitVoteFlags
(
cmd
*
cobra
.
Command
)
{
cmd
.
Flags
()
.
StringP
(
"voteID"
,
"v"
,
""
,
"vote id"
)
cmd
.
Flags
()
.
StringP
(
"groupID"
,
"g"
,
""
,
"belonging group id"
)
cmd
.
Flags
()
.
Uint32P
(
"optionIndex"
,
"o"
,
0
,
"voting option index in option array"
)
markRequired
(
cmd
,
"voteID"
,
"groupID"
,
"optionIndex"
)
}
func
commitVote
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
voteID
,
_
:=
cmd
.
Flags
()
.
GetString
(
"voteID"
)
groupID
,
_
:=
cmd
.
Flags
()
.
GetString
(
"groupID"
)
optionIndex
,
_
:=
cmd
.
Flags
()
.
GetUint32
(
"optionIndex"
)
if
voteID
==
""
{
fmt
.
Fprintf
(
os
.
Stderr
,
"ErrNilVoteID"
)
}
if
len
(
groupID
)
==
0
{
fmt
.
Fprintf
(
os
.
Stderr
,
"ErrNilGroupID"
)
}
params
:=
&
vty
.
CommitVote
{
VoteID
:
voteID
,
GroupID
:
groupID
,
OptionIndex
:
optionIndex
,
}
sendCreateTxRPC
(
cmd
,
vty
.
NameCommitVoteAction
,
params
)
}
plugin/dapp/vote/commands/query.go
0 → 100644
View file @
5226c257
package
commands
import
(
"fmt"
"os"
"github.com/33cn/chain33/types"
vty
"github.com/33cn/plugin/plugin/dapp/vote/types"
"github.com/spf13/cobra"
)
func
groupInfoCMD
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"groupInfo"
,
Short
:
"show group info"
,
Run
:
groupInfo
,
}
groupInfoFlags
(
cmd
)
return
cmd
}
func
groupInfoFlags
(
cmd
*
cobra
.
Command
)
{
cmd
.
Flags
()
.
StringP
(
"groupID"
,
"g"
,
""
,
"group id"
)
markRequired
(
cmd
,
"groupID"
)
}
func
groupInfo
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
groupID
,
_
:=
cmd
.
Flags
()
.
GetString
(
"groupID"
)
if
len
(
groupID
)
==
0
{
fmt
.
Fprintf
(
os
.
Stderr
,
"ErrNilGroupID"
)
}
params
:=
&
types
.
ReqString
{
Data
:
groupID
,
}
info
:=
&
vty
.
GroupVoteInfo
{}
sendQueryRPC
(
cmd
,
"GetGroup"
,
params
,
info
)
}
func
voteInfoCMD
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"voteInfo"
,
Short
:
"show vote info"
,
Run
:
voteInfo
,
}
voteInfoFlags
(
cmd
)
return
cmd
}
func
voteInfoFlags
(
cmd
*
cobra
.
Command
)
{
cmd
.
Flags
()
.
StringP
(
"voteID"
,
"v"
,
""
,
"vote id"
)
markRequired
(
cmd
,
"voteID"
)
}
func
voteInfo
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
voteID
,
_
:=
cmd
.
Flags
()
.
GetString
(
"voteID"
)
if
len
(
voteID
)
==
0
{
fmt
.
Fprintf
(
os
.
Stderr
,
"ErrNilVoteID"
)
}
params
:=
&
types
.
ReqString
{
Data
:
voteID
,
}
info
:=
&
vty
.
VoteInfo
{}
sendQueryRPC
(
cmd
,
"GetVote"
,
params
,
info
)
}
func
memberInfoCMD
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"memberInfo"
,
Short
:
"show member info"
,
Run
:
memberInfo
,
}
memberInfoFlags
(
cmd
)
return
cmd
}
func
memberInfoFlags
(
cmd
*
cobra
.
Command
)
{
cmd
.
Flags
()
.
StringP
(
"addr"
,
"a"
,
""
,
"member address"
)
markRequired
(
cmd
,
"addr"
)
}
func
memberInfo
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
addr
,
_
:=
cmd
.
Flags
()
.
GetString
(
"addr"
)
if
len
(
addr
)
==
0
{
fmt
.
Fprintf
(
os
.
Stderr
,
"ErrNilAddress"
)
}
params
:=
&
types
.
ReqString
{
Data
:
addr
,
}
info
:=
&
vty
.
MemberInfo
{}
sendQueryRPC
(
cmd
,
"GetMember"
,
params
,
info
)
}
func
listGroupCMD
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"listGroup"
,
Short
:
"show group list"
,
Run
:
listGroup
,
}
listCmdFlags
(
cmd
)
return
cmd
}
func
listGroup
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
runListCMD
(
cmd
,
args
,
"ListGroup"
,
&
vty
.
GroupVoteInfos
{})
}
func
listVoteCMD
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"listVote"
,
Short
:
"show vote list"
,
Run
:
listVote
,
}
listCmdFlags
(
cmd
)
return
cmd
}
func
listVote
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
runListCMD
(
cmd
,
args
,
"ListVote"
,
&
vty
.
VoteInfos
{})
}
func
listMemberCMD
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"listMember"
,
Short
:
"show member list"
,
Run
:
listMember
,
}
listCmdFlags
(
cmd
)
return
cmd
}
func
listMember
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
runListCMD
(
cmd
,
args
,
"ListMember"
,
&
vty
.
MemberInfos
{})
}
func
listCmdFlags
(
cmd
*
cobra
.
Command
)
{
cmd
.
Flags
()
.
StringP
(
"startItem"
,
"s"
,
""
,
"list start item id, default nil value"
)
cmd
.
Flags
()
.
Uint32P
(
"count"
,
"c"
,
10
,
"list count, default 10"
)
cmd
.
Flags
()
.
Uint32P
(
"direction"
,
"d"
,
0
,
"list direction, default 1 (Ascending order)"
)
}
func
runListCMD
(
cmd
*
cobra
.
Command
,
args
[]
string
,
funcName
string
,
reply
types
.
Message
)
{
startID
,
_
:=
cmd
.
Flags
()
.
GetString
(
"startItem"
)
count
,
_
:=
cmd
.
Flags
()
.
GetUint32
(
"count"
)
direction
,
_
:=
cmd
.
Flags
()
.
GetUint32
(
"direction"
)
params
:=
&
vty
.
ReqListItem
{
StartItemID
:
startID
,
Count
:
int32
(
count
),
Direction
:
int32
(
direction
),
}
sendQueryRPC
(
cmd
,
funcName
,
params
,
reply
)
}
plugin/dapp/vote/executor/action.go
0 → 100644
View file @
5226c257
package
executor
import
(
"encoding/hex"
dbm
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/types"
vty
"github.com/33cn/plugin/plugin/dapp/vote/types"
)
type
action
struct
{
db
dbm
.
KV
txHash
[]
byte
fromAddr
string
blockTime
int64
height
int64
index
int
}
func
newAction
(
v
*
vote
,
tx
*
types
.
Transaction
,
index
int
)
*
action
{
return
&
action
{
db
:
v
.
GetStateDB
(),
txHash
:
tx
.
Hash
(),
fromAddr
:
tx
.
From
(),
blockTime
:
v
.
GetBlockTime
(),
height
:
v
.
GetHeight
(),
index
:
index
}
}
func
(
a
*
action
)
getGroupInfo
(
groupID
string
)
(
*
vty
.
GroupInfo
,
error
)
{
info
:=
&
vty
.
GroupInfo
{}
err
:=
readStateDB
(
a
.
db
,
formatStateIDKey
(
groupID
),
info
)
if
err
==
types
.
ErrNotFound
{
err
=
errGroupNotExist
}
return
info
,
err
}
func
(
a
*
action
)
getVoteInfo
(
voteID
string
)
(
*
vty
.
VoteInfo
,
error
)
{
info
:=
&
vty
.
VoteInfo
{}
err
:=
readStateDB
(
a
.
db
,
formatStateIDKey
(
voteID
),
info
)
if
err
==
types
.
ErrNotFound
{
err
=
errVoteNotExist
}
return
info
,
err
}
func
(
a
*
action
)
createGroup
(
create
*
vty
.
CreateGroup
)
(
*
types
.
Receipt
,
error
)
{
receipt
:=
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
}
xhash
:=
hex
.
EncodeToString
(
a
.
txHash
)
group
:=
&
vty
.
GroupInfo
{}
group
.
Name
=
create
.
Name
group
.
ID
=
formatGroupID
(
xhash
)
//添加创建者作为默认管理员
group
.
Admins
=
append
(
group
.
Admins
,
create
.
Admins
...
)
if
!
checkSliceItemExist
(
a
.
fromAddr
,
create
.
Admins
)
{
group
.
Admins
=
append
(
group
.
Admins
,
a
.
fromAddr
)
}
group
.
Members
=
create
.
Members
// set default vote weight
for
_
,
member
:=
range
group
.
Members
{
if
member
.
VoteWeight
<
1
{
member
.
VoteWeight
=
1
}
}
group
.
MemberNum
=
uint32
(
len
(
group
.
Members
))
group
.
Creator
=
a
.
fromAddr
groupValue
:=
types
.
Encode
(
group
)
receipt
.
KV
=
append
(
receipt
.
KV
,
&
types
.
KeyValue
{
Key
:
formatStateIDKey
(
group
.
ID
),
Value
:
groupValue
})
receipt
.
Logs
=
append
(
receipt
.
Logs
,
&
types
.
ReceiptLog
{
Ty
:
vty
.
TyCreateGroupLog
,
Log
:
groupValue
})
return
receipt
,
nil
}
func
(
a
*
action
)
updateMember
(
update
*
vty
.
UpdateMember
)
(
*
types
.
Receipt
,
error
)
{
receipt
:=
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
}
group
,
err
:=
a
.
getGroupInfo
(
update
.
GroupID
)
if
err
!=
nil
{
elog
.
Error
(
"vote exec updateMember"
,
"txHash"
,
a
.
txHash
,
"err"
,
err
)
return
nil
,
errStateDBGet
}
addrMap
:=
make
(
map
[
string
]
int
)
for
index
,
member
:=
range
group
.
Members
{
addrMap
[
member
.
Addr
]
=
index
}
// remove members
for
_
,
addr
:=
range
update
.
GetRemoveMemberAddrs
()
{
if
index
,
ok
:=
addrMap
[
addr
];
ok
{
group
.
Members
=
append
(
group
.
Members
[
:
index
],
group
.
Members
[
index
+
1
:
]
...
)
}
}
// add members
for
_
,
member
:=
range
update
.
GetAddMembers
()
{
group
.
Members
=
append
(
group
.
Members
,
member
)
}
groupValue
:=
types
.
Encode
(
group
)
receipt
.
KV
=
append
(
receipt
.
KV
,
&
types
.
KeyValue
{
Key
:
formatStateIDKey
(
group
.
ID
),
Value
:
groupValue
})
receipt
.
Logs
=
append
(
receipt
.
Logs
,
&
types
.
ReceiptLog
{
Ty
:
vty
.
TyUpdateMemberLog
,
Log
:
groupValue
})
return
receipt
,
nil
}
func
(
a
*
action
)
createVote
(
create
*
vty
.
CreateVote
)
(
*
types
.
Receipt
,
error
)
{
receipt
:=
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
}
vote
:=
&
vty
.
VoteInfo
{}
vote
.
ID
=
formatVoteID
(
hex
.
EncodeToString
(
a
.
txHash
))
vote
.
BeginTimestamp
=
create
.
BeginTimestamp
vote
.
EndTimestamp
=
create
.
EndTimestamp
vote
.
Name
=
create
.
Name
vote
.
VoteGroups
=
create
.
VoteGroups
vote
.
VoteOptions
=
make
([]
*
vty
.
VoteOption
,
0
)
for
_
,
option
:=
range
create
.
VoteOptions
{
vote
.
VoteOptions
=
append
(
vote
.
VoteOptions
,
&
vty
.
VoteOption
{
Option
:
option
})
}
vote
.
Creator
=
a
.
fromAddr
voteValue
:=
types
.
Encode
(
vote
)
receipt
.
KV
=
append
(
receipt
.
KV
,
&
types
.
KeyValue
{
Key
:
formatStateIDKey
(
vote
.
ID
),
Value
:
voteValue
})
receipt
.
Logs
=
append
(
receipt
.
Logs
,
&
types
.
ReceiptLog
{
Ty
:
vty
.
TyCreateVoteLog
,
Log
:
voteValue
})
return
receipt
,
nil
}
func
(
a
*
action
)
commitVote
(
commit
*
vty
.
CommitVote
)
(
*
types
.
Receipt
,
error
)
{
receipt
:=
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
}
vote
,
err
:=
a
.
getVoteInfo
(
commit
.
VoteID
)
group
,
err1
:=
a
.
getGroupInfo
(
commit
.
GroupID
)
if
err
!=
nil
||
err1
!=
nil
{
elog
.
Error
(
"vote exec commitVote"
,
"txHash"
,
a
.
txHash
,
"err"
,
err
,
"err1"
,
err1
)
return
nil
,
errStateDBGet
}
for
_
,
member
:=
range
group
.
Members
{
if
member
.
Addr
==
a
.
fromAddr
{
vote
.
VoteOptions
[
commit
.
OptionIndex
]
.
Score
+=
member
.
VoteWeight
}
}
vote
.
VotedMembers
=
append
(
vote
.
VotedMembers
,
a
.
fromAddr
)
voteValue
:=
types
.
Encode
(
vote
)
receipt
.
KV
=
append
(
receipt
.
KV
,
&
types
.
KeyValue
{
Key
:
formatStateIDKey
(
vote
.
ID
),
Value
:
voteValue
})
receipt
.
Logs
=
append
(
receipt
.
Logs
,
&
types
.
ReceiptLog
{
Ty
:
vty
.
TyCommitVoteLog
,
Log
:
voteValue
})
return
receipt
,
nil
}
plugin/dapp/vote/executor/checktx.go
0 → 100644
View file @
5226c257
package
executor
import
(
"encoding/hex"
"github.com/33cn/chain33/types"
vty
"github.com/33cn/plugin/plugin/dapp/vote/types"
)
// CheckTx 实现自定义检验交易接口,供框架调用
func
(
v
*
vote
)
CheckTx
(
tx
*
types
.
Transaction
,
index
int
)
error
{
// implement code
txHash
:=
hex
.
EncodeToString
(
tx
.
Hash
())
var
action
vty
.
VoteAction
err
:=
types
.
Decode
(
tx
.
Payload
,
&
action
)
if
err
!=
nil
{
elog
.
Error
(
"vote CheckTx"
,
"txHash"
,
txHash
,
"Decode payload error"
,
err
)
return
types
.
ErrActionNotSupport
}
if
action
.
Ty
==
vty
.
TyCreateGroupAction
{
err
=
v
.
checkCreateGroup
(
action
.
GetCreateGroup
())
}
else
if
action
.
Ty
==
vty
.
TyUpdateMemberAction
{
err
=
v
.
checkUpdateMember
(
action
.
GetUpdateMember
())
}
else
if
action
.
Ty
==
vty
.
TyCreateVoteAction
{
err
=
v
.
checkCreateVote
(
action
.
GetCreateVote
())
}
else
if
action
.
Ty
==
vty
.
TyCommitVoteAction
{
err
=
v
.
checkCommitVote
(
action
.
GetCommitVote
(),
tx
,
index
)
}
else
{
err
=
types
.
ErrActionNotSupport
}
if
err
!=
nil
{
elog
.
Error
(
"vote CheckTx"
,
"txHash"
,
txHash
,
"actionName"
,
tx
.
ActionName
(),
"err"
,
err
,
"actionData"
,
action
)
}
return
err
}
func
checkMemberValidity
(
members
[]
*
vty
.
GroupMember
)
error
{
filter
:=
make
(
map
[
string
]
struct
{},
len
(
members
))
for
_
,
member
:=
range
members
{
if
member
.
GetAddr
()
==
""
{
return
errNilMember
}
if
_
,
ok
:=
filter
[
member
.
Addr
];
ok
{
return
errDuplicateMember
}
filter
[
member
.
Addr
]
=
struct
{}{}
}
return
nil
}
func
(
v
*
vote
)
checkCreateGroup
(
create
*
vty
.
CreateGroup
)
error
{
if
create
.
GetName
()
==
""
{
return
errEmptyName
}
//检测组成员是否有重复
if
err
:=
checkMemberValidity
(
create
.
GetMembers
());
err
!=
nil
{
return
err
}
//检测管理员是否有重复
if
checkSliceItemDuplicate
(
create
.
GetAdmins
())
{
return
errDuplicateAdmin
}
return
nil
}
func
(
v
*
vote
)
checkUpdateMember
(
update
*
vty
.
UpdateMember
)
error
{
if
len
(
update
.
GetGroupID
())
!=
IDLen
{
return
errInvalidGroupID
}
for
_
,
member
:=
range
update
.
AddMembers
{
if
len
(
member
.
Addr
)
!=
addrLen
{
return
types
.
ErrInvalidAddress
}
}
for
_
,
addr
:=
range
update
.
RemoveMemberAddrs
{
if
len
(
addr
)
!=
addrLen
{
return
types
.
ErrInvalidAddress
}
}
return
nil
}
func
(
v
*
vote
)
checkCreateVote
(
create
*
vty
.
CreateVote
)
error
{
if
create
.
GetName
()
==
""
{
return
errEmptyName
}
if
create
.
GetEndTimestamp
()
<=
v
.
GetBlockTime
()
||
create
.
EndTimestamp
<=
create
.
BeginTimestamp
{
return
errInvalidVoteTime
}
if
len
(
create
.
VoteOptions
)
<
2
{
return
errInvalidVoteOption
}
if
len
(
create
.
VoteGroups
)
==
0
{
return
errEmptyVoteGroup
}
if
checkSliceItemDuplicate
(
create
.
VoteGroups
)
{
return
errDuplicateGroup
}
return
nil
}
func
(
v
*
vote
)
checkCommitVote
(
commit
*
vty
.
CommitVote
,
tx
*
types
.
Transaction
,
index
int
)
error
{
voteID
:=
commit
.
GetVoteID
()
groupID
:=
commit
.
GetGroupID
()
if
len
(
voteID
)
!=
IDLen
{
return
errInvalidVoteID
}
if
len
(
groupID
)
!=
IDLen
{
return
errInvalidGroupID
}
action
:=
newAction
(
v
,
tx
,
index
)
voteInfo
,
err
:=
action
.
getVoteInfo
(
voteID
)
if
err
!=
nil
{
return
err
}
if
voteInfo
.
EndTimestamp
<=
action
.
blockTime
{
return
errVoteAlreadyFinished
}
if
commit
.
OptionIndex
>=
uint32
(
len
(
voteInfo
.
VoteOptions
))
{
return
errInvalidOptionIndex
}
//check group validity
if
!
checkSliceItemExist
(
commit
.
GroupID
,
voteInfo
.
VoteGroups
)
{
return
errInvalidGroupID
}
// check if already vote
if
checkSliceItemExist
(
action
.
fromAddr
,
voteInfo
.
VotedMembers
)
{
return
errAlreadyVoted
}
groupInfo
,
err
:=
action
.
getGroupInfo
(
commit
.
GroupID
)
if
err
!=
nil
{
return
err
}
// check if exist in group members
if
!
checkMemberExist
(
action
.
fromAddr
,
groupInfo
.
Members
)
{
return
errInvalidGroupMember
}
return
nil
}
plugin/dapp/vote/executor/errors.go
0 → 100644
View file @
5226c257
package
executor
import
"errors"
var
(
errEmptyName
=
errors
.
New
(
"ErrEmptyName"
)
errInvalidMemberWeights
=
errors
.
New
(
"errInvalidMemberWeights"
)
errNilMember
=
errors
.
New
(
"errNilMember"
)
errDuplicateMember
=
errors
.
New
(
"errDuplicateMember"
)
errDuplicateGroup
=
errors
.
New
(
"errDuplicateGroup"
)
errDuplicateAdmin
=
errors
.
New
(
"errDuplicateAdmin"
)
errInvalidVoteTime
=
errors
.
New
(
"errInvalidVoteTime"
)
errInvalidVoteOption
=
errors
.
New
(
"errInvalidVoteOption"
)
errEmptyVoteGroup
=
errors
.
New
(
"errEmptyVoteGroup"
)
errVoteNotExist
=
errors
.
New
(
"errVoteNotExist"
)
errGroupNotExist
=
errors
.
New
(
"errGroupNotExist"
)
errStateDBGet
=
errors
.
New
(
"errStateDBGet"
)
errInvalidVoteID
=
errors
.
New
(
"errInvalidVoteID"
)
errInvalidGroupID
=
errors
.
New
(
"errInvalidGroupID"
)
errInvalidOptionIndex
=
errors
.
New
(
"errInvalidOptionIndex"
)
errAlreadyVoted
=
errors
.
New
(
"errAlreadyVoted"
)
errInvalidGroupMember
=
errors
.
New
(
"errInvalidGroupMember"
)
errVoteAlreadyFinished
=
errors
.
New
(
"errVoteAlreadyFinished"
)
)
plugin/dapp/vote/executor/exec.go
0 → 100644
View file @
5226c257
package
executor
import
(
"github.com/33cn/chain33/types"
votetypes
"github.com/33cn/plugin/plugin/dapp/vote/types"
)
/*
* 实现交易的链上执行接口
* 关键数据上链(statedb)并生成交易回执(log)
*/
func
(
v
*
vote
)
Exec_CreateGroup
(
payload
*
votetypes
.
CreateGroup
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
action
:=
newAction
(
v
,
tx
,
index
)
return
action
.
createGroup
(
payload
)
}
func
(
v
*
vote
)
Exec_UpdateMember
(
payload
*
votetypes
.
UpdateMember
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
action
:=
newAction
(
v
,
tx
,
index
)
return
action
.
updateMember
(
payload
)
}
func
(
v
*
vote
)
Exec_CreateVote
(
payload
*
votetypes
.
CreateVote
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
action
:=
newAction
(
v
,
tx
,
index
)
return
action
.
createVote
(
payload
)
}
func
(
v
*
vote
)
Exec_CommitVote
(
payload
*
votetypes
.
CommitVote
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
action
:=
newAction
(
v
,
tx
,
index
)
return
action
.
commitVote
(
payload
)
}
plugin/dapp/vote/executor/exec_del_local.go
0 → 100644
View file @
5226c257
package
executor
import
(
"github.com/33cn/chain33/types"
)
/*
* 实现区块回退时本地执行的数据清除
*/
// ExecDelLocal localdb kv数据自动回滚接口
func
(
v
*
vote
)
ExecDelLocal
(
tx
*
types
.
Transaction
,
receipt
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
kvs
,
err
:=
v
.
DelRollbackKV
(
tx
,
tx
.
Execer
)
if
err
!=
nil
{
return
nil
,
err
}
dbSet
:=
&
types
.
LocalDBSet
{}
dbSet
.
KV
=
append
(
dbSet
.
KV
,
kvs
...
)
return
dbSet
,
nil
}
plugin/dapp/vote/executor/exec_local.go
0 → 100644
View file @
5226c257
package
executor
import
(
"encoding/hex"
"github.com/33cn/chain33/types"
vty
"github.com/33cn/plugin/plugin/dapp/vote/types"
)
/*
* 实现交易相关数据本地执行,数据不上链
* 非关键数据,本地存储(localDB), 用于辅助查询,效率高
*/
func
(
v
*
vote
)
ExecLocal_CreateGroup
(
payload
*
vty
.
CreateGroup
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
dbSet
:=
&
types
.
LocalDBSet
{}
groupInfo
:=
decodeGroupInfo
(
receiptData
.
Logs
[
0
]
.
Log
)
table
:=
newGroupTable
(
v
.
GetLocalDB
())
err
:=
table
.
Add
(
&
vty
.
GroupVoteInfo
{
GroupInfo
:
groupInfo
})
if
err
!=
nil
{
elog
.
Error
(
"execLocal createGroup"
,
"txHash"
,
hex
.
EncodeToString
(
tx
.
Hash
()),
"table add"
,
err
)
return
nil
,
err
}
kvs
,
err
:=
table
.
Save
()
if
err
!=
nil
{
elog
.
Error
(
"execLocal createGroup"
,
"txHash"
,
hex
.
EncodeToString
(
tx
.
Hash
()),
"table save"
,
err
)
return
nil
,
err
}
dbSet
.
KV
=
kvs
kvs
,
err
=
v
.
addGroupMember
(
groupInfo
.
GetID
(),
groupInfo
.
Members
)
if
err
!=
nil
{
elog
.
Error
(
"execLocal createGroup"
,
"txHash"
,
hex
.
EncodeToString
(
tx
.
Hash
()),
"addMemberErr"
,
err
)
return
nil
,
err
}
dbSet
.
KV
=
append
(
dbSet
.
KV
,
kvs
...
)
//auto gen for localdb auto rollback
return
v
.
addAutoRollBack
(
tx
,
dbSet
.
KV
),
nil
}
func
(
v
*
vote
)
ExecLocal_UpdateMember
(
update
*
vty
.
UpdateMember
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
dbSet
:=
&
types
.
LocalDBSet
{}
groupInfo
:=
decodeGroupInfo
(
receiptData
.
Logs
[
0
]
.
Log
)
table
:=
newGroupTable
(
v
.
GetLocalDB
())
err
:=
table
.
Replace
(
&
vty
.
GroupVoteInfo
{
GroupInfo
:
groupInfo
})
if
err
!=
nil
{
elog
.
Error
(
"execLocal updateMember"
,
"txHash"
,
hex
.
EncodeToString
(
tx
.
Hash
()),
"groupID"
,
groupInfo
.
ID
,
"table replace"
,
err
)
return
nil
,
err
}
kvs
,
err
:=
table
.
Save
()
if
err
!=
nil
{
elog
.
Error
(
"execLocal updateMember"
,
"txHash"
,
hex
.
EncodeToString
(
tx
.
Hash
()),
"groupID"
,
groupInfo
.
ID
,
"table save"
,
err
)
return
nil
,
err
}
dbSet
.
KV
=
kvs
kvs
,
err
=
v
.
addGroupMember
(
groupInfo
.
GetID
(),
update
.
AddMembers
)
if
err
!=
nil
{
elog
.
Error
(
"execLocal updateMember"
,
"txHash"
,
hex
.
EncodeToString
(
tx
.
Hash
()),
"addMemberErr"
,
err
)
return
nil
,
err
}
dbSet
.
KV
=
append
(
dbSet
.
KV
,
kvs
...
)
kvs
,
err
=
v
.
removeGroupMember
(
groupInfo
.
GetID
(),
update
.
RemoveMemberAddrs
)
if
err
!=
nil
{
elog
.
Error
(
"execLocal updateMember"
,
"txHash"
,
hex
.
EncodeToString
(
tx
.
Hash
()),
"removeMemberErr"
,
err
)
return
nil
,
err
}
dbSet
.
KV
=
append
(
dbSet
.
KV
,
kvs
...
)
//auto gen for localdb auto rollback
return
v
.
addAutoRollBack
(
tx
,
dbSet
.
KV
),
nil
}
func
(
v
*
vote
)
ExecLocal_CreateVote
(
payload
*
vty
.
CreateVote
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
dbSet
:=
&
types
.
LocalDBSet
{}
voteInfo
:=
decodeVoteInfo
(
receiptData
.
Logs
[
0
]
.
Log
)
table
:=
newVoteTable
(
v
.
GetLocalDB
())
err
:=
table
.
Add
(
voteInfo
)
if
err
!=
nil
{
elog
.
Error
(
"execLocal createVote"
,
"txHash"
,
hex
.
EncodeToString
(
tx
.
Hash
()),
"voteTable add"
,
err
)
return
nil
,
err
}
kvs
,
err
:=
table
.
Save
()
if
err
!=
nil
{
elog
.
Error
(
"execLocal createVote"
,
"txHash"
,
hex
.
EncodeToString
(
tx
.
Hash
()),
"voteTable save"
,
err
)
return
nil
,
err
}
dbSet
.
KV
=
kvs
// 在关联的投票组表中记录voteID信息
table
=
newGroupTable
(
v
.
GetLocalDB
())
for
_
,
groupID
:=
range
voteInfo
.
VoteGroups
{
row
,
err
:=
table
.
GetData
([]
byte
(
groupID
))
if
err
!=
nil
{
continue
}
if
info
,
ok
:=
row
.
Data
.
(
*
vty
.
GroupVoteInfo
);
ok
{
info
.
VoteIDs
=
append
(
info
.
VoteIDs
,
voteInfo
.
ID
)
err
=
table
.
Replace
(
info
)
if
err
!=
nil
{
elog
.
Error
(
"execLocal createVote"
,
"txHash"
,
hex
.
EncodeToString
(
tx
.
Hash
()),
"groupID"
,
groupID
,
"groupTable replace"
,
err
)
return
nil
,
err
}
}
}
kvs
,
err
=
table
.
Save
()
if
err
!=
nil
{
elog
.
Error
(
"execLocal createVote"
,
"txHash"
,
hex
.
EncodeToString
(
tx
.
Hash
()),
"groupTable save"
,
err
)
return
nil
,
err
}
dbSet
.
KV
=
append
(
dbSet
.
KV
,
kvs
...
)
//auto gen for localdb auto rollback
return
v
.
addAutoRollBack
(
tx
,
dbSet
.
KV
),
nil
}
func
(
v
*
vote
)
ExecLocal_CommitVote
(
payload
*
vty
.
CommitVote
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
dbSet
:=
&
types
.
LocalDBSet
{}
//implement code, add customize kv to dbSet...
voteInfo
:=
decodeVoteInfo
(
receiptData
.
Logs
[
0
]
.
Log
)
table
:=
newVoteTable
(
v
.
GetLocalDB
())
err
:=
table
.
Replace
(
voteInfo
)
if
err
!=
nil
{
elog
.
Error
(
"execLocal commitVote"
,
"txHash"
,
hex
.
EncodeToString
(
tx
.
Hash
()),
"voteTable add"
,
err
)
return
nil
,
err
}
kvs
,
err
:=
table
.
Save
()
if
err
!=
nil
{
elog
.
Error
(
"execLocal commitVote"
,
"txHash"
,
hex
.
EncodeToString
(
tx
.
Hash
()),
"voteTable save"
,
err
)
return
nil
,
err
}
dbSet
.
KV
=
kvs
//auto gen for localdb auto rollback
return
v
.
addAutoRollBack
(
tx
,
dbSet
.
KV
),
nil
}
//当区块回滚时,框架支持自动回滚localdb kv,需要对exec-local返回的kv进行封装
func
(
v
*
vote
)
addAutoRollBack
(
tx
*
types
.
Transaction
,
kv
[]
*
types
.
KeyValue
)
*
types
.
LocalDBSet
{
dbSet
:=
&
types
.
LocalDBSet
{}
dbSet
.
KV
=
v
.
AddRollbackKV
(
tx
,
tx
.
Execer
,
kv
)
return
dbSet
}
func
(
v
*
vote
)
addGroupMember
(
groupID
string
,
members
[]
*
vty
.
GroupMember
)
([]
*
types
.
KeyValue
,
error
)
{
table
:=
newMemberTable
(
v
.
GetLocalDB
())
for
_
,
member
:=
range
members
{
addrKey
:=
[]
byte
(
member
.
Addr
)
row
,
err
:=
table
.
GetData
(
addrKey
)
if
err
==
nil
{
info
,
ok
:=
row
.
Data
.
(
*
vty
.
MemberInfo
)
if
ok
&&
!
checkSliceItemExist
(
groupID
,
info
.
GroupIDs
)
{
info
.
GroupIDs
=
append
(
info
.
GroupIDs
,
groupID
)
err
=
table
.
Replace
(
info
)
}
}
else
if
err
==
types
.
ErrNotFound
{
err
=
table
.
Add
(
&
vty
.
MemberInfo
{
Addr
:
member
.
Addr
,
GroupIDs
:
[]
string
{
groupID
}})
}
// 这个错可能由GetData,Replace,Add返回
if
err
!=
nil
{
elog
.
Error
(
"execLocal addMember"
,
"member table Add/Replace"
,
err
)
return
nil
,
err
}
}
kvs
,
err
:=
table
.
Save
()
if
err
!=
nil
{
elog
.
Error
(
"execLocal addMember"
,
"member table save"
,
err
)
return
nil
,
err
}
return
kvs
,
nil
}
func
(
v
*
vote
)
removeGroupMember
(
groupID
string
,
addrs
[]
string
)
([]
*
types
.
KeyValue
,
error
)
{
table
:=
newMemberTable
(
v
.
GetLocalDB
())
for
_
,
addr
:=
range
addrs
{
addrKey
:=
[]
byte
(
addr
)
row
,
err
:=
table
.
GetData
(
addrKey
)
if
err
==
types
.
ErrNotFound
{
return
nil
,
nil
}
else
if
err
!=
nil
{
elog
.
Error
(
"execLocal removeMember"
,
"member table getData"
,
err
)
return
nil
,
err
}
info
,
ok
:=
row
.
Data
.
(
*
vty
.
MemberInfo
)
if
!
ok
{
return
nil
,
types
.
ErrTypeAsset
}
for
index
,
id
:=
range
info
.
GroupIDs
{
if
id
==
groupID
{
info
.
GroupIDs
=
append
(
info
.
GroupIDs
[
:
index
],
info
.
GroupIDs
[
index
+
1
:
]
...
)
err
=
table
.
Replace
(
info
)
if
err
!=
nil
{
elog
.
Error
(
"execLocal removeMember"
,
"member table replace"
,
err
)
return
nil
,
err
}
break
}
}
}
kvs
,
err
:=
table
.
Save
()
if
err
!=
nil
{
elog
.
Error
(
"execLocal addMember"
,
"member table save"
,
err
)
return
nil
,
err
}
return
kvs
,
nil
}
plugin/dapp/vote/executor/key.go
0 → 100644
View file @
5226c257
package
executor
/*
* 用户合约存取kv数据时,key值前缀需要满足一定规范
* 即key = keyPrefix + userKey
* 需要字段前缀查询时,使用’-‘作为分割符号
*/
var
(
//keyPrefixStateDB state db key必须前缀
keyPrefixStateDB
=
"mavl-vote-"
//keyPrefixLocalDB local db的key必须前缀
keyPrefixLocalDB
=
"LODB-vote-"
)
// groupID or voteID
func
formatStateIDKey
(
id
string
)
[]
byte
{
return
[]
byte
(
keyPrefixStateDB
+
id
)
}
plugin/dapp/vote/executor/query.go
0 → 100644
View file @
5226c257
package
executor
import
(
"github.com/33cn/chain33/types"
vty
"github.com/33cn/plugin/plugin/dapp/vote/types"
)
// Query_GroupInfo query group info
func
(
v
*
vote
)
Query_GetGroup
(
in
*
types
.
ReqString
)
(
types
.
Message
,
error
)
{
if
len
(
in
.
GetData
())
!=
IDLen
{
return
nil
,
errInvalidGroupID
}
groupID
:=
in
.
Data
table
:=
newGroupTable
(
v
.
GetLocalDB
())
row
,
err
:=
table
.
GetData
([]
byte
(
groupID
))
if
err
!=
nil
{
elog
.
Error
(
"query getGroup"
,
"id"
,
groupID
,
"err"
,
err
)
return
nil
,
err
}
info
,
ok
:=
row
.
Data
.
(
*
vty
.
GroupVoteInfo
)
if
!
ok
{
return
nil
,
types
.
ErrTypeAsset
}
return
info
,
nil
}
func
(
v
*
vote
)
Query_GetVote
(
in
*
types
.
ReqString
)
(
types
.
Message
,
error
)
{
if
len
(
in
.
GetData
())
!=
IDLen
{
return
nil
,
errInvalidVoteID
}
voteID
:=
in
.
Data
table
:=
newVoteTable
(
v
.
GetLocalDB
())
row
,
err
:=
table
.
GetData
([]
byte
(
voteID
))
if
err
!=
nil
{
elog
.
Error
(
"query getVote"
,
"id"
,
voteID
,
"err"
,
err
)
return
nil
,
err
}
info
,
ok
:=
row
.
Data
.
(
*
vty
.
VoteInfo
)
if
!
ok
{
return
nil
,
types
.
ErrTypeAsset
}
return
info
,
nil
}
func
(
v
*
vote
)
Query_GetMember
(
in
*
types
.
ReqString
)
(
types
.
Message
,
error
)
{
if
len
(
in
.
GetData
())
!=
addrLen
{
return
nil
,
types
.
ErrInvalidAddress
}
addr
:=
in
.
Data
table
:=
newMemberTable
(
v
.
GetLocalDB
())
row
,
err
:=
table
.
GetData
([]
byte
(
addr
))
if
err
!=
nil
{
elog
.
Error
(
"query getMember"
,
"addr"
,
addr
,
"err"
,
err
)
return
nil
,
err
}
info
,
ok
:=
row
.
Data
.
(
*
vty
.
MemberInfo
)
if
!
ok
{
return
nil
,
types
.
ErrTypeAsset
}
return
info
,
nil
}
func
(
v
*
vote
)
Query_ListGroup
(
in
*
vty
.
ReqListItem
)
(
types
.
Message
,
error
)
{
if
in
==
nil
{
return
nil
,
types
.
ErrInvalidParam
}
table
:=
newGroupTable
(
v
.
GetLocalDB
())
var
primaryKey
[]
byte
primaryKey
=
append
(
primaryKey
,
[]
byte
(
in
.
StartItemID
)
...
)
rows
,
err
:=
table
.
ListIndex
(
groupTablePrimary
,
nil
,
primaryKey
,
in
.
Count
,
in
.
Direction
)
if
err
!=
nil
{
elog
.
Error
(
"query listGroup"
,
"err"
,
err
,
"param"
,
in
)
return
nil
,
err
}
list
:=
&
vty
.
GroupVoteInfos
{
GroupList
:
make
([]
*
vty
.
GroupVoteInfo
,
0
)}
for
_
,
row
:=
range
rows
{
info
,
ok
:=
row
.
Data
.
(
*
vty
.
GroupVoteInfo
)
if
!
ok
{
return
nil
,
types
.
ErrTypeAsset
}
list
.
GroupList
=
append
(
list
.
GroupList
,
info
)
}
return
list
,
nil
}
func
(
v
*
vote
)
Query_ListVote
(
in
*
vty
.
ReqListItem
)
(
types
.
Message
,
error
)
{
if
in
==
nil
{
return
nil
,
types
.
ErrInvalidParam
}
table
:=
newVoteTable
(
v
.
GetLocalDB
())
var
primaryKey
[]
byte
primaryKey
=
append
(
primaryKey
,
[]
byte
(
in
.
StartItemID
)
...
)
rows
,
err
:=
table
.
ListIndex
(
voteTablePrimary
,
nil
,
primaryKey
,
in
.
Count
,
in
.
Direction
)
if
err
!=
nil
{
elog
.
Error
(
"query listVote"
,
"err"
,
err
,
"param"
,
in
)
return
nil
,
err
}
list
:=
&
vty
.
VoteInfos
{
VoteList
:
make
([]
*
vty
.
VoteInfo
,
0
)}
for
_
,
row
:=
range
rows
{
info
,
ok
:=
row
.
Data
.
(
*
vty
.
VoteInfo
)
if
!
ok
{
return
nil
,
types
.
ErrTypeAsset
}
list
.
VoteList
=
append
(
list
.
VoteList
,
info
)
}
return
list
,
nil
}
func
(
v
*
vote
)
Query_ListMember
(
in
*
vty
.
ReqListItem
)
(
types
.
Message
,
error
)
{
if
in
==
nil
{
return
nil
,
types
.
ErrInvalidParam
}
table
:=
newMemberTable
(
v
.
GetLocalDB
())
var
primaryKey
[]
byte
primaryKey
=
append
(
primaryKey
,
[]
byte
(
in
.
StartItemID
)
...
)
rows
,
err
:=
table
.
ListIndex
(
memberTablePrimary
,
nil
,
primaryKey
,
in
.
Count
,
in
.
Direction
)
if
err
!=
nil
{
elog
.
Error
(
"query listMember"
,
"err"
,
err
,
"param"
,
in
)
return
nil
,
err
}
list
:=
&
vty
.
MemberInfos
{
MemberList
:
make
([]
*
vty
.
MemberInfo
,
0
)}
for
_
,
row
:=
range
rows
{
info
,
ok
:=
row
.
Data
.
(
*
vty
.
MemberInfo
)
if
!
ok
{
return
nil
,
types
.
ErrTypeAsset
}
list
.
MemberList
=
append
(
list
.
MemberList
,
info
)
}
return
list
,
nil
}
plugin/dapp/vote/executor/table.go
0 → 100644
View file @
5226c257
package
executor
import
(
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/common/db/table"
"github.com/33cn/chain33/types"
vty
"github.com/33cn/plugin/plugin/dapp/vote/types"
)
var
(
groupTablePrimary
=
"groupid"
voteTablePrimary
=
"voteid"
memberTablePrimary
=
"addr"
)
var
groupTableOpt
=
&
table
.
Option
{
Prefix
:
keyPrefixLocalDB
,
Name
:
"group"
,
Primary
:
groupTablePrimary
,
}
var
voteTableOpt
=
&
table
.
Option
{
Prefix
:
keyPrefixLocalDB
,
Name
:
"vote"
,
Primary
:
voteTablePrimary
,
}
var
memberTableOpt
=
&
table
.
Option
{
Prefix
:
keyPrefixLocalDB
,
Name
:
"member"
,
Primary
:
memberTablePrimary
,
}
//新建表
func
newTable
(
kvDB
db
.
KV
,
rowMeta
table
.
RowMeta
,
opt
*
table
.
Option
)
*
table
.
Table
{
table
,
err
:=
table
.
NewTable
(
rowMeta
,
kvDB
,
opt
)
if
err
!=
nil
{
panic
(
err
)
}
return
table
}
func
newGroupTable
(
kvDB
db
.
KV
)
*
table
.
Table
{
return
newTable
(
kvDB
,
&
groupTableRow
{},
groupTableOpt
)
}
func
newVoteTable
(
kvDB
db
.
KV
)
*
table
.
Table
{
return
newTable
(
kvDB
,
&
voteTableRow
{},
voteTableOpt
)
}
func
newMemberTable
(
kvDB
db
.
KV
)
*
table
.
Table
{
return
newTable
(
kvDB
,
&
memberTableRow
{},
memberTableOpt
)
}
//groupTableRow table meta 结构
type
groupTableRow
struct
{
*
vty
.
GroupVoteInfo
}
//CreateRow 新建数据行
func
(
r
*
groupTableRow
)
CreateRow
()
*
table
.
Row
{
return
&
table
.
Row
{
Data
:
&
vty
.
GroupVoteInfo
{}}
}
//SetPayload 设置数据
func
(
r
*
groupTableRow
)
SetPayload
(
data
types
.
Message
)
error
{
if
d
,
ok
:=
data
.
(
*
vty
.
GroupVoteInfo
);
ok
{
r
.
GroupVoteInfo
=
d
return
nil
}
return
types
.
ErrTypeAsset
}
//Get 按照indexName 查询 indexValue
func
(
r
*
groupTableRow
)
Get
(
key
string
)
([]
byte
,
error
)
{
if
key
==
groupTablePrimary
{
return
[]
byte
(
r
.
GroupVoteInfo
.
GetGroupInfo
()
.
GetID
()),
nil
}
return
nil
,
types
.
ErrNotFound
}
//voteTableRow table meta 结构
type
voteTableRow
struct
{
*
vty
.
VoteInfo
}
//CreateRow 新建数据行
func
(
r
*
voteTableRow
)
CreateRow
()
*
table
.
Row
{
return
&
table
.
Row
{
Data
:
&
vty
.
VoteInfo
{}}
}
//SetPayload 设置数据
func
(
r
*
voteTableRow
)
SetPayload
(
data
types
.
Message
)
error
{
if
d
,
ok
:=
data
.
(
*
vty
.
VoteInfo
);
ok
{
r
.
VoteInfo
=
d
return
nil
}
return
types
.
ErrTypeAsset
}
//Get 按照indexName 查询 indexValue
func
(
r
*
voteTableRow
)
Get
(
key
string
)
([]
byte
,
error
)
{
if
key
==
voteTablePrimary
{
return
[]
byte
(
r
.
VoteInfo
.
GetID
()),
nil
}
return
nil
,
types
.
ErrNotFound
}
type
memberTableRow
struct
{
*
vty
.
MemberInfo
}
//CreateRow 新建数据行
func
(
r
*
memberTableRow
)
CreateRow
()
*
table
.
Row
{
return
&
table
.
Row
{
Data
:
&
vty
.
MemberInfo
{}}
}
//SetPayload 设置数据
func
(
r
*
memberTableRow
)
SetPayload
(
data
types
.
Message
)
error
{
if
d
,
ok
:=
data
.
(
*
vty
.
MemberInfo
);
ok
{
r
.
MemberInfo
=
d
return
nil
}
return
types
.
ErrTypeAsset
}
//Get 按照indexName 查询 indexValue
func
(
r
*
memberTableRow
)
Get
(
key
string
)
([]
byte
,
error
)
{
if
key
==
memberTablePrimary
{
return
[]
byte
(
r
.
MemberInfo
.
GetAddr
()),
nil
}
return
nil
,
types
.
ErrNotFound
}
plugin/dapp/vote/executor/util.go
0 → 100644
View file @
5226c257
package
executor
import
(
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/types"
vty
"github.com/33cn/plugin/plugin/dapp/vote/types"
)
const
(
// IDLen length of groupID or voteID
IDLen
=
65
addrLen
=
34
)
func
formatGroupID
(
txHash
string
)
string
{
return
"g"
+
txHash
}
func
formatVoteID
(
txHash
string
)
string
{
return
"v"
+
txHash
}
func
checkMemberExist
(
addr
string
,
members
[]
*
vty
.
GroupMember
)
bool
{
for
_
,
item
:=
range
members
{
if
addr
==
item
.
Addr
{
return
true
}
}
return
false
}
func
checkSliceItemExist
(
target
string
,
items
[]
string
)
bool
{
for
_
,
item
:=
range
items
{
if
target
==
item
{
return
true
}
}
return
false
}
func
checkSliceItemDuplicate
(
items
[]
string
)
bool
{
filter
:=
make
(
map
[
string
]
struct
{},
len
(
items
))
for
_
,
item
:=
range
items
{
if
_
,
ok
:=
filter
[
item
];
ok
{
return
true
}
filter
[
item
]
=
struct
{}{}
}
return
false
}
func
readStateDB
(
stateDB
db
.
KV
,
key
[]
byte
,
result
types
.
Message
)
error
{
val
,
err
:=
stateDB
.
Get
(
key
)
if
err
!=
nil
{
return
err
}
return
types
.
Decode
(
val
,
result
)
}
func
mustDecodeProto
(
data
[]
byte
,
msg
types
.
Message
)
{
if
err
:=
types
.
Decode
(
data
,
msg
);
err
!=
nil
{
panic
(
err
.
Error
())
}
}
func
decodeGroupInfo
(
data
[]
byte
)
*
vty
.
GroupInfo
{
info
:=
&
vty
.
GroupInfo
{}
mustDecodeProto
(
data
,
info
)
return
info
}
func
decodeVoteInfo
(
data
[]
byte
)
*
vty
.
VoteInfo
{
info
:=
&
vty
.
VoteInfo
{}
mustDecodeProto
(
data
,
info
)
return
info
}
plugin/dapp/vote/executor/vote.go
0 → 100644
View file @
5226c257
package
executor
import
(
log
"github.com/33cn/chain33/common/log/log15"
drivers
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
votetypes
"github.com/33cn/plugin/plugin/dapp/vote/types"
)
/*
* 执行器相关定义
* 重载基类相关接口
*/
var
(
//日志
elog
=
log
.
New
(
"module"
,
"vote.executor"
)
)
var
driverName
=
votetypes
.
VoteX
// Init register dapp
func
Init
(
name
string
,
cfg
*
types
.
Chain33Config
,
sub
[]
byte
)
{
drivers
.
Register
(
cfg
,
GetName
(),
newVote
,
cfg
.
GetDappFork
(
driverName
,
"Enable"
))
InitExecType
()
}
// InitExecType Init Exec Type
func
InitExecType
()
{
ety
:=
types
.
LoadExecutorType
(
driverName
)
ety
.
InitFuncList
(
types
.
ListMethod
(
&
vote
{}))
}
type
vote
struct
{
drivers
.
DriverBase
}
func
newVote
()
drivers
.
Driver
{
t
:=
&
vote
{}
t
.
SetChild
(
t
)
t
.
SetExecutorType
(
types
.
LoadExecutorType
(
driverName
))
return
t
}
// GetName get driver name
func
GetName
()
string
{
return
newVote
()
.
GetName
()
}
func
(
v
*
vote
)
GetDriverName
()
string
{
return
driverName
}
plugin/dapp/vote/plugin.go
0 → 100644
View file @
5226c257
package
types
import
(
"github.com/33cn/chain33/pluginmgr"
"github.com/33cn/plugin/plugin/dapp/vote/commands"
"github.com/33cn/plugin/plugin/dapp/vote/executor"
"github.com/33cn/plugin/plugin/dapp/vote/rpc"
votetypes
"github.com/33cn/plugin/plugin/dapp/vote/types"
)
/*
* 初始化dapp相关的组件
*/
func
init
()
{
pluginmgr
.
Register
(
&
pluginmgr
.
PluginBase
{
Name
:
votetypes
.
VoteX
,
ExecName
:
executor
.
GetName
(),
Exec
:
executor
.
Init
,
Cmd
:
commands
.
Cmd
,
RPC
:
rpc
.
Init
,
})
}
plugin/dapp/vote/proto/Makefile
0 → 100644
View file @
5226c257
all
:
bash ./create_protobuf.sh
plugin/dapp/vote/proto/create_protobuf.sh
0 → 100644
View file @
5226c257
#!/bin/bash
# proto生成命令,将pb.go文件生成到types/目录下, chain33_path支持引用chain33框架的proto文件
chain33_path
=
$(
go list
-f
'{{.Dir}}'
"github.com/33cn/chain33"
)
protoc
--go_out
=
plugins
=
grpc:../types ./
*
.proto
--proto_path
=
.
--proto_path
=
"
${
chain33_path
}
/types/proto/"
plugin/dapp/vote/proto/vote.proto
0 → 100644
View file @
5226c257
syntax
=
"proto3"
;
package
types
;
// vote 合约交易行为总类型
message
VoteAction
{
int32
ty
=
1
;
oneof
value
{
CreateGroup
createGroup
=
2
;
UpdateMember
updateMember
=
3
;
CreateVote
createVote
=
4
;
CommitVote
commitVote
=
5
;
}
}
message
GroupMember
{
string
addr
=
1
;
uint32
voteWeight
=
2
;
}
//创建投票组
message
CreateGroup
{
string
name
=
1
;
repeated
string
admins
=
2
;
repeated
GroupMember
members
=
3
;
}
//更新投票组
message
UpdateMember
{
string
groupID
=
1
;
repeated
GroupMember
addMembers
=
2
;
repeated
string
removeMemberAddrs
=
3
;
}
//
message
GroupInfo
{
string
ID
=
1
;
string
name
=
2
;
uint32
memberNum
=
3
;
string
creator
=
4
;
repeated
string
admins
=
5
;
repeated
GroupMember
members
=
6
;
}
message
VoteOption
{
string
option
=
1
;
uint32
score
=
2
;
}
//
message
CreateVote
{
string
name
=
1
;
repeated
string
voteGroups
=
2
;
repeated
string
voteOptions
=
3
;
int64
beginTimestamp
=
4
;
int64
endTimestamp
=
5
;
}
//
message
CommitVote
{
string
voteID
=
1
;
string
groupID
=
2
;
uint32
optionIndex
=
3
;
}
//
message
VoteInfo
{
string
ID
=
1
;
string
name
=
2
;
string
creator
=
3
;
repeated
string
voteGroups
=
4
;
repeated
VoteOption
voteOptions
=
5
;
int64
beginTimestamp
=
6
;
int64
endTimestamp
=
7
;
repeated
string
votedMembers
=
8
;
}
message
VoteInfos
{
repeated
VoteInfo
voteList
=
1
;
}
message
GroupVoteInfo
{
GroupInfo
groupInfo
=
1
;
repeated
string
voteIDs
=
2
;
}
message
GroupVoteInfos
{
repeated
GroupVoteInfo
groupList
=
1
;
}
message
MemberInfo
{
string
addr
=
1
;
repeated
string
groupIDs
=
2
;
}
message
MemberInfos
{
repeated
MemberInfo
memberList
=
1
;
}
message
ReqListItem
{
string
startItemID
=
1
;
int32
count
=
2
;
int32
direction
=
3
;
}
plugin/dapp/vote/rpc/rpc.go
0 → 100644
View file @
5226c257
package
rpc
/*
* 实现json rpc和grpc service接口
* json rpc用Jrpc结构作为接收实例
* grpc使用channelClient结构作为接收实例
*/
plugin/dapp/vote/rpc/types.go
0 → 100644
View file @
5226c257
package
rpc
import
(
rpctypes
"github.com/33cn/chain33/rpc/types"
)
/*
* rpc相关结构定义和初始化
*/
// 实现grpc的service接口
type
channelClient
struct
{
rpctypes
.
ChannelClient
}
// Jrpc 实现json rpc调用实例
type
Jrpc
struct
{
cli
*
channelClient
}
// Grpc grpc
type
Grpc
struct
{
*
channelClient
}
// Init init rpc
func
Init
(
name
string
,
s
rpctypes
.
RPCServer
)
{
cli
:=
&
channelClient
{}
grpc
:=
&
Grpc
{
channelClient
:
cli
}
cli
.
Init
(
name
,
s
,
&
Jrpc
{
cli
:
cli
},
grpc
)
}
plugin/dapp/vote/types/vote.go
0 → 100644
View file @
5226c257
package
types
import
(
"reflect"
log
"github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/types"
)
/*
* 交易相关类型定义
* 交易action通常有对应的log结构,用于交易回执日志记录
* 每一种action和log需要用id数值和name名称加以区分
*/
// action类型id和name,这些常量可以自定义修改
const
(
TyUnknowAction
=
iota
+
100
TyCreateGroupAction
TyUpdateMemberAction
TyCreateVoteAction
TyCommitVoteAction
NameCreateGroupAction
=
"CreateGroup"
NameUpdateMemberAction
=
"UpdateMember"
NameCreateVoteAction
=
"CreateVote"
NameCommitVoteAction
=
"CommitVote"
)
// log类型id值
const
(
TyUnknownLog
=
iota
+
100
TyCreateGroupLog
TyUpdateMemberLog
TyCreateVoteLog
TyCommitVoteLog
NameCreateGroupLog
=
"CreateGroupLog"
NameUpdateMemberLog
=
"UpdateMemberLog"
NameCreateVoteLog
=
"CreateVoteLog"
NameCommitVoteLog
=
"CommitVoteLog"
)
var
(
//VoteX 执行器名称定义
VoteX
=
"vote"
//定义actionMap
actionMap
=
map
[
string
]
int32
{
NameCreateGroupAction
:
TyCreateGroupAction
,
NameUpdateMemberAction
:
TyUpdateMemberAction
,
NameCreateVoteAction
:
TyCreateVoteAction
,
NameCommitVoteAction
:
TyCommitVoteAction
,
}
//定义log的id和具体log类型及名称,填入具体自定义log类型
logMap
=
map
[
int64
]
*
types
.
LogInfo
{
TyCreateGroupLog
:
{
Ty
:
reflect
.
TypeOf
(
GroupInfo
{}),
Name
:
NameCreateGroupLog
},
TyUpdateMemberLog
:
{
Ty
:
reflect
.
TypeOf
(
GroupInfo
{}),
Name
:
NameUpdateMemberLog
},
TyCreateVoteLog
:
{
Ty
:
reflect
.
TypeOf
(
VoteInfo
{}),
Name
:
NameCreateVoteLog
},
TyCommitVoteLog
:
{
Ty
:
reflect
.
TypeOf
(
VoteInfo
{}),
Name
:
NameCommitVoteLog
},
}
tlog
=
log
.
New
(
"module"
,
"vote.types"
)
)
// init defines a register function
func
init
()
{
types
.
AllowUserExec
=
append
(
types
.
AllowUserExec
,
[]
byte
(
VoteX
))
//注册合约启用高度
types
.
RegFork
(
VoteX
,
InitFork
)
types
.
RegExec
(
VoteX
,
InitExecutor
)
}
// InitFork defines register fork
func
InitFork
(
cfg
*
types
.
Chain33Config
)
{
cfg
.
RegisterDappFork
(
VoteX
,
"Enable"
,
0
)
}
// InitExecutor defines register executor
func
InitExecutor
(
cfg
*
types
.
Chain33Config
)
{
types
.
RegistorExecutor
(
VoteX
,
NewType
(
cfg
))
}
type
voteType
struct
{
types
.
ExecTypeBase
}
func
NewType
(
cfg
*
types
.
Chain33Config
)
*
voteType
{
c
:=
&
voteType
{}
c
.
SetChild
(
c
)
c
.
SetConfig
(
cfg
)
return
c
}
// GetPayload 获取合约action结构
func
(
v
*
voteType
)
GetPayload
()
types
.
Message
{
return
&
VoteAction
{}
}
// GeTypeMap 获取合约action的id和name信息
func
(
v
*
voteType
)
GetTypeMap
()
map
[
string
]
int32
{
return
actionMap
}
// GetLogMap 获取合约log相关信息
func
(
v
*
voteType
)
GetLogMap
()
map
[
int64
]
*
types
.
LogInfo
{
return
logMap
}
plugin/dapp/vote/types/vote.pb.go
0 → 100644
View file @
5226c257
This diff is collapsed.
Click to expand it.
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