| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- package service
- import (
- "bytes"
- "encoding/hex"
- "errors"
- "fmt"
- "github.com/ethereum/go-ethereum/accounts/abi"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- tronaddr "github.com/fbsobreira/gotron-sdk/pkg/address"
- troncore "github.com/fbsobreira/gotron-sdk/pkg/proto/core"
- "google.golang.org/protobuf/reflect/protoreflect"
- "math/big"
- )
- const (
- ethUsdt = "0xdAC17F958D2ee523a2206206994597C13D831ec7"
- ethUsdc = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
- tronUsdt = "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t"
- tronUsdc = "TEkxiTehnzSmSe2XqrBj4w32RUN966rdz8"
- )
- var (
- transferId, _ = hex.DecodeString("a9059cbb")
- approveId, _ = hex.DecodeString("095ea7b3")
- )
- var (
- addressTy, _ = abi.NewType("address", "", nil)
- uint256Ty, _ = abi.NewType("uint256", "", nil)
- arguments = abi.Arguments{{Type: addressTy}, {Type: uint256Ty}}
- )
- func checkErc(tx *types.Transaction, whitelists map[string]struct{}) (string, string, string, error) {
- if tx.To().String() == ethUsdt || tx.To().String() == ethUsdc {
- input := tx.Data()
- var methodId [4]byte
- copy(methodId[:], input[:4])
- if !(bytes.Equal(methodId[:], transferId) || bytes.Equal(methodId[:], approveId)) {
- return "", "", "", errors.New("erc20: only sign transfer and approve")
- }
- unpack, err := arguments.Unpack(input[4:])
- if err != nil {
- return "", "", "", err
- }
- to, ok := unpack[0].(common.Address)
- if !ok {
- return "", "", "", errors.New("erc20: to parameter error")
- }
- amount, ok := unpack[1].(*big.Int)
- if !ok {
- return "", "", "", errors.New("erc20: amount parameter error")
- }
- if _, exist := whitelists[to.String()]; !exist {
- return "", "", "", errors.New("erc20: to is not a whitelist address")
- }
- coin := usdtCoin
- if tx.To().String() == ethUsdc {
- coin = usdcCoin
- }
- return coin, to.String(), amount.String(), nil
- } else {
- if _, exist := whitelists[tx.To().String()]; !exist {
- return "", "", "", errors.New("eth: to is not a whitelist address")
- }
- }
- return ethCoin, tx.To().String(), tx.Value().String(), nil
- }
- func checkTron(tx *troncore.Transaction, whitelists map[string]struct{}) (string, string, string, error) {
- if len(tx.GetRawData().Contract) != 1 {
- return "", "", "", errors.New("Transaction_Contract length must be 1")
- }
- contract := tx.GetRawData().Contract[0]
- var c interface{}
- switch contract.Type {
- case troncore.Transaction_Contract_TransferContract:
- c = &troncore.TransferContract{}
- case troncore.Transaction_Contract_TriggerSmartContract:
- c = &troncore.TriggerSmartContract{}
- default:
- return "", "", "", errors.New("Transaction_Contract Type must be Transaction_Contract_TransferContract and Transaction_Contract_TriggerSmartContract")
- }
- if err := contract.GetParameter().UnmarshalTo(c.(protoreflect.ProtoMessage)); err != nil {
- return "", "", "", fmt.Errorf("proto unmarshal any: %+w", err)
- }
- if contract.Type == troncore.Transaction_Contract_TransferContract {
- transferContract := c.(*troncore.TransferContract)
- to := tronaddr.Address(transferContract.ToAddress)
- if _, exist := whitelists[to.String()]; !exist {
- return "", "", "", errors.New("trx: to is not a whitelist address")
- }
- return trxCoin, to.String(), big.NewInt(0).SetInt64(transferContract.Amount).String(), nil
- } else {
- triggerSmartContract := c.(*troncore.TriggerSmartContract)
- contractAddr := tronaddr.Address(triggerSmartContract.ContractAddress)
- if contractAddr.String() != tronUsdt && contractAddr.String() != tronUsdc {
- return "", "", "", errors.New("trc20: only sign usdt and usdc")
- }
- input := triggerSmartContract.Data
- var methodId [4]byte
- copy(methodId[:], input[:4])
- if !(bytes.Equal(methodId[:], transferId) || bytes.Equal(methodId[:], approveId)) {
- return "", "", "", errors.New("trc20: only sign transfer and approve")
- }
- unpack, err := arguments.Unpack(input[4:])
- if err != nil {
- return "", "", "", err
- }
- to, ok := unpack[0].(common.Address)
- if !ok {
- return "", "", "", errors.New("trc20: to parameter error")
- }
- amount, ok := unpack[1].(*big.Int)
- if !ok {
- return "", "", "", errors.New("erc20: amount parameter error")
- }
- toTron := make([]byte, 0)
- toTron = append(toTron, tronaddr.TronBytePrefix)
- toTron = append(toTron, to.Bytes()...)
- if _, exist := whitelists[tronaddr.Address(toTron).String()]; !exist {
- return "", "", "", errors.New("trc20: to is not a whitelist address")
- }
- coin := usdtCoin
- if contractAddr.String() == tronUsdc {
- coin = usdcCoin
- }
- return coin, to.String(), amount.String(), nil
- }
- }
|