-
Notifications
You must be signed in to change notification settings - Fork 4
/
ethereum.go
103 lines (91 loc) · 2.88 KB
/
ethereum.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
package imx
import (
"context"
"errors"
"fmt"
"regexp"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/immutable/imx-core-sdk-golang/imx/contracts"
)
const (
ContractInvalidError = "contract_invalid_error"
EthClientError = "ethereum_client_error"
)
func (c *Client) NewIERC20Contract(ctx context.Context, address string) (*contracts.IERC20, error) {
if err := c.validateContract(ctx, address); err != nil {
return nil, err
}
return contracts.NewIERC20(common.HexToAddress(address), c.EthClient)
}
func (c *Client) NewIERC721Contract(ctx context.Context, address string) (*contracts.IERC721, error) {
if err := c.validateContract(ctx, address); err != nil {
return nil, err
}
return contracts.NewIERC721(common.HexToAddress(address), c.EthClient)
}
func (c *Client) attachRegistrationContract(ctx context.Context) error {
if err := c.validateContract(ctx, c.Environment.RegistrationContractAddress); err != nil {
return err
}
client, err := contracts.NewRegistration(common.HexToAddress(c.Environment.RegistrationContractAddress), c.EthClient)
if err != nil {
return err
}
c.RegistrationContract = client
return nil
}
func (c *Client) attachCoreContract(ctx context.Context) error {
if err := c.validateContract(ctx, c.Environment.CoreContractAddress); err != nil {
return err
}
client, err := contracts.NewCore(common.HexToAddress(c.Environment.CoreContractAddress), c.EthClient)
if err != nil {
return err
}
c.CoreContract = client
return nil
}
func (c *Client) validateContract(ctx context.Context, address string) error {
if err := validateEthereumAddress(address); err != nil {
return err
}
if err := c.isValidContract(ctx, address); err != nil {
return err
}
return nil
}
func validateEthereumAddress(address string) error {
re := regexp.MustCompile("^0x[0-9a-fA-F]{40}$")
if !re.MatchString(address) {
return fmt.Errorf("invalid ethereum address")
}
return nil
}
func (c *Client) buildTransactOpts(ctx context.Context, l1signer L1Signer, overrides *bind.TransactOpts) *bind.TransactOpts {
keyAddr := common.HexToAddress(l1signer.GetAddress())
if overrides == nil {
overrides = new(bind.TransactOpts)
}
overrides.From = keyAddr
overrides.Context = ctx
overrides.Signer = func(address common.Address, tx *types.Transaction) (*types.Transaction, error) {
if address != keyAddr {
return nil, bind.ErrNotAuthorized
}
return l1signer.SignTx(tx)
}
return overrides
}
// isValidContract validates whether the given address is a contract
func (c *Client) isValidContract(ctx context.Context, address string) error {
bytecode, err := c.EthClient.CodeAt(ctx, common.HexToAddress(address), nil) // nil: latest head block
if err != nil {
return errors.New(EthClientError)
}
if len(bytecode) == 0 {
return errors.New(ContractInvalidError)
}
return nil
}