wallet/pkg/eth/eth_transaction.go
Anton Nesterov 5efcf35dd6
[init]
2024-08-31 16:59:34 +02:00

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
}