You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
2.5 KiB
118 lines
2.5 KiB
package chain
|
|
|
|
import (
|
|
"fmt"
|
|
"math/big"
|
|
|
|
"github.com/ethereum/go-ethereum/accounts/abi"
|
|
"github.com/ethereum/go-ethereum/common"
|
|
"github.com/ethereum/go-ethereum/core/types"
|
|
)
|
|
|
|
type ParsedEvent struct {
|
|
Name string
|
|
Data map[string]interface{}
|
|
TxHash common.Hash
|
|
BlockNumber uint64
|
|
}
|
|
|
|
func ParseEventsFromLogs(logs []*types.Log, contractABI abi.ABI) ([]*ParsedEvent, error) {
|
|
var events []*ParsedEvent
|
|
|
|
for _, log := range logs {
|
|
if len(log.Topics) == 0 {
|
|
continue
|
|
}
|
|
|
|
event, err := parseEvent(log, contractABI)
|
|
if err == nil && event != nil {
|
|
events = append(events, event)
|
|
}
|
|
}
|
|
|
|
return events, nil
|
|
}
|
|
|
|
func parseEvent(log *types.Log, contractABI abi.ABI) (*ParsedEvent, error) {
|
|
for name, event := range contractABI.Events {
|
|
if event.ID != log.Topics[0] {
|
|
continue
|
|
}
|
|
|
|
data := make(map[string]interface{})
|
|
|
|
indexedIdx := 1
|
|
for _, arg := range event.Inputs {
|
|
if arg.Indexed {
|
|
if indexedIdx < len(log.Topics) {
|
|
if arg.Type.T == abi.AddressTy {
|
|
data[arg.Name] = common.BytesToAddress(log.Topics[indexedIdx].Bytes())
|
|
} else if arg.Type.T == abi.UintTy || arg.Type.T == abi.IntTy {
|
|
data[arg.Name] = new(big.Int).SetBytes(log.Topics[indexedIdx].Bytes())
|
|
} else {
|
|
data[arg.Name] = log.Topics[indexedIdx].Hex()
|
|
}
|
|
indexedIdx++
|
|
}
|
|
}
|
|
}
|
|
|
|
if len(log.Data) > 0 {
|
|
unpacked, err := event.Inputs.Unpack(log.Data)
|
|
if err == nil {
|
|
nonIndexedIdx := 0
|
|
for _, arg := range event.Inputs {
|
|
if !arg.Indexed {
|
|
if nonIndexedIdx < len(unpacked) {
|
|
data[arg.Name] = unpacked[nonIndexedIdx]
|
|
nonIndexedIdx++
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return &ParsedEvent{
|
|
Name: name,
|
|
Data: data,
|
|
TxHash: log.TxHash,
|
|
BlockNumber: log.BlockNumber,
|
|
}, nil
|
|
}
|
|
|
|
return nil, fmt.Errorf("unknown event: %s", log.Topics[0].Hex())
|
|
}
|
|
|
|
func GetPacketIDFromEvent(event *ParsedEvent) *big.Int {
|
|
if id, ok := event.Data["packetId"]; ok {
|
|
if b, ok := id.(*big.Int); ok {
|
|
return b
|
|
}
|
|
}
|
|
return big.NewInt(0)
|
|
}
|
|
|
|
func GetAddressFromEvent(event *ParsedEvent, key string) common.Address {
|
|
value, ok := event.Data[key]
|
|
if !ok {
|
|
return common.Address{}
|
|
}
|
|
addr, _ := value.(common.Address)
|
|
return addr
|
|
}
|
|
|
|
func GetAmountFromEvent(event *ParsedEvent) *big.Int {
|
|
return GetUintFromEvent(event, "amount")
|
|
}
|
|
|
|
func GetUintFromEvent(event *ParsedEvent, key string) *big.Int {
|
|
value, ok := event.Data[key]
|
|
if !ok {
|
|
return big.NewInt(0)
|
|
}
|
|
if b, ok := value.(*big.Int); ok {
|
|
return b
|
|
}
|
|
return big.NewInt(0)
|
|
}
|