| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- package service
- import (
- "context"
- "encoding/hex"
- "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/accounts/abi"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethclient"
- "math/big"
- "time"
- )
- var (
- ethUsdt = common.HexToAddress("0xdAC17F958D2ee523a2206206994597C13D831ec7")
- ethUsdc = common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48")
- )
- var (
- transferId, _ = hex.DecodeString("a9059cbb")
- )
- var (
- addressTy, _ = abi.NewType("address", "", nil)
- uint256Ty, _ = abi.NewType("uint256", "", nil)
- arguments = abi.Arguments{{Type: addressTy}, {Type: uint256Ty}}
- )
- func buildTransferEth(ethClient *ethclient.Client, from, to string, amount *big.Int) (*types.Transaction, error) {
- fromAddr := common.HexToAddress(from)
- toAddr := common.HexToAddress(to)
- return createTransaction(ethClient, &fromAddr, &toAddr, amount, nil)
- }
- func buildTransferUsdtOfEth(ethClient *ethclient.Client, from, to string, amount *big.Int) (*types.Transaction, error) {
- fromAddr := common.HexToAddress(from)
- toAddr := common.HexToAddress(to)
- data, err := arguments.Pack(toAddr, amount)
- if err != nil {
- return nil, err
- }
- return createTransaction(ethClient, &fromAddr, ðUsdt, big.NewInt(0), append(transferId, data...))
- }
- func buildTransferUsdcOfEth(ethClient *ethclient.Client, from, to string, amount *big.Int) (*types.Transaction, error) {
- fromAddr := common.HexToAddress(from)
- toAddr := common.HexToAddress(to)
- data, err := arguments.Pack(toAddr, amount)
- if err != nil {
- return nil, err
- }
- return createTransaction(ethClient, &fromAddr, ðUsdc, big.NewInt(0), append(transferId, data...))
- }
- func createTransaction(ethClient *ethclient.Client, from, to *common.Address, amount *big.Int, data []byte) (*types.Transaction, error) {
- tx := &types.DynamicFeeTx{
- ChainID: big.NewInt(1),
- To: to,
- Value: amount,
- Data: data,
- }
- err := estimateGas(ethClient, from, tx)
- if err != nil {
- return nil, err
- }
- return types.NewTx(tx), nil
- }
- func estimateGas(ethClient *ethclient.Client, from *common.Address, tx *types.DynamicFeeTx) error {
- ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
- defer cancel()
- head, err := ethClient.HeaderByNumber(ctx, nil)
- if err != nil {
- return err
- }
- gasTipCap, err := ethClient.SuggestGasTipCap(ctx)
- if err != nil {
- return err
- }
- gasFeeCap := new(big.Int).Add(
- gasTipCap,
- new(big.Int).Mul(head.BaseFee, big.NewInt(2)),
- )
- msg := ethereum.CallMsg{
- From: *from,
- To: tx.To,
- GasPrice: nil,
- GasTipCap: gasTipCap,
- GasFeeCap: gasFeeCap,
- Value: tx.Value,
- Data: tx.Data,
- }
- gasLimit, err := ethClient.EstimateGas(ctx, msg)
- if err != nil {
- return err
- }
- nonce, err := ethClient.PendingNonceAt(ctx, *from)
- if err != nil {
- return err
- }
- tx.Nonce = nonce
- tx.Gas = gasLimit
- tx.GasFeeCap = gasFeeCap
- tx.GasTipCap = gasTipCap
- return nil
- }
|