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
Registry
Registry
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
cd952ee4
Unverified
Commit
cd952ee4
authored
Jan 09, 2019
by
vipwzw
Committed by
GitHub
Jan 09, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #157 from zzh33cn/guess
Guess
parents
ec143947
5e4c5cd9
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
1323 additions
and
0 deletions
+1323
-0
game.go
plugin/dapp/guess/commands/game.go
+0
-0
doc.go
plugin/dapp/guess/executor/doc.go
+55
-0
exec.go
plugin/dapp/guess/executor/exec.go
+40
-0
exec_del_local.go
plugin/dapp/guess/executor/exec_del_local.go
+151
-0
exec_local.go
plugin/dapp/guess/executor/exec_local.go
+126
-0
guess.go
plugin/dapp/guess/executor/guess.go
+72
-0
guessdb.go
plugin/dapp/guess/executor/guessdb.go
+0
-0
query.go
plugin/dapp/guess/executor/query.go
+84
-0
plugin.go
plugin/dapp/guess/plugin.go
+21
-0
Makefile
plugin/dapp/guess/proto/Makefile
+2
-0
create_protobuf.sh
plugin/dapp/guess/proto/create_protobuf.sh
+2
-0
guess.proto
plugin/dapp/guess/proto/guess.proto
+248
-0
jrpc_channel_test.go
plugin/dapp/guess/rpc/jrpc_channel_test.go
+220
-0
const.go
plugin/dapp/guess/types/const.go
+94
-0
errors.go
plugin/dapp/guess/types/errors.go
+18
-0
guess.pb.go
plugin/dapp/guess/types/guess.pb.go
+0
-0
table.go
plugin/dapp/guess/types/table.go
+130
-0
types.go
plugin/dapp/guess/types/types.go
+59
-0
init.go
plugin/dapp/init/init.go
+1
-0
No files found.
plugin/dapp/guess/commands/game.go
0 → 100644
View file @
cd952ee4
This diff is collapsed.
Click to expand it.
plugin/dapp/guess/executor/doc.go
0 → 100644
View file @
cd952ee4
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
executor
/*
区块链游戏:竞猜
一、玩法简介:
博彩平台的管理员可以发布竞猜游戏,玩家可以对竞猜游戏进行投注.
截止投注时间达到后,管理员改变游戏状态为停止投注状态,玩家不能再进行投注,等待管理员公布结果.
竞猜内容的结果出来以后,管理员根据竞猜内容的真实结果触发智能合约进行输赢判断及结算。
二、创建及参与游戏
1、游戏管理员创建一局竞猜游戏时,可以设定竞猜内容,选项,赌注类型、大小及上限,截止区块高度等,比如竞猜一场足球比赛的结果,每注10BTY,单次最多可下100注,比赛开始前2小时截止投注(换算成游戏创建后多少个区块)。
2、玩家按规则进行投注,如果已过截止高度或者游戏状态已经被管理员修改为停止投注状态,则不能继续投注。
三、制胜策略
1、竞猜游戏对应的现实世界的结果出来以后,游戏管理员向区块链合约公布胜出的竞猜选项。
2、合约将投注的所有赌注向压注正确选项的玩家进行分配,分配原则根据每个地址实际投注的数额占比进行分配,比如一个地址投注占了正确选项投注总额的1/2,则该地址将获得所有赌注总额的1/2。
3、如果因为现实世界的突发异常导致竞猜不能继续(比如某场足球比赛因为不可抗力取消了,比如自然灾害、政治事件等),则管理员可以终止竞猜,合约将把所有地址的投注返还。
4、在分配奖金前,合约将向开发者地址和平台地址按预定的比率收取手续费,奖励给开发者和平台,剩余奖金在圣者之间分配。
四、游戏过程和状态
1、创建游戏,一个地址可以作为本局竞猜游戏的管理员发起竞猜游戏。
2、管理员创建游戏时指定
竞猜的内容(比如:未来的一场足球比赛)、
选项(比如:A队赢或者B队赢或者打平)、
赌注类型(比如BTY)、
单注大小(比如5BTY)、
单次最多可下注数量(比如100个BTY)、
截止下注高度(从创建游戏的高度算起,比如:区块高度差500000)
游戏超时高度(从创建游戏的高度算起,比如:区块高度差1000000)
可下注的最大数量(比如20000个BTY)
3、截止下注高度之前,玩家可根据游戏要求进行下注,下注金额注入合约地址。如果投注数量已经超过上限,则不允许新的投注。
4、截止下注高度达到后,玩家不可再下注。或者管理员将游戏状态设定为停止投注状态。
5、现实世界的竞猜结果出现后,管理员在游戏超时时间之前公布游戏结果。
6、(1)合约先对所有赌注收取一定比例的佣金,比如5‰给开发者地址,5‰给平台地址,(2)合约根据管理员输入的正确结果,对每个投注地址进行输赢判断,并将提取佣金后的剩余所有赌注对所有竞猜正确的地址按各自的投注额占比进行比例分配(比如A选项正确,所有选A的赌注共10000个BTY,某个地址向A下注100BTY,则该地址分得1/100)。
7、如果因为现实世界的突发异常导致竞猜不能继续(比如某场足球比赛因为不可抗力取消了),则管理员可以终止竞猜,合约将把所有地址的投注返还。
8、如果游戏超时,管理员仍未公布结果,则任何地址都可以触发合约异常终止竞猜,合约中的投注返还给原投注地址。
8、游戏状态:
start(管理员)->bet(玩家)->stopbet(管理员)->publish(管理员)
start(管理员)->bet(玩家)->stopbet(管理员)->abort(管理员)
start(管理员)->bet(玩家)->abort(管理员)
start(管理员)->abort(管理员)
start(管理员)->bet(玩家)->stopbet(管理员)->timeout->abort(任何人)
start(管理员)->bet(玩家)->timeout->abort(任何人)
start(管理员)->timeout->abort(任何人)
start(管理员)->stopbet(管理员)->publish(管理员)
start(管理员)->bet(玩家)->publish(管理员)
start(管理员)->publish(管理员)
说明:这里的管理员不是特殊地址,而是谁创建本局竞猜游戏,谁就是本局竞猜游戏的管理员。
*/
plugin/dapp/guess/executor/exec.go
0 → 100644
View file @
cd952ee4
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
executor
import
(
"github.com/33cn/chain33/types"
gty
"github.com/33cn/plugin/plugin/dapp/guess/types"
)
//Exec_Start Guess执行器创建游戏
func
(
c
*
Guess
)
Exec_Start
(
payload
*
gty
.
GuessGameStart
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
action
:=
NewAction
(
c
,
tx
,
index
)
return
action
.
GameStart
(
payload
)
}
//Exec_Bet Guess执行器参与游戏
func
(
c
*
Guess
)
Exec_Bet
(
payload
*
gty
.
GuessGameBet
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
action
:=
NewAction
(
c
,
tx
,
index
)
return
action
.
GameBet
(
payload
)
}
//Exec_StopBet Guess执行器停止游戏下注
func
(
c
*
Guess
)
Exec_StopBet
(
payload
*
gty
.
GuessGameStopBet
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
action
:=
NewAction
(
c
,
tx
,
index
)
return
action
.
GameStopBet
(
payload
)
}
//Exec_Publish Guess执行器公布游戏结果
func
(
c
*
Guess
)
Exec_Publish
(
payload
*
gty
.
GuessGamePublish
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
action
:=
NewAction
(
c
,
tx
,
index
)
return
action
.
GamePublish
(
payload
)
}
//Exec_Abort Guess执行器撤销未结束游戏
func
(
c
*
Guess
)
Exec_Abort
(
payload
*
gty
.
GuessGameAbort
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
action
:=
NewAction
(
c
,
tx
,
index
)
return
action
.
GameAbort
(
payload
)
}
plugin/dapp/guess/executor/exec_del_local.go
0 → 100644
View file @
cd952ee4
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
executor
import
(
"fmt"
"github.com/33cn/chain33/common/db/table"
"github.com/33cn/chain33/types"
gty
"github.com/33cn/plugin/plugin/dapp/guess/types"
)
func
(
g
*
Guess
)
rollbackGame
(
game
*
gty
.
GuessGame
,
log
*
gty
.
ReceiptGuessGame
)
{
if
game
==
nil
||
log
==
nil
{
return
}
//如果状态发生了变化,则需要将游戏状态恢复到前一状态
if
log
.
StatusChange
{
game
.
Status
=
log
.
PreStatus
game
.
Index
=
log
.
PreIndex
//玩家信息中的index回滚
for
i
:=
0
;
i
<
len
(
game
.
Plays
);
i
++
{
player
:=
game
.
Plays
[
i
]
player
.
Bet
.
Index
=
player
.
Bet
.
PreIndex
}
}
//如果下注了,则需要把下注回滚
if
log
.
Bet
{
//统计信息回滚
game
.
BetStat
.
TotalBetTimes
--
game
.
BetStat
.
TotalBetsNumber
-=
log
.
BetsNumber
for
i
:=
0
;
i
<
len
(
game
.
BetStat
.
Items
);
i
++
{
item
:=
game
.
BetStat
.
Items
[
i
]
if
item
.
Option
==
log
.
Option
{
item
.
BetsTimes
--
item
.
BetsNumber
-=
log
.
BetsNumber
break
}
}
//玩家下注信息回滚
for
i
:=
0
;
i
<
len
(
game
.
Plays
);
i
++
{
player
:=
game
.
Plays
[
i
]
if
player
.
Addr
==
log
.
Addr
&&
player
.
Bet
.
Index
==
log
.
Index
{
game
.
Plays
=
append
(
game
.
Plays
[
:
i
],
game
.
Plays
[
i
+
1
:
]
...
)
break
}
}
}
}
func
(
g
*
Guess
)
rollbackIndex
(
log
*
gty
.
ReceiptGuessGame
)
(
kvs
[]
*
types
.
KeyValue
)
{
userTable
:=
gty
.
NewGuessUserTable
(
g
.
GetLocalDB
())
gameTable
:=
gty
.
NewGuessGameTable
(
g
.
GetLocalDB
())
tablejoin
,
err
:=
table
.
NewJoinTable
(
userTable
,
gameTable
,
[]
string
{
"addr#status"
})
if
err
!=
nil
{
return
nil
}
if
log
.
Status
==
gty
.
GuessGameStatusStart
{
//新创建游戏回滚,game表删除记录
err
=
gameTable
.
Del
([]
byte
(
fmt
.
Sprintf
(
"%018d"
,
log
.
StartIndex
)))
if
err
!=
nil
{
return
nil
}
kvs
,
_
=
tablejoin
.
Save
()
return
kvs
}
else
if
log
.
Status
==
gty
.
GuessGameStatusBet
{
//下注阶段,需要更新游戏信息,回滚下注信息
game
:=
log
.
Game
log
.
Game
=
nil
//先回滚游戏信息,再进行更新
g
.
rollbackGame
(
game
,
log
)
err
=
tablejoin
.
MustGetTable
(
"game"
)
.
Replace
(
game
)
if
err
!=
nil
{
return
nil
}
err
=
tablejoin
.
MustGetTable
(
"user"
)
.
Del
([]
byte
(
fmt
.
Sprintf
(
"%018d"
,
log
.
Index
)))
if
err
!=
nil
{
return
nil
}
kvs
,
_
=
tablejoin
.
Save
()
}
else
if
log
.
StatusChange
{
//如果是其他状态下仅发生了状态变化,则需要恢复游戏状态,并更新游戏记录。
game
:=
log
.
Game
log
.
Game
=
nil
//先回滚游戏信息,再进行更新
g
.
rollbackGame
(
game
,
log
)
err
=
tablejoin
.
MustGetTable
(
"game"
)
.
Replace
(
game
)
if
err
!=
nil
{
return
nil
}
kvs
,
_
=
tablejoin
.
Save
()
}
return
kvs
}
func
(
g
*
Guess
)
execDelLocal
(
receipt
*
types
.
ReceiptData
)
(
*
types
.
LocalDBSet
,
error
)
{
dbSet
:=
&
types
.
LocalDBSet
{}
if
receipt
.
GetTy
()
!=
types
.
ExecOk
{
return
dbSet
,
nil
}
for
_
,
log
:=
range
receipt
.
Logs
{
switch
log
.
GetTy
()
{
case
gty
.
TyLogGuessGameStart
,
gty
.
TyLogGuessGameBet
,
gty
.
TyLogGuessGameStopBet
,
gty
.
TyLogGuessGameAbort
,
gty
.
TyLogGuessGamePublish
,
gty
.
TyLogGuessGameTimeout
:
receiptGame
:=
&
gty
.
ReceiptGuessGame
{}
if
err
:=
types
.
Decode
(
log
.
Log
,
receiptGame
);
err
!=
nil
{
return
nil
,
err
}
kv
:=
g
.
rollbackIndex
(
receiptGame
)
dbSet
.
KV
=
append
(
dbSet
.
KV
,
kv
...
)
}
}
return
dbSet
,
nil
}
//ExecDelLocal_Start Guess执行器Start交易撤销
func
(
g
*
Guess
)
ExecDelLocal_Start
(
payload
*
gty
.
GuessGameStart
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
return
g
.
execLocal
(
receiptData
)
}
//ExecDelLocal_Bet Guess执行器Bet交易撤销
func
(
g
*
Guess
)
ExecDelLocal_Bet
(
payload
*
gty
.
GuessGameBet
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
return
g
.
execLocal
(
receiptData
)
}
//ExecDelLocal_Publish Guess执行器Publish交易撤销
func
(
g
*
Guess
)
ExecDelLocal_Publish
(
payload
*
gty
.
GuessGamePublish
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
return
g
.
execLocal
(
receiptData
)
}
//ExecDelLocal_Abort Guess执行器Abort交易撤销
func
(
g
*
Guess
)
ExecDelLocal_Abort
(
payload
*
gty
.
GuessGameAbort
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
return
g
.
execLocal
(
receiptData
)
}
plugin/dapp/guess/executor/exec_local.go
0 → 100644
View file @
cd952ee4
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
executor
import
(
"github.com/33cn/chain33/common/db/table"
"github.com/33cn/chain33/types"
gty
"github.com/33cn/plugin/plugin/dapp/guess/types"
)
func
(
g
*
Guess
)
getUserBet
(
log
*
gty
.
ReceiptGuessGame
)
(
userBet
*
gty
.
UserBet
)
{
userBet
=
&
gty
.
UserBet
{}
userBet
.
StartIndex
=
log
.
StartIndex
userBet
.
Index
=
log
.
Index
userBet
.
GameID
=
log
.
GameID
userBet
.
Addr
=
log
.
Addr
if
log
.
Bet
{
userBet
.
Option
=
log
.
Option
userBet
.
BetsNumber
=
log
.
BetsNumber
}
return
userBet
}
func
(
g
*
Guess
)
updateIndex
(
log
*
gty
.
ReceiptGuessGame
)
(
kvs
[]
*
types
.
KeyValue
)
{
userTable
:=
gty
.
NewGuessUserTable
(
g
.
GetLocalDB
())
gameTable
:=
gty
.
NewGuessGameTable
(
g
.
GetLocalDB
())
tablejoin
,
err
:=
table
.
NewJoinTable
(
userTable
,
gameTable
,
[]
string
{
"addr#status"
})
if
err
!=
nil
{
return
nil
}
if
log
.
Status
==
gty
.
GuessGameStatusStart
{
//新创建游戏,game表新增记录
game
:=
log
.
Game
log
.
Game
=
nil
err
=
tablejoin
.
MustGetTable
(
"game"
)
.
Replace
(
game
)
if
err
!=
nil
{
return
nil
}
kvs
,
_
=
tablejoin
.
Save
()
return
kvs
}
else
if
log
.
Status
==
gty
.
GuessGameStatusBet
{
//用户下注,game表发生更新(game中下注信息有更新),user表新增下注记录
game
:=
log
.
Game
log
.
Game
=
nil
userBet
:=
g
.
getUserBet
(
log
)
err
=
tablejoin
.
MustGetTable
(
"game"
)
.
Replace
(
game
)
if
err
!=
nil
{
return
nil
}
err
=
tablejoin
.
MustGetTable
(
"user"
)
.
Replace
(
userBet
)
if
err
!=
nil
{
return
nil
}
kvs
,
_
=
tablejoin
.
Save
()
return
kvs
}
else
if
log
.
StatusChange
{
//其他状态,游戏状态变化,只需要更新game表
game
:=
log
.
Game
log
.
Game
=
nil
err
=
tablejoin
.
MustGetTable
(
"game"
)
.
Replace
(
game
)
if
err
!=
nil
{
return
nil
}
kvs
,
_
=
tablejoin
.
Save
()
return
kvs
}
return
kvs
}
func
(
g
*
Guess
)
execLocal
(
receipt
*
types
.
ReceiptData
)
(
*
types
.
LocalDBSet
,
error
)
{
dbSet
:=
&
types
.
LocalDBSet
{}
if
receipt
.
GetTy
()
!=
types
.
ExecOk
{
return
dbSet
,
nil
}
for
_
,
item
:=
range
receipt
.
Logs
{
if
item
.
Ty
>=
gty
.
TyLogGuessGameStart
&&
item
.
Ty
<=
gty
.
TyLogGuessGameTimeout
{
var
gameLog
gty
.
ReceiptGuessGame
err
:=
types
.
Decode
(
item
.
Log
,
&
gameLog
)
if
err
!=
nil
{
return
nil
,
err
}
kvs
:=
g
.
updateIndex
(
&
gameLog
)
dbSet
.
KV
=
append
(
dbSet
.
KV
,
kvs
...
)
}
}
return
dbSet
,
nil
}
//ExecLocal_Start method
func
(
g
*
Guess
)
ExecLocal_Start
(
payload
*
gty
.
GuessGameStart
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
return
g
.
execLocal
(
receiptData
)
}
//ExecLocal_Bet method
func
(
g
*
Guess
)
ExecLocal_Bet
(
payload
*
gty
.
GuessGameBet
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
return
g
.
execLocal
(
receiptData
)
}
//ExecLocal_StopBet method
func
(
g
*
Guess
)
ExecLocal_StopBet
(
payload
*
gty
.
GuessGameStopBet
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
return
g
.
execLocal
(
receiptData
)
}
//ExecLocal_Publish method
func
(
g
*
Guess
)
ExecLocal_Publish
(
payload
*
gty
.
GuessGamePublish
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
return
g
.
execLocal
(
receiptData
)
}
//ExecLocal_Abort method
func
(
g
*
Guess
)
ExecLocal_Abort
(
payload
*
gty
.
GuessGameAbort
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
return
g
.
execLocal
(
receiptData
)
}
plugin/dapp/guess/executor/guess.go
0 → 100644
View file @
cd952ee4
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
executor
import
(
log
"github.com/33cn/chain33/common/log/log15"
drivers
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
gty
"github.com/33cn/plugin/plugin/dapp/guess/types"
)
var
logger
=
log
.
New
(
"module"
,
"execs.guess"
)
var
driverName
=
gty
.
GuessX
func
init
()
{
ety
:=
types
.
LoadExecutorType
(
driverName
)
ety
.
InitFuncList
(
types
.
ListMethod
(
&
Guess
{}))
}
type
subConfig
struct
{
ParaRemoteGrpcClient
string
`json:"paraRemoteGrpcClient"`
}
var
cfg
subConfig
// Init Guess
func
Init
(
name
string
,
sub
[]
byte
)
{
driverName
:=
GetName
()
if
name
!=
driverName
{
panic
(
"system dapp can't be rename"
)
}
if
sub
!=
nil
{
types
.
MustDecode
(
sub
,
&
cfg
)
}
drivers
.
Register
(
driverName
,
newGuessGame
,
types
.
GetDappFork
(
driverName
,
"Enable"
))
}
//Guess 执行器,用于竞猜合约的具体执行
type
Guess
struct
{
drivers
.
DriverBase
}
func
newGuessGame
()
drivers
.
Driver
{
t
:=
&
Guess
{}
t
.
SetChild
(
t
)
t
.
SetExecutorType
(
types
.
LoadExecutorType
(
driverName
))
return
t
}
//GetName 获取Guess执行器的名称
func
GetName
()
string
{
return
newGuessGame
()
.
GetName
()
}
//GetDriverName 获取Guess执行器的名称
func
(
g
*
Guess
)
GetDriverName
()
string
{
return
gty
.
GuessX
}
/*
// GetPayloadValue GuessAction
func (g *Guess) GetPayloadValue() types.Message {
return &pkt.GuessGameAction{}
}*/
// CheckReceiptExecOk return true to check if receipt ty is ok
func
(
g
*
Guess
)
CheckReceiptExecOk
()
bool
{
return
true
}
plugin/dapp/guess/executor/guessdb.go
0 → 100644
View file @
cd952ee4
This diff is collapsed.
Click to expand it.
plugin/dapp/guess/executor/query.go
0 → 100644
View file @
cd952ee4
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
executor
import
(
"fmt"
"github.com/33cn/chain33/common/db/table"
"github.com/33cn/chain33/types"
gty
"github.com/33cn/plugin/plugin/dapp/guess/types"
)
//Query_QueryGamesByIDs method
func
(
g
*
Guess
)
Query_QueryGamesByIDs
(
in
*
gty
.
QueryGuessGameInfos
)
(
types
.
Message
,
error
)
{
return
queryGameInfos
(
g
.
GetLocalDB
(),
in
)
}
//Query_QueryGameByID method
func
(
g
*
Guess
)
Query_QueryGameByID
(
in
*
gty
.
QueryGuessGameInfo
)
(
types
.
Message
,
error
)
{
game
,
err
:=
queryGameInfo
(
g
.
GetLocalDB
(),
[]
byte
(
in
.
GetGameID
()))
if
err
!=
nil
{
return
nil
,
err
}
return
&
gty
.
ReplyGuessGameInfo
{
Game
:
game
},
nil
}
//Query_QueryGamesByAddr method
func
(
g
*
Guess
)
Query_QueryGamesByAddr
(
in
*
gty
.
QueryGuessGameInfo
)
(
types
.
Message
,
error
)
{
gameTable
:=
gty
.
NewGuessUserTable
(
g
.
GetLocalDB
())
query
:=
gameTable
.
GetQuery
(
g
.
GetLocalDB
())
return
queryUserTableData
(
query
,
"addr"
,
[]
byte
(
in
.
Addr
),
[]
byte
(
in
.
PrimaryKey
))
}
//Query_QueryGamesByStatus method
func
(
g
*
Guess
)
Query_QueryGamesByStatus
(
in
*
gty
.
QueryGuessGameInfo
)
(
types
.
Message
,
error
)
{
gameTable
:=
gty
.
NewGuessGameTable
(
g
.
GetLocalDB
())
query
:=
gameTable
.
GetQuery
(
g
.
GetLocalDB
())
return
queryGameTableData
(
query
,
"status"
,
[]
byte
(
fmt
.
Sprintf
(
"%2d"
,
in
.
Status
)),
[]
byte
(
in
.
PrimaryKey
))
}
//Query_QueryGamesByAdminAddr method
func
(
g
*
Guess
)
Query_QueryGamesByAdminAddr
(
in
*
gty
.
QueryGuessGameInfo
)
(
types
.
Message
,
error
)
{
gameTable
:=
gty
.
NewGuessGameTable
(
g
.
GetLocalDB
())
query
:=
gameTable
.
GetQuery
(
g
.
GetLocalDB
())
prefix
:=
[]
byte
(
in
.
AdminAddr
)
return
queryGameTableData
(
query
,
"admin"
,
prefix
,
[]
byte
(
in
.
PrimaryKey
))
}
//Query_QueryGamesByAddrStatus method
func
(
g
*
Guess
)
Query_QueryGamesByAddrStatus
(
in
*
gty
.
QueryGuessGameInfo
)
(
types
.
Message
,
error
)
{
userTable
:=
gty
.
NewGuessUserTable
(
g
.
GetLocalDB
())
gameTable
:=
gty
.
NewGuessGameTable
(
g
.
GetLocalDB
())
tableJoin
,
err
:=
table
.
NewJoinTable
(
userTable
,
gameTable
,
[]
string
{
"addr#status"
})
if
err
!=
nil
{
return
nil
,
err
}
prefix
:=
table
.
JoinKey
([]
byte
(
in
.
Addr
),
[]
byte
(
fmt
.
Sprintf
(
"%2d"
,
in
.
Status
)))
return
queryJoinTableData
(
tableJoin
,
"addr#status"
,
prefix
,
[]
byte
(
in
.
PrimaryKey
))
}
//Query_QueryGamesByAdminStatus method
func
(
g
*
Guess
)
Query_QueryGamesByAdminStatus
(
in
*
gty
.
QueryGuessGameInfo
)
(
types
.
Message
,
error
)
{
gameTable
:=
gty
.
NewGuessGameTable
(
g
.
GetLocalDB
())
query
:=
gameTable
.
GetQuery
(
g
.
GetLocalDB
())
prefix
:=
[]
byte
(
fmt
.
Sprintf
(
"%s:%2d"
,
in
.
AdminAddr
,
in
.
Status
))
return
queryGameTableData
(
query
,
"admin_status"
,
prefix
,
[]
byte
(
in
.
PrimaryKey
))
}
//Query_QueryGamesByCategoryStatus method
func
(
g
*
Guess
)
Query_QueryGamesByCategoryStatus
(
in
*
gty
.
QueryGuessGameInfo
)
(
types
.
Message
,
error
)
{
gameTable
:=
gty
.
NewGuessGameTable
(
g
.
GetLocalDB
())
query
:=
gameTable
.
GetQuery
(
g
.
GetLocalDB
())
prefix
:=
[]
byte
(
fmt
.
Sprintf
(
"%s:%2d"
,
in
.
Category
,
in
.
Status
))
return
queryGameTableData
(
query
,
"category_status"
,
prefix
,
[]
byte
(
in
.
PrimaryKey
))
}
plugin/dapp/guess/plugin.go
0 → 100644
View file @
cd952ee4
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
guess
import
(
"github.com/33cn/chain33/pluginmgr"
"github.com/33cn/plugin/plugin/dapp/guess/commands"
"github.com/33cn/plugin/plugin/dapp/guess/executor"
"github.com/33cn/plugin/plugin/dapp/guess/types"
)
func
init
()
{
pluginmgr
.
Register
(
&
pluginmgr
.
PluginBase
{
Name
:
types
.
GuessX
,
ExecName
:
executor
.
GetName
(),
Exec
:
executor
.
Init
,
Cmd
:
commands
.
GuessCmd
,
})
}
plugin/dapp/guess/proto/Makefile
0 → 100644
View file @
cd952ee4
all
:
sh ./create_protobuf.sh
plugin/dapp/guess/proto/create_protobuf.sh
0 → 100755
View file @
cd952ee4
#!/bin/sh
protoc
--go_out
=
plugins
=
grpc:../types ./
*
.proto
--proto_path
=
.
--proto_path
=
"../../../../vendor/github.com/33cn/chain33/types/proto/"
plugin/dapp/guess/proto/guess.proto
0 → 100644
View file @
cd952ee4
syntax
=
"proto3"
;
import
"transaction.proto"
;
package
types
;
//GuessGame 竞猜游戏详情
message
GuessGame
{
string
gameID
=
1
;
//游戏ID
int32
status
=
2
;
//游戏的状态:创建->投注->截止投注->开奖
int32
preStatus
=
3
;
int64
startTime
=
4
;
//创建游戏的时间
int64
startHeight
=
5
;
//创建游戏的时间
string
startTxHash
=
6
;
//创建游戏的交易hash
int64
startIndex
=
7
;
//创建游戏的交易index
string
topic
=
8
;
//主题
string
category
=
9
;
//分类
string
options
=
10
;
//选项
int64
maxBetHeight
=
11
;
//截止下注的块高
int64
maxBetsOneTime
=
12
;
//单次可以下多少注,默认100
int64
maxBetsNumber
=
13
;
//最多可以下多少注
int64
devFeeFactor
=
14
;
//开发者抽成比例
string
devFeeAddr
=
15
;
//开发者地址
int64
platFeeFactor
=
16
;
//平台抽成比例
string
platFeeAddr
=
17
;
//平台地址
int64
expireHeight
=
18
;
//游戏过期区块高度
string
adminAddr
=
19
;
//游戏创建者地址,只有该地址可以开奖
int64
betsNumber
=
20
;
//已下注数,如果数量达到maxBetsNumber,则不允许再下注
repeated
GuessPlayer
plays
=
21
;
//参与游戏下注的玩家投注信息
string
result
=
22
;
//公布的中奖结果
GuessBetStat
betStat
=
23
;
int64
index
=
24
;
int64
preIndex
=
25
;
bool
drivenByAdmin
=
26
;
}
//GuessPlayer 竞猜玩家信息
message
GuessPlayer
{
string
addr
=
1
;
GuessBet
bet
=
2
;
}
//GuessBet 竞猜下注信息
message
GuessBet
{
string
option
=
1
;
int64
betsNumber
=
2
;
bool
isWinner
=
3
;
int64
profit
=
4
;
int64
index
=
5
;
int64
preIndex
=
6
;
}
//GuessBetStat 竞猜下注统计信息
message
GuessBetStat
{
int64
totalBetTimes
=
1
;
int64
totalBetsNumber
=
2
;
repeated
GuessBetStatItem
items
=
3
;
}
//GuessBetStat 竞猜下注子选项统计信息
message
GuessBetStatItem
{
string
option
=
1
;
int64
betsNumber
=
2
;
int64
betsTimes
=
3
;
}
//GuessGameAction 竞猜游戏动作
message
GuessGameAction
{
oneof
value
{
GuessGameStart
start
=
1
;
GuessGameBet
bet
=
2
;
GuessGameStopBet
stopBet
=
3
;
GuessGameAbort
abort
=
4
;
GuessGamePublish
publish
=
5
;
GuessGameQuery
query
=
6
;
}
int32
ty
=
7
;
}
//GuessGameStart 游戏创建
message
GuessGameStart
{
string
topic
=
1
;
string
options
=
2
;
string
category
=
3
;
int64
maxBetHeight
=
4
;
int64
maxBetsOneTime
=
5
;
int64
maxBetsNumber
=
6
;
int64
devFeeFactor
=
7
;
//开发者抽成比例
string
devFeeAddr
=
8
;
//开发者地址
int64
platFeeFactor
=
9
;
//平台抽成比例
string
platFeeAddr
=
10
;
//平台地址
int64
expireHeight
=
11
;
bool
drivenByAdmin
=
12
;
}
//GuessGameBet 参与游戏下注
message
GuessGameBet
{
string
gameID
=
1
;
string
option
=
2
;
int64
betsNum
=
3
;
}
//GuessGameStopBet 游戏停止下注
message
GuessGameStopBet
{
string
gameID
=
1
;
}
//GuessGameAbort 游戏异常终止,退还下注
message
GuessGameAbort
{
string
gameID
=
1
;
}
//GuessGamePublish 游戏结果揭晓
message
GuessGamePublish
{
string
gameID
=
1
;
string
result
=
2
;
}
//GuessGameQuery 查询游戏结果
message
GuessGameQuery
{
string
gameID
=
1
;
uint32
ty
=
2
;
}
//QueryGuessGameInfo 游戏信息查询消息
message
QueryGuessGameInfo
{
string
gameID
=
1
;
string
addr
=
2
;
int32
status
=
3
;
int64
index
=
4
;
string
adminAddr
=
5
;
string
category
=
6
;
string
primaryKey
=
7
;
}
//ReplyGuessGameInfo 游戏信息查询响应消息
message
ReplyGuessGameInfo
{
GuessGame
game
=
1
;
}
//QueryGuessGameInfos 游戏信息列表查询消息
message
QueryGuessGameInfos
{
repeated
string
gameIDs
=
1
;
}
//ReplyGuessGameInfos 游戏信息列表查询响应消息
message
ReplyGuessGameInfos
{
repeated
GuessGame
games
=
1
;
}
//ReceiptGuessGame 竞猜游戏收据信息
message
ReceiptGuessGame
{
int64
startIndex
=
1
;
string
gameID
=
2
;
int32
preStatus
=
3
;
int32
status
=
4
;
string
addr
=
5
;
string
adminAddr
=
6
;
int64
preIndex
=
7
;
int64
index
=
8
;
string
category
=
9
;
bool
statusChange
=
10
;
bool
bet
=
11
;
string
option
=
12
;
int64
betsNumber
=
13
;
GuessGame
game
=
14
;
}
//UserBet 用户下注信息
message
UserBet
{
int64
startIndex
=
1
;
int64
index
=
2
;
string
gameID
=
3
;
string
addr
=
4
;
string
option
=
5
;
int64
betsNumber
=
6
;
}
//GuessStartTxReq 构造start交易的请求
message
GuessStartTxReq
{
string
topic
=
1
;
string
options
=
2
;
string
category
=
3
;
int64
maxHeight
=
4
;
int64
maxBetHeight
=
5
;
int64
maxBetsOneTime
=
6
;
int64
maxBetsNumber
=
7
;
int64
devFeeFactor
=
8
;
string
devFeeAddr
=
9
;
int64
platFeeFactor
=
10
;
string
platFeeAddr
=
11
;
int64
expireHeight
=
12
;
int64
fee
=
13
;
}
//GuessBetTxReq 构造bet交易的请求
message
GuessBetTxReq
{
string
gameID
=
1
;
string
option
=
2
;
int64
bets
=
3
;
int64
fee
=
4
;
}
//GuessStopBetTxReq 构造stopBet交易的请求
message
GuessStopBetTxReq
{
string
gameID
=
1
;
int64
fee
=
2
;
}
//GuessAbortTxReq 构造abort交易的请求
message
GuessAbortTxReq
{
string
gameID
=
1
;
int64
fee
=
2
;
}
//GuessPublishTxReq 构造publish交易的请求
message
GuessPublishTxReq
{
string
gameID
=
1
;
string
result
=
2
;
int64
fee
=
3
;
}
// GuessGameRecord game信息查询记录
message
GuessGameRecord
{
string
gameID
=
1
;
int64
startIndex
=
2
;
}
// GuessGameRecords game信息查询记录集
message
GuessGameRecords
{
repeated
GuessGameRecord
records
=
1
;
string
primaryKey
=
2
;
}
// service guess 为guess 对外提供服务的接口
service
guess
{
//游戏开始
rpc
GuessStart
(
GuessGameStart
)
returns
(
UnsignTx
)
{}
//游戏下注
rpc
GuessBet
(
GuessGameBet
)
returns
(
UnsignTx
)
{}
//游戏终止下注
rpc
GuessStopBet
(
GuessGameStopBet
)
returns
(
UnsignTx
)
{}
//游戏异常终止
rpc
GuessAbort
(
GuessGameAbort
)
returns
(
UnsignTx
)
{}
//游戏结束
rpc
GuessPublish
(
GuessGamePublish
)
returns
(
UnsignTx
)
{}
}
plugin/dapp/guess/rpc/jrpc_channel_test.go
0 → 100644
View file @
cd952ee4
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
rpc_test
import
(
"fmt"
"testing"
commonlog
"github.com/33cn/chain33/common/log"
"github.com/33cn/chain33/rpc/jsonclient"
rpctypes
"github.com/33cn/chain33/rpc/types"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util/testnode"
pty
"github.com/33cn/plugin/plugin/dapp/guess/types"
"github.com/stretchr/testify/assert"
_
"github.com/33cn/chain33/system"
_
"github.com/33cn/plugin/plugin"
)
func
init
()
{
commonlog
.
SetLogLevel
(
"error"
)
}
func
TestJRPCChannel
(
t
*
testing
.
T
)
{
// 启动RPCmocker
mocker
:=
testnode
.
New
(
"--notset--"
,
nil
)
defer
func
()
{
mocker
.
Close
()
}()
mocker
.
Listen
()
jrpcClient
:=
mocker
.
GetJSONC
()
assert
.
NotNil
(
t
,
jrpcClient
)
testCases
:=
[]
struct
{
fn
func
(
*
testing
.
T
,
*
jsonclient
.
JSONClient
)
error
}{
{
fn
:
testStartRawTxCmd
},
{
fn
:
testBetRawTxCmd
},
{
fn
:
testStopBetRawTxCmd
},
{
fn
:
testPublishRawTxCmd
},
{
fn
:
testAbortRawTxCmd
},
}
for
_
,
testCase
:=
range
testCases
{
err
:=
testCase
.
fn
(
t
,
jrpcClient
)
assert
.
Nil
(
t
,
err
)
}
testCases
=
[]
struct
{
fn
func
(
*
testing
.
T
,
*
jsonclient
.
JSONClient
)
error
}{
{
fn
:
testQueryGameByID
},
{
fn
:
testQueryGamesByAddr
},
{
fn
:
testQueryGamesByStatus
},
{
fn
:
testQueryGamesByAdminAddr
},
{
fn
:
testQueryGamesByAddrStatus
},
{
fn
:
testQueryGamesByAdminStatus
},
{
fn
:
testQueryGamesByCategoryStatus
},
}
for
index
,
testCase
:=
range
testCases
{
err
:=
testCase
.
fn
(
t
,
jrpcClient
)
assert
.
Equal
(
t
,
err
,
types
.
ErrNotFound
,
fmt
.
Sprint
(
index
))
}
testCases
=
[]
struct
{
fn
func
(
*
testing
.
T
,
*
jsonclient
.
JSONClient
)
error
}{
{
fn
:
testQueryGamesByIDs
},
}
for
index
,
testCase
:=
range
testCases
{
err
:=
testCase
.
fn
(
t
,
jrpcClient
)
assert
.
Equal
(
t
,
err
,
nil
,
fmt
.
Sprint
(
index
))
}
}
func
testStartRawTxCmd
(
t
*
testing
.
T
,
jrpc
*
jsonclient
.
JSONClient
)
error
{
payload
:=
&
pty
.
GuessGameStart
{
Topic
:
"WorldCup Final"
,
Options
:
"A:France;B:Claodia"
,
Category
:
"football"
,
MaxBetsOneTime
:
100e8
,
MaxBetsNumber
:
1000e8
,
DevFeeFactor
:
5
,
DevFeeAddr
:
"1D6RFZNp2rh6QdbcZ1d7RWuBUz61We6SD7"
,
PlatFeeFactor
:
5
,
PlatFeeAddr
:
"1PHtChNt3UcfssR7v7trKSk3WJtAWjKjjX"
}
params
:=
&
rpctypes
.
CreateTxIn
{
Execer
:
types
.
ExecName
(
pty
.
GuessX
),
ActionName
:
pty
.
CreateStartTx
,
Payload
:
types
.
MustPBToJSON
(
payload
),
}
var
res
string
return
jrpc
.
Call
(
"Chain33.CreateTransaction"
,
params
,
&
res
)
}
func
testBetRawTxCmd
(
t
*
testing
.
T
,
jrpc
*
jsonclient
.
JSONClient
)
error
{
payload
:=
&
pty
.
GuessGameBet
{
GameID
:
"0x76dae82fcbe554d4b8df5ed1460d71dcac86a50864649a0df43e0c50b245f004"
,
Option
:
"A"
,
BetsNum
:
5e8
}
params
:=
&
rpctypes
.
CreateTxIn
{
Execer
:
types
.
ExecName
(
pty
.
GuessX
),
ActionName
:
pty
.
CreateBetTx
,
Payload
:
types
.
MustPBToJSON
(
payload
),
}
var
res
string
return
jrpc
.
Call
(
"Chain33.CreateTransaction"
,
params
,
&
res
)
}
func
testStopBetRawTxCmd
(
t
*
testing
.
T
,
jrpc
*
jsonclient
.
JSONClient
)
error
{
payload
:=
&
pty
.
GuessGameStopBet
{
GameID
:
"0x76dae82fcbe554d4b8df5ed1460d71dcac86a50864649a0df43e0c50b245f004"
}
params
:=
&
rpctypes
.
CreateTxIn
{
Execer
:
types
.
ExecName
(
pty
.
GuessX
),
ActionName
:
pty
.
CreateStopBetTx
,
Payload
:
types
.
MustPBToJSON
(
payload
),
}
var
res
string
return
jrpc
.
Call
(
"Chain33.CreateTransaction"
,
params
,
&
res
)
}
func
testPublishRawTxCmd
(
t
*
testing
.
T
,
jrpc
*
jsonclient
.
JSONClient
)
error
{
payload
:=
&
pty
.
GuessGamePublish
{
GameID
:
"0x76dae82fcbe554d4b8df5ed1460d71dcac86a50864649a0df43e0c50b245f004"
,
Result
:
"A"
}
params
:=
&
rpctypes
.
CreateTxIn
{
Execer
:
types
.
ExecName
(
pty
.
GuessX
),
ActionName
:
pty
.
CreatePublishTx
,
Payload
:
types
.
MustPBToJSON
(
payload
),
}
var
res
string
return
jrpc
.
Call
(
"Chain33.CreateTransaction"
,
params
,
&
res
)
}
func
testAbortRawTxCmd
(
t
*
testing
.
T
,
jrpc
*
jsonclient
.
JSONClient
)
error
{
payload
:=
&
pty
.
GuessGameAbort
{
GameID
:
"0x76dae82fcbe554d4b8df5ed1460d71dcac86a50864649a0df43e0c50b245f004"
}
params
:=
&
rpctypes
.
CreateTxIn
{
Execer
:
types
.
ExecName
(
pty
.
GuessX
),
ActionName
:
pty
.
CreateAbortTx
,
Payload
:
types
.
MustPBToJSON
(
payload
),
}
var
res
string
return
jrpc
.
Call
(
"Chain33.CreateTransaction"
,
params
,
&
res
)
}
func
testQueryGameByID
(
t
*
testing
.
T
,
jrpc
*
jsonclient
.
JSONClient
)
error
{
var
rep
interface
{}
var
params
rpctypes
.
Query4Jrpc
req
:=
&
pty
.
QueryGuessGameInfo
{}
params
.
Execer
=
pty
.
GuessX
params
.
FuncName
=
pty
.
FuncNameQueryGameByID
params
.
Payload
=
types
.
MustPBToJSON
(
req
)
rep
=
&
pty
.
ReplyGuessGameInfo
{}
return
jrpc
.
Call
(
"Chain33.Query"
,
params
,
rep
)
}
func
testQueryGamesByAddr
(
t
*
testing
.
T
,
jrpc
*
jsonclient
.
JSONClient
)
error
{
var
rep
interface
{}
var
params
rpctypes
.
Query4Jrpc
req
:=
&
pty
.
QueryGuessGameInfo
{}
params
.
Execer
=
pty
.
GuessX
params
.
FuncName
=
pty
.
FuncNameQueryGameByAddr
params
.
Payload
=
types
.
MustPBToJSON
(
req
)
rep
=
&
pty
.
GuessGameRecords
{}
return
jrpc
.
Call
(
"Chain33.Query"
,
params
,
rep
)
}
func
testQueryGamesByIDs
(
t
*
testing
.
T
,
jrpc
*
jsonclient
.
JSONClient
)
error
{
var
rep
interface
{}
var
params
rpctypes
.
Query4Jrpc
req
:=
&
pty
.
QueryGuessGameInfos
{}
params
.
Execer
=
pty
.
GuessX
params
.
FuncName
=
pty
.
FuncNameQueryGamesByIDs
params
.
Payload
=
types
.
MustPBToJSON
(
req
)
rep
=
&
pty
.
ReplyGuessGameInfos
{}
return
jrpc
.
Call
(
"Chain33.Query"
,
params
,
rep
)
}
func
testQueryGamesByStatus
(
t
*
testing
.
T
,
jrpc
*
jsonclient
.
JSONClient
)
error
{
var
rep
interface
{}
var
params
rpctypes
.
Query4Jrpc
req
:=
&
pty
.
QueryGuessGameInfo
{}
params
.
Execer
=
pty
.
GuessX
params
.
FuncName
=
pty
.
FuncNameQueryGameByStatus
params
.
Payload
=
types
.
MustPBToJSON
(
req
)
rep
=
&
pty
.
GuessGameRecords
{}
return
jrpc
.
Call
(
"Chain33.Query"
,
params
,
rep
)
}
func
testQueryGamesByAdminAddr
(
t
*
testing
.
T
,
jrpc
*
jsonclient
.
JSONClient
)
error
{
var
rep
interface
{}
var
params
rpctypes
.
Query4Jrpc
req
:=
&
pty
.
QueryGuessGameInfo
{}
params
.
Execer
=
pty
.
GuessX
params
.
FuncName
=
pty
.
FuncNameQueryGameByAdminAddr
params
.
Payload
=
types
.
MustPBToJSON
(
req
)
rep
=
&
pty
.
GuessGameRecords
{}
return
jrpc
.
Call
(
"Chain33.Query"
,
params
,
rep
)
}
func
testQueryGamesByAddrStatus
(
t
*
testing
.
T
,
jrpc
*
jsonclient
.
JSONClient
)
error
{
var
rep
interface
{}
var
params
rpctypes
.
Query4Jrpc
req
:=
&
pty
.
QueryGuessGameInfo
{}
params
.
Execer
=
pty
.
GuessX
params
.
FuncName
=
pty
.
FuncNameQueryGameByAddrStatus
params
.
Payload
=
types
.
MustPBToJSON
(
req
)
rep
=
&
pty
.
GuessGameRecords
{}
return
jrpc
.
Call
(
"Chain33.Query"
,
params
,
rep
)
}
func
testQueryGamesByAdminStatus
(
t
*
testing
.
T
,
jrpc
*
jsonclient
.
JSONClient
)
error
{
var
rep
interface
{}
var
params
rpctypes
.
Query4Jrpc
req
:=
&
pty
.
QueryGuessGameInfo
{}
params
.
Execer
=
pty
.
GuessX
params
.
FuncName
=
pty
.
FuncNameQueryGameByAdminStatus
params
.
Payload
=
types
.
MustPBToJSON
(
req
)
rep
=
&
pty
.
GuessGameRecords
{}
return
jrpc
.
Call
(
"Chain33.Query"
,
params
,
rep
)
}
func
testQueryGamesByCategoryStatus
(
t
*
testing
.
T
,
jrpc
*
jsonclient
.
JSONClient
)
error
{
var
rep
interface
{}
var
params
rpctypes
.
Query4Jrpc
req
:=
&
pty
.
QueryGuessGameInfo
{}
params
.
Execer
=
pty
.
GuessX
params
.
FuncName
=
pty
.
FuncNameQueryGameByCategoryStatus
params
.
Payload
=
types
.
MustPBToJSON
(
req
)
rep
=
&
pty
.
GuessGameRecords
{}
return
jrpc
.
Call
(
"Chain33.Query"
,
params
,
rep
)
}
plugin/dapp/guess/types/const.go
0 → 100644
View file @
cd952ee4
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
types
//game action ty
const
(
PBGameActionStart
=
iota
+
1
PBGameActionContinue
PBGameActionQuit
PBGameActionQuery
GuessGameActionStart
=
iota
+
1
GuessGameActionBet
GuessGameActionStopBet
GuessGameActionAbort
GuessGameActionPublish
GuessGameActionQuery
GuessGameStatusStart
=
iota
+
1
GuessGameStatusBet
GuessGameStatusStopBet
GuessGameStatusAbort
GuessGameStatusPublish
GuessGameStatusTimeOut
)
//game log ty
const
(
TyLogGuessGameStart
=
901
TyLogGuessGameBet
=
902
TyLogGuessGameStopBet
=
903
TyLogGuessGameAbort
=
904
TyLogGuessGamePublish
=
905
TyLogGuessGameTimeout
=
906
)
//包的名字可以通过配置文件来配置
//建议用github的组织名称,或者用户名字开头, 再加上自己的插件的名字
//如果发生重名,可以通过配置文件修改这些名字
var
(
GuessX
=
"guess"
ExecerGuess
=
[]
byte
(
GuessX
)
)
const
(
//FuncNameQueryGamesByIDs func name
FuncNameQueryGamesByIDs
=
"QueryGamesByIDs"
//FuncNameQueryGameByID func name
FuncNameQueryGameByID
=
"QueryGameByID"
//FuncNameQueryGameByAddr func name
FuncNameQueryGameByAddr
=
"QueryGamesByAddr"
//FuncNameQueryGameByStatus func name
FuncNameQueryGameByStatus
=
"QueryGamesByStatus"
//FuncNameQueryGameByAdminAddr func name
FuncNameQueryGameByAdminAddr
=
"QueryGamesByAdminAddr"
//FuncNameQueryGameByAddrStatus func name
FuncNameQueryGameByAddrStatus
=
"QueryGamesByAddrStatus"
//FuncNameQueryGameByAdminStatus func name
FuncNameQueryGameByAdminStatus
=
"QueryGamesByAdminStatus"
//FuncNameQueryGameByCategoryStatus func name
FuncNameQueryGameByCategoryStatus
=
"QueryGamesByCategoryStatus"
//CreateStartTx 创建开始交易
CreateStartTx
=
"Start"
//CreateBetTx 创建下注交易
CreateBetTx
=
"Bet"
//CreateStopBetTx 创建停止下注交易
CreateStopBetTx
=
"StopBet"
//CreatePublishTx 创建公布结果交易
CreatePublishTx
=
"Publish"
//CreateAbortTx 创建撤销游戏交易
CreateAbortTx
=
"Abort"
)
const
(
//DevShareAddr default value
DevShareAddr
=
"1D6RFZNp2rh6QdbcZ1d7RWuBUz61We6SD7"
//PlatformShareAddr default value
PlatformShareAddr
=
"1PHtChNt3UcfssR7v7trKSk3WJtAWjKjjX"
)
plugin/dapp/guess/types/errors.go
0 → 100755
View file @
cd952ee4
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
types
import
"errors"
// Errors for lottery
var
(
ErrNoPrivilege
=
errors
.
New
(
"ErrNoPrivilege"
)
ErrGuessStatus
=
errors
.
New
(
"ErrGuessStatus"
)
ErrOverBetsLimit
=
errors
.
New
(
"ErrOverBetsLimit"
)
ErrParamStatusInvalid
=
errors
.
New
(
"ErrParamStatusInvalid"
)
ErrParamAddressMustnotEmpty
=
errors
.
New
(
"ErrParamAddressMustnotEmpty"
)
ErrGameNotExist
=
errors
.
New
(
"ErrGameNotExist"
)
ErrSaveTable
=
errors
.
New
(
"ErrSaveTable"
)
)
plugin/dapp/guess/types/guess.pb.go
0 → 100644
View file @
cd952ee4
This diff is collapsed.
Click to expand it.
plugin/dapp/guess/types/table.go
0 → 100644
View file @
cd952ee4
package
types
import
(
"fmt"
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/common/db/table"
"github.com/33cn/chain33/types"
)
/*
table struct
data: guess
index: addr,status,addr_status,admin,admin_status,category_status
*/
var
opt_guess_user
=
&
table
.
Option
{
Prefix
:
"LODB_guess"
,
Name
:
"user"
,
Primary
:
"index"
,
Index
:
[]
string
{
"addr"
,
"startindex"
},
}
//NewGuessUserTable 新建表
func
NewGuessUserTable
(
kvdb
db
.
KV
)
*
table
.
Table
{
rowmeta
:=
NewGuessUserRow
()
table
,
err
:=
table
.
NewTable
(
rowmeta
,
kvdb
,
opt_guess_user
)
if
err
!=
nil
{
panic
(
err
)
}
return
table
}
//GuessUserRow table meta 结构
type
GuessUserRow
struct
{
*
UserBet
}
//NewGuessUserRow 新建一个meta 结构
func
NewGuessUserRow
()
*
GuessUserRow
{
return
&
GuessUserRow
{
UserBet
:
&
UserBet
{}}
}
//CreateRow 新建数据行(注意index 数据一定也要保存到数据中,不能就保存eventid)
func
(
tx
*
GuessUserRow
)
CreateRow
()
*
table
.
Row
{
return
&
table
.
Row
{
Data
:
&
UserBet
{}}
}
//SetPayload 设置数据
func
(
tx
*
GuessUserRow
)
SetPayload
(
data
types
.
Message
)
error
{
if
txdata
,
ok
:=
data
.
(
*
UserBet
);
ok
{
tx
.
UserBet
=
txdata
return
nil
}
return
types
.
ErrTypeAsset
}
//Get 按照indexName 查询 indexValue
func
(
tx
*
GuessUserRow
)
Get
(
key
string
)
([]
byte
,
error
)
{
if
key
==
"index"
{
return
[]
byte
(
fmt
.
Sprintf
(
"%018d"
,
tx
.
Index
)),
nil
}
else
if
key
==
"addr"
{
return
[]
byte
(
tx
.
Addr
),
nil
}
else
if
key
==
"startindex"
{
return
[]
byte
(
fmt
.
Sprintf
(
"%018d"
,
tx
.
StartIndex
)),
nil
}
return
nil
,
types
.
ErrNotFound
}
var
opt_guess_game
=
&
table
.
Option
{
Prefix
:
"LODB_guess"
,
Name
:
"game"
,
Primary
:
"startindex"
,
Index
:
[]
string
{
"gameid"
,
"status"
,
"admin"
,
"admin_status"
,
"category_status"
},
}
//NewGuessGameTable 新建表
func
NewGuessGameTable
(
kvdb
db
.
KV
)
*
table
.
Table
{
rowmeta
:=
NewGuessGameRow
()
table
,
err
:=
table
.
NewTable
(
rowmeta
,
kvdb
,
opt_guess_game
)
if
err
!=
nil
{
panic
(
err
)
}
return
table
}
//GuessGameRow table meta 结构
type
GuessGameRow
struct
{
*
GuessGame
}
//NewGuessGameRow 新建一个meta 结构
func
NewGuessGameRow
()
*
GuessGameRow
{
return
&
GuessGameRow
{
GuessGame
:
&
GuessGame
{}}
}
//CreateRow 新建数据行(注意index 数据一定也要保存到数据中,不能就保存eventid)
func
(
tx
*
GuessGameRow
)
CreateRow
()
*
table
.
Row
{
return
&
table
.
Row
{
Data
:
&
GuessGame
{}}
}
//SetPayload 设置数据
func
(
tx
*
GuessGameRow
)
SetPayload
(
data
types
.
Message
)
error
{
if
txdata
,
ok
:=
data
.
(
*
GuessGame
);
ok
{
tx
.
GuessGame
=
txdata
return
nil
}
return
types
.
ErrTypeAsset
}
//Get 按照indexName 查询 indexValue
func
(
tx
*
GuessGameRow
)
Get
(
key
string
)
([]
byte
,
error
)
{
if
key
==
"startindex"
{
return
[]
byte
(
fmt
.
Sprintf
(
"%018d"
,
tx
.
StartIndex
)),
nil
}
else
if
key
==
"gameid"
{
return
[]
byte
(
tx
.
GameID
),
nil
}
else
if
key
==
"status"
{
return
[]
byte
(
fmt
.
Sprintf
(
"%2d"
,
tx
.
Status
)),
nil
}
else
if
key
==
"admin"
{
return
[]
byte
(
tx
.
AdminAddr
),
nil
}
else
if
key
==
"admin_status"
{
return
[]
byte
(
fmt
.
Sprintf
(
"%s:%2d"
,
tx
.
AdminAddr
,
tx
.
Status
)),
nil
}
else
if
key
==
"category_status"
{
return
[]
byte
(
fmt
.
Sprintf
(
"%s:%2d"
,
tx
.
Category
,
tx
.
Status
)),
nil
}
return
nil
,
types
.
ErrNotFound
}
plugin/dapp/guess/types/types.go
0 → 100644
View file @
cd952ee4
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
types
import
(
"reflect"
"github.com/33cn/chain33/types"
)
func
init
()
{
// init executor type
types
.
RegistorExecutor
(
GuessX
,
NewType
())
types
.
AllowUserExec
=
append
(
types
.
AllowUserExec
,
ExecerGuess
)
types
.
RegisterDappFork
(
GuessX
,
"Enable"
,
0
)
}
// GuessType struct
type
GuessType
struct
{
types
.
ExecTypeBase
}
// NewType method
func
NewType
()
*
GuessType
{
c
:=
&
GuessType
{}
c
.
SetChild
(
c
)
return
c
}
// GetPayload method
func
(
t
*
GuessType
)
GetPayload
()
types
.
Message
{
return
&
GuessGameAction
{}
}
// GetTypeMap method
func
(
t
*
GuessType
)
GetTypeMap
()
map
[
string
]
int32
{
return
map
[
string
]
int32
{
"Start"
:
GuessGameActionStart
,
"Bet"
:
GuessGameActionBet
,
"StopBet"
:
GuessGameActionStopBet
,
"Abort"
:
GuessGameActionAbort
,
"Publish"
:
GuessGameActionPublish
,
"Query"
:
GuessGameActionQuery
,
}
}
// GetLogMap method
func
(
t
*
GuessType
)
GetLogMap
()
map
[
int64
]
*
types
.
LogInfo
{
return
map
[
int64
]
*
types
.
LogInfo
{
TyLogGuessGameStart
:
{
Ty
:
reflect
.
TypeOf
(
ReceiptGuessGame
{}),
Name
:
"TyLogGuessGameStart"
},
TyLogGuessGameBet
:
{
Ty
:
reflect
.
TypeOf
(
ReceiptGuessGame
{}),
Name
:
"TyLogGuessGameBet"
},
TyLogGuessGameStopBet
:
{
Ty
:
reflect
.
TypeOf
(
ReceiptGuessGame
{}),
Name
:
"TyLogGuessGameStopBet"
},
TyLogGuessGameAbort
:
{
Ty
:
reflect
.
TypeOf
(
ReceiptGuessGame
{}),
Name
:
"TyLogGuessGameAbort"
},
TyLogGuessGamePublish
:
{
Ty
:
reflect
.
TypeOf
(
ReceiptGuessGame
{}),
Name
:
"TyLogGuessGamePublish"
},
TyLogGuessGameTimeout
:
{
Ty
:
reflect
.
TypeOf
(
ReceiptGuessGame
{}),
Name
:
"TyLogGuessGameTimeout"
},
}
}
plugin/dapp/init/init.go
View file @
cd952ee4
...
...
@@ -6,6 +6,7 @@ import (
_
"github.com/33cn/plugin/plugin/dapp/echo"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/evm"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/game"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/guess"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/hashlock"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/js"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/lottery"
//auto gen
...
...
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