-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy patherc20.go
More file actions
128 lines (118 loc) · 3.25 KB
/
erc20.go
File metadata and controls
128 lines (118 loc) · 3.25 KB
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package beth
import (
"context"
"math/big"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
)
type erc20 struct {
account *account
cerc20 *CompatibleERC20
}
type ERC20 interface {
BalanceOf(ctx context.Context, who common.Address) (*big.Int, error)
Allowance(ctx context.Context, owner, spender common.Address) (*big.Int, error)
Transfer(ctx context.Context, to common.Address, amount, gasPrice *big.Int, sendAll bool) (*types.Transaction, error)
Approve(ctx context.Context, spender common.Address, amount, gasPrice *big.Int) (*types.Transaction, error)
TransferFrom(ctx context.Context, from, to common.Address, amount, gasPrice *big.Int) (*types.Transaction, error)
}
func (account *account) NewERC20(addressOrAlias string) (ERC20, error) {
address, ok := account.addressBook[addressOrAlias]
if !ok {
address = common.HexToAddress(addressOrAlias)
}
compatibleERC20, err := NewCompatibleERC20(address, bind.ContractBackend(account.EthClient()))
if err != nil {
return nil, err
}
return &erc20{
account: account,
cerc20: compatibleERC20,
}, nil
}
func (erc20 *erc20) BalanceOf(ctx context.Context, who common.Address) (*big.Int, error) {
client := erc20.account.Client()
var balance *big.Int
return balance, client.Get(ctx, func() error {
bal, err := erc20.cerc20.BalanceOf(&bind.CallOpts{}, who)
if err != nil {
return err
}
balance = bal
return nil
})
}
func (erc20 *erc20) Allowance(ctx context.Context, owner, spender common.Address) (*big.Int, error) {
client := erc20.account.Client()
var allowance *big.Int
return allowance, client.Get(ctx, func() error {
alw, err := erc20.cerc20.Allowance(&bind.CallOpts{}, owner, spender)
if err != nil {
return err
}
allowance = alw
return nil
})
}
func (erc20 *erc20) Transfer(ctx context.Context, to common.Address, amount, gasPrice *big.Int, sendAll bool) (*types.Transaction, error) {
if sendAll {
balance, err := erc20.BalanceOf(ctx, erc20.account.Address())
if err != nil {
return nil, err
}
amount = balance
}
return erc20.account.Transact(
ctx,
nil,
func(tops *bind.TransactOpts) (*types.Transaction, error) {
if gasPrice != nil {
tops.GasPrice = gasPrice
}
tx, err := erc20.cerc20.Transfer(tops, to, amount)
if err != nil {
return tx, err
}
return tx, nil
},
nil,
1,
)
}
func (erc20 *erc20) Approve(ctx context.Context, spender common.Address, amount, gasPrice *big.Int) (*types.Transaction, error) {
return erc20.account.Transact(
ctx,
nil,
func(tops *bind.TransactOpts) (*types.Transaction, error) {
if gasPrice != nil {
tops.GasPrice = gasPrice
}
tx, err := erc20.cerc20.Approve(tops, spender, amount)
if err != nil {
return tx, err
}
return tx, nil
},
nil,
1,
)
}
func (erc20 *erc20) TransferFrom(ctx context.Context, from, to common.Address, amount, gasPrice *big.Int) (*types.Transaction, error) {
return erc20.account.Transact(
ctx,
nil,
func(tops *bind.TransactOpts) (*types.Transaction, error) {
if gasPrice != nil {
tops.GasPrice = gasPrice
}
tx, err := erc20.cerc20.TransferFrom(tops, from, to, amount)
if err != nil {
return tx, err
}
return tx, nil
},
nil,
1,
)
}