Commit a8e53ba4 authored by 张振华's avatar 张振华

guess

parent 82b582dc
......@@ -62,9 +62,13 @@ func addGuessStartFlags(cmd *cobra.Command) {
cmd.Flags().Uint32P("maxBetsNumber", "n", 100000, "max bets number")
//cmd.MarkFlagRequired("maxBetsNumber")
cmd.Flags().Float64P("fee", "f", 0, "fee")
cmd.Flags().Int64P("devFeeFactor", "df", 0, "dev fee factor, unit: 1/1000")
cmd.Flags().StringP("feeAddr", "a", "", "fee address")
cmd.Flags().StringP("devFeeAddr", "dfa", "", "dev address to receive share")
cmd.Flags().Int64P("platFeeFactor", "pf", 0, "plat fee factor, unit: 1/1000")
cmd.Flags().StringP("platFeeAddr", "pfa", "", "plat address to receive share")
cmd.Flags().StringP("expire", "ex", "", "expire time of the game, after this any addr can abort it")
......@@ -82,13 +86,13 @@ func guessStart(cmd *cobra.Command, args []string) {
oneBet, _ := cmd.Flags().GetUint32("oneBet")
maxBets, _ := cmd.Flags().GetUint32("maxBets")
maxBetsNumber, _ := cmd.Flags().GetUint32("maxBetsNumber")
fee, _ := cmd.Flags().GetFloat64("fee")
feeAddr, _ := cmd.Flags().GetString("feeAddr")
devFeeFactor, _ := cmd.Flags().GetInt64("devFeeFactor")
devFeeAddr, _ := cmd.Flags().GetString("devFeeAddr")
platFeeFactor, _ := cmd.Flags().GetInt64("platFeeFactor")
platFeeAddr, _ := cmd.Flags().GetString("platFeeAddr")
expire, _ := cmd.Flags().GetString("expire")
expireHeight, _ := cmd.Flags().GetUint32("expireHeight")
feeInt64 := uint64(fee * 1e4)
params := &pkt.GuessStartTxReq{
Topic: topic,
Options: options,
......@@ -99,8 +103,10 @@ func guessStart(cmd *cobra.Command, args []string) {
OneBet: oneBet,
MaxBets: maxBets,
MaxBetsNumber: maxBetsNumber,
Fee: feeInt64,
FeeAddr: feeAddr,
DevFeeFactor: devFeeFactor,
DevFeeAddr: devFeeAddr,
PlatFeeFactor: platFeeFactor,
PlatFeeAddr: platFeeAddr,
Expire: expire,
ExpireHeight: expireHeight,
}
......
......@@ -8,8 +8,8 @@ package executor
区块链游戏:竞猜
一、玩法简介:
菠菜平台的管理员可以发布竞猜游戏,玩家可以对竞猜游戏进行投注.
截止时间达到后,玩家不能再进行投注,等待管理员公布结果.
博彩平台的管理员可以发布竞猜游戏,玩家可以对竞猜游戏进行投注.
截止投注时间达到后,管理员改变游戏状态为停止投注状态,玩家不能再进行投注,等待管理员公布结果.
竞猜内容的结果出来以后,管理员根据竞猜内容的真实结果触发智能合约进行输赢判断及结算。
二、创建及参与游戏
......@@ -19,7 +19,7 @@ package executor
三、制胜策略
1、竞猜游戏对应的现实世界的结果出来以后,游戏管理员向区块链合约公布胜出的竞猜选项。
2、合约将投注的所有赌注向压注正确选项的玩家进行分配,分配原则根据每个地址实际投注的数额占比进行分配,比如一个地址投注占了正确选项投注总额的1/2,则该地址将获得所有赌注总额的1/2。
3、如果因为现实世界的突发异常导致竞猜不能继续(比如某场足球比赛因为不可抗力取消了),则管理员可以终止竞猜,合约将把所有地址的投注返还。
3、如果因为现实世界的突发异常导致竞猜不能继续(比如某场足球比赛因为不可抗力取消了,比如自然灾害、政治事件等),则管理员可以终止竞猜,合约将把所有地址的投注返还。
四、游戏过程和状态
1、创建游戏,一个地址可以作为本局竞猜游戏的管理员发起竞猜游戏。
......@@ -31,16 +31,24 @@ package executor
单次最多可下注数量(比如100注)、
截止下注时间(比如UTC时间2018-12-12 10:00:00或者区块高度1000000)
游戏超时时间(比如UTC时间2018-12-20 10:00:00或者区块高度1080000)
可下注的最大地址数量(比如20000个
3、截止下注时间之前,玩家可根据游戏要求进行下注,下注金额注入合约地址。如果投注地址数量已经超过上限,则不允许新的地址投注。
可下注的最大数量(比如20000个BTY
3、截止下注时间之前,玩家可根据游戏要求进行下注,下注金额注入合约地址。如果投注数量已经超过上限,则不允许新的投注。
4、截止下注时间达到后,玩家不可再下注。
5、现实世界的竞猜结果出现后,管理员在游戏超时时间之前公布游戏结果。
6、合约根据管理员输入的正确结果,对每个地址的投注进行输赢判断,并将所有赌注对所有竞猜正确的地址按各自的投注额占比进行比例分配
6、(1)合约先对所有赌注收取一定比例的佣金,比如5‰给开发者地址,5‰给平台地址,(2)合约根据管理员输入的正确结果,对每个投注地址进行输赢判断,并将提取佣金后的剩余所有赌注对所有竞猜正确的地址按各自的投注额占比进行比例分配(比如A选项正确,所有选A的赌注共10000个BTY,某个地址向A下注100BTY,则该地址分得1/100)
7、如果因为现实世界的突发异常导致竞猜不能继续(比如某场足球比赛因为不可抗力取消了),则管理员可以终止竞猜,合约将把所有地址的投注返还。
8、如果游戏超时,管理员仍未公布结果,则任何地址都可以触发合约异常终止竞猜,合约中的投注返还给投注地址。
8、如果游戏超时,管理员仍未公布结果,则任何地址都可以触发合约异常终止竞猜,合约中的投注返还给投注地址。
8、游戏状态:
start(管理员)->bet(玩家)->publish(管理员)
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(管理员)
说明:这里的管理员不是特殊地址,而是谁创建本局竞猜游戏,谁就是本局竞猜游戏的管理员。
*/
......@@ -19,6 +19,11 @@ func (c *Guess) Exec_Bet(payload *pkt.GuessGameBet, tx *types.Transaction, index
return action.GameBet(payload)
}
func (c *Guess) Exec_StopBet(payload *pkt.GuessGameStopBet, tx *types.Transaction, index int) (*types.Receipt, error) {
action := NewAction(c, tx, index)
return action.GameStopBet(payload)
}
func (c *Guess) Exec_Publish(payload *pkt.GuessGamePublish, tx *types.Transaction, index int) (*types.Receipt, error) {
action := NewAction(c, tx, index)
return action.GamePublish(payload)
......
This diff is collapsed.
......@@ -22,19 +22,64 @@ func (g *Guess) Query_QueryGameById(in *pkt.QueryGuessGameInfo) (types.Message,
}
func (g *Guess) Query_QueryGameByAddr(in *pkt.QueryGuessGameInfo) (types.Message, error) {
gameIds, err := getGameListByAddr(g.GetLocalDB(), in.Addr, in.Index)
records, err := getGameListByAddr(g.GetLocalDB(), in.Addr, in.Index)
if err != nil {
return nil, err
}
return gameIds, nil
return records, nil
}
func (g *Guess) Query_QueryGameByAddrStatus(in *pkt.QueryGuessGameInfo) (types.Message, error) {
records, err := getGameListByAddr(g.GetLocalDB(), in.Addr, in.Index)
if err != nil {
return nil, err
}
return records, nil
}
func (g *Guess) Query_QueryGameByStatus(in *pkt.QueryGuessGameInfo) (types.Message, error) {
gameIds, err := getGameListByStatus(g.GetLocalDB(), in.Status, in.Index)
records, err := getGameListByStatus(g.GetLocalDB(), in.Status, in.Index)
if err != nil {
return nil, err
}
return records, nil
}
func (g *Guess) Query_QueryGameByAdminAddr(in *pkt.QueryGuessGameInfo) (types.Message, error) {
records, err := getGameListByAdminAddr(g.GetLocalDB(), in.AdminAddr, in.Index)
if err != nil {
return nil, err
}
return records, nil
}
func (g *Guess) Query_QueryGameByAddrStatusAddr(in *pkt.QueryGuessGameInfo) (types.Message, error) {
records, err := getGameListByAddrStatus(g.GetLocalDB(), in.Addr, in.Status, in.Index)
if err != nil {
return nil, err
}
return records, nil
}
func (g *Guess) Query_QueryGameByAdminStatusAddr(in *pkt.QueryGuessGameInfo) (types.Message, error) {
records, err := getGameListByAdminStatus(g.GetLocalDB(), in.AdminAddr, in.Status, in.Index)
if err != nil {
return nil, err
}
return records, nil
}
func (g *Guess) Query_QueryGameByCategoryStatusAddr(in *pkt.QueryGuessGameInfo) (types.Message, error) {
records, err := getGameListByCategoryStatus(g.GetLocalDB(), in.Category, in.Status, in.Index)
if err != nil {
return nil, err
}
return gameIds, nil
return records, nil
}
......@@ -21,17 +21,19 @@ message GuessGame {
uint32 oneBet = 13; //一注等于多少bty或者token
uint32 maxBets = 14; //单次可以下多少注,默认100
uint32 maxBetsNumber = 15; //最多可以下多少注
int64 fee = 16; //收取费用,不带则表示不收费
string feeAddr = 17; //收费地址
string expire = 18; //游戏过期时间
int64 expireHeight = 19; //游戏过期区块高度
string adminAddr = 20; //游戏创建者地址,只有该地址可以开奖
uint32 betsNumber = 21; //已下注数,如果数量达到maxBetsNumber,则不允许再下注
repeated GuessPlayer plays = 22; //参与游戏下注的玩家投注信息
string result = 23; //公布的中奖结果
GuessBetStat betStat = 24;
int64 index = 25;
int64 preIndex = 26;
int64 devFeeFactor = 16; //开发者抽成比例
string devFeeAddr = 17; //开发者地址
int64 platFeeFactor = 18; //平台抽成比例
string platFeeAddr = 19; //平台地址
string expire = 20; //游戏过期时间
int64 expireHeight = 21; //游戏过期区块高度
string adminAddr = 22; //游戏创建者地址,只有该地址可以开奖
uint32 betsNumber = 23; //已下注数,如果数量达到maxBetsNumber,则不允许再下注
repeated GuessPlayer plays = 24; //参与游戏下注的玩家投注信息
string result = 25; //公布的中奖结果
GuessBetStat betStat = 26;
int64 index = 27;
int64 preIndex = 28;
}
message GuessPlayer {
......@@ -43,7 +45,7 @@ message GuessBet {
string option = 1;
uint32 betsNumber = 2;
bool isWinner = 3;
uint32 profit = 4;
int64 profit = 4;
int64 index = 5;
int64 preIndex = 6;
}
......@@ -65,11 +67,12 @@ message GuessGameAction {
oneof value {
GuessGameStart start = 1;
GuessGameBet bet = 2;
GuessGameAbort abort = 3;
GuessGamePublish publish = 4;
GuessGameQuery query = 5;
GuessGameStopBet stopBet = 3;
GuessGameAbort abort = 4;
GuessGamePublish publish = 5;
GuessGameQuery query = 6;
}
uint32 ty = 6;
uint32 ty = 7;
}
//游戏启动
......@@ -78,16 +81,19 @@ message GuessGameStart{
string options = 2;
string category = 3;
string maxTime = 4;
int64 maxHeight = 5;
int64 maxHeight = 5;
string symbol = 6;
string exec = 7;
uint32 oneBet = 8;
uint32 maxBets = 9;
uint32 maxBetsNumber = 10;
int64 fee = 11;
string feeAddr = 12;
string expire = 13;
int64 expireHeight = 14;
int64 devFeeFactor = 11; //开发者抽成比例
string devFeeAddr = 12; //开发者地址
int64 platFeeFactor = 13; //平台抽成比例
string platFeeAddr = 14; //平台地址
string expire = 15;
int64 expireHeight = 16;
int64 fee = 17;
}
//参与游戏下注
......@@ -98,6 +104,12 @@ message GuessGameBet{
int64 fee = 4;
}
//游戏停止下注
message GuessGameStopBet{
string gameId = 1;
int64 fee = 2;
}
//游戏异常终止,退还下注
message GuessGameAbort{
string gameId = 1;
......@@ -124,6 +136,8 @@ message QueryGuessGameInfo {
string addr = 2;
int32 status = 3;
int64 index = 4;
string adminAddr = 5;
string category = 6;
}
message ReplyGuessGameInfo {
......@@ -161,10 +175,13 @@ message GuessStartTxReq {
uint32 oneBet = 8;
uint32 maxBets = 9;
uint32 maxBetsNumber = 10;
uint64 fee = 11;
string feeAddr = 12;
string expire = 13;
uint32 expireHeight = 14;
int64 devFeeFactor = 11;
string devFeeAddr = 12;
int64 platFeeFactor = 13;
string platFeeAddr = 14;
string feeAddr = 15;
string expire = 16;
uint32 expireHeight = 17;
}
message GuessBetTxReq {
......
......@@ -25,11 +25,12 @@ func (c *Jrpc) GuessStartTx(parm *pb.GuessStartTxReq, result *interface{}) error
OneBet: parm.OneBet,
MaxBets: parm.MaxBets,
MaxBetsNumber: parm.MaxBetsNumber,
Fee: parm.Fee,
FeeAddr: parm.FeeAddr,
DevFeeFactor: parm.DevFeeFactor,
DevFeeAddr: parm.DevFeeAddr,
PlatFeeFactor: parm.PlatFeeFactor,
PlatFeeAddr: parm.PlatFeeAddr,
}
reply, err := c.cli.GuessStart(context.Background(), head)
if err != nil {
return err
......
......@@ -4,23 +4,45 @@
package rpc
type PokerBullStartTx struct {
Value int64 `json:"value"`
PlayerNum int32 `json:"playerNum"`
Fee int64 `json:"fee"`
type GuessGameStart struct {
Topic string `json:"topic,omitempty"`
Options string `json:"options,omitempty"`
Category string `json:"category,omitempty"`
MaxTime string `json:"maxTime,omitempty"`
MaxHeight int64 `json:"maxHeight,omitempty"`
Symbol string `json:"symbol,omitempty"`
Exec string `json:"exec,omitempty"`
OneBet uint32 `json:"oneBet,omitempty"`
MaxBets uint32 `json:"maxBets,omitempty"`
MaxBetsNumber uint32 `json:"maxBetsNumber,omitempty"`
DevFeeFactor int64 `json:"devFeeFactor,omitempty"`
DevFeeAddr string `json:"devFeeAddr,omitempty"`
PlatFeeFactor int64 `json:"platFeeFactor,omitempty"`
PlatFeeAddr string `json:"platFeeAddr,omitempty"`
Expire string `json:"expire,omitempty"`
ExpireHeight int64 `json:"expireHeight,omitempty"`
Fee int64 `json:"fee,omitempty"`
}
type PBContinueTxReq struct {
GameId string `json:"gameId"`
Fee int64 `json:"fee"`
type GuessGameBet struct {
GameId string `json:"gameId,omitempty"`
Option string `json:"option,omitempty"`
BetsNum uint32 `json:"betsNum,omitempty"`
Fee int64 `json:"fee,omitempty"`
}
type PBQuitTxReq struct {
GameId string `json:"gameId"`
Fee int64 `json:"fee"`
type GuessGameStopBet struct {
GameId string `json:"gameId,omitempty"`
Fee int64 `json:"fee,omitempty"`
}
type PBQueryReq struct {
GameId string `json:"GameId"`
Fee int64 `json:"fee"`
type GuessGamePublish struct {
GameId string `json:"gameId,omitempty"`
Result string `json:"result,omitempty"`
Fee int64 `json:"fee,omitempty"`
}
type GuessGameAbort struct {
GameId string `json:"gameId,omitempty"`
Fee int64 `json:"fee,omitempty"`
}
......@@ -13,6 +13,7 @@ const (
GuessGameActionStart = iota + 1
GuessGameActionBet
GuessGameActionStopBet
GuessGameActionAbort
GuessGameActionPublish
GuessGameActionQuery
......@@ -52,3 +53,8 @@ const (
//FuncName_QueryGameByAdminAddr = "QueryGameByAdminAddr"
//FuncName_QueryGameByCategory = "QueryGameByCategory"
)
const (
DevShareAddr = "1D6RFZNp2rh6QdbcZ1d7RWuBUz61We6SD7"
PlatformShareAddr = "1PHtChNt3UcfssR7v7trKSk3WJtAWjKjjX"
)
\ No newline at end of file
This diff is collapsed.
......@@ -43,6 +43,7 @@ func (t *GuessType) GetTypeMap() map[string]int32 {
return map[string]int32{
"Start": GuessGameActionStart,
"Bet": GuessGameActionBet,
"StopBet":GuessGameActionStopBet,
"Abort": GuessGameActionAbort,
"Publish": GuessGameActionPublish,
"Query": GuessGameActionQuery,
......@@ -153,6 +154,32 @@ func CreateRawGuessBetTx(parm *GuessGameBet) (*types.Transaction, error) {
return tx, nil
}
// CreateRawGuessStopBetTx method
func CreateRawGuessBetTx(parm *GuessGameStopBet) (*types.Transaction, error) {
if parm == nil {
llog.Error("CreateRawGuessBet", "parm", parm)
return nil, types.ErrInvalidParam
}
val := &GuessGameAction{
Ty: GuessGameActionStopBet,
Value: &GuessGameAction_StopBet{StopBet: parm},
}
name := types.ExecName(GuessX)
tx := &types.Transaction{
Execer: []byte(types.ExecName(GuessX)),
Payload: types.Encode(val),
Fee: parm.Fee,
To: address.ExecAddress(name),
}
tx, err := types.FormatTx(name, tx)
if err != nil {
return nil, err
}
return tx, nil
}
// CreateRawGuessPublishTx method
func CreateRawGuessPublishTx(parm *GuessGamePublish) (*types.Transaction, error) {
if parm == nil {
......
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