package eth import ( "context" "math" "math/big" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/rpc" ) type EthAccountBalance struct { Address string `json:"address"` USDT string `json:"usdt"` ETH string `json:"eth"` USDTRaw int64 `json:"usdtRaw"` ETHRaw int64 `json:"ethRaw"` TxFee string `json:"txFee"` } type request struct { To string `json:"to"` Data string `json:"data"` } func EthBalance(address string) (*EthAccountBalance, error) { client, err := ethclient.Dial(ethNode.rpcNode) if err != nil { return nil, err } account := common.HexToAddress(address) balance, err := client.BalanceAt(context.Background(), account, nil) if err != nil { return nil, err } fbalance := new(big.Float) fbalance.SetString(balance.String()) ethValue := new(big.Float).Quo(fbalance, big.NewFloat(math.Pow10(18))) rpcClient, err := rpc.DialHTTP(ethNode.rpcNode) if err != nil { return nil, err } data := crypto.Keccak256Hash([]byte("balanceOf(address)")).String()[0:10] + "000000000000000000000000" + address[2:] msg := request{ethNode.usdtContractAddress, data} var res string err = rpcClient.Call(&res, "eth_call", msg, "latest") if err != nil { return nil, err } addr := common.HexToAddress(ethNode.usdtContractAddress) estimation, _ := client.EstimateGas(context.Background(), ethereum.CallMsg{ To: &addr, Data: []byte(data + address[2:]), }) txFeeValue := new(big.Float).Quo(big.NewFloat(float64(estimation)*1.5), big.NewFloat(math.Pow10(8))) usdtRaw := new(big.Int) if len(res) > 2 { usdtRaw.SetString(string(res[2:]), 16) } usdtValue := new(big.Float).Quo(big.NewFloat(float64(usdtRaw.Int64())), big.NewFloat(math.Pow10(ethNode.usdtContractDecimals))) var accountBalance EthAccountBalance = EthAccountBalance{ Address: address, USDT: usdtValue.String(), ETH: ethValue.String(), USDTRaw: usdtRaw.Int64(), ETHRaw: balance.Int64(), TxFee: txFeeValue.String(), } return &accountBalance, nil } func EthAllowance(address string, spender string) (int64, error) { rpcClient, err := rpc.DialHTTP(ethNode.rpcNode) if err != nil { return 0, err } data := crypto.Keccak256Hash([]byte("allowance(address,address)")).String()[0:10] + "000000000000000000000000" + address[2:] + "000000000000000000000000" + spender[2:] msg := request{ethNode.usdtContractAddress, data} var res string err = rpcClient.Call(&res, "eth_call", msg, "latest") if err != nil { return 0, err } usdtRaw := new(big.Int) if len(res) > 2 { usdtRaw.SetString(string(res[2:]), 16) } return usdtRaw.Int64(), nil }