108 lines
2.7 KiB
Go
108 lines
2.7 KiB
Go
|
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
|
||
|
}
|