eth.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. package service
  2. import (
  3. "context"
  4. "encoding/hex"
  5. "github.com/ethereum/go-ethereum"
  6. "github.com/ethereum/go-ethereum/accounts/abi"
  7. "github.com/ethereum/go-ethereum/common"
  8. "github.com/ethereum/go-ethereum/core/types"
  9. "github.com/ethereum/go-ethereum/ethclient"
  10. "math/big"
  11. "time"
  12. )
  13. var (
  14. ethUsdt = common.HexToAddress("0xdAC17F958D2ee523a2206206994597C13D831ec7")
  15. ethUsdc = common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48")
  16. )
  17. var (
  18. transferId, _ = hex.DecodeString("a9059cbb")
  19. )
  20. var (
  21. addressTy, _ = abi.NewType("address", "", nil)
  22. uint256Ty, _ = abi.NewType("uint256", "", nil)
  23. arguments = abi.Arguments{{Type: addressTy}, {Type: uint256Ty}}
  24. )
  25. func buildTransferEth(ethClient *ethclient.Client, from, to string, amount *big.Int) (*types.Transaction, error) {
  26. fromAddr := common.HexToAddress(from)
  27. toAddr := common.HexToAddress(to)
  28. return createTransaction(ethClient, &fromAddr, &toAddr, amount, nil)
  29. }
  30. func buildTransferUsdtOfEth(ethClient *ethclient.Client, from, to string, amount *big.Int) (*types.Transaction, error) {
  31. fromAddr := common.HexToAddress(from)
  32. toAddr := common.HexToAddress(to)
  33. data, err := arguments.Pack(toAddr, amount)
  34. if err != nil {
  35. return nil, err
  36. }
  37. return createTransaction(ethClient, &fromAddr, &ethUsdt, big.NewInt(0), append(transferId, data...))
  38. }
  39. func buildTransferUsdcOfEth(ethClient *ethclient.Client, from, to string, amount *big.Int) (*types.Transaction, error) {
  40. fromAddr := common.HexToAddress(from)
  41. toAddr := common.HexToAddress(to)
  42. data, err := arguments.Pack(toAddr, amount)
  43. if err != nil {
  44. return nil, err
  45. }
  46. return createTransaction(ethClient, &fromAddr, &ethUsdc, big.NewInt(0), append(transferId, data...))
  47. }
  48. func createTransaction(ethClient *ethclient.Client, from, to *common.Address, amount *big.Int, data []byte) (*types.Transaction, error) {
  49. tx := &types.DynamicFeeTx{
  50. ChainID: big.NewInt(1),
  51. To: to,
  52. Value: amount,
  53. Data: data,
  54. }
  55. err := estimateGas(ethClient, from, tx)
  56. if err != nil {
  57. return nil, err
  58. }
  59. return types.NewTx(tx), nil
  60. }
  61. func estimateGas(ethClient *ethclient.Client, from *common.Address, tx *types.DynamicFeeTx) error {
  62. ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
  63. defer cancel()
  64. head, err := ethClient.HeaderByNumber(ctx, nil)
  65. if err != nil {
  66. return err
  67. }
  68. gasTipCap, err := ethClient.SuggestGasTipCap(ctx)
  69. if err != nil {
  70. return err
  71. }
  72. gasFeeCap := new(big.Int).Add(
  73. gasTipCap,
  74. new(big.Int).Mul(head.BaseFee, big.NewInt(2)),
  75. )
  76. msg := ethereum.CallMsg{
  77. From: *from,
  78. To: tx.To,
  79. GasPrice: nil,
  80. GasTipCap: gasTipCap,
  81. GasFeeCap: gasFeeCap,
  82. Value: tx.Value,
  83. Data: tx.Data,
  84. }
  85. gasLimit, err := ethClient.EstimateGas(ctx, msg)
  86. if err != nil {
  87. return err
  88. }
  89. nonce, err := ethClient.PendingNonceAt(ctx, *from)
  90. if err != nil {
  91. return err
  92. }
  93. tx.Nonce = nonce
  94. tx.Gas = gasLimit
  95. tx.GasFeeCap = gasFeeCap
  96. tx.GasTipCap = gasTipCap
  97. return nil
  98. }