96 lines
2.1 KiB
Go
96 lines
2.1 KiB
Go
|
package oracleexample
|
||
|
|
||
|
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
|
||
|
gear []int
|
||
|
}
|
||
|
|
||
|
func player(playerID string) Player {
|
||
|
ctx := storage.GetContext()
|
||
|
data := storage.Get(ctx, playerID)
|
||
|
if data == nil {
|
||
|
panic("player is not exists")
|
||
|
}
|
||
|
|
||
|
return std.Deserialize(data.([]byte)).(Player)
|
||
|
}
|
||
|
|
||
|
func _deploy(data interface{}, isUpdate bool) {
|
||
|
if isUpdate {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
callie := Player{
|
||
|
balance: 3000,
|
||
|
gear: []int{},
|
||
|
}
|
||
|
|
||
|
ctx := storage.GetContext()
|
||
|
storage.Put(ctx, "Callie", std.Serialize(callie))
|
||
|
|
||
|
requestURI := "https://git.frostfs.info/alexvanin/oracle-test/raw/branch/master/data.json"
|
||
|
storage.Put(ctx, "db", requestURI)
|
||
|
}
|
||
|
|
||
|
func Balance(playerID string) int {
|
||
|
p := player(playerID)
|
||
|
return p.balance
|
||
|
}
|
||
|
|
||
|
func Items(playerID string) []int {
|
||
|
p := player(playerID)
|
||
|
return p.gear
|
||
|
}
|
||
|
|
||
|
func BuyItem(playerID string, itemID int) {
|
||
|
p := player(playerID)
|
||
|
for i := range p.gear {
|
||
|
if itemID == p.gear[i] {
|
||
|
panic("item already purchased")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ctx := storage.GetContext()
|
||
|
uri := storage.Get(ctx, "db").(string)
|
||
|
|
||
|
filter := []byte("$.store.item[" + std.Itoa10(itemID) + "]")
|
||
|
|
||
|
oracle.Request(uri, filter, "cbBuyItem", playerID, 2*oracle.MinimumResponseGas)
|
||
|
}
|
||
|
|
||
|
func CbBuyItem(url string, userdata any, code int, res []byte) {
|
||
|
callingHash := runtime.GetCallingScriptHash()
|
||
|
if !callingHash.Equals(oracle.Hash) {
|
||
|
panic("not called from oracle contract")
|
||
|
}
|
||
|
if code != oracle.Success {
|
||
|
panic("request failed for " + url + " with code " + std.Itoa(code, 10))
|
||
|
}
|
||
|
runtime.Log("result for " + url + ": " + string(res))
|
||
|
|
||
|
ln := len(res)
|
||
|
data := std.JSONDeserialize(res[1 : ln-1]).(map[string]any)
|
||
|
|
||
|
playerID := userdata.(string)
|
||
|
p := player(playerID)
|
||
|
|
||
|
price := data["price"].(int)
|
||
|
|
||
|
if p.balance < price {
|
||
|
panic("not enough")
|
||
|
}
|
||
|
|
||
|
p.balance -= price
|
||
|
p.gear = append(p.gear, data["id"].(int))
|
||
|
|
||
|
ctx := storage.GetContext()
|
||
|
storage.Put(ctx, playerID, std.Serialize(p))
|
||
|
}
|