Unverified Commit cd952ee4 authored by vipwzw's avatar vipwzw Committed by GitHub

Merge pull request #157 from zzh33cn/guess

Guess
parents ec143947 5e4c5cd9
// 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 commands
import (
"fmt"
"strings"
jsonrpc "github.com/33cn/chain33/rpc/jsonclient"
rpctypes "github.com/33cn/chain33/rpc/types"
"github.com/33cn/chain33/types"
gty "github.com/33cn/plugin/plugin/dapp/guess/types"
"github.com/spf13/cobra"
)
//GuessCmd Guess合约命令行
func GuessCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "guess",
Short: "guess game management",
Args: cobra.MinimumNArgs(1),
}
cmd.AddCommand(
GuessStartRawTxCmd(),
GuessBetRawTxCmd(),
GuessAbortRawTxCmd(),
GuessQueryRawTxCmd(),
GuessPublishRawTxCmd(),
GuessStopBetRawTxCmd(),
)
return cmd
}
//GuessStartRawTxCmd 构造Guess合约的start原始交易(未签名)的命令行
func GuessStartRawTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "start",
Short: "start a new guess game",
Run: guessStart,
}
addGuessStartFlags(cmd)
return cmd
}
func addGuessStartFlags(cmd *cobra.Command) {
cmd.Flags().StringP("topic", "t", "", "topic")
cmd.MarkFlagRequired("topic")
cmd.Flags().StringP("options", "o", "", "options")
cmd.MarkFlagRequired("options")
cmd.Flags().StringP("category", "c", "default", "options")
cmd.Flags().Int64P("maxBetHeight", "m", 0, "max height to bet, after this bet is forbidden")
cmd.Flags().Int64P("maxBetsOneTime", "s", 10000, "max bets one time")
cmd.Flags().Int64P("maxBetsNumber", "n", 100000, "max bets number")
cmd.Flags().Int64P("devFeeFactor", "d", 0, "dev fee factor, unit: 1/1000")
cmd.Flags().StringP("devFeeAddr", "f", "", "dev address to receive share")
cmd.Flags().Int64P("platFeeFactor", "p", 0, "plat fee factor, unit: 1/1000")
cmd.Flags().StringP("platFeeAddr", "q", "", "plat address to receive share")
cmd.Flags().Int64P("expireHeight", "e", 0, "expire height of the game, after this any addr can abort it")
}
func guessStart(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
topic, _ := cmd.Flags().GetString("topic")
category, _ := cmd.Flags().GetString("category")
options, _ := cmd.Flags().GetString("options")
maxBetHeight, _ := cmd.Flags().GetInt64("maxBetHeight")
maxBetsOneTime, _ := cmd.Flags().GetInt64("maxBetsOneTime")
maxBetsNumber, _ := cmd.Flags().GetInt64("maxBetsNumber")
devFeeFactor, _ := cmd.Flags().GetInt64("devFeeFactor")
devFeeAddr, _ := cmd.Flags().GetString("devFeeAddr")
platFeeFactor, _ := cmd.Flags().GetInt64("platFeeFactor")
platFeeAddr, _ := cmd.Flags().GetString("platFeeAddr")
expireHeight, _ := cmd.Flags().GetInt64("expireHeight")
payload := fmt.Sprintf("{\"topic\":\"%s\", \"options\":\"%s\", \"category\":\"%s\", \"maxBetHeight\":%d, \"maxBetsOneTime\":%d,\"maxBetsNumber\":%d,\"devFeeFactor\":%d,\"platFeeFactor\":%d,\"expireHeight\":%d,\"devFeeAddr\":\"%s\",\"platFeeAddr\":\"%s\"}", topic, options, category, maxBetHeight, maxBetsOneTime, maxBetsNumber, devFeeFactor, platFeeFactor, expireHeight, devFeeAddr, platFeeAddr)
params := &rpctypes.CreateTxIn{
Execer: types.ExecName(gty.GuessX),
ActionName: gty.CreateStartTx,
Payload: []byte(payload),
}
var res string
ctx := jsonrpc.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", params, &res)
ctx.RunWithoutMarshal()
}
//GuessBetRawTxCmd 构造Guess合约的bet原始交易(未签名)的命令行
func GuessBetRawTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "bet",
Short: "bet for one option in a guess game",
Run: guessBet,
}
addGuessBetFlags(cmd)
return cmd
}
func addGuessBetFlags(cmd *cobra.Command) {
cmd.Flags().StringP("gameId", "g", "", "game ID")
cmd.MarkFlagRequired("gameId")
cmd.Flags().StringP("option", "o", "", "option")
cmd.MarkFlagRequired("option")
cmd.Flags().Int64P("betsNumber", "b", 1, "bets number for one option in a guess game")
cmd.MarkFlagRequired("betsNumber")
}
func guessBet(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
gameID, _ := cmd.Flags().GetString("gameId")
option, _ := cmd.Flags().GetString("option")
betsNumber, _ := cmd.Flags().GetInt64("betsNumber")
payload := fmt.Sprintf("{\"gameID\":\"%s\", \"option\":\"%s\", \"betsNum\":%d}", gameID, option, betsNumber)
params := &rpctypes.CreateTxIn{
Execer: types.ExecName(gty.GuessX),
ActionName: gty.CreateBetTx,
Payload: []byte(payload),
}
var res string
ctx := jsonrpc.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", params, &res)
ctx.RunWithoutMarshal()
}
//GuessStopBetRawTxCmd 构造Guess合约的停止下注(stopBet)原始交易(未签名)的命令行
func GuessStopBetRawTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "stop bet",
Short: "stop bet for a guess game",
Run: guessStopBet,
}
addGuessStopBetFlags(cmd)
return cmd
}
func addGuessStopBetFlags(cmd *cobra.Command) {
cmd.Flags().StringP("gameId", "g", "", "game ID")
cmd.MarkFlagRequired("gameId")
cmd.Flags().Float64P("fee", "f", 0.01, "tx fee")
}
func guessStopBet(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
gameID, _ := cmd.Flags().GetString("gameId")
payload := fmt.Sprintf("{\"gameID\":\"%s\"}", gameID)
params := &rpctypes.CreateTxIn{
Execer: types.ExecName(gty.GuessX),
ActionName: gty.CreateStopBetTx,
Payload: []byte(payload),
}
var res string
ctx := jsonrpc.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", params, &res)
ctx.RunWithoutMarshal()
}
//GuessAbortRawTxCmd 构造Guess合约的撤销(Abort)原始交易(未签名)的命令行
func GuessAbortRawTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "abort",
Short: "abort a guess game",
Run: guessAbort,
}
addGuessAbortFlags(cmd)
return cmd
}
func addGuessAbortFlags(cmd *cobra.Command) {
cmd.Flags().StringP("gameId", "g", "", "game Id")
cmd.MarkFlagRequired("gameId")
}
func guessAbort(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
gameID, _ := cmd.Flags().GetString("gameId")
payload := fmt.Sprintf("{\"gameID\":\"%s\"}", gameID)
params := &rpctypes.CreateTxIn{
Execer: types.ExecName(gty.GuessX),
ActionName: gty.CreateAbortTx,
Payload: []byte(payload),
}
var res string
ctx := jsonrpc.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", params, &res)
ctx.RunWithoutMarshal()
}
//GuessPublishRawTxCmd 构造Guess合约的发布结果(Publish)原始交易(未签名)的命令行
func GuessPublishRawTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "publish",
Short: "publish the result of a guess game",
Run: guessPublish,
}
addGuessPublishFlags(cmd)
return cmd
}
func addGuessPublishFlags(cmd *cobra.Command) {
cmd.Flags().StringP("gameId", "g", "", "game Id of a guess game")
cmd.MarkFlagRequired("gameId")
cmd.Flags().StringP("result", "r", "", "result of a guess game")
cmd.MarkFlagRequired("result")
}
func guessPublish(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
gameID, _ := cmd.Flags().GetString("gameId")
result, _ := cmd.Flags().GetString("result")
payload := fmt.Sprintf("{\"gameID\":\"%s\",\"result\":\"%s\"}", gameID, result)
params := &rpctypes.CreateTxIn{
Execer: types.ExecName(gty.GuessX),
ActionName: gty.CreatePublishTx,
Payload: []byte(payload),
}
var res string
ctx := jsonrpc.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", params, &res)
ctx.RunWithoutMarshal()
}
//GuessQueryRawTxCmd 构造Guess合约的查询(Query)命令行
func GuessQueryRawTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "query",
Short: "query info",
Run: guessQuery,
}
addGuessQueryFlags(cmd)
return cmd
}
func addGuessQueryFlags(cmd *cobra.Command) {
cmd.Flags().StringP("type", "t", "", "query type:ids,id,addr,status,adminAddr,addrStatus,adminStatus,categoryStatus")
cmd.Flags().StringP("gameId", "g", "", "game Id")
cmd.Flags().StringP("addr", "a", "", "address")
cmd.Flags().StringP("adminAddr", "m", "", "admin address")
cmd.Flags().Int64P("index", "i", 0, "index")
cmd.Flags().Int32P("status", "s", 0, "status")
cmd.Flags().StringP("gameIDs", "d", "", "gameIDs")
cmd.Flags().StringP("category", "c", "default", "game category")
cmd.Flags().StringP("primary", "p", "", "the primary to query from")
}
func guessQuery(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
ty, _ := cmd.Flags().GetString("type")
gameID, _ := cmd.Flags().GetString("gameId")
addr, _ := cmd.Flags().GetString("addr")
adminAddr, _ := cmd.Flags().GetString("adminAddr")
status, _ := cmd.Flags().GetInt32("status")
index, _ := cmd.Flags().GetInt64("index")
gameIDs, _ := cmd.Flags().GetString("gameIDs")
category, _ := cmd.Flags().GetString("category")
primary, _ := cmd.Flags().GetString("primary")
//var primaryKey []byte
//if len(primary) > 0 {
// primaryKey = []byte(primary)
//}
var params rpctypes.Query4Jrpc
params.Execer = gty.GuessX
//query type,
//1:QueryGamesByIds,
//2:QueryGameById,
//3:QueryGameByAddr,
//4:QueryGameByStatus,
//5:QueryGameByAdminAddr,
//6:QueryGameByAddrStatus,
//7:QueryGameByAdminStatus,
//8:QueryGameByCategoryStatus,
switch ty {
case "ids":
gameIds := strings.Split(gameIDs, ";")
req := &gty.QueryGuessGameInfos{
GameIDs: gameIds,
}
params.FuncName = gty.FuncNameQueryGamesByIDs
params.Payload = types.MustPBToJSON(req)
var res gty.ReplyGuessGameInfos
ctx := jsonrpc.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &res)
ctx.Run()
case "id":
req := &gty.QueryGuessGameInfo{
GameID: gameID,
}
params.FuncName = gty.FuncNameQueryGameByID
params.Payload = types.MustPBToJSON(req)
var res gty.ReplyGuessGameInfo
ctx := jsonrpc.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &res)
ctx.Run()
case "addr":
req := &gty.QueryGuessGameInfo{
Addr: addr,
Index: index,
PrimaryKey: primary,
}
params.FuncName = gty.FuncNameQueryGameByAddr
params.Payload = types.MustPBToJSON(req)
var res gty.GuessGameRecords
ctx := jsonrpc.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &res)
ctx.Run()
case "status":
req := &gty.QueryGuessGameInfo{
Status: status,
Index: index,
PrimaryKey: primary,
}
params.FuncName = gty.FuncNameQueryGameByStatus
params.Payload = types.MustPBToJSON(req)
var res gty.GuessGameRecords
ctx := jsonrpc.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &res)
ctx.Run()
case "adminAddr":
req := &gty.QueryGuessGameInfo{
AdminAddr: adminAddr,
Index: index,
PrimaryKey: primary,
}
params.FuncName = gty.FuncNameQueryGameByAdminAddr
params.Payload = types.MustPBToJSON(req)
var res gty.GuessGameRecords
ctx := jsonrpc.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &res)
ctx.Run()
case "addrStatus":
req := &gty.QueryGuessGameInfo{
Addr: addr,
Status: status,
Index: index,
PrimaryKey: primary,
}
params.FuncName = gty.FuncNameQueryGameByAddrStatus
params.Payload = types.MustPBToJSON(req)
var res gty.GuessGameRecords
ctx := jsonrpc.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &res)
ctx.Run()
case "adminStatus":
req := &gty.QueryGuessGameInfo{
AdminAddr: adminAddr,
Status: status,
Index: index,
PrimaryKey: primary,
}
params.FuncName = gty.FuncNameQueryGameByAdminStatus
params.Payload = types.MustPBToJSON(req)
var res gty.GuessGameRecords
ctx := jsonrpc.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &res)
ctx.Run()
case "categoryStatus":
req := &gty.QueryGuessGameInfo{
Category: category,
Status: status,
Index: index,
PrimaryKey: primary,
}
params.FuncName = gty.FuncNameQueryGameByCategoryStatus
params.Payload = types.MustPBToJSON(req)
var res gty.GuessGameRecords
ctx := jsonrpc.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &res)
ctx.Run()
default:
fmt.Println("Wrong type:", ty, " ,only support: ids,id,addr,status,adminAddr,addrStatus,adminStatus,categoryStatus")
}
}
// 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(管理员)
说明:这里的管理员不是特殊地址,而是谁创建本局竞猜游戏,谁就是本局竞猜游戏的管理员。
*/
// 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)
}
// 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)
}
// 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)
}
// 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
}
// 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 (
"context"
"fmt"
"strings"
"time"
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/common/db/table"
"github.com/33cn/chain33/client"
"google.golang.org/grpc"
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/common"
dbm "github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
gty "github.com/33cn/plugin/plugin/dapp/guess/types"
)
const (
//ListDESC 表示记录降序排列
ListDESC = int32(0)
//ListASC 表示记录升序排列
ListASC = int32(1)
//DefaultCount 默认一次获取的记录数
DefaultCount = int32(6)
//DefaultCategory 默认分类
DefaultCategory = "default"
//MaxBetsOneTime 一次最多下多少注
MaxBetsOneTime = 10000e8
//MaxBetsNumber 一局游戏最多接受多少注
MaxBetsNumber = 10000000e8
//MaxBetHeight 距离游戏创建区块的最大可下注高度差
MaxBetHeight = 1000000
//MaxExpireHeight 距离游戏创建区块的最大过期高度差
MaxExpireHeight = 1000000
//grpcRecSize 接收缓冲大小
grpcRecSize int = 30 * 1024 * 1024
//retryNum 失败时的重试次数
retryNum = 10
)
//Action 具体动作执行
type Action struct {
coinsAccount *account.DB
db dbm.KV
txhash []byte
fromaddr string
blocktime int64
height int64
execaddr string
localDB dbm.KVDB
index int
api client.QueueProtocolAPI
conn *grpc.ClientConn
grpcClient types.Chain33Client
}
//NewAction 生成Action对象
func NewAction(guess *Guess, tx *types.Transaction, index int) *Action {
hash := tx.Hash()
fromAddr := tx.From()
msgRecvOp := grpc.WithMaxMsgSize(grpcRecSize)
paraRemoteGrpcClient := types.Conf("config.consensus").GStr("ParaRemoteGrpcClient")
if types.IsPara() && paraRemoteGrpcClient == "" {
panic("ParaRemoteGrpcClient error")
}
conn, err := grpc.Dial(paraRemoteGrpcClient, grpc.WithInsecure(), msgRecvOp)
if err != nil {
panic(err)
}
grpcClient := types.NewChain33Client(conn)
return &Action{
coinsAccount: guess.GetCoinsAccount(),
db: guess.GetStateDB(),
txhash: hash,
fromaddr: fromAddr,
blocktime: guess.GetBlockTime(),
height: guess.GetHeight(),
execaddr: dapp.ExecAddress(string(tx.Execer)),
localDB: guess.GetLocalDB(),
index: index,
api: guess.GetAPI(),
conn: conn,
grpcClient: grpcClient,
}
}
//CheckExecAccountBalance 检查地址在Guess合约中的余额是否足够
func (action *Action) CheckExecAccountBalance(fromAddr string, ToFrozen, ToActive int64) bool {
acc := action.coinsAccount.LoadExecAccount(fromAddr, action.execaddr)
if acc.GetBalance() >= ToFrozen && acc.GetFrozen() >= ToActive {
return true
}
return false
}
//Key State数据库中存储记录的Key值格式转换
func Key(id string) (key []byte) {
//key = append(key, []byte("mavl-"+types.ExecName(pkt.GuessX)+"-")...)
key = append(key, []byte("mavl-"+gty.GuessX+"-")...)
key = append(key, []byte(id)...)
return key
}
//queryGameInfos 根据游戏id列表查询多个游戏详情信息
func queryGameInfos(kvdb db.KVDB, infos *gty.QueryGuessGameInfos) (types.Message, error) {
var games []*gty.GuessGame
gameTable := gty.NewGuessGameTable(kvdb)
query := gameTable.GetQuery(kvdb)
for i := 0; i < len(infos.GameIDs); i++ {
rows, err := query.ListIndex("gameid", []byte(infos.GameIDs[i]), nil, 1, 0)
if err != nil {
return nil, err
}
game := rows[0].Data.(*gty.GuessGame)
games = append(games, game)
}
return &gty.ReplyGuessGameInfos{Games: games}, nil
}
//queryGameInfo 根据gameid查询game信息
func queryGameInfo(kvdb db.KVDB, gameID []byte) (*gty.GuessGame, error) {
gameTable := gty.NewGuessGameTable(kvdb)
query := gameTable.GetQuery(kvdb)
rows, err := query.ListIndex("gameid", gameID, nil, 1, 0)
if err != nil {
return nil, err
}
game := rows[0].Data.(*gty.GuessGame)
return game, nil
}
//queryUserTableData 查询user表数据
func queryUserTableData(query *table.Query, indexName string, prefix, primaryKey []byte) (types.Message, error) {
rows, err := query.ListIndex(indexName, prefix, primaryKey, DefaultCount, 0)
if err != nil {
return nil, err
}
var records []*gty.GuessGameRecord
for i := 0; i < len(rows); i++ {
userBet := rows[i].Data.(*gty.UserBet)
var record gty.GuessGameRecord
record.GameID = userBet.GameID
record.StartIndex = userBet.StartIndex
records = append(records, &record)
}
var primary string
if len(rows) == int(DefaultCount) {
primary = string(rows[len(rows)-1].Primary)
}
return &gty.GuessGameRecords{Records: records, PrimaryKey: primary}, nil
}
//queryGameTableData 查询game表数据
func queryGameTableData(query *table.Query, indexName string, prefix, primaryKey []byte) (types.Message, error) {
rows, err := query.ListIndex(indexName, prefix, primaryKey, DefaultCount, 0)
if err != nil {
return nil, err
}
var records []*gty.GuessGameRecord
for i := 0; i < len(rows); i++ {
game := rows[i].Data.(*gty.GuessGame)
var record gty.GuessGameRecord
record.GameID = game.GameID
record.StartIndex = game.StartIndex
records = append(records, &record)
}
var primary string
if len(rows) == int(DefaultCount) {
primary = string(rows[len(rows)-1].Primary)
}
return &gty.GuessGameRecords{Records: records, PrimaryKey: primary}, nil
}
//queryJoinTableData 查询join表数据
func queryJoinTableData(talbeJoin *table.JoinTable, indexName string, prefix, primaryKey []byte) (types.Message, error) {
rows, err := talbeJoin.ListIndex(indexName, prefix, primaryKey, DefaultCount, 0)
if err != nil {
return nil, err
}
var records []*gty.GuessGameRecord
for i := 0; i < len(rows); i++ {
game := rows[i].Data.(*table.JoinData).Right.(*gty.GuessGame)
var record gty.GuessGameRecord
record.GameID = game.GameID
record.StartIndex = game.StartIndex
records = append(records, &record)
}
var primary string
if len(rows) == int(DefaultCount) {
primary = fmt.Sprintf("%018d", rows[len(rows)-1].Data.(*table.JoinData).Left.(*gty.UserBet).Index)
}
return &gty.GuessGameRecords{Records: records, PrimaryKey: primary}, nil
}
func (action *Action) saveGame(game *gty.GuessGame) (kvset []*types.KeyValue) {
value := types.Encode(game)
action.db.Set(Key(game.GetGameID()), value)
kvset = append(kvset, &types.KeyValue{Key: Key(game.GameID), Value: value})
return kvset
}
func (action *Action) getIndex() int64 {
return action.height*types.MaxTxsPerBlock + int64(action.index)
}
//getReceiptLog 根据游戏信息生成收据记录
func (action *Action) getReceiptLog(game *gty.GuessGame, statusChange bool, bet *gty.GuessGameBet) *types.ReceiptLog {
log := &types.ReceiptLog{}
r := &gty.ReceiptGuessGame{}
r.Addr = action.fromaddr
if game.Status == gty.GuessGameStatusStart {
log.Ty = gty.TyLogGuessGameStart
} else if game.Status == gty.GuessGameStatusBet {
log.Ty = gty.TyLogGuessGameBet
} else if game.Status == gty.GuessGameStatusStopBet {
log.Ty = gty.TyLogGuessGameStopBet
} else if game.Status == gty.GuessGameStatusAbort {
log.Ty = gty.TyLogGuessGameAbort
} else if game.Status == gty.GuessGameStatusPublish {
log.Ty = gty.TyLogGuessGamePublish
} else if game.Status == gty.GuessGameStatusTimeOut {
log.Ty = gty.TyLogGuessGameTimeout
}
r.StartIndex = game.StartIndex
r.Index = action.getIndex()
r.GameID = game.GameID
r.Status = game.Status
r.AdminAddr = game.AdminAddr
r.PreStatus = game.PreStatus
r.StatusChange = statusChange
r.PreIndex = game.PreIndex
r.Category = game.Category
if nil != bet {
r.Bet = true
r.Option = bet.Option
r.BetsNumber = bet.BetsNum
}
r.Game = game
log.Log = types.Encode(r)
return log
}
func (action *Action) readGame(id string) (*gty.GuessGame, error) {
data, err := action.db.Get(Key(id))
if err != nil {
logger.Error("readGame have err:", err.Error())
return nil, err
}
var game gty.GuessGame
//decode
err = types.Decode(data, &game)
if err != nil {
logger.Error("decode game have err:", err.Error())
return nil, err
}
return &game, nil
}
// 新建一局游戏
func (action *Action) newGame(gameID string, start *gty.GuessGameStart) (*gty.GuessGame, error) {
game := &gty.GuessGame{
GameID: gameID,
Status: gty.GuessGameActionStart,
//StartTime: action.blocktime,
StartTxHash: gameID,
Topic: start.Topic,
Category: start.Category,
Options: start.Options,
MaxBetHeight: start.MaxBetHeight,
MaxBetsOneTime: start.MaxBetsOneTime,
MaxBetsNumber: start.MaxBetsNumber,
DevFeeFactor: start.DevFeeFactor,
DevFeeAddr: start.DevFeeAddr,
PlatFeeFactor: start.PlatFeeFactor,
PlatFeeAddr: start.PlatFeeAddr,
ExpireHeight: start.ExpireHeight,
//AdminAddr: action.fromaddr,
BetsNumber: 0,
//Index: action.getIndex(game),
DrivenByAdmin: start.DrivenByAdmin,
}
return game, nil
}
//GameStart 创建游戏动作执行
func (action *Action) GameStart(start *gty.GuessGameStart) (*types.Receipt, error) {
var logs []*types.ReceiptLog
var kv []*types.KeyValue
if start.MaxBetHeight >= MaxBetHeight {
logger.Error("GameStart", "addr", action.fromaddr, "execaddr", action.execaddr,
"err", fmt.Sprintf("The maximum height diff number is %d which is less than start.MaxBetHeight %d", MaxBetHeight, start.MaxBetHeight))
return nil, types.ErrInvalidParam
}
if start.ExpireHeight >= MaxExpireHeight {
logger.Error("GameStart", "addr", action.fromaddr, "execaddr", action.execaddr,
"err", fmt.Sprintf("The maximum height diff number is %d which is less than start.MaxBetHeight %d", MaxBetHeight, start.MaxBetHeight))
return nil, types.ErrInvalidParam
}
if start.MaxBetsNumber >= MaxBetsNumber {
logger.Error("GameStart", "addr", action.fromaddr, "execaddr", action.execaddr,
"err", fmt.Sprintf("The maximum bets number is %d which is less than start.MaxBetsNumber %d", int64(MaxBetsNumber), start.MaxBetsNumber))
return nil, gty.ErrOverBetsLimit
}
if len(start.Topic) == 0 || len(start.Options) == 0 {
logger.Error("GameStart", "addr", action.fromaddr, "execaddr", action.execaddr,
"err", fmt.Sprintf("Illegal parameters,Topic:%s | options: %s | category: %s", start.Topic, start.Options, start.Category))
return nil, types.ErrInvalidParam
}
options, ok := getOptions(start.Options)
if !ok {
logger.Error("GameStart", "addr", action.fromaddr, "execaddr", action.execaddr,
"err", fmt.Sprintf("The options is illegal:%s", start.Options))
return nil, types.ErrInvalidParam
}
if !action.checkTime(start) {
logger.Error("GameStart", "addr", action.fromaddr, "execaddr", action.execaddr,
"err", fmt.Sprintf("The height and time parameters are illegal:MaxHeight %d ,ExpireHeight %d", start.MaxBetHeight, start.ExpireHeight))
return nil, types.ErrInvalidParam
}
if len(start.Category) == 0 {
start.Category = DefaultCategory
}
if start.MaxBetsOneTime >= MaxBetsOneTime {
start.MaxBetsOneTime = MaxBetsOneTime
}
gameID := common.ToHex(action.txhash)
game, _ := action.newGame(gameID, start)
game.StartTime = action.blocktime
if types.IsPara() {
mainHeight := action.GetMainHeightByTxHash(action.txhash)
if mainHeight < 0 {
logger.Error("GameStart", "mainHeight", mainHeight)
return nil, gty.ErrGuessStatus
}
game.StartHeight = mainHeight
} else {
game.StartHeight = action.height
}
game.AdminAddr = action.fromaddr
game.PreIndex = 0
game.Index = action.getIndex()
game.StartIndex = game.Index
game.Status = gty.GuessGameStatusStart
game.BetStat = &gty.GuessBetStat{TotalBetTimes: 0, TotalBetsNumber: 0}
for i := 0; i < len(options); i++ {
item := &gty.GuessBetStatItem{Option: options[i], BetsNumber: 0, BetsTimes: 0}
game.BetStat.Items = append(game.BetStat.Items, item)
}
receiptLog := action.getReceiptLog(game, false, nil)
logs = append(logs, receiptLog)
kv = append(kv, action.saveGame(game)...)
return &types.Receipt{Ty: types.ExecOk, KV: kv, Logs: logs}, nil
}
//GameBet 参与游戏动作执行
func (action *Action) GameBet(pbBet *gty.GuessGameBet) (*types.Receipt, error) {
var logs []*types.ReceiptLog
var kv []*types.KeyValue
game, err := action.readGame(pbBet.GetGameID())
if err != nil || game == nil {
logger.Error("GameBet", "addr", action.fromaddr, "execaddr", action.execaddr, "get game failed",
pbBet.GetGameID(), "err", err)
return nil, err
}
prevStatus := game.Status
if game.Status != gty.GuessGameStatusStart && game.Status != gty.GuessGameStatusBet {
logger.Error("GameBet", "addr", action.fromaddr, "execaddr", action.execaddr, "Status error",
game.GetStatus())
return nil, gty.ErrGuessStatus
}
canBet := action.refreshStatusByTime(game)
if !canBet {
var receiptLog *types.ReceiptLog
if prevStatus != game.Status {
//状态发生了变化,且是变到了不可下注的状态,那么对于所有下注的addr来说,其addr:status主键的数据都需要更新
action.changeAllAddrIndex(game)
receiptLog = action.getReceiptLog(game, true, nil)
} else {
receiptLog = action.getReceiptLog(game, false, nil)
}
logs = append(logs, receiptLog)
kv = append(kv, action.saveGame(game)...)
return &types.Receipt{Ty: types.ExecOk, KV: kv, Logs: logs}, nil
}
//检查竞猜选项是否合法
options, legal := getOptions(game.GetOptions())
if !legal || len(options) == 0 {
logger.Error("GameBet", "addr", action.fromaddr, "execaddr", action.execaddr, "Game Options illegal",
game.GetOptions())
return nil, types.ErrInvalidParam
}
if !isLegalOption(options, pbBet.GetOption()) {
logger.Error("GameBet", "addr", action.fromaddr, "execaddr", action.execaddr, "Option illegal",
pbBet.GetOption())
return nil, types.ErrInvalidParam
}
//检查下注金额是否超限,如果超限,按最大值
if pbBet.GetBetsNum() > game.GetMaxBetsOneTime() {
pbBet.BetsNum = game.GetMaxBetsOneTime()
}
if game.BetsNumber+pbBet.GetBetsNum() > game.MaxBetsNumber {
logger.Error("GameBet", "addr", action.fromaddr, "execaddr", action.execaddr, "MaxBetsNumber over limit",
game.MaxBetsNumber, "current Bets Number", game.BetsNumber)
return nil, types.ErrInvalidParam
}
// 检查账户余额
checkValue := pbBet.BetsNum
if !action.CheckExecAccountBalance(action.fromaddr, checkValue, 0) {
logger.Error("GameBet", "addr", action.fromaddr, "execaddr", action.execaddr, "id",
pbBet.GetGameID(), "err", types.ErrNoBalance)
return nil, types.ErrNoBalance
}
receipt, err := action.coinsAccount.ExecFrozen(action.fromaddr, action.execaddr, checkValue)
if err != nil {
logger.Error("GameCreate.ExecFrozen", "addr", action.fromaddr, "execaddr", action.execaddr, "amount", checkValue, "err", err.Error())
return nil, err
}
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
var receiptLog *types.ReceiptLog
if prevStatus != gty.GuessGameStatusBet {
action.changeStatus(game, gty.GuessGameStatusBet)
action.addGuessBet(game, pbBet)
receiptLog = action.getReceiptLog(game, true, pbBet)
} else {
action.addGuessBet(game, pbBet)
receiptLog = action.getReceiptLog(game, false, pbBet)
}
logs = append(logs, receiptLog)
kv = append(kv, action.saveGame(game)...)
return &types.Receipt{Ty: types.ExecOk, KV: kv, Logs: logs}, nil
}
//GameStopBet 停止游戏下注动作执行
func (action *Action) GameStopBet(pbBet *gty.GuessGameStopBet) (*types.Receipt, error) {
var logs []*types.ReceiptLog
var kv []*types.KeyValue
game, err := action.readGame(pbBet.GetGameID())
if err != nil || game == nil {
logger.Error("GameStopBet", "addr", action.fromaddr, "execaddr", action.execaddr, "get game failed",
pbBet.GetGameID(), "err", err)
return nil, err
}
if game.Status != gty.GuessGameStatusStart && game.Status != gty.GuessGameStatusBet {
logger.Error("GameBet", "addr", action.fromaddr, "execaddr", action.execaddr, "Status error",
game.GetStatus())
return nil, gty.ErrGuessStatus
}
//只有adminAddr可以发起stopBet
if game.AdminAddr != action.fromaddr {
logger.Error("GameStopBet", "addr", action.fromaddr, "execaddr", action.execaddr, "fromAddr is not adminAddr",
action.fromaddr, "adminAddr", game.AdminAddr)
return nil, gty.ErrNoPrivilege
}
action.changeStatus(game, gty.GuessGameStatusStopBet)
var receiptLog *types.ReceiptLog
//状态发生变化,更新所有addr对应记录的index
action.changeAllAddrIndex(game)
receiptLog = action.getReceiptLog(game, true, nil)
logs = append(logs, receiptLog)
kv = append(kv, action.saveGame(game)...)
return &types.Receipt{Ty: types.ExecOk, KV: kv, Logs: logs}, nil
}
//addGuessBet 向游戏结构中加入下注信息
func (action *Action) addGuessBet(game *gty.GuessGame, pbBet *gty.GuessGameBet) {
bet := &gty.GuessBet{Option: pbBet.GetOption(), BetsNumber: pbBet.BetsNum, Index: action.getIndex()}
player := &gty.GuessPlayer{Addr: action.fromaddr, Bet: bet}
game.Plays = append(game.Plays, player)
for i := 0; i < len(game.BetStat.Items); i++ {
if game.BetStat.Items[i].Option == pbBet.GetOption() {
//针对具体选项更新统计项
game.BetStat.Items[i].BetsNumber += pbBet.GetBetsNum()
game.BetStat.Items[i].BetsTimes++
//更新整体统计
game.BetStat.TotalBetsNumber += pbBet.GetBetsNum()
game.BetStat.TotalBetTimes++
break
}
}
game.BetsNumber += pbBet.GetBetsNum()
}
//GamePublish 公布竞猜游戏结果动作执行
func (action *Action) GamePublish(publish *gty.GuessGamePublish) (*types.Receipt, error) {
var logs []*types.ReceiptLog
var kv []*types.KeyValue
game, err := action.readGame(publish.GetGameID())
if err != nil || game == nil {
logger.Error("GamePublish", "addr", action.fromaddr, "execaddr", action.execaddr, "get game failed",
publish.GetGameID(), "err", err)
return nil, err
}
//只有adminAddr可以发起publish
if game.AdminAddr != action.fromaddr {
logger.Error("GamePublish", "addr", action.fromaddr, "execaddr", action.execaddr, "fromAddr is not adminAddr",
action.fromaddr, "adminAddr", game.AdminAddr)
return nil, gty.ErrNoPrivilege
}
if game.Status != gty.GuessGameStatusStart && game.Status != gty.GuessGameStatusBet && game.Status != gty.GuessGameStatusStopBet {
logger.Error("GamePublish", "addr", action.fromaddr, "execaddr", action.execaddr, "Status error",
game.GetStatus())
return nil, gty.ErrGuessStatus
}
//检查竞猜选项是否合法
options, legal := getOptions(game.GetOptions())
if !legal || len(options) == 0 {
logger.Error("GamePublish", "addr", action.fromaddr, "execaddr", action.execaddr, "Game Options illegal",
game.GetOptions())
return nil, types.ErrInvalidParam
}
if !isLegalOption(options, publish.GetResult()) {
logger.Error("GamePublish", "addr", action.fromaddr, "execaddr", action.execaddr, "Option illegal",
publish.GetResult())
return nil, types.ErrInvalidParam
}
game.Result = publish.Result
//先遍历所有下注数据,转移资金到Admin账户合约地址;
for i := 0; i < len(game.Plays); i++ {
player := game.Plays[i]
value := player.Bet.BetsNumber
receipt, err := action.coinsAccount.ExecActive(player.Addr, action.execaddr, value)
if err != nil {
logger.Error("GamePublish.ExecActive", "addr", player.Addr, "execaddr", action.execaddr, "amount", value,
"err", err)
return nil, err
}
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
receipt, err = action.coinsAccount.ExecTransfer(player.Addr, game.AdminAddr, action.execaddr, value)
if err != nil {
action.coinsAccount.ExecFrozen(game.AdminAddr, action.execaddr, value) // rollback
logger.Error("GamePublish", "addr", player.Addr, "execaddr", action.execaddr,
"amount", value, "err", err)
return nil, err
}
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
}
action.changeStatus(game, gty.GuessGameStatusPublish)
//计算竞猜正确的筹码总数
totalBetsNumber := game.BetStat.TotalBetsNumber
winBetsNumber := int64(0)
for j := 0; j < len(game.BetStat.Items); j++ {
if game.BetStat.Items[j].Option == game.Result {
winBetsNumber = game.BetStat.Items[j].BetsNumber
}
}
//按创建游戏时设定的比例,转移佣金到开发者账户和平台账户
devAddr := gty.DevShareAddr
platAddr := gty.PlatformShareAddr
devFee := int64(0)
platFee := int64(0)
if len(game.DevFeeAddr) > 0 {
devAddr = game.DevFeeAddr
}
if len(game.PlatFeeAddr) > 0 {
platAddr = game.PlatFeeAddr
}
if game.DevFeeFactor > 0 {
devFee = totalBetsNumber * game.DevFeeFactor / 1000
receipt, err := action.coinsAccount.ExecTransfer(game.AdminAddr, devAddr, action.execaddr, devFee)
if err != nil {
action.coinsAccount.ExecFrozen(game.AdminAddr, action.execaddr, devFee) // rollback
logger.Error("GamePublish", "adminAddr", game.AdminAddr, "execaddr", action.execaddr,
"amount", devFee, "err", err)
return nil, err
}
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
}
if game.PlatFeeFactor > 0 {
platFee = totalBetsNumber * game.PlatFeeFactor / 1000
receipt, err := action.coinsAccount.ExecTransfer(game.AdminAddr, platAddr, action.execaddr, platFee)
if err != nil {
action.coinsAccount.ExecFrozen(game.AdminAddr, action.execaddr, platFee) // rollback
logger.Error("GamePublish", "adminAddr", game.AdminAddr, "execaddr", action.execaddr,
"amount", platFee, "err", err)
return nil, err
}
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
}
//再遍历赢家,按照投注占比分配所有筹码
winValue := totalBetsNumber - devFee - platFee
for j := 0; j < len(game.Plays); j++ {
player := game.Plays[j]
if player.Bet.Option == game.Result {
value := player.Bet.BetsNumber * winValue / winBetsNumber
receipt, err := action.coinsAccount.ExecTransfer(game.AdminAddr, player.Addr, action.execaddr, value)
if err != nil {
action.coinsAccount.ExecFrozen(player.Addr, action.execaddr, value) // rollback
logger.Error("GamePublish", "addr", player.Addr, "execaddr", action.execaddr,
"amount", value, "err", err)
return nil, err
}
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
player.Bet.IsWinner = true
player.Bet.Profit = value
}
}
var receiptLog *types.ReceiptLog
action.changeAllAddrIndex(game)
receiptLog = action.getReceiptLog(game, true, nil)
logs = append(logs, receiptLog)
kv = append(kv, action.saveGame(game)...)
return &types.Receipt{Ty: types.ExecOk, KV: kv, Logs: logs}, nil
}
//GameAbort 撤销游戏动作执行
func (action *Action) GameAbort(pbend *gty.GuessGameAbort) (*types.Receipt, error) {
var logs []*types.ReceiptLog
var kv []*types.KeyValue
game, err := action.readGame(pbend.GetGameID())
if err != nil || game == nil {
logger.Error("GameAbort", "addr", action.fromaddr, "execaddr", action.execaddr, "get game failed",
pbend.GetGameID(), "err", err)
return nil, err
}
if game.Status == gty.GuessGameStatusPublish || game.Status == gty.GuessGameStatusAbort {
logger.Error("GameAbort", "addr", action.fromaddr, "execaddr", action.execaddr, "game status not allow abort",
game.Status)
return nil, gty.ErrGuessStatus
}
preStatus := game.Status
//根据区块链高度或时间刷新游戏状态。
action.refreshStatusByTime(game)
//如果游戏超时,则任何地址都可以Abort,否则只有创建游戏的地址可以Abort
if game.Status != gty.GuessGameStatusTimeOut {
if game.AdminAddr != action.fromaddr {
logger.Error("GameAbort", "addr", action.fromaddr, "execaddr", action.execaddr, "Only admin can abort",
action.fromaddr, "status", game.Status)
return nil, err
}
}
//激活冻结账户
for i := 0; i < len(game.Plays); i++ {
player := game.Plays[i]
value := player.Bet.BetsNumber
receipt, err := action.coinsAccount.ExecActive(player.Addr, action.execaddr, value)
if err != nil {
logger.Error("GameAbort", "addr", player.Addr, "execaddr", action.execaddr, "amount", value, "err", err)
continue
}
player.Bet.IsWinner = true
player.Bet.Profit = value
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
}
if game.Status != preStatus {
//说明action.RefreshStatusByTime(game)调用时已经更新过状态和index了,这里直接再改状态就行了。
game.Status = gty.GuessGameStatusAbort
} else {
action.changeStatus(game, gty.GuessGameStatusAbort)
}
//状态发生变化,统一更新所有addr记录的index
action.changeAllAddrIndex(game)
receiptLog := action.getReceiptLog(game, true, nil)
logs = append(logs, receiptLog)
kv = append(kv, action.saveGame(game)...)
return &types.Receipt{Ty: types.ExecOk, KV: kv, Logs: logs}, nil
}
//getOptions 获得竞猜选项,并判断是否符合约定格式,类似"A:xxxx;B:xxxx;C:xxx",“:”前为选项名称,不能重复,":"后为选项说明。
func getOptions(strOptions string) (options []string, legal bool) {
legal = true
items := strings.Split(strOptions, ";")
for i := 0; i < len(items); i++ {
item := strings.Split(items[i], ":")
for j := 0; j < len(options); j++ {
if item[0] == options[j] {
legal = false
return
}
}
options = append(options, item[0])
}
return options, legal
}
//isLegalOption 判断选项是否为合法选项
func isLegalOption(options []string, option string) bool {
for i := 0; i < len(options); i++ {
if options[i] == option {
return true
}
}
return false
}
//changeStatus 修改游戏状态,同步更新历史记录
func (action *Action) changeStatus(game *gty.GuessGame, destStatus int32) {
if game.Status != destStatus {
game.PreStatus = game.Status
game.PreIndex = game.Index
game.Status = destStatus
game.Index = action.getIndex()
}
}
//changeAllAddrIndex 状态更新时,更新下注记录的历史信息
func (action *Action) changeAllAddrIndex(game *gty.GuessGame) {
for i := 0; i < len(game.Plays); i++ {
player := game.Plays[i]
player.Bet.PreIndex = player.Bet.Index
player.Bet.Index = action.getIndex()
}
}
//refreshStatusByTime 检测游戏是否过期,是否可以下注
func (action *Action) refreshStatusByTime(game *gty.GuessGame) (canBet bool) {
var mainHeight int64
if types.IsPara() {
mainHeight = action.GetMainHeightByTxHash(action.txhash)
if mainHeight < 0 {
logger.Error("RefreshStatusByTime", "mainHeight err", mainHeight)
return true
}
} else {
mainHeight = action.height
}
//如果完全由管理员驱动状态变化,则除了保护性过期判断外,不需要做其他判断。
if game.DrivenByAdmin {
if (mainHeight - game.StartHeight) >= game.ExpireHeight {
action.changeStatus(game, gty.GuessGameStatusTimeOut)
canBet = false
return canBet
}
return true
}
// 检查区块高度是否超过最大可下注高度限制,看是否可以下注
heightDiff := mainHeight - game.StartHeight
if heightDiff >= game.MaxBetHeight {
logger.Error("GameBet", "addr", action.fromaddr, "execaddr", action.execaddr, "Height over limit",
mainHeight, "startHeight", game.StartHeight, "MaxHeightDiff", game.GetMaxBetHeight())
if game.ExpireHeight > heightDiff {
action.changeStatus(game, gty.GuessGameStatusStopBet)
} else {
action.changeStatus(game, gty.GuessGameStatusTimeOut)
}
canBet = false
return canBet
}
canBet = true
return canBet
}
//checkTime 检测游戏的过期设置。
func (action *Action) checkTime(start *gty.GuessGameStart) bool {
if start.MaxBetHeight == 0 && start.ExpireHeight == 0 {
//如果上述字段都不携带,则认为完全由admin的指令驱动。
start.DrivenByAdmin = true
//依然设定最大过期高度差,作为最后的保护
start.ExpireHeight = MaxExpireHeight
return true
}
if start.MaxBetHeight == 0 {
start.MaxBetHeight = MaxBetHeight
}
if start.ExpireHeight == 0 {
start.ExpireHeight = MaxExpireHeight
}
if start.MaxBetHeight <= start.ExpireHeight {
return true
}
return false
}
// GetMainHeightByTxHash get Block height
func (action *Action) GetMainHeightByTxHash(txHash []byte) int64 {
for i := 0; i < retryNum; i++ {
req := &types.ReqHash{Hash: txHash}
txDetail, err := action.grpcClient.QueryTransaction(context.Background(), req)
if err != nil {
time.Sleep(time.Second)
} else {
return txDetail.GetHeight()
}
}
return -1
}
// 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))
}
// 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,
})
}
all:
sh ./create_protobuf.sh
#!/bin/sh
protoc --go_out=plugins=grpc:../types ./*.proto --proto_path=. --proto_path="../../../../vendor/github.com/33cn/chain33/types/proto/"
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) {}
}
// 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)
}
// 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"
)
// 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")
)
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: guess.proto
package types
import (
context "context"
fmt "fmt"
math "math"
types "github.com/33cn/chain33/types"
proto "github.com/golang/protobuf/proto"
grpc "google.golang.org/grpc"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
//GuessGame 竞猜游戏详情
type GuessGame struct {
GameID string `protobuf:"bytes,1,opt,name=gameID,proto3" json:"gameID,omitempty"`
Status int32 `protobuf:"varint,2,opt,name=status,proto3" json:"status,omitempty"`
PreStatus int32 `protobuf:"varint,3,opt,name=preStatus,proto3" json:"preStatus,omitempty"`
StartTime int64 `protobuf:"varint,4,opt,name=startTime,proto3" json:"startTime,omitempty"`
StartHeight int64 `protobuf:"varint,5,opt,name=startHeight,proto3" json:"startHeight,omitempty"`
StartTxHash string `protobuf:"bytes,6,opt,name=startTxHash,proto3" json:"startTxHash,omitempty"`
StartIndex int64 `protobuf:"varint,7,opt,name=startIndex,proto3" json:"startIndex,omitempty"`
Topic string `protobuf:"bytes,8,opt,name=topic,proto3" json:"topic,omitempty"`
Category string `protobuf:"bytes,9,opt,name=category,proto3" json:"category,omitempty"`
Options string `protobuf:"bytes,10,opt,name=options,proto3" json:"options,omitempty"`
MaxBetHeight int64 `protobuf:"varint,11,opt,name=maxBetHeight,proto3" json:"maxBetHeight,omitempty"`
MaxBetsOneTime int64 `protobuf:"varint,12,opt,name=maxBetsOneTime,proto3" json:"maxBetsOneTime,omitempty"`
MaxBetsNumber int64 `protobuf:"varint,13,opt,name=maxBetsNumber,proto3" json:"maxBetsNumber,omitempty"`
DevFeeFactor int64 `protobuf:"varint,14,opt,name=devFeeFactor,proto3" json:"devFeeFactor,omitempty"`
DevFeeAddr string `protobuf:"bytes,15,opt,name=devFeeAddr,proto3" json:"devFeeAddr,omitempty"`
PlatFeeFactor int64 `protobuf:"varint,16,opt,name=platFeeFactor,proto3" json:"platFeeFactor,omitempty"`
PlatFeeAddr string `protobuf:"bytes,17,opt,name=platFeeAddr,proto3" json:"platFeeAddr,omitempty"`
ExpireHeight int64 `protobuf:"varint,18,opt,name=expireHeight,proto3" json:"expireHeight,omitempty"`
AdminAddr string `protobuf:"bytes,19,opt,name=adminAddr,proto3" json:"adminAddr,omitempty"`
BetsNumber int64 `protobuf:"varint,20,opt,name=betsNumber,proto3" json:"betsNumber,omitempty"`
Plays []*GuessPlayer `protobuf:"bytes,21,rep,name=plays,proto3" json:"plays,omitempty"`
Result string `protobuf:"bytes,22,opt,name=result,proto3" json:"result,omitempty"`
BetStat *GuessBetStat `protobuf:"bytes,23,opt,name=betStat,proto3" json:"betStat,omitempty"`
Index int64 `protobuf:"varint,24,opt,name=index,proto3" json:"index,omitempty"`
PreIndex int64 `protobuf:"varint,25,opt,name=preIndex,proto3" json:"preIndex,omitempty"`
DrivenByAdmin bool `protobuf:"varint,26,opt,name=drivenByAdmin,proto3" json:"drivenByAdmin,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GuessGame) Reset() { *m = GuessGame{} }
func (m *GuessGame) String() string { return proto.CompactTextString(m) }
func (*GuessGame) ProtoMessage() {}
func (*GuessGame) Descriptor() ([]byte, []int) {
return fileDescriptor_7574406c5d3430e8, []int{0}
}
func (m *GuessGame) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GuessGame.Unmarshal(m, b)
}
func (m *GuessGame) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GuessGame.Marshal(b, m, deterministic)
}
func (m *GuessGame) XXX_Merge(src proto.Message) {
xxx_messageInfo_GuessGame.Merge(m, src)
}
func (m *GuessGame) XXX_Size() int {
return xxx_messageInfo_GuessGame.Size(m)
}
func (m *GuessGame) XXX_DiscardUnknown() {
xxx_messageInfo_GuessGame.DiscardUnknown(m)
}
var xxx_messageInfo_GuessGame proto.InternalMessageInfo
func (m *GuessGame) GetGameID() string {
if m != nil {
return m.GameID
}
return ""
}
func (m *GuessGame) GetStatus() int32 {
if m != nil {
return m.Status
}
return 0
}
func (m *GuessGame) GetPreStatus() int32 {
if m != nil {
return m.PreStatus
}
return 0
}
func (m *GuessGame) GetStartTime() int64 {
if m != nil {
return m.StartTime
}
return 0
}
func (m *GuessGame) GetStartHeight() int64 {
if m != nil {
return m.StartHeight
}
return 0
}
func (m *GuessGame) GetStartTxHash() string {
if m != nil {
return m.StartTxHash
}
return ""
}
func (m *GuessGame) GetStartIndex() int64 {
if m != nil {
return m.StartIndex
}
return 0
}
func (m *GuessGame) GetTopic() string {
if m != nil {
return m.Topic
}
return ""
}
func (m *GuessGame) GetCategory() string {
if m != nil {
return m.Category
}
return ""
}
func (m *GuessGame) GetOptions() string {
if m != nil {
return m.Options
}
return ""
}
func (m *GuessGame) GetMaxBetHeight() int64 {
if m != nil {
return m.MaxBetHeight
}
return 0
}
func (m *GuessGame) GetMaxBetsOneTime() int64 {
if m != nil {
return m.MaxBetsOneTime
}
return 0
}
func (m *GuessGame) GetMaxBetsNumber() int64 {
if m != nil {
return m.MaxBetsNumber
}
return 0
}
func (m *GuessGame) GetDevFeeFactor() int64 {
if m != nil {
return m.DevFeeFactor
}
return 0
}
func (m *GuessGame) GetDevFeeAddr() string {
if m != nil {
return m.DevFeeAddr
}
return ""
}
func (m *GuessGame) GetPlatFeeFactor() int64 {
if m != nil {
return m.PlatFeeFactor
}
return 0
}
func (m *GuessGame) GetPlatFeeAddr() string {
if m != nil {
return m.PlatFeeAddr
}
return ""
}
func (m *GuessGame) GetExpireHeight() int64 {
if m != nil {
return m.ExpireHeight
}
return 0
}
func (m *GuessGame) GetAdminAddr() string {
if m != nil {
return m.AdminAddr
}
return ""
}
func (m *GuessGame) GetBetsNumber() int64 {
if m != nil {
return m.BetsNumber
}
return 0
}
func (m *GuessGame) GetPlays() []*GuessPlayer {
if m != nil {
return m.Plays
}
return nil
}
func (m *GuessGame) GetResult() string {
if m != nil {
return m.Result
}
return ""
}
func (m *GuessGame) GetBetStat() *GuessBetStat {
if m != nil {
return m.BetStat
}
return nil
}
func (m *GuessGame) GetIndex() int64 {
if m != nil {
return m.Index
}
return 0
}
func (m *GuessGame) GetPreIndex() int64 {
if m != nil {
return m.PreIndex
}
return 0
}
func (m *GuessGame) GetDrivenByAdmin() bool {
if m != nil {
return m.DrivenByAdmin
}
return false
}
//GuessPlayer 竞猜玩家信息
type GuessPlayer struct {
Addr string `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"`
Bet *GuessBet `protobuf:"bytes,2,opt,name=bet,proto3" json:"bet,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GuessPlayer) Reset() { *m = GuessPlayer{} }
func (m *GuessPlayer) String() string { return proto.CompactTextString(m) }
func (*GuessPlayer) ProtoMessage() {}
func (*GuessPlayer) Descriptor() ([]byte, []int) {
return fileDescriptor_7574406c5d3430e8, []int{1}
}
func (m *GuessPlayer) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GuessPlayer.Unmarshal(m, b)
}
func (m *GuessPlayer) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GuessPlayer.Marshal(b, m, deterministic)
}
func (m *GuessPlayer) XXX_Merge(src proto.Message) {
xxx_messageInfo_GuessPlayer.Merge(m, src)
}
func (m *GuessPlayer) XXX_Size() int {
return xxx_messageInfo_GuessPlayer.Size(m)
}
func (m *GuessPlayer) XXX_DiscardUnknown() {
xxx_messageInfo_GuessPlayer.DiscardUnknown(m)
}
var xxx_messageInfo_GuessPlayer proto.InternalMessageInfo
func (m *GuessPlayer) GetAddr() string {
if m != nil {
return m.Addr
}
return ""
}
func (m *GuessPlayer) GetBet() *GuessBet {
if m != nil {
return m.Bet
}
return nil
}
//GuessBet 竞猜下注信息
type GuessBet struct {
Option string `protobuf:"bytes,1,opt,name=option,proto3" json:"option,omitempty"`
BetsNumber int64 `protobuf:"varint,2,opt,name=betsNumber,proto3" json:"betsNumber,omitempty"`
IsWinner bool `protobuf:"varint,3,opt,name=isWinner,proto3" json:"isWinner,omitempty"`
Profit int64 `protobuf:"varint,4,opt,name=profit,proto3" json:"profit,omitempty"`
Index int64 `protobuf:"varint,5,opt,name=index,proto3" json:"index,omitempty"`
PreIndex int64 `protobuf:"varint,6,opt,name=preIndex,proto3" json:"preIndex,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GuessBet) Reset() { *m = GuessBet{} }
func (m *GuessBet) String() string { return proto.CompactTextString(m) }
func (*GuessBet) ProtoMessage() {}
func (*GuessBet) Descriptor() ([]byte, []int) {
return fileDescriptor_7574406c5d3430e8, []int{2}
}
func (m *GuessBet) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GuessBet.Unmarshal(m, b)
}
func (m *GuessBet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GuessBet.Marshal(b, m, deterministic)
}
func (m *GuessBet) XXX_Merge(src proto.Message) {
xxx_messageInfo_GuessBet.Merge(m, src)
}
func (m *GuessBet) XXX_Size() int {
return xxx_messageInfo_GuessBet.Size(m)
}
func (m *GuessBet) XXX_DiscardUnknown() {
xxx_messageInfo_GuessBet.DiscardUnknown(m)
}
var xxx_messageInfo_GuessBet proto.InternalMessageInfo
func (m *GuessBet) GetOption() string {
if m != nil {
return m.Option
}
return ""
}
func (m *GuessBet) GetBetsNumber() int64 {
if m != nil {
return m.BetsNumber
}
return 0
}
func (m *GuessBet) GetIsWinner() bool {
if m != nil {
return m.IsWinner
}
return false
}
func (m *GuessBet) GetProfit() int64 {
if m != nil {
return m.Profit
}
return 0
}
func (m *GuessBet) GetIndex() int64 {
if m != nil {
return m.Index
}
return 0
}
func (m *GuessBet) GetPreIndex() int64 {
if m != nil {
return m.PreIndex
}
return 0
}
//GuessBetStat 竞猜下注统计信息
type GuessBetStat struct {
TotalBetTimes int64 `protobuf:"varint,1,opt,name=totalBetTimes,proto3" json:"totalBetTimes,omitempty"`
TotalBetsNumber int64 `protobuf:"varint,2,opt,name=totalBetsNumber,proto3" json:"totalBetsNumber,omitempty"`
Items []*GuessBetStatItem `protobuf:"bytes,3,rep,name=items,proto3" json:"items,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GuessBetStat) Reset() { *m = GuessBetStat{} }
func (m *GuessBetStat) String() string { return proto.CompactTextString(m) }
func (*GuessBetStat) ProtoMessage() {}
func (*GuessBetStat) Descriptor() ([]byte, []int) {
return fileDescriptor_7574406c5d3430e8, []int{3}
}
func (m *GuessBetStat) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GuessBetStat.Unmarshal(m, b)
}
func (m *GuessBetStat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GuessBetStat.Marshal(b, m, deterministic)
}
func (m *GuessBetStat) XXX_Merge(src proto.Message) {
xxx_messageInfo_GuessBetStat.Merge(m, src)
}
func (m *GuessBetStat) XXX_Size() int {
return xxx_messageInfo_GuessBetStat.Size(m)
}
func (m *GuessBetStat) XXX_DiscardUnknown() {
xxx_messageInfo_GuessBetStat.DiscardUnknown(m)
}
var xxx_messageInfo_GuessBetStat proto.InternalMessageInfo
func (m *GuessBetStat) GetTotalBetTimes() int64 {
if m != nil {
return m.TotalBetTimes
}
return 0
}
func (m *GuessBetStat) GetTotalBetsNumber() int64 {
if m != nil {
return m.TotalBetsNumber
}
return 0
}
func (m *GuessBetStat) GetItems() []*GuessBetStatItem {
if m != nil {
return m.Items
}
return nil
}
//GuessBetStat 竞猜下注子选项统计信息
type GuessBetStatItem struct {
Option string `protobuf:"bytes,1,opt,name=option,proto3" json:"option,omitempty"`
BetsNumber int64 `protobuf:"varint,2,opt,name=betsNumber,proto3" json:"betsNumber,omitempty"`
BetsTimes int64 `protobuf:"varint,3,opt,name=betsTimes,proto3" json:"betsTimes,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GuessBetStatItem) Reset() { *m = GuessBetStatItem{} }
func (m *GuessBetStatItem) String() string { return proto.CompactTextString(m) }
func (*GuessBetStatItem) ProtoMessage() {}
func (*GuessBetStatItem) Descriptor() ([]byte, []int) {
return fileDescriptor_7574406c5d3430e8, []int{4}
}
func (m *GuessBetStatItem) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GuessBetStatItem.Unmarshal(m, b)
}
func (m *GuessBetStatItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GuessBetStatItem.Marshal(b, m, deterministic)
}
func (m *GuessBetStatItem) XXX_Merge(src proto.Message) {
xxx_messageInfo_GuessBetStatItem.Merge(m, src)
}
func (m *GuessBetStatItem) XXX_Size() int {
return xxx_messageInfo_GuessBetStatItem.Size(m)
}
func (m *GuessBetStatItem) XXX_DiscardUnknown() {
xxx_messageInfo_GuessBetStatItem.DiscardUnknown(m)
}
var xxx_messageInfo_GuessBetStatItem proto.InternalMessageInfo
func (m *GuessBetStatItem) GetOption() string {
if m != nil {
return m.Option
}
return ""
}
func (m *GuessBetStatItem) GetBetsNumber() int64 {
if m != nil {
return m.BetsNumber
}
return 0
}
func (m *GuessBetStatItem) GetBetsTimes() int64 {
if m != nil {
return m.BetsTimes
}
return 0
}
//GuessGameAction 竞猜游戏动作
type GuessGameAction struct {
// Types that are valid to be assigned to Value:
// *GuessGameAction_Start
// *GuessGameAction_Bet
// *GuessGameAction_StopBet
// *GuessGameAction_Abort
// *GuessGameAction_Publish
// *GuessGameAction_Query
Value isGuessGameAction_Value `protobuf_oneof:"value"`
Ty int32 `protobuf:"varint,7,opt,name=ty,proto3" json:"ty,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GuessGameAction) Reset() { *m = GuessGameAction{} }
func (m *GuessGameAction) String() string { return proto.CompactTextString(m) }
func (*GuessGameAction) ProtoMessage() {}
func (*GuessGameAction) Descriptor() ([]byte, []int) {
return fileDescriptor_7574406c5d3430e8, []int{5}
}
func (m *GuessGameAction) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GuessGameAction.Unmarshal(m, b)
}
func (m *GuessGameAction) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GuessGameAction.Marshal(b, m, deterministic)
}
func (m *GuessGameAction) XXX_Merge(src proto.Message) {
xxx_messageInfo_GuessGameAction.Merge(m, src)
}
func (m *GuessGameAction) XXX_Size() int {
return xxx_messageInfo_GuessGameAction.Size(m)
}
func (m *GuessGameAction) XXX_DiscardUnknown() {
xxx_messageInfo_GuessGameAction.DiscardUnknown(m)
}
var xxx_messageInfo_GuessGameAction proto.InternalMessageInfo
type isGuessGameAction_Value interface {
isGuessGameAction_Value()
}
type GuessGameAction_Start struct {
Start *GuessGameStart `protobuf:"bytes,1,opt,name=start,proto3,oneof"`
}
type GuessGameAction_Bet struct {
Bet *GuessGameBet `protobuf:"bytes,2,opt,name=bet,proto3,oneof"`
}
type GuessGameAction_StopBet struct {
StopBet *GuessGameStopBet `protobuf:"bytes,3,opt,name=stopBet,proto3,oneof"`
}
type GuessGameAction_Abort struct {
Abort *GuessGameAbort `protobuf:"bytes,4,opt,name=abort,proto3,oneof"`
}
type GuessGameAction_Publish struct {
Publish *GuessGamePublish `protobuf:"bytes,5,opt,name=publish,proto3,oneof"`
}
type GuessGameAction_Query struct {
Query *GuessGameQuery `protobuf:"bytes,6,opt,name=query,proto3,oneof"`
}
func (*GuessGameAction_Start) isGuessGameAction_Value() {}
func (*GuessGameAction_Bet) isGuessGameAction_Value() {}
func (*GuessGameAction_StopBet) isGuessGameAction_Value() {}
func (*GuessGameAction_Abort) isGuessGameAction_Value() {}
func (*GuessGameAction_Publish) isGuessGameAction_Value() {}
func (*GuessGameAction_Query) isGuessGameAction_Value() {}
func (m *GuessGameAction) GetValue() isGuessGameAction_Value {
if m != nil {
return m.Value
}
return nil
}
func (m *GuessGameAction) GetStart() *GuessGameStart {
if x, ok := m.GetValue().(*GuessGameAction_Start); ok {
return x.Start
}
return nil
}
func (m *GuessGameAction) GetBet() *GuessGameBet {
if x, ok := m.GetValue().(*GuessGameAction_Bet); ok {
return x.Bet
}
return nil
}
func (m *GuessGameAction) GetStopBet() *GuessGameStopBet {
if x, ok := m.GetValue().(*GuessGameAction_StopBet); ok {
return x.StopBet
}
return nil
}
func (m *GuessGameAction) GetAbort() *GuessGameAbort {
if x, ok := m.GetValue().(*GuessGameAction_Abort); ok {
return x.Abort
}
return nil
}
func (m *GuessGameAction) GetPublish() *GuessGamePublish {
if x, ok := m.GetValue().(*GuessGameAction_Publish); ok {
return x.Publish
}
return nil
}
func (m *GuessGameAction) GetQuery() *GuessGameQuery {
if x, ok := m.GetValue().(*GuessGameAction_Query); ok {
return x.Query
}
return nil
}
func (m *GuessGameAction) GetTy() int32 {
if m != nil {
return m.Ty
}
return 0
}
// XXX_OneofFuncs is for the internal use of the proto package.
func (*GuessGameAction) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
return _GuessGameAction_OneofMarshaler, _GuessGameAction_OneofUnmarshaler, _GuessGameAction_OneofSizer, []interface{}{
(*GuessGameAction_Start)(nil),
(*GuessGameAction_Bet)(nil),
(*GuessGameAction_StopBet)(nil),
(*GuessGameAction_Abort)(nil),
(*GuessGameAction_Publish)(nil),
(*GuessGameAction_Query)(nil),
}
}
func _GuessGameAction_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
m := msg.(*GuessGameAction)
// value
switch x := m.Value.(type) {
case *GuessGameAction_Start:
b.EncodeVarint(1<<3 | proto.WireBytes)
if err := b.EncodeMessage(x.Start); err != nil {
return err
}
case *GuessGameAction_Bet:
b.EncodeVarint(2<<3 | proto.WireBytes)
if err := b.EncodeMessage(x.Bet); err != nil {
return err
}
case *GuessGameAction_StopBet:
b.EncodeVarint(3<<3 | proto.WireBytes)
if err := b.EncodeMessage(x.StopBet); err != nil {
return err
}
case *GuessGameAction_Abort:
b.EncodeVarint(4<<3 | proto.WireBytes)
if err := b.EncodeMessage(x.Abort); err != nil {
return err
}
case *GuessGameAction_Publish:
b.EncodeVarint(5<<3 | proto.WireBytes)
if err := b.EncodeMessage(x.Publish); err != nil {
return err
}
case *GuessGameAction_Query:
b.EncodeVarint(6<<3 | proto.WireBytes)
if err := b.EncodeMessage(x.Query); err != nil {
return err
}
case nil:
default:
return fmt.Errorf("GuessGameAction.Value has unexpected type %T", x)
}
return nil
}
func _GuessGameAction_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
m := msg.(*GuessGameAction)
switch tag {
case 1: // value.start
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
msg := new(GuessGameStart)
err := b.DecodeMessage(msg)
m.Value = &GuessGameAction_Start{msg}
return true, err
case 2: // value.bet
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
msg := new(GuessGameBet)
err := b.DecodeMessage(msg)
m.Value = &GuessGameAction_Bet{msg}
return true, err
case 3: // value.stopBet
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
msg := new(GuessGameStopBet)
err := b.DecodeMessage(msg)
m.Value = &GuessGameAction_StopBet{msg}
return true, err
case 4: // value.abort
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
msg := new(GuessGameAbort)
err := b.DecodeMessage(msg)
m.Value = &GuessGameAction_Abort{msg}
return true, err
case 5: // value.publish
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
msg := new(GuessGamePublish)
err := b.DecodeMessage(msg)
m.Value = &GuessGameAction_Publish{msg}
return true, err
case 6: // value.query
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
msg := new(GuessGameQuery)
err := b.DecodeMessage(msg)
m.Value = &GuessGameAction_Query{msg}
return true, err
default:
return false, nil
}
}
func _GuessGameAction_OneofSizer(msg proto.Message) (n int) {
m := msg.(*GuessGameAction)
// value
switch x := m.Value.(type) {
case *GuessGameAction_Start:
s := proto.Size(x.Start)
n += 1 // tag and wire
n += proto.SizeVarint(uint64(s))
n += s
case *GuessGameAction_Bet:
s := proto.Size(x.Bet)
n += 1 // tag and wire
n += proto.SizeVarint(uint64(s))
n += s
case *GuessGameAction_StopBet:
s := proto.Size(x.StopBet)
n += 1 // tag and wire
n += proto.SizeVarint(uint64(s))
n += s
case *GuessGameAction_Abort:
s := proto.Size(x.Abort)
n += 1 // tag and wire
n += proto.SizeVarint(uint64(s))
n += s
case *GuessGameAction_Publish:
s := proto.Size(x.Publish)
n += 1 // tag and wire
n += proto.SizeVarint(uint64(s))
n += s
case *GuessGameAction_Query:
s := proto.Size(x.Query)
n += 1 // tag and wire
n += proto.SizeVarint(uint64(s))
n += s
case nil:
default:
panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
}
return n
}
//GuessGameStart 游戏创建
type GuessGameStart struct {
Topic string `protobuf:"bytes,1,opt,name=topic,proto3" json:"topic,omitempty"`
Options string `protobuf:"bytes,2,opt,name=options,proto3" json:"options,omitempty"`
Category string `protobuf:"bytes,3,opt,name=category,proto3" json:"category,omitempty"`
MaxBetHeight int64 `protobuf:"varint,4,opt,name=maxBetHeight,proto3" json:"maxBetHeight,omitempty"`
MaxBetsOneTime int64 `protobuf:"varint,5,opt,name=maxBetsOneTime,proto3" json:"maxBetsOneTime,omitempty"`
MaxBetsNumber int64 `protobuf:"varint,6,opt,name=maxBetsNumber,proto3" json:"maxBetsNumber,omitempty"`
DevFeeFactor int64 `protobuf:"varint,7,opt,name=devFeeFactor,proto3" json:"devFeeFactor,omitempty"`
DevFeeAddr string `protobuf:"bytes,8,opt,name=devFeeAddr,proto3" json:"devFeeAddr,omitempty"`
PlatFeeFactor int64 `protobuf:"varint,9,opt,name=platFeeFactor,proto3" json:"platFeeFactor,omitempty"`
PlatFeeAddr string `protobuf:"bytes,10,opt,name=platFeeAddr,proto3" json:"platFeeAddr,omitempty"`
ExpireHeight int64 `protobuf:"varint,11,opt,name=expireHeight,proto3" json:"expireHeight,omitempty"`
DrivenByAdmin bool `protobuf:"varint,12,opt,name=drivenByAdmin,proto3" json:"drivenByAdmin,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GuessGameStart) Reset() { *m = GuessGameStart{} }
func (m *GuessGameStart) String() string { return proto.CompactTextString(m) }
func (*GuessGameStart) ProtoMessage() {}
func (*GuessGameStart) Descriptor() ([]byte, []int) {
return fileDescriptor_7574406c5d3430e8, []int{6}
}
func (m *GuessGameStart) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GuessGameStart.Unmarshal(m, b)
}
func (m *GuessGameStart) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GuessGameStart.Marshal(b, m, deterministic)
}
func (m *GuessGameStart) XXX_Merge(src proto.Message) {
xxx_messageInfo_GuessGameStart.Merge(m, src)
}
func (m *GuessGameStart) XXX_Size() int {
return xxx_messageInfo_GuessGameStart.Size(m)
}
func (m *GuessGameStart) XXX_DiscardUnknown() {
xxx_messageInfo_GuessGameStart.DiscardUnknown(m)
}
var xxx_messageInfo_GuessGameStart proto.InternalMessageInfo
func (m *GuessGameStart) GetTopic() string {
if m != nil {
return m.Topic
}
return ""
}
func (m *GuessGameStart) GetOptions() string {
if m != nil {
return m.Options
}
return ""
}
func (m *GuessGameStart) GetCategory() string {
if m != nil {
return m.Category
}
return ""
}
func (m *GuessGameStart) GetMaxBetHeight() int64 {
if m != nil {
return m.MaxBetHeight
}
return 0
}
func (m *GuessGameStart) GetMaxBetsOneTime() int64 {
if m != nil {
return m.MaxBetsOneTime
}
return 0
}
func (m *GuessGameStart) GetMaxBetsNumber() int64 {
if m != nil {
return m.MaxBetsNumber
}
return 0
}
func (m *GuessGameStart) GetDevFeeFactor() int64 {
if m != nil {
return m.DevFeeFactor
}
return 0
}
func (m *GuessGameStart) GetDevFeeAddr() string {
if m != nil {
return m.DevFeeAddr
}
return ""
}
func (m *GuessGameStart) GetPlatFeeFactor() int64 {
if m != nil {
return m.PlatFeeFactor
}
return 0
}
func (m *GuessGameStart) GetPlatFeeAddr() string {
if m != nil {
return m.PlatFeeAddr
}
return ""
}
func (m *GuessGameStart) GetExpireHeight() int64 {
if m != nil {
return m.ExpireHeight
}
return 0
}
func (m *GuessGameStart) GetDrivenByAdmin() bool {
if m != nil {
return m.DrivenByAdmin
}
return false
}
//GuessGameBet 参与游戏下注
type GuessGameBet struct {
GameID string `protobuf:"bytes,1,opt,name=gameID,proto3" json:"gameID,omitempty"`
Option string `protobuf:"bytes,2,opt,name=option,proto3" json:"option,omitempty"`
BetsNum int64 `protobuf:"varint,3,opt,name=betsNum,proto3" json:"betsNum,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GuessGameBet) Reset() { *m = GuessGameBet{} }
func (m *GuessGameBet) String() string { return proto.CompactTextString(m) }
func (*GuessGameBet) ProtoMessage() {}
func (*GuessGameBet) Descriptor() ([]byte, []int) {
return fileDescriptor_7574406c5d3430e8, []int{7}
}
func (m *GuessGameBet) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GuessGameBet.Unmarshal(m, b)
}
func (m *GuessGameBet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GuessGameBet.Marshal(b, m, deterministic)
}
func (m *GuessGameBet) XXX_Merge(src proto.Message) {
xxx_messageInfo_GuessGameBet.Merge(m, src)
}
func (m *GuessGameBet) XXX_Size() int {
return xxx_messageInfo_GuessGameBet.Size(m)
}
func (m *GuessGameBet) XXX_DiscardUnknown() {
xxx_messageInfo_GuessGameBet.DiscardUnknown(m)
}
var xxx_messageInfo_GuessGameBet proto.InternalMessageInfo
func (m *GuessGameBet) GetGameID() string {
if m != nil {
return m.GameID
}
return ""
}
func (m *GuessGameBet) GetOption() string {
if m != nil {
return m.Option
}
return ""
}
func (m *GuessGameBet) GetBetsNum() int64 {
if m != nil {
return m.BetsNum
}
return 0
}
//GuessGameStopBet 游戏停止下注
type GuessGameStopBet struct {
GameID string `protobuf:"bytes,1,opt,name=gameID,proto3" json:"gameID,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GuessGameStopBet) Reset() { *m = GuessGameStopBet{} }
func (m *GuessGameStopBet) String() string { return proto.CompactTextString(m) }
func (*GuessGameStopBet) ProtoMessage() {}
func (*GuessGameStopBet) Descriptor() ([]byte, []int) {
return fileDescriptor_7574406c5d3430e8, []int{8}
}
func (m *GuessGameStopBet) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GuessGameStopBet.Unmarshal(m, b)
}
func (m *GuessGameStopBet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GuessGameStopBet.Marshal(b, m, deterministic)
}
func (m *GuessGameStopBet) XXX_Merge(src proto.Message) {
xxx_messageInfo_GuessGameStopBet.Merge(m, src)
}
func (m *GuessGameStopBet) XXX_Size() int {
return xxx_messageInfo_GuessGameStopBet.Size(m)
}
func (m *GuessGameStopBet) XXX_DiscardUnknown() {
xxx_messageInfo_GuessGameStopBet.DiscardUnknown(m)
}
var xxx_messageInfo_GuessGameStopBet proto.InternalMessageInfo
func (m *GuessGameStopBet) GetGameID() string {
if m != nil {
return m.GameID
}
return ""
}
//GuessGameAbort 游戏异常终止,退还下注
type GuessGameAbort struct {
GameID string `protobuf:"bytes,1,opt,name=gameID,proto3" json:"gameID,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GuessGameAbort) Reset() { *m = GuessGameAbort{} }
func (m *GuessGameAbort) String() string { return proto.CompactTextString(m) }
func (*GuessGameAbort) ProtoMessage() {}
func (*GuessGameAbort) Descriptor() ([]byte, []int) {
return fileDescriptor_7574406c5d3430e8, []int{9}
}
func (m *GuessGameAbort) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GuessGameAbort.Unmarshal(m, b)
}
func (m *GuessGameAbort) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GuessGameAbort.Marshal(b, m, deterministic)
}
func (m *GuessGameAbort) XXX_Merge(src proto.Message) {
xxx_messageInfo_GuessGameAbort.Merge(m, src)
}
func (m *GuessGameAbort) XXX_Size() int {
return xxx_messageInfo_GuessGameAbort.Size(m)
}
func (m *GuessGameAbort) XXX_DiscardUnknown() {
xxx_messageInfo_GuessGameAbort.DiscardUnknown(m)
}
var xxx_messageInfo_GuessGameAbort proto.InternalMessageInfo
func (m *GuessGameAbort) GetGameID() string {
if m != nil {
return m.GameID
}
return ""
}
//GuessGamePublish 游戏结果揭晓
type GuessGamePublish struct {
GameID string `protobuf:"bytes,1,opt,name=gameID,proto3" json:"gameID,omitempty"`
Result string `protobuf:"bytes,2,opt,name=result,proto3" json:"result,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GuessGamePublish) Reset() { *m = GuessGamePublish{} }
func (m *GuessGamePublish) String() string { return proto.CompactTextString(m) }
func (*GuessGamePublish) ProtoMessage() {}
func (*GuessGamePublish) Descriptor() ([]byte, []int) {
return fileDescriptor_7574406c5d3430e8, []int{10}
}
func (m *GuessGamePublish) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GuessGamePublish.Unmarshal(m, b)
}
func (m *GuessGamePublish) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GuessGamePublish.Marshal(b, m, deterministic)
}
func (m *GuessGamePublish) XXX_Merge(src proto.Message) {
xxx_messageInfo_GuessGamePublish.Merge(m, src)
}
func (m *GuessGamePublish) XXX_Size() int {
return xxx_messageInfo_GuessGamePublish.Size(m)
}
func (m *GuessGamePublish) XXX_DiscardUnknown() {
xxx_messageInfo_GuessGamePublish.DiscardUnknown(m)
}
var xxx_messageInfo_GuessGamePublish proto.InternalMessageInfo
func (m *GuessGamePublish) GetGameID() string {
if m != nil {
return m.GameID
}
return ""
}
func (m *GuessGamePublish) GetResult() string {
if m != nil {
return m.Result
}
return ""
}
//GuessGameQuery 查询游戏结果
type GuessGameQuery struct {
GameID string `protobuf:"bytes,1,opt,name=gameID,proto3" json:"gameID,omitempty"`
Ty uint32 `protobuf:"varint,2,opt,name=ty,proto3" json:"ty,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GuessGameQuery) Reset() { *m = GuessGameQuery{} }
func (m *GuessGameQuery) String() string { return proto.CompactTextString(m) }
func (*GuessGameQuery) ProtoMessage() {}
func (*GuessGameQuery) Descriptor() ([]byte, []int) {
return fileDescriptor_7574406c5d3430e8, []int{11}
}
func (m *GuessGameQuery) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GuessGameQuery.Unmarshal(m, b)
}
func (m *GuessGameQuery) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GuessGameQuery.Marshal(b, m, deterministic)
}
func (m *GuessGameQuery) XXX_Merge(src proto.Message) {
xxx_messageInfo_GuessGameQuery.Merge(m, src)
}
func (m *GuessGameQuery) XXX_Size() int {
return xxx_messageInfo_GuessGameQuery.Size(m)
}
func (m *GuessGameQuery) XXX_DiscardUnknown() {
xxx_messageInfo_GuessGameQuery.DiscardUnknown(m)
}
var xxx_messageInfo_GuessGameQuery proto.InternalMessageInfo
func (m *GuessGameQuery) GetGameID() string {
if m != nil {
return m.GameID
}
return ""
}
func (m *GuessGameQuery) GetTy() uint32 {
if m != nil {
return m.Ty
}
return 0
}
//QueryGuessGameInfo 游戏信息查询消息
type QueryGuessGameInfo struct {
GameID string `protobuf:"bytes,1,opt,name=gameID,proto3" json:"gameID,omitempty"`
Addr string `protobuf:"bytes,2,opt,name=addr,proto3" json:"addr,omitempty"`
Status int32 `protobuf:"varint,3,opt,name=status,proto3" json:"status,omitempty"`
Index int64 `protobuf:"varint,4,opt,name=index,proto3" json:"index,omitempty"`
AdminAddr string `protobuf:"bytes,5,opt,name=adminAddr,proto3" json:"adminAddr,omitempty"`
Category string `protobuf:"bytes,6,opt,name=category,proto3" json:"category,omitempty"`
PrimaryKey string `protobuf:"bytes,7,opt,name=primaryKey,proto3" json:"primaryKey,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *QueryGuessGameInfo) Reset() { *m = QueryGuessGameInfo{} }
func (m *QueryGuessGameInfo) String() string { return proto.CompactTextString(m) }
func (*QueryGuessGameInfo) ProtoMessage() {}
func (*QueryGuessGameInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_7574406c5d3430e8, []int{12}
}
func (m *QueryGuessGameInfo) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_QueryGuessGameInfo.Unmarshal(m, b)
}
func (m *QueryGuessGameInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_QueryGuessGameInfo.Marshal(b, m, deterministic)
}
func (m *QueryGuessGameInfo) XXX_Merge(src proto.Message) {
xxx_messageInfo_QueryGuessGameInfo.Merge(m, src)
}
func (m *QueryGuessGameInfo) XXX_Size() int {
return xxx_messageInfo_QueryGuessGameInfo.Size(m)
}
func (m *QueryGuessGameInfo) XXX_DiscardUnknown() {
xxx_messageInfo_QueryGuessGameInfo.DiscardUnknown(m)
}
var xxx_messageInfo_QueryGuessGameInfo proto.InternalMessageInfo
func (m *QueryGuessGameInfo) GetGameID() string {
if m != nil {
return m.GameID
}
return ""
}
func (m *QueryGuessGameInfo) GetAddr() string {
if m != nil {
return m.Addr
}
return ""
}
func (m *QueryGuessGameInfo) GetStatus() int32 {
if m != nil {
return m.Status
}
return 0
}
func (m *QueryGuessGameInfo) GetIndex() int64 {
if m != nil {
return m.Index
}
return 0
}
func (m *QueryGuessGameInfo) GetAdminAddr() string {
if m != nil {
return m.AdminAddr
}
return ""
}
func (m *QueryGuessGameInfo) GetCategory() string {
if m != nil {
return m.Category
}
return ""
}
func (m *QueryGuessGameInfo) GetPrimaryKey() string {
if m != nil {
return m.PrimaryKey
}
return ""
}
//ReplyGuessGameInfo 游戏信息查询响应消息
type ReplyGuessGameInfo struct {
Game *GuessGame `protobuf:"bytes,1,opt,name=game,proto3" json:"game,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ReplyGuessGameInfo) Reset() { *m = ReplyGuessGameInfo{} }
func (m *ReplyGuessGameInfo) String() string { return proto.CompactTextString(m) }
func (*ReplyGuessGameInfo) ProtoMessage() {}
func (*ReplyGuessGameInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_7574406c5d3430e8, []int{13}
}
func (m *ReplyGuessGameInfo) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ReplyGuessGameInfo.Unmarshal(m, b)
}
func (m *ReplyGuessGameInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ReplyGuessGameInfo.Marshal(b, m, deterministic)
}
func (m *ReplyGuessGameInfo) XXX_Merge(src proto.Message) {
xxx_messageInfo_ReplyGuessGameInfo.Merge(m, src)
}
func (m *ReplyGuessGameInfo) XXX_Size() int {
return xxx_messageInfo_ReplyGuessGameInfo.Size(m)
}
func (m *ReplyGuessGameInfo) XXX_DiscardUnknown() {
xxx_messageInfo_ReplyGuessGameInfo.DiscardUnknown(m)
}
var xxx_messageInfo_ReplyGuessGameInfo proto.InternalMessageInfo
func (m *ReplyGuessGameInfo) GetGame() *GuessGame {
if m != nil {
return m.Game
}
return nil
}
//QueryGuessGameInfos 游戏信息列表查询消息
type QueryGuessGameInfos struct {
GameIDs []string `protobuf:"bytes,1,rep,name=gameIDs,proto3" json:"gameIDs,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *QueryGuessGameInfos) Reset() { *m = QueryGuessGameInfos{} }
func (m *QueryGuessGameInfos) String() string { return proto.CompactTextString(m) }
func (*QueryGuessGameInfos) ProtoMessage() {}
func (*QueryGuessGameInfos) Descriptor() ([]byte, []int) {
return fileDescriptor_7574406c5d3430e8, []int{14}
}
func (m *QueryGuessGameInfos) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_QueryGuessGameInfos.Unmarshal(m, b)
}
func (m *QueryGuessGameInfos) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_QueryGuessGameInfos.Marshal(b, m, deterministic)
}
func (m *QueryGuessGameInfos) XXX_Merge(src proto.Message) {
xxx_messageInfo_QueryGuessGameInfos.Merge(m, src)
}
func (m *QueryGuessGameInfos) XXX_Size() int {
return xxx_messageInfo_QueryGuessGameInfos.Size(m)
}
func (m *QueryGuessGameInfos) XXX_DiscardUnknown() {
xxx_messageInfo_QueryGuessGameInfos.DiscardUnknown(m)
}
var xxx_messageInfo_QueryGuessGameInfos proto.InternalMessageInfo
func (m *QueryGuessGameInfos) GetGameIDs() []string {
if m != nil {
return m.GameIDs
}
return nil
}
//ReplyGuessGameInfos 游戏信息列表查询响应消息
type ReplyGuessGameInfos struct {
Games []*GuessGame `protobuf:"bytes,1,rep,name=games,proto3" json:"games,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ReplyGuessGameInfos) Reset() { *m = ReplyGuessGameInfos{} }
func (m *ReplyGuessGameInfos) String() string { return proto.CompactTextString(m) }
func (*ReplyGuessGameInfos) ProtoMessage() {}
func (*ReplyGuessGameInfos) Descriptor() ([]byte, []int) {
return fileDescriptor_7574406c5d3430e8, []int{15}
}
func (m *ReplyGuessGameInfos) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ReplyGuessGameInfos.Unmarshal(m, b)
}
func (m *ReplyGuessGameInfos) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ReplyGuessGameInfos.Marshal(b, m, deterministic)
}
func (m *ReplyGuessGameInfos) XXX_Merge(src proto.Message) {
xxx_messageInfo_ReplyGuessGameInfos.Merge(m, src)
}
func (m *ReplyGuessGameInfos) XXX_Size() int {
return xxx_messageInfo_ReplyGuessGameInfos.Size(m)
}
func (m *ReplyGuessGameInfos) XXX_DiscardUnknown() {
xxx_messageInfo_ReplyGuessGameInfos.DiscardUnknown(m)
}
var xxx_messageInfo_ReplyGuessGameInfos proto.InternalMessageInfo
func (m *ReplyGuessGameInfos) GetGames() []*GuessGame {
if m != nil {
return m.Games
}
return nil
}
//ReceiptGuessGame 竞猜游戏收据信息
type ReceiptGuessGame struct {
StartIndex int64 `protobuf:"varint,1,opt,name=startIndex,proto3" json:"startIndex,omitempty"`
GameID string `protobuf:"bytes,2,opt,name=gameID,proto3" json:"gameID,omitempty"`
PreStatus int32 `protobuf:"varint,3,opt,name=preStatus,proto3" json:"preStatus,omitempty"`
Status int32 `protobuf:"varint,4,opt,name=status,proto3" json:"status,omitempty"`
Addr string `protobuf:"bytes,5,opt,name=addr,proto3" json:"addr,omitempty"`
AdminAddr string `protobuf:"bytes,6,opt,name=adminAddr,proto3" json:"adminAddr,omitempty"`
PreIndex int64 `protobuf:"varint,7,opt,name=preIndex,proto3" json:"preIndex,omitempty"`
Index int64 `protobuf:"varint,8,opt,name=index,proto3" json:"index,omitempty"`
Category string `protobuf:"bytes,9,opt,name=category,proto3" json:"category,omitempty"`
StatusChange bool `protobuf:"varint,10,opt,name=statusChange,proto3" json:"statusChange,omitempty"`
Bet bool `protobuf:"varint,11,opt,name=bet,proto3" json:"bet,omitempty"`
Option string `protobuf:"bytes,12,opt,name=option,proto3" json:"option,omitempty"`
BetsNumber int64 `protobuf:"varint,13,opt,name=betsNumber,proto3" json:"betsNumber,omitempty"`
Game *GuessGame `protobuf:"bytes,14,opt,name=game,proto3" json:"game,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ReceiptGuessGame) Reset() { *m = ReceiptGuessGame{} }
func (m *ReceiptGuessGame) String() string { return proto.CompactTextString(m) }
func (*ReceiptGuessGame) ProtoMessage() {}
func (*ReceiptGuessGame) Descriptor() ([]byte, []int) {
return fileDescriptor_7574406c5d3430e8, []int{16}
}
func (m *ReceiptGuessGame) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ReceiptGuessGame.Unmarshal(m, b)
}
func (m *ReceiptGuessGame) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ReceiptGuessGame.Marshal(b, m, deterministic)
}
func (m *ReceiptGuessGame) XXX_Merge(src proto.Message) {
xxx_messageInfo_ReceiptGuessGame.Merge(m, src)
}
func (m *ReceiptGuessGame) XXX_Size() int {
return xxx_messageInfo_ReceiptGuessGame.Size(m)
}
func (m *ReceiptGuessGame) XXX_DiscardUnknown() {
xxx_messageInfo_ReceiptGuessGame.DiscardUnknown(m)
}
var xxx_messageInfo_ReceiptGuessGame proto.InternalMessageInfo
func (m *ReceiptGuessGame) GetStartIndex() int64 {
if m != nil {
return m.StartIndex
}
return 0
}
func (m *ReceiptGuessGame) GetGameID() string {
if m != nil {
return m.GameID
}
return ""
}
func (m *ReceiptGuessGame) GetPreStatus() int32 {
if m != nil {
return m.PreStatus
}
return 0
}
func (m *ReceiptGuessGame) GetStatus() int32 {
if m != nil {
return m.Status
}
return 0
}
func (m *ReceiptGuessGame) GetAddr() string {
if m != nil {
return m.Addr
}
return ""
}
func (m *ReceiptGuessGame) GetAdminAddr() string {
if m != nil {
return m.AdminAddr
}
return ""
}
func (m *ReceiptGuessGame) GetPreIndex() int64 {
if m != nil {
return m.PreIndex
}
return 0
}
func (m *ReceiptGuessGame) GetIndex() int64 {
if m != nil {
return m.Index
}
return 0
}
func (m *ReceiptGuessGame) GetCategory() string {
if m != nil {
return m.Category
}
return ""
}
func (m *ReceiptGuessGame) GetStatusChange() bool {
if m != nil {
return m.StatusChange
}
return false
}
func (m *ReceiptGuessGame) GetBet() bool {
if m != nil {
return m.Bet
}
return false
}
func (m *ReceiptGuessGame) GetOption() string {
if m != nil {
return m.Option
}
return ""
}
func (m *ReceiptGuessGame) GetBetsNumber() int64 {
if m != nil {
return m.BetsNumber
}
return 0
}
func (m *ReceiptGuessGame) GetGame() *GuessGame {
if m != nil {
return m.Game
}
return nil
}
//UserBet 用户下注信息
type UserBet struct {
StartIndex int64 `protobuf:"varint,1,opt,name=startIndex,proto3" json:"startIndex,omitempty"`
Index int64 `protobuf:"varint,2,opt,name=index,proto3" json:"index,omitempty"`
GameID string `protobuf:"bytes,3,opt,name=gameID,proto3" json:"gameID,omitempty"`
Addr string `protobuf:"bytes,4,opt,name=addr,proto3" json:"addr,omitempty"`
Option string `protobuf:"bytes,5,opt,name=option,proto3" json:"option,omitempty"`
BetsNumber int64 `protobuf:"varint,6,opt,name=betsNumber,proto3" json:"betsNumber,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *UserBet) Reset() { *m = UserBet{} }
func (m *UserBet) String() string { return proto.CompactTextString(m) }
func (*UserBet) ProtoMessage() {}
func (*UserBet) Descriptor() ([]byte, []int) {
return fileDescriptor_7574406c5d3430e8, []int{17}
}
func (m *UserBet) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_UserBet.Unmarshal(m, b)
}
func (m *UserBet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_UserBet.Marshal(b, m, deterministic)
}
func (m *UserBet) XXX_Merge(src proto.Message) {
xxx_messageInfo_UserBet.Merge(m, src)
}
func (m *UserBet) XXX_Size() int {
return xxx_messageInfo_UserBet.Size(m)
}
func (m *UserBet) XXX_DiscardUnknown() {
xxx_messageInfo_UserBet.DiscardUnknown(m)
}
var xxx_messageInfo_UserBet proto.InternalMessageInfo
func (m *UserBet) GetStartIndex() int64 {
if m != nil {
return m.StartIndex
}
return 0
}
func (m *UserBet) GetIndex() int64 {
if m != nil {
return m.Index
}
return 0
}
func (m *UserBet) GetGameID() string {
if m != nil {
return m.GameID
}
return ""
}
func (m *UserBet) GetAddr() string {
if m != nil {
return m.Addr
}
return ""
}
func (m *UserBet) GetOption() string {
if m != nil {
return m.Option
}
return ""
}
func (m *UserBet) GetBetsNumber() int64 {
if m != nil {
return m.BetsNumber
}
return 0
}
//GuessStartTxReq 构造start交易的请求
type GuessStartTxReq struct {
Topic string `protobuf:"bytes,1,opt,name=topic,proto3" json:"topic,omitempty"`
Options string `protobuf:"bytes,2,opt,name=options,proto3" json:"options,omitempty"`
Category string `protobuf:"bytes,3,opt,name=category,proto3" json:"category,omitempty"`
MaxHeight int64 `protobuf:"varint,4,opt,name=maxHeight,proto3" json:"maxHeight,omitempty"`
MaxBetHeight int64 `protobuf:"varint,5,opt,name=maxBetHeight,proto3" json:"maxBetHeight,omitempty"`
MaxBetsOneTime int64 `protobuf:"varint,6,opt,name=maxBetsOneTime,proto3" json:"maxBetsOneTime,omitempty"`
MaxBetsNumber int64 `protobuf:"varint,7,opt,name=maxBetsNumber,proto3" json:"maxBetsNumber,omitempty"`
DevFeeFactor int64 `protobuf:"varint,8,opt,name=devFeeFactor,proto3" json:"devFeeFactor,omitempty"`
DevFeeAddr string `protobuf:"bytes,9,opt,name=devFeeAddr,proto3" json:"devFeeAddr,omitempty"`
PlatFeeFactor int64 `protobuf:"varint,10,opt,name=platFeeFactor,proto3" json:"platFeeFactor,omitempty"`
PlatFeeAddr string `protobuf:"bytes,11,opt,name=platFeeAddr,proto3" json:"platFeeAddr,omitempty"`
ExpireHeight int64 `protobuf:"varint,12,opt,name=expireHeight,proto3" json:"expireHeight,omitempty"`
Fee int64 `protobuf:"varint,13,opt,name=fee,proto3" json:"fee,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GuessStartTxReq) Reset() { *m = GuessStartTxReq{} }
func (m *GuessStartTxReq) String() string { return proto.CompactTextString(m) }
func (*GuessStartTxReq) ProtoMessage() {}
func (*GuessStartTxReq) Descriptor() ([]byte, []int) {
return fileDescriptor_7574406c5d3430e8, []int{18}
}
func (m *GuessStartTxReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GuessStartTxReq.Unmarshal(m, b)
}
func (m *GuessStartTxReq) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GuessStartTxReq.Marshal(b, m, deterministic)
}
func (m *GuessStartTxReq) XXX_Merge(src proto.Message) {
xxx_messageInfo_GuessStartTxReq.Merge(m, src)
}
func (m *GuessStartTxReq) XXX_Size() int {
return xxx_messageInfo_GuessStartTxReq.Size(m)
}
func (m *GuessStartTxReq) XXX_DiscardUnknown() {
xxx_messageInfo_GuessStartTxReq.DiscardUnknown(m)
}
var xxx_messageInfo_GuessStartTxReq proto.InternalMessageInfo
func (m *GuessStartTxReq) GetTopic() string {
if m != nil {
return m.Topic
}
return ""
}
func (m *GuessStartTxReq) GetOptions() string {
if m != nil {
return m.Options
}
return ""
}
func (m *GuessStartTxReq) GetCategory() string {
if m != nil {
return m.Category
}
return ""
}
func (m *GuessStartTxReq) GetMaxHeight() int64 {
if m != nil {
return m.MaxHeight
}
return 0
}
func (m *GuessStartTxReq) GetMaxBetHeight() int64 {
if m != nil {
return m.MaxBetHeight
}
return 0
}
func (m *GuessStartTxReq) GetMaxBetsOneTime() int64 {
if m != nil {
return m.MaxBetsOneTime
}
return 0
}
func (m *GuessStartTxReq) GetMaxBetsNumber() int64 {
if m != nil {
return m.MaxBetsNumber
}
return 0
}
func (m *GuessStartTxReq) GetDevFeeFactor() int64 {
if m != nil {
return m.DevFeeFactor
}
return 0
}
func (m *GuessStartTxReq) GetDevFeeAddr() string {
if m != nil {
return m.DevFeeAddr
}
return ""
}
func (m *GuessStartTxReq) GetPlatFeeFactor() int64 {
if m != nil {
return m.PlatFeeFactor
}
return 0
}
func (m *GuessStartTxReq) GetPlatFeeAddr() string {
if m != nil {
return m.PlatFeeAddr
}
return ""
}
func (m *GuessStartTxReq) GetExpireHeight() int64 {
if m != nil {
return m.ExpireHeight
}
return 0
}
func (m *GuessStartTxReq) GetFee() int64 {
if m != nil {
return m.Fee
}
return 0
}
//GuessBetTxReq 构造bet交易的请求
type GuessBetTxReq struct {
GameID string `protobuf:"bytes,1,opt,name=gameID,proto3" json:"gameID,omitempty"`
Option string `protobuf:"bytes,2,opt,name=option,proto3" json:"option,omitempty"`
Bets int64 `protobuf:"varint,3,opt,name=bets,proto3" json:"bets,omitempty"`
Fee int64 `protobuf:"varint,4,opt,name=fee,proto3" json:"fee,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GuessBetTxReq) Reset() { *m = GuessBetTxReq{} }
func (m *GuessBetTxReq) String() string { return proto.CompactTextString(m) }
func (*GuessBetTxReq) ProtoMessage() {}
func (*GuessBetTxReq) Descriptor() ([]byte, []int) {
return fileDescriptor_7574406c5d3430e8, []int{19}
}
func (m *GuessBetTxReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GuessBetTxReq.Unmarshal(m, b)
}
func (m *GuessBetTxReq) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GuessBetTxReq.Marshal(b, m, deterministic)
}
func (m *GuessBetTxReq) XXX_Merge(src proto.Message) {
xxx_messageInfo_GuessBetTxReq.Merge(m, src)
}
func (m *GuessBetTxReq) XXX_Size() int {
return xxx_messageInfo_GuessBetTxReq.Size(m)
}
func (m *GuessBetTxReq) XXX_DiscardUnknown() {
xxx_messageInfo_GuessBetTxReq.DiscardUnknown(m)
}
var xxx_messageInfo_GuessBetTxReq proto.InternalMessageInfo
func (m *GuessBetTxReq) GetGameID() string {
if m != nil {
return m.GameID
}
return ""
}
func (m *GuessBetTxReq) GetOption() string {
if m != nil {
return m.Option
}
return ""
}
func (m *GuessBetTxReq) GetBets() int64 {
if m != nil {
return m.Bets
}
return 0
}
func (m *GuessBetTxReq) GetFee() int64 {
if m != nil {
return m.Fee
}
return 0
}
//GuessStopBetTxReq 构造stopBet交易的请求
type GuessStopBetTxReq struct {
GameID string `protobuf:"bytes,1,opt,name=gameID,proto3" json:"gameID,omitempty"`
Fee int64 `protobuf:"varint,2,opt,name=fee,proto3" json:"fee,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GuessStopBetTxReq) Reset() { *m = GuessStopBetTxReq{} }
func (m *GuessStopBetTxReq) String() string { return proto.CompactTextString(m) }
func (*GuessStopBetTxReq) ProtoMessage() {}
func (*GuessStopBetTxReq) Descriptor() ([]byte, []int) {
return fileDescriptor_7574406c5d3430e8, []int{20}
}
func (m *GuessStopBetTxReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GuessStopBetTxReq.Unmarshal(m, b)
}
func (m *GuessStopBetTxReq) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GuessStopBetTxReq.Marshal(b, m, deterministic)
}
func (m *GuessStopBetTxReq) XXX_Merge(src proto.Message) {
xxx_messageInfo_GuessStopBetTxReq.Merge(m, src)
}
func (m *GuessStopBetTxReq) XXX_Size() int {
return xxx_messageInfo_GuessStopBetTxReq.Size(m)
}
func (m *GuessStopBetTxReq) XXX_DiscardUnknown() {
xxx_messageInfo_GuessStopBetTxReq.DiscardUnknown(m)
}
var xxx_messageInfo_GuessStopBetTxReq proto.InternalMessageInfo
func (m *GuessStopBetTxReq) GetGameID() string {
if m != nil {
return m.GameID
}
return ""
}
func (m *GuessStopBetTxReq) GetFee() int64 {
if m != nil {
return m.Fee
}
return 0
}
//GuessAbortTxReq 构造abort交易的请求
type GuessAbortTxReq struct {
GameID string `protobuf:"bytes,1,opt,name=gameID,proto3" json:"gameID,omitempty"`
Fee int64 `protobuf:"varint,2,opt,name=fee,proto3" json:"fee,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GuessAbortTxReq) Reset() { *m = GuessAbortTxReq{} }
func (m *GuessAbortTxReq) String() string { return proto.CompactTextString(m) }
func (*GuessAbortTxReq) ProtoMessage() {}
func (*GuessAbortTxReq) Descriptor() ([]byte, []int) {
return fileDescriptor_7574406c5d3430e8, []int{21}
}
func (m *GuessAbortTxReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GuessAbortTxReq.Unmarshal(m, b)
}
func (m *GuessAbortTxReq) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GuessAbortTxReq.Marshal(b, m, deterministic)
}
func (m *GuessAbortTxReq) XXX_Merge(src proto.Message) {
xxx_messageInfo_GuessAbortTxReq.Merge(m, src)
}
func (m *GuessAbortTxReq) XXX_Size() int {
return xxx_messageInfo_GuessAbortTxReq.Size(m)
}
func (m *GuessAbortTxReq) XXX_DiscardUnknown() {
xxx_messageInfo_GuessAbortTxReq.DiscardUnknown(m)
}
var xxx_messageInfo_GuessAbortTxReq proto.InternalMessageInfo
func (m *GuessAbortTxReq) GetGameID() string {
if m != nil {
return m.GameID
}
return ""
}
func (m *GuessAbortTxReq) GetFee() int64 {
if m != nil {
return m.Fee
}
return 0
}
//GuessPublishTxReq 构造publish交易的请求
type GuessPublishTxReq struct {
GameID string `protobuf:"bytes,1,opt,name=gameID,proto3" json:"gameID,omitempty"`
Result string `protobuf:"bytes,2,opt,name=result,proto3" json:"result,omitempty"`
Fee int64 `protobuf:"varint,3,opt,name=fee,proto3" json:"fee,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GuessPublishTxReq) Reset() { *m = GuessPublishTxReq{} }
func (m *GuessPublishTxReq) String() string { return proto.CompactTextString(m) }
func (*GuessPublishTxReq) ProtoMessage() {}
func (*GuessPublishTxReq) Descriptor() ([]byte, []int) {
return fileDescriptor_7574406c5d3430e8, []int{22}
}
func (m *GuessPublishTxReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GuessPublishTxReq.Unmarshal(m, b)
}
func (m *GuessPublishTxReq) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GuessPublishTxReq.Marshal(b, m, deterministic)
}
func (m *GuessPublishTxReq) XXX_Merge(src proto.Message) {
xxx_messageInfo_GuessPublishTxReq.Merge(m, src)
}
func (m *GuessPublishTxReq) XXX_Size() int {
return xxx_messageInfo_GuessPublishTxReq.Size(m)
}
func (m *GuessPublishTxReq) XXX_DiscardUnknown() {
xxx_messageInfo_GuessPublishTxReq.DiscardUnknown(m)
}
var xxx_messageInfo_GuessPublishTxReq proto.InternalMessageInfo
func (m *GuessPublishTxReq) GetGameID() string {
if m != nil {
return m.GameID
}
return ""
}
func (m *GuessPublishTxReq) GetResult() string {
if m != nil {
return m.Result
}
return ""
}
func (m *GuessPublishTxReq) GetFee() int64 {
if m != nil {
return m.Fee
}
return 0
}
// GuessGameRecord game信息查询记录
type GuessGameRecord struct {
GameID string `protobuf:"bytes,1,opt,name=gameID,proto3" json:"gameID,omitempty"`
StartIndex int64 `protobuf:"varint,2,opt,name=startIndex,proto3" json:"startIndex,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GuessGameRecord) Reset() { *m = GuessGameRecord{} }
func (m *GuessGameRecord) String() string { return proto.CompactTextString(m) }
func (*GuessGameRecord) ProtoMessage() {}
func (*GuessGameRecord) Descriptor() ([]byte, []int) {
return fileDescriptor_7574406c5d3430e8, []int{23}
}
func (m *GuessGameRecord) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GuessGameRecord.Unmarshal(m, b)
}
func (m *GuessGameRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GuessGameRecord.Marshal(b, m, deterministic)
}
func (m *GuessGameRecord) XXX_Merge(src proto.Message) {
xxx_messageInfo_GuessGameRecord.Merge(m, src)
}
func (m *GuessGameRecord) XXX_Size() int {
return xxx_messageInfo_GuessGameRecord.Size(m)
}
func (m *GuessGameRecord) XXX_DiscardUnknown() {
xxx_messageInfo_GuessGameRecord.DiscardUnknown(m)
}
var xxx_messageInfo_GuessGameRecord proto.InternalMessageInfo
func (m *GuessGameRecord) GetGameID() string {
if m != nil {
return m.GameID
}
return ""
}
func (m *GuessGameRecord) GetStartIndex() int64 {
if m != nil {
return m.StartIndex
}
return 0
}
// GuessGameRecords game信息查询记录集
type GuessGameRecords struct {
Records []*GuessGameRecord `protobuf:"bytes,1,rep,name=records,proto3" json:"records,omitempty"`
PrimaryKey string `protobuf:"bytes,2,opt,name=primaryKey,proto3" json:"primaryKey,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GuessGameRecords) Reset() { *m = GuessGameRecords{} }
func (m *GuessGameRecords) String() string { return proto.CompactTextString(m) }
func (*GuessGameRecords) ProtoMessage() {}
func (*GuessGameRecords) Descriptor() ([]byte, []int) {
return fileDescriptor_7574406c5d3430e8, []int{24}
}
func (m *GuessGameRecords) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GuessGameRecords.Unmarshal(m, b)
}
func (m *GuessGameRecords) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GuessGameRecords.Marshal(b, m, deterministic)
}
func (m *GuessGameRecords) XXX_Merge(src proto.Message) {
xxx_messageInfo_GuessGameRecords.Merge(m, src)
}
func (m *GuessGameRecords) XXX_Size() int {
return xxx_messageInfo_GuessGameRecords.Size(m)
}
func (m *GuessGameRecords) XXX_DiscardUnknown() {
xxx_messageInfo_GuessGameRecords.DiscardUnknown(m)
}
var xxx_messageInfo_GuessGameRecords proto.InternalMessageInfo
func (m *GuessGameRecords) GetRecords() []*GuessGameRecord {
if m != nil {
return m.Records
}
return nil
}
func (m *GuessGameRecords) GetPrimaryKey() string {
if m != nil {
return m.PrimaryKey
}
return ""
}
func init() {
proto.RegisterType((*GuessGame)(nil), "types.GuessGame")
proto.RegisterType((*GuessPlayer)(nil), "types.GuessPlayer")
proto.RegisterType((*GuessBet)(nil), "types.GuessBet")
proto.RegisterType((*GuessBetStat)(nil), "types.GuessBetStat")
proto.RegisterType((*GuessBetStatItem)(nil), "types.GuessBetStatItem")
proto.RegisterType((*GuessGameAction)(nil), "types.GuessGameAction")
proto.RegisterType((*GuessGameStart)(nil), "types.GuessGameStart")
proto.RegisterType((*GuessGameBet)(nil), "types.GuessGameBet")
proto.RegisterType((*GuessGameStopBet)(nil), "types.GuessGameStopBet")
proto.RegisterType((*GuessGameAbort)(nil), "types.GuessGameAbort")
proto.RegisterType((*GuessGamePublish)(nil), "types.GuessGamePublish")
proto.RegisterType((*GuessGameQuery)(nil), "types.GuessGameQuery")
proto.RegisterType((*QueryGuessGameInfo)(nil), "types.QueryGuessGameInfo")
proto.RegisterType((*ReplyGuessGameInfo)(nil), "types.ReplyGuessGameInfo")
proto.RegisterType((*QueryGuessGameInfos)(nil), "types.QueryGuessGameInfos")
proto.RegisterType((*ReplyGuessGameInfos)(nil), "types.ReplyGuessGameInfos")
proto.RegisterType((*ReceiptGuessGame)(nil), "types.ReceiptGuessGame")
proto.RegisterType((*UserBet)(nil), "types.UserBet")
proto.RegisterType((*GuessStartTxReq)(nil), "types.GuessStartTxReq")
proto.RegisterType((*GuessBetTxReq)(nil), "types.GuessBetTxReq")
proto.RegisterType((*GuessStopBetTxReq)(nil), "types.GuessStopBetTxReq")
proto.RegisterType((*GuessAbortTxReq)(nil), "types.GuessAbortTxReq")
proto.RegisterType((*GuessPublishTxReq)(nil), "types.GuessPublishTxReq")
proto.RegisterType((*GuessGameRecord)(nil), "types.GuessGameRecord")
proto.RegisterType((*GuessGameRecords)(nil), "types.GuessGameRecords")
}
func init() { proto.RegisterFile("guess.proto", fileDescriptor_7574406c5d3430e8) }
var fileDescriptor_7574406c5d3430e8 = []byte{
// 1367 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0xc9, 0x8e, 0xdb, 0x46,
0x13, 0x1e, 0x92, 0xa2, 0x96, 0x92, 0x66, 0x46, 0xee, 0xf1, 0xc2, 0x7f, 0x60, 0x18, 0xfa, 0x09,
0xc3, 0x11, 0x02, 0xd8, 0x09, 0x64, 0x20, 0x08, 0x1c, 0xf8, 0x30, 0x8a, 0x61, 0x7b, 0x10, 0x20,
0x71, 0x68, 0x1b, 0xc9, 0x95, 0x92, 0x7a, 0x34, 0x04, 0x24, 0x92, 0x26, 0x5b, 0x03, 0xe9, 0x21,
0x72, 0xcb, 0x1b, 0x38, 0x87, 0xdc, 0xf2, 0x1a, 0x41, 0x4e, 0x79, 0xa4, 0xa0, 0xaa, 0x9b, 0x62,
0x93, 0xa2, 0x16, 0x07, 0xb9, 0xb1, 0x96, 0xee, 0xaa, 0xae, 0xed, 0x2b, 0x09, 0xda, 0xd3, 0x05,
0x4f, 0xd3, 0x27, 0x71, 0x12, 0x89, 0x88, 0xd9, 0x62, 0x15, 0xf3, 0xf4, 0xfc, 0x96, 0x48, 0xfc,
0x30, 0xf5, 0xc7, 0x22, 0x88, 0x42, 0x29, 0x71, 0xff, 0xae, 0x43, 0xeb, 0x15, 0x6a, 0xbe, 0xf2,
0xe7, 0x9c, 0xdd, 0x85, 0xfa, 0xd4, 0x9f, 0xf3, 0xcb, 0x17, 0x8e, 0xd1, 0x33, 0xfa, 0x2d, 0x4f,
0x51, 0xc8, 0x4f, 0x85, 0x2f, 0x16, 0xa9, 0x63, 0xf6, 0x8c, 0xbe, 0xed, 0x29, 0x8a, 0xdd, 0x87,
0x56, 0x9c, 0xf0, 0xb7, 0x52, 0x64, 0x91, 0x28, 0x67, 0xa0, 0x34, 0x15, 0x7e, 0x22, 0xde, 0x05,
0x73, 0xee, 0xd4, 0x7a, 0x46, 0xdf, 0xf2, 0x72, 0x06, 0xeb, 0x41, 0x9b, 0x88, 0xd7, 0x3c, 0x98,
0x5e, 0x0b, 0xc7, 0x26, 0xb9, 0xce, 0x5a, 0x6b, 0xbc, 0x5b, 0xbe, 0xf6, 0xd3, 0x6b, 0xa7, 0x4e,
0x2e, 0xe9, 0x2c, 0xf6, 0x00, 0x80, 0xc8, 0xcb, 0x70, 0xc2, 0x97, 0x4e, 0x83, 0xae, 0xd0, 0x38,
0xec, 0x36, 0xd8, 0x22, 0x8a, 0x83, 0xb1, 0xd3, 0xa4, 0xb3, 0x92, 0x60, 0xe7, 0xd0, 0x1c, 0xfb,
0x82, 0x4f, 0xa3, 0x64, 0xe5, 0xb4, 0x48, 0xb0, 0xa6, 0x99, 0x03, 0x8d, 0x28, 0xc6, 0xf8, 0xa4,
0x0e, 0x90, 0x28, 0x23, 0x99, 0x0b, 0x9d, 0xb9, 0xbf, 0x1c, 0xf2, 0xcc, 0xe1, 0x36, 0x59, 0x2b,
0xf0, 0xd8, 0x23, 0x38, 0x91, 0x74, 0xfa, 0x43, 0xc8, 0xe9, 0xd9, 0x1d, 0xd2, 0x2a, 0x71, 0xd9,
0x43, 0x38, 0x56, 0x9c, 0xef, 0x17, 0xf3, 0x11, 0x4f, 0x9c, 0x63, 0x52, 0x2b, 0x32, 0xd1, 0xe2,
0x84, 0xdf, 0xbc, 0xe4, 0xfc, 0xa5, 0x3f, 0x16, 0x51, 0xe2, 0x9c, 0x48, 0x8b, 0x3a, 0x0f, 0x23,
0x20, 0xe9, 0x8b, 0xc9, 0x24, 0x71, 0x4e, 0xc9, 0x65, 0x8d, 0x83, 0x96, 0xe2, 0x99, 0x2f, 0xf2,
0x4b, 0xba, 0xd2, 0x52, 0x81, 0x89, 0x91, 0x56, 0x0c, 0xba, 0xe6, 0x96, 0x8c, 0xb4, 0xc6, 0x42,
0x5f, 0xf8, 0x32, 0x0e, 0x12, 0xae, 0x5e, 0xcf, 0xa4, 0x2f, 0x3a, 0x0f, 0xf3, 0xed, 0x4f, 0xe6,
0x41, 0x48, 0x77, 0x9c, 0xd1, 0x1d, 0x39, 0x03, 0x3d, 0x1d, 0xe5, 0x0f, 0xbe, 0x2d, 0x73, 0x95,
0x73, 0x58, 0x1f, 0xec, 0x78, 0xe6, 0xaf, 0x52, 0xe7, 0x4e, 0xcf, 0xea, 0xb7, 0x07, 0xec, 0x09,
0xd5, 0xec, 0x13, 0x2a, 0xce, 0x37, 0x33, 0x7f, 0xc5, 0x13, 0x4f, 0x2a, 0x60, 0x35, 0x26, 0x3c,
0x5d, 0xcc, 0x84, 0x73, 0x57, 0x56, 0xa9, 0xa4, 0xd8, 0x63, 0x68, 0x8c, 0xb8, 0xc0, 0xe2, 0x73,
0xee, 0xf5, 0x8c, 0x7e, 0x7b, 0x70, 0xa6, 0xdf, 0x31, 0x94, 0x22, 0x2f, 0xd3, 0xc1, 0xe2, 0x08,
0xa8, 0x6e, 0x1c, 0xf2, 0x45, 0x12, 0x58, 0x1c, 0x71, 0xc2, 0x65, 0x41, 0xfd, 0x8f, 0x04, 0x6b,
0x1a, 0x83, 0x39, 0x49, 0x82, 0x1b, 0x1e, 0x0e, 0x57, 0x17, 0xf8, 0x2e, 0xe7, 0xbc, 0x67, 0xf4,
0x9b, 0x5e, 0x91, 0xe9, 0xbe, 0x80, 0xb6, 0xe6, 0x34, 0x63, 0x50, 0xf3, 0x31, 0x20, 0xb2, 0xa3,
0xe8, 0x9b, 0xfd, 0x1f, 0xac, 0x11, 0x17, 0xd4, 0x4c, 0xed, 0xc1, 0x69, 0xc9, 0x4b, 0x0f, 0x65,
0xee, 0xef, 0x06, 0x34, 0x33, 0x0e, 0xbe, 0x58, 0x96, 0x61, 0xd6, 0x97, 0x92, 0x2a, 0xc5, 0xd4,
0xdc, 0x88, 0xe9, 0x39, 0x34, 0x83, 0xf4, 0xa7, 0x20, 0x0c, 0x79, 0x42, 0xed, 0xd9, 0xf4, 0xd6,
0x34, 0xde, 0x19, 0x27, 0xd1, 0x55, 0x20, 0x54, 0x6b, 0x2a, 0x2a, 0x0f, 0x8b, 0xbd, 0x2d, 0x2c,
0xf5, 0x62, 0x58, 0xdc, 0x5f, 0x0c, 0xe8, 0xe8, 0x21, 0xc6, 0x38, 0x89, 0x48, 0xf8, 0xb3, 0x21,
0xa7, 0x56, 0x4f, 0xc9, 0x6b, 0xcb, 0x2b, 0x32, 0x59, 0x1f, 0x4e, 0x33, 0x46, 0xf1, 0x05, 0x65,
0x36, 0x7b, 0x0c, 0x76, 0x20, 0xf8, 0x1c, 0x47, 0x0c, 0x96, 0xc6, 0xbd, 0x8a, 0xb4, 0x5e, 0x0a,
0x3e, 0xf7, 0xa4, 0x96, 0x7b, 0x0d, 0xdd, 0xb2, 0xe8, 0x5f, 0x47, 0xf0, 0x3e, 0xb4, 0x90, 0x92,
0xcf, 0xb0, 0xe4, 0x0c, 0x5b, 0x33, 0xdc, 0xbf, 0x4c, 0x38, 0x5d, 0x4f, 0xcf, 0x0b, 0x9a, 0xab,
0xe8, 0x2c, 0x4d, 0x20, 0x32, 0xd4, 0x1e, 0xdc, 0xd1, 0x9d, 0x45, 0xb5, 0xb7, 0x34, 0xe1, 0x8e,
0x3c, 0xa9, 0xc5, 0x3e, 0xd3, 0x4b, 0xe1, 0xac, 0xac, 0x8c, 0xa3, 0xe5, 0x88, 0x0a, 0x82, 0x3d,
0x85, 0x46, 0x2a, 0xa2, 0x78, 0xc8, 0x05, 0xf9, 0x51, 0x0a, 0x83, 0xbc, 0x99, 0xc4, 0xaf, 0x8f,
0xbc, 0x4c, 0x13, 0x9d, 0xf1, 0x47, 0x51, 0x22, 0x73, 0x5c, 0xe1, 0xcc, 0x05, 0x0a, 0xd1, 0x19,
0xd2, 0x42, 0x1b, 0xf1, 0x62, 0x34, 0x0b, 0xd2, 0x6b, 0xca, 0x7e, 0x85, 0x8d, 0x37, 0x52, 0x8c,
0x36, 0x94, 0x26, 0xda, 0xf8, 0xb0, 0xe0, 0xc9, 0x8a, 0xea, 0xa2, 0xc2, 0xc6, 0x8f, 0x28, 0x44,
0x1b, 0xa4, 0xc5, 0x4e, 0xc0, 0x14, 0x2b, 0x9a, 0xd5, 0xb6, 0x67, 0x8a, 0xd5, 0xb0, 0x01, 0xf6,
0x8d, 0x3f, 0x5b, 0x70, 0xf7, 0x37, 0x0b, 0x4e, 0x8a, 0x51, 0xca, 0xe7, 0xb7, 0xa1, 0xcf, 0x6f,
0x6d, 0x46, 0x9b, 0xc5, 0x19, 0xad, 0x4f, 0x76, 0xab, 0x34, 0xd9, 0xcb, 0xf3, 0xbb, 0x76, 0xd0,
0xfc, 0xb6, 0x0f, 0x9b, 0xdf, 0xf5, 0x43, 0xe6, 0x77, 0x63, 0xef, 0xfc, 0x6e, 0xee, 0x9f, 0xdf,
0xad, 0x03, 0xe6, 0x37, 0xec, 0x9f, 0xdf, 0xed, 0x8a, 0xf9, 0xbd, 0x31, 0xde, 0x3a, 0x55, 0xe3,
0xed, 0x67, 0xd5, 0xec, 0xaa, 0x3c, 0x77, 0xed, 0x0c, 0xaa, 0xe3, 0xcc, 0x42, 0xc7, 0x39, 0x34,
0xa5, 0x31, 0x46, 0xaa, 0x9f, 0x32, 0xd2, 0xfd, 0x5c, 0xf5, 0xad, 0x56, 0xcb, 0xdb, 0x6e, 0x77,
0xfb, 0x5a, 0xad, 0x50, 0x11, 0x6f, 0xd5, 0x1c, 0x6a, 0xb7, 0xaa, 0xea, 0xdd, 0xe5, 0xb3, 0x42,
0x16, 0x53, 0x47, 0x16, 0xf7, 0x6b, 0xcd, 0x1a, 0x95, 0xf3, 0xd6, 0x1b, 0x64, 0x75, 0xe3, 0xe9,
0x63, 0xac, 0x6e, 0xf7, 0x4f, 0x03, 0x18, 0x9d, 0x58, 0x9f, 0xbf, 0x0c, 0xaf, 0xa2, 0xad, 0xc7,
0x33, 0xb0, 0x30, 0x35, 0xb0, 0xc8, 0x97, 0x2f, 0xab, 0xb0, 0x7c, 0xad, 0x07, 0x75, 0x4d, 0x1f,
0xd4, 0x05, 0x10, 0xb6, 0xcb, 0x20, 0xac, 0x37, 0x48, 0xbd, 0xd4, 0x20, 0x0f, 0x00, 0xe2, 0x24,
0x98, 0xfb, 0xc9, 0xea, 0x3b, 0x2e, 0x1b, 0xb4, 0xe5, 0x69, 0x1c, 0xf7, 0x19, 0x30, 0x8f, 0xc7,
0xb3, 0xd2, 0x4b, 0x1e, 0x42, 0x0d, 0x7d, 0x57, 0xd3, 0xae, 0x5b, 0x6e, 0x7e, 0x8f, 0xa4, 0xee,
0x17, 0x70, 0xb6, 0x19, 0x85, 0x14, 0x6b, 0x41, 0x3e, 0x1c, 0x21, 0xc2, 0xc2, 0x4e, 0x56, 0xa4,
0xfb, 0x1c, 0xce, 0x36, 0x8d, 0xa5, 0xec, 0x11, 0xd8, 0xa8, 0x21, 0xd5, 0xab, 0xcc, 0x49, 0xb1,
0xfb, 0xab, 0x05, 0x5d, 0x8f, 0x8f, 0x79, 0x10, 0x8b, 0x7c, 0xbb, 0x2d, 0x6e, 0x8b, 0xc6, 0xc6,
0xb6, 0x98, 0x27, 0xc5, 0x2c, 0x24, 0x65, 0xf7, 0x96, 0x9b, 0xa7, 0xa7, 0x56, 0x48, 0x4f, 0x96,
0x4a, 0x5b, 0x4b, 0x65, 0x21, 0x39, 0xf5, 0x8a, 0xe4, 0xac, 0x31, 0xb6, 0x51, 0x5a, 0x3d, 0xd6,
0xc9, 0x6e, 0x96, 0x50, 0x79, 0xeb, 0x26, 0xeb, 0x42, 0x47, 0x7a, 0xf2, 0xed, 0xb5, 0x1f, 0x4e,
0x39, 0x0d, 0x85, 0xa6, 0x57, 0xe0, 0xb1, 0xae, 0x04, 0x9f, 0x36, 0x89, 0x08, 0x65, 0xf2, 0xae,
0xed, 0xec, 0xc0, 0xc9, 0xe3, 0x0d, 0x9c, 0xcc, 0xca, 0xe0, 0x64, 0x67, 0x19, 0x7c, 0x34, 0xa0,
0xf1, 0x3e, 0xe5, 0x09, 0x76, 0xf6, 0xbe, 0x6c, 0xac, 0x5f, 0x6c, 0xea, 0x2f, 0xce, 0x73, 0x64,
0x55, 0x36, 0x4e, 0xad, 0xd8, 0x38, 0xea, 0x2d, 0xf6, 0x8e, 0xb7, 0xd4, 0xcb, 0x6f, 0x71, 0xff,
0xb0, 0x14, 0xaa, 0xbf, 0x95, 0x3f, 0x35, 0x3c, 0xfe, 0xe1, 0x3f, 0x45, 0xa2, 0xfb, 0xd0, 0x9a,
0xfb, 0xcb, 0x02, 0x0c, 0xe5, 0x8c, 0x0d, 0x9c, 0xb2, 0x0f, 0xc2, 0xa9, 0xfa, 0x61, 0x38, 0xd5,
0x38, 0x04, 0xa7, 0x9a, 0x7b, 0x71, 0xaa, 0xb5, 0x1f, 0xa7, 0xe0, 0x00, 0x9c, 0x6a, 0xef, 0xc7,
0xa9, 0x4e, 0x05, 0x4e, 0x75, 0xc1, 0xba, 0xe2, 0x5c, 0x15, 0x21, 0x7e, 0xba, 0x1c, 0x8e, 0xb3,
0x8d, 0x4f, 0xa6, 0xeb, 0x53, 0x41, 0x89, 0x41, 0x0d, 0x0b, 0x40, 0x21, 0x12, 0x7d, 0x67, 0x66,
0x6a, 0xb9, 0x99, 0xe7, 0x70, 0x4b, 0xd5, 0x05, 0x81, 0xd3, 0x6e, 0x53, 0xea, 0xb8, 0x99, 0x1f,
0xff, 0x46, 0x95, 0x15, 0xe1, 0xd5, 0xa7, 0x1e, 0x7e, 0xaf, 0x6c, 0x2b, 0x08, 0xdb, 0xfb, 0xcc,
0x2a, 0x1c, 0xcb, 0xae, 0xb5, 0xf2, 0x6b, 0x2f, 0xb5, 0x05, 0xd6, 0xe3, 0xe3, 0x28, 0x99, 0x6c,
0xbd, 0xb4, 0xd8, 0xb0, 0x66, 0xb9, 0x61, 0xdd, 0x89, 0x06, 0xb4, 0xf2, 0xaa, 0x94, 0x7d, 0x09,
0x8d, 0x44, 0x7e, 0xaa, 0x89, 0x7d, 0x77, 0x63, 0x32, 0x90, 0xd8, 0xcb, 0xd4, 0x4a, 0x28, 0x64,
0x96, 0x51, 0x68, 0xf0, 0xd1, 0x04, 0x9b, 0xfe, 0xda, 0x60, 0x5f, 0x01, 0xe4, 0x5d, 0xca, 0xaa,
0xf7, 0xec, 0xf3, 0xec, 0xc7, 0xd5, 0xfb, 0x30, 0x0d, 0xa6, 0xe1, 0xbb, 0xa5, 0x7b, 0xc4, 0x06,
0xda, 0x0f, 0xab, 0xaa, 0x85, 0xbb, 0xea, 0xcc, 0x33, 0xb5, 0xf4, 0x64, 0x6b, 0xc9, 0xb6, 0xdd,
0xbb, 0xea, 0x6c, 0xe6, 0xa7, 0x5c, 0x53, 0xaa, 0x57, 0xf0, 0x5d, 0x36, 0xb3, 0xa5, 0x65, 0xdb,
0x2e, 0x5e, 0x71, 0x76, 0x54, 0xa7, 0x7f, 0x77, 0x9e, 0xfe, 0x13, 0x00, 0x00, 0xff, 0xff, 0xd2,
0x0f, 0x63, 0x87, 0x06, 0x12, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// GuessClient is the client API for Guess service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type GuessClient interface {
//游戏开始
GuessStart(ctx context.Context, in *GuessGameStart, opts ...grpc.CallOption) (*types.UnsignTx, error)
//游戏下注
GuessBet(ctx context.Context, in *GuessGameBet, opts ...grpc.CallOption) (*types.UnsignTx, error)
//游戏终止下注
GuessStopBet(ctx context.Context, in *GuessGameStopBet, opts ...grpc.CallOption) (*types.UnsignTx, error)
//游戏异常终止
GuessAbort(ctx context.Context, in *GuessGameAbort, opts ...grpc.CallOption) (*types.UnsignTx, error)
//游戏结束
GuessPublish(ctx context.Context, in *GuessGamePublish, opts ...grpc.CallOption) (*types.UnsignTx, error)
}
type guessClient struct {
cc *grpc.ClientConn
}
func NewGuessClient(cc *grpc.ClientConn) GuessClient {
return &guessClient{cc}
}
func (c *guessClient) GuessStart(ctx context.Context, in *GuessGameStart, opts ...grpc.CallOption) (*types.UnsignTx, error) {
out := new(types.UnsignTx)
err := c.cc.Invoke(ctx, "/types.guess/GuessStart", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *guessClient) GuessBet(ctx context.Context, in *GuessGameBet, opts ...grpc.CallOption) (*types.UnsignTx, error) {
out := new(types.UnsignTx)
err := c.cc.Invoke(ctx, "/types.guess/GuessBet", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *guessClient) GuessStopBet(ctx context.Context, in *GuessGameStopBet, opts ...grpc.CallOption) (*types.UnsignTx, error) {
out := new(types.UnsignTx)
err := c.cc.Invoke(ctx, "/types.guess/GuessStopBet", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *guessClient) GuessAbort(ctx context.Context, in *GuessGameAbort, opts ...grpc.CallOption) (*types.UnsignTx, error) {
out := new(types.UnsignTx)
err := c.cc.Invoke(ctx, "/types.guess/GuessAbort", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *guessClient) GuessPublish(ctx context.Context, in *GuessGamePublish, opts ...grpc.CallOption) (*types.UnsignTx, error) {
out := new(types.UnsignTx)
err := c.cc.Invoke(ctx, "/types.guess/GuessPublish", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// GuessServer is the server API for Guess service.
type GuessServer interface {
//游戏开始
GuessStart(context.Context, *GuessGameStart) (*types.UnsignTx, error)
//游戏下注
GuessBet(context.Context, *GuessGameBet) (*types.UnsignTx, error)
//游戏终止下注
GuessStopBet(context.Context, *GuessGameStopBet) (*types.UnsignTx, error)
//游戏异常终止
GuessAbort(context.Context, *GuessGameAbort) (*types.UnsignTx, error)
//游戏结束
GuessPublish(context.Context, *GuessGamePublish) (*types.UnsignTx, error)
}
func RegisterGuessServer(s *grpc.Server, srv GuessServer) {
s.RegisterService(&_Guess_serviceDesc, srv)
}
func _Guess_GuessStart_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GuessGameStart)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(GuessServer).GuessStart(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/types.guess/GuessStart",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(GuessServer).GuessStart(ctx, req.(*GuessGameStart))
}
return interceptor(ctx, in, info, handler)
}
func _Guess_GuessBet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GuessGameBet)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(GuessServer).GuessBet(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/types.guess/GuessBet",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(GuessServer).GuessBet(ctx, req.(*GuessGameBet))
}
return interceptor(ctx, in, info, handler)
}
func _Guess_GuessStopBet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GuessGameStopBet)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(GuessServer).GuessStopBet(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/types.guess/GuessStopBet",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(GuessServer).GuessStopBet(ctx, req.(*GuessGameStopBet))
}
return interceptor(ctx, in, info, handler)
}
func _Guess_GuessAbort_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GuessGameAbort)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(GuessServer).GuessAbort(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/types.guess/GuessAbort",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(GuessServer).GuessAbort(ctx, req.(*GuessGameAbort))
}
return interceptor(ctx, in, info, handler)
}
func _Guess_GuessPublish_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GuessGamePublish)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(GuessServer).GuessPublish(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/types.guess/GuessPublish",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(GuessServer).GuessPublish(ctx, req.(*GuessGamePublish))
}
return interceptor(ctx, in, info, handler)
}
var _Guess_serviceDesc = grpc.ServiceDesc{
ServiceName: "types.guess",
HandlerType: (*GuessServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "GuessStart",
Handler: _Guess_GuessStart_Handler,
},
{
MethodName: "GuessBet",
Handler: _Guess_GuessBet_Handler,
},
{
MethodName: "GuessStopBet",
Handler: _Guess_GuessStopBet_Handler,
},
{
MethodName: "GuessAbort",
Handler: _Guess_GuessAbort_Handler,
},
{
MethodName: "GuessPublish",
Handler: _Guess_GuessPublish_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "guess.proto",
}
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
}
// 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"},
}
}
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment