//go:build !exclude_crypto_ecdsa package main import ( "github.com/nspcc-dev/neo-go/pkg/interop" "github.com/nspcc-dev/neo-go/pkg/interop/native/gas" "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 Wallet struct { Tokens map[string]int } func (w Wallet) getTokenBalance(token string) int { value := getValueFromStringIntMap(w.Tokens, token) if value == nil { return 0 } return value.(int) } var prices map[string]int // Prices are multiplied by 1e14 and rounded to be represented as fixed point int func init() {   prices = map[string]int{     "XMR":  152100000,     "XRP":  603500,     "ADA":  579300,     "AVAX": 39690000,     "BNB":  308300000,     "BTC":  46648920000,     "ETH":  2623000000,     "SOL":  101180000,   } } func TopUp(address interop.Hash160, token string, amount int) bool { if !isKnownToken(token) { runtime.Log("Token " + token + " is unkown") return false } wallet := getWallet(address) balance := wallet.getTokenBalance(token) wallet.Tokens[token] = balance + amount saveWallet(address, wallet) return true } func GetTokenBalance(address interop.Hash160, token string) int { return getWallet(address).getTokenBalance(token) } func Exchange(address interop.Hash160, amount int, fromToken string, toToken string) bool { if amount <= 0 { runtime.Log("Invalid amount") return false } wallet := getWallet(address) fromBalance := wallet.getTokenBalance(fromToken) if fromBalance < amount { runtime.Log("Not enough funds to exchange") return false } fromTokenPrice := getPrice(fromToken) toTokenPrice := getPrice(toToken) convertedAmount := amount * fromTokenPrice / toTokenPrice wallet.Tokens[fromToken] -= amount wallet.Tokens[toToken] = wallet.getTokenBalance(toToken) + convertedAmount saveWallet(address, wallet) runtime.Log("Exchange successful: " + std.Itoa10(amount) + " " + fromToken + " exchanged for " + std.Itoa10(convertedAmount) + " " + toToken) return true } func PrintWallet(address interop.Hash160) { wallet := getWallet(address) runtime.Log("Wallet " + ":") for key, value := range wallet.Tokens { runtime.Log(key + ":" + std.Itoa10(value)) } } func getWallet(address interop.Hash160) Wallet { ctx := storage.GetContext() walletBytes := storage.Get(ctx, address) if walletBytes == nil { return Wallet{ Tokens: make(map[string]int), } } walletBytesAsBytes := walletBytes.([]byte) deserialized := std.Deserialize(walletBytesAsBytes) if deserialized == nil { return Wallet{} } return deserialized.(Wallet) } func saveWallet(address interop.Hash160, wallet Wallet) { ctx := storage.GetContext() serialized := std.Serialize(wallet) storage.Put(ctx, address, serialized) } func getPrice(token string) int { if !isKnownToken(token) { panic("trying to get price for unknown token") } return prices[token] } func getValueFromStringIntMap(mp map[string]int, key string) any { defer func() { recover() }() return mp[key] } func isKnownToken(token string) bool { return getValueFromStringIntMap(prices, token) != nil }