package player import ( "github.com/nspcc-dev/neo-go/pkg/interop/native/oracle" "github.com/nspcc-dev/neo-go/pkg/interop/native/std" "github.com/nspcc-dev/neo-go/pkg/interop/runtime" "github.com/nspcc-dev/neo-go/pkg/interop/storage" ) type Player struct { balance int items []int } const storeURLKey = "storeURL" func _deploy(data interface{}, isUpdate bool) { if isUpdate { return } // TODO: change url to point to the new repository after we merge PR ctx := storage.GetContext() storeURL := "https://git.frostfs.info/vdomnich-yadro/oracle-demo/raw/branch/master/data.json" storage.Put(ctx, storeURLKey, storeURL) } func NewPlayer(playerName string) { ctx := storage.GetContext() existingPlayer := storage.Get(ctx, playerName) if existingPlayer != nil { panic("player already exists") } items := make([]int, 0) // NOTE: the commented code below requires `lottery/lottery_contract.go` to be deployed on the chain // If you would like to uncomment it, please: // 1. Deploy `lottery/lottery_contract.go` contract to your chain // 2. Replace hash inisde `address.ToHash160` with the hash of deployed contract // 3. Add imports to this file: // "github.com/nspcc-dev/neo-go/pkg/interop/contract" // "github.com/nspcc-dev/neo-go/pkg/interop/lib/address" // 4. Now you're ready to uncomment the code and run player contract in integration with lottery. // // lotteryHash := address.ToHash160("NVBGxUL69FJEV9nhrZQQhPbhkzzvsJqF8q") // isWinner := contract.Call(lotteryHash, "isWinner", contract.ReadOnly, playerName).(bool) // if isWinner { // items = append(items, 0) // } player := Player{ balance: 3000, items: items, } storage.Put(ctx, playerName, std.Serialize(player)) } func getPlayer(playerName string) Player { ctx := storage.GetReadOnlyContext() data := storage.Get(ctx, playerName) if data == nil { panic("player not found") } return std.Deserialize(data.([]byte)).(Player) } func Balance(playerName string) int { p := getPlayer(playerName) return p.balance } func Items(playerName string) []int { p := getPlayer(playerName) return p.items } func BuyItem(playerName string, itemID int) { player := getPlayer(playerName) for i := range player.items { if itemID == player.items[i] { panic("item has already been purchased") } } ctx := storage.GetContext() storeURL := storage.Get(ctx, storeURLKey).(string) filter := []byte("$.store.item[" + std.Itoa10(itemID) + "]") oracle.Request(storeURL, filter, "cbBuyItem", playerName, 2*oracle.MinimumResponseGas) } func CbBuyItem(url string, userData any, code int, result []byte) { callingHash := runtime.GetCallingScriptHash() if !callingHash.Equals(oracle.Hash) { panic("not called from the oracle contract") } if code != oracle.Success { panic("request failed for " + url + " with code " + std.Itoa(code, 10)) } runtime.Log("result for " + url + " is: " + string(result)) // Remove quotes that surround resulting JSON resultLen := len(result) data := std.JSONDeserialize(result[1 : resultLen-1]).(map[string]any) price := data["price"].(int) gearID := data["id"].(int) playerName := userData.(string) player := getPlayer(playerName) if player.balance < price { panic("insufficient balance") } player.balance -= price player.items = append(player.items, gearID) ctx := storage.GetContext() storage.Put(ctx, playerName, std.Serialize(player)) }