Search Apps Documentation Source Content File Folder Download Copy Actions Download

coinflip.gno

2.25 Kb ยท 112 lines
  1package coinflip
  2
  3import (
  4	"chain"
  5	"chain/banker"
  6	"chain/runtime"
  7	"math/rand"
  8
  9	"gno.land/p/demo/entropy"
 10	"gno.land/p/moul/fifo"
 11	"gno.land/r/sacha/config"
 12)
 13
 14const denom = "ugnot"
 15const minBetAmount = 1
 16
 17var (
 18	bets       = []Bet{}
 19	latestBets = fifo.New(8)
 20)
 21
 22func Heads(cur realm) {
 23	runtime.AssertOriginCall()
 24
 25	flipResult := flip(1)
 26	betLogic(flipResult)
 27}
 28
 29func Tails(cur realm) {
 30	runtime.AssertOriginCall()
 31
 32	flipResult := flip(0)
 33	betLogic(flipResult)
 34}
 35
 36func GetResults(cur realm) []Bet {
 37	return bets
 38}
 39
 40func GetRealmBalance(cur realm) int64 {
 41	banker_ := banker.NewBanker(banker.BankerTypeReadonly)
 42	coins := banker_.GetCoins(runtime.CurrentRealm().Address())
 43	balance := coins.AmountOf(denom)
 44
 45	return balance
 46}
 47
 48func Withdrawal(cur realm, amount int64) {
 49	if !config.IsAuthorized(runtime.PreviousRealm().Address()) {
 50		panic(config.ErrUnauthorized)
 51	}
 52
 53	runtime.AssertOriginCall()
 54
 55	banker_ := banker.NewBanker(banker.BankerTypeRealmSend)
 56
 57	if GetRealmBalance(cur) < amount {
 58		panic("insufficient balance")
 59	}
 60
 61	banker_.SendCoins(runtime.CurrentRealm().Address(), runtime.OriginCaller(), chain.NewCoins(chain.NewCoin(denom, amount)))
 62}
 63
 64func flip(choice int) bool {
 65	seed1 := uint64(entropy.New().Seed())
 66	seed2 := uint64(entropy.New().Seed())
 67
 68	r := rand.New(rand.NewPCG(seed1, seed2))
 69	result := r.IntN(2)
 70
 71	return result == choice
 72}
 73
 74func getBet() chain.Coin {
 75	bet := banker.OriginSend()
 76	if len(bet) != 1 || bet[0].Denom != denom {
 77		panic("bet is invalid")
 78	}
 79
 80	amount := bet[0].Amount
 81
 82	if amount < minBetAmount {
 83		panic("Bet too low")
 84	}
 85	if amount*2 > GetRealmBalance(cross) {
 86		panic("Bet too high")
 87	}
 88
 89	return bet[0]
 90}
 91
 92func sendPrize(cur realm, caller address, amount int64) {
 93	banker_ := banker.NewBanker(banker.BankerTypeRealmSend)
 94	wonCoins := chain.NewCoins(chain.NewCoin(denom, amount))
 95
 96	banker_.SendCoins(runtime.CurrentRealm().Address(), caller, wonCoins)
 97}
 98
 99func betLogic(flipResult bool) {
100	caller := runtime.OriginCaller()
101	bet := getBet()
102
103	if flipResult == true {
104		sendPrize(cross, caller, bet.Amount*2)
105		chain.Emit("BetResult", "Result", "win")
106	} else {
107		chain.Emit("BetResult", "Result", "lose")
108	}
109
110	bets = append(bets, Bet{Address: caller, Result: flipResult, Amount: bet})
111	latestBets.Append(Bet{Address: caller, Result: flipResult, Amount: bet})
112}