-
Notifications
You must be signed in to change notification settings - Fork 12
/
fip20.go
114 lines (98 loc) · 2.7 KB
/
fip20.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package types
import (
"math/big"
"strings"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
)
const (
FIP20EventTransferCrossChain = "TransferCrossChain"
)
const (
FIP20TransferToChainPrefix = "chain/"
FIP20TransferToIBCPrefix = "ibc/"
)
const (
FIP20TargetUnknown Fip20TargetType = iota
FIP20TargetChain
FIP20TargetIBC
)
type Fip20TargetType int
func (tt Fip20TargetType) String() string {
switch tt {
case FIP20TargetChain:
return "chain"
case FIP20TargetIBC:
return "ibc"
default:
return "unknown"
}
}
type TransferCrossChainEvent struct {
From common.Address
Recipient string
Amount *big.Int
Fee *big.Int
Target [32]byte
}
func ParseTransferCrossChainEvent(fip20ABI abi.ABI, log *ethtypes.Log) (*TransferCrossChainEvent, bool, error) {
if len(log.Topics) != 2 {
return nil, false, nil
}
tc := new(TransferCrossChainEvent)
if log.Topics[0] != fip20ABI.Events[FIP20EventTransferCrossChain].ID {
return nil, false, nil
}
if len(log.Data) > 0 {
if err := fip20ABI.UnpackIntoInterface(tc, FIP20EventTransferCrossChain, log.Data); err != nil {
return nil, false, err
}
}
var indexed abi.Arguments
for _, arg := range fip20ABI.Events[FIP20EventTransferCrossChain].Inputs {
if arg.Indexed {
indexed = append(indexed, arg)
}
}
if err := abi.ParseTopics(tc, indexed, log.Topics[1:]); err != nil {
return nil, false, err
}
return tc, true, nil
}
func (event *TransferCrossChainEvent) GetFrom() sdk.AccAddress {
return event.From.Bytes()
}
func (event *TransferCrossChainEvent) GetAmount(denom string) sdk.Coin {
return sdk.NewCoin(denom, sdk.NewIntFromBigInt(event.Amount))
}
func (event *TransferCrossChainEvent) GetFee(denom string) sdk.Coin {
return sdk.NewCoin(denom, sdk.NewIntFromBigInt(event.Fee))
}
func (event *TransferCrossChainEvent) GetTarget() (Fip20TargetType, string) {
target := Byte32ToString(event.Target)
if strings.HasPrefix(target, FIP20TransferToChainPrefix) {
return FIP20TargetChain, strings.TrimPrefix(target, FIP20TransferToChainPrefix)
}
if strings.HasPrefix(target, FIP20TransferToIBCPrefix) {
return FIP20TargetIBC, strings.TrimPrefix(target, FIP20TransferToIBCPrefix)
}
return FIP20TargetUnknown, target
}
func (event *TransferCrossChainEvent) TotalAmount(denom string) sdk.Coins {
return sdk.NewCoins(event.GetAmount(denom)).Add(event.GetFee(denom))
}
func StringToByte32(str string) [32]byte {
var bz [32]byte
copy(bz[:], str)
return bz
}
func Byte32ToString(bytes [32]byte) string {
for i := len(bytes) - 1; i >= 0; i-- {
if bytes[i] != 0 {
return string(bytes[:i+1])
}
}
return ""
}