139 lines
3.2 KiB
Go
139 lines
3.2 KiB
Go
package eth
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"math/big"
|
|
"strings"
|
|
|
|
"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"
|
|
)
|
|
|
|
func (e *EthAccount) SignTx(tx *types.Transaction) (*types.Transaction, error) {
|
|
client, err := ethclient.Dial(ethNode.rpcNode)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
chainID, err := client.NetworkID(context.Background())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(chainID), e.PrivateKey())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return signedTx, nil
|
|
}
|
|
|
|
func GetTransactionByHash(hash string) (*types.Receipt, error) {
|
|
fmt.Println("GetTransactionByHash", hash)
|
|
client, err := ethclient.Dial(ethNode.rpcNode)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
_byte, err := common.ParseHexOrString(hash)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
_hash := common.BytesToHash(_byte)
|
|
tx, err := client.TransactionReceipt(context.Background(), _hash)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return tx, nil
|
|
}
|
|
|
|
func GetTransactionReceipt(txHash common.Hash) *types.Receipt {
|
|
client, err := ethclient.Dial(ethNode.rpcNode)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
receipt, err := client.TransactionReceipt(context.Background(), txHash)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
return receipt
|
|
}
|
|
|
|
type ERC20TransferEvent struct {
|
|
From string
|
|
To string
|
|
Value string
|
|
}
|
|
|
|
func decodeTransactionLogs(receipt *types.Receipt, contractABI *abi.ABI) ERC20TransferEvent {
|
|
|
|
for _, vLog := range receipt.Logs {
|
|
// topic[0] is the event name
|
|
event, err := contractABI.EventByID(vLog.Topics[0])
|
|
if err != nil {
|
|
return ERC20TransferEvent{}
|
|
}
|
|
|
|
events := map[string]bool{
|
|
"Transfer": true,
|
|
"TransferFrom": true,
|
|
}
|
|
|
|
if !events[event.Name] {
|
|
continue
|
|
}
|
|
// topic[1:] is other indexed params in event
|
|
ev := ERC20TransferEvent{}
|
|
if len(vLog.Topics) > 1 {
|
|
ev.From = common.HexToAddress(vLog.Topics[1].Hex()).String()
|
|
ev.To = common.HexToAddress(vLog.Topics[2].Hex()).String()
|
|
}
|
|
|
|
if len(vLog.Data) > 0 {
|
|
//fmt.Printf("Log Data in Hex: %s\n", hex.EncodeToString(vLog.Data))
|
|
outputDataMap := make(map[string]interface{})
|
|
err = contractABI.UnpackIntoMap(outputDataMap, event.Name, vLog.Data)
|
|
if err == nil {
|
|
ev.Value = outputDataMap["_value"].(*big.Int).String()
|
|
}
|
|
}
|
|
//fmt.Println(">>>>>", ev)
|
|
return ev
|
|
}
|
|
return ERC20TransferEvent{}
|
|
}
|
|
|
|
func GetErc20Tranfer(txHash common.Hash) ERC20TransferEvent {
|
|
abi, err := abi.JSON(strings.NewReader(COMMON_ABI))
|
|
receipt := GetTransactionReceipt(txHash)
|
|
if receipt == nil || len(receipt.Logs) == 0 || err != nil {
|
|
return ERC20TransferEvent{}
|
|
}
|
|
return decodeTransactionLogs(receipt, &abi)
|
|
}
|
|
|
|
type TransactionData = map[string]interface{}
|
|
|
|
func DecodeERC20Transfer(data []byte) (tx TransactionData, err error) {
|
|
abi, err := abi.JSON(strings.NewReader(COMMON_ABI))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
tx = make(TransactionData)
|
|
if len(data) < 4 {
|
|
return nil, nil
|
|
}
|
|
methodSigData := data[:4]
|
|
method, err := abi.MethodById(methodSigData)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
inputsSigData := data[4:]
|
|
if err := method.Inputs.UnpackIntoMap(tx, inputsSigData); err != nil {
|
|
return nil, err
|
|
}
|
|
return tx, nil
|
|
}
|