package smart_contract_exchange import ( "encoding/json" "fmt" "github.com/go-resty/resty/v2" "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/runtime" "github.com/nspcc-dev/neo-go/pkg/interop/storage" "strconv" ) type Wallet struct { Tokens map[string]int } type TickerPrice struct { Symbol string `json:"symbol"` Price string `json:"price"` } func GetWallet(address interop.Hash160) Wallet { ctx := storage.GetContext() walletBytes := storage.Get(ctx, address) if walletBytes == nil { return Wallet{ Tokens: make(map[string]int), } } var wallet Wallet walletBytesAsBytes, _ := walletBytes.([]byte) err := json.Unmarshal(walletBytesAsBytes, &wallet) if err != nil { return Wallet{} } return wallet } func UpdateWallet(address interop.Hash160, wallet Wallet) { ctx := storage.GetContext() serialized, _ := json.Marshal(wallet) storage.Put(ctx, address, serialized) } func GetBalance(address interop.Hash160, token string) int { wallet := GetWallet(address) return wallet.Tokens[token] } func RequestExchangeRate(fromToken string, toToken string) float64 { originalString := "https://api.binance.com/api/v3/ticker/price?symbol=%sUSDT" urlFrom := fmt.Sprintf(originalString, fromToken) urlTo := fmt.Sprintf(originalString, toToken) client := resty.New() responseFrom, errFrom := client.R().Get(urlFrom) responseTo, errTo := client.R().Get(urlTo) if errFrom != nil || errTo != nil { fmt.Println("Error during doing response") return 0 } var tickerPriceFrom TickerPrice var tickerPriceTo TickerPrice errFrom = json.Unmarshal(responseFrom.Body(), &tickerPriceFrom) errTo = json.Unmarshal(responseTo.Body(), &tickerPriceTo) if errFrom != nil || errTo != nil { fmt.Println("Error during unpacking JSON") return 0 } priceFrom, _ := strconv.ParseFloat(tickerPriceFrom.Price, 64) priceTo, _ := strconv.ParseFloat(tickerPriceTo.Price, 64) result := priceFrom / priceTo return result } func Transfer(address interop.Hash160, amount int, fromToken string, toToken string) bool { if amount <= 0 { runtime.Log("Invalid amount") return false } balance := gas.BalanceOf(address) if balance < amount { runtime.Log("Low gas balance for transaction") return false } contractHash := runtime.GetExecutingScriptHash() result := gas.Transfer(address, contractHash, amount, nil) if !result { runtime.Log("Transfer operation failed") return false } wallet := GetWallet(address) if GetBalance(address, fromToken) < amount { runtime.Log("Not enough funds to exchange") return false } exchangeRate := RequestExchangeRate(fromToken, toToken) if exchangeRate == 0 { return false } convertedAmount := float64(amount) * exchangeRate wallet.Tokens[fromToken] -= amount wallet.Tokens[toToken] += int(convertedAmount) UpdateWallet(address, wallet) runtime.Log("Exchange successful: " + strconv.Itoa(amount) + " " + fromToken + " exchanged for " + strconv.Itoa(int(convertedAmount)) + " " + toToken) return true } func printBalance(address interop.Hash160) bool { wallet := GetWallet(address) fmt.Println("Balance: ") for key, value := range wallet.Tokens { fmt.Println(key + ":" + strconv.Itoa(value)) } return true }