-
Notifications
You must be signed in to change notification settings - Fork 40
/
keyfile.go
110 lines (95 loc) · 2.88 KB
/
keyfile.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
package seth
import (
"context"
"crypto/ecdsa"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
"github.com/pkg/errors"
"golang.org/x/sync/errgroup"
)
// NewAddress creates a new address
func NewAddress() (string, string, error) {
privateKey, err := crypto.GenerateKey()
if err != nil {
return "", "", err
}
privateKeyBytes := crypto.FromECDSA(privateKey)
publicKey := privateKey.Public()
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
if !ok {
return "", "", errors.New("error casting public key to ECDSA")
}
address := crypto.PubkeyToAddress(*publicKeyECDSA).Hex()
L.Info().
Str("Addr", address).
Msg("New address created")
return address, hexutil.Encode(privateKeyBytes)[2:], nil
}
// ReturnFunds returns funds to the root key from all other keys
func ReturnFunds(c *Client, toAddr string) error {
if toAddr == "" {
if err := c.validateAddressesKeyNum(0); err != nil {
return err
}
toAddr = c.Addresses[0].Hex()
}
gasPrice, err := c.GetSuggestedLegacyFees(context.Background(), Priority_Standard)
if err != nil {
gasPrice = big.NewInt(c.Cfg.Network.GasPrice)
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
eg, egCtx := errgroup.WithContext(ctx)
if len(c.Addresses) == 1 {
return errors.New("No addresses to return funds from. Have you passed correct key file?")
}
for i := 1; i < len(c.Addresses); i++ {
idx := i //nolint
eg.Go(func() error {
ctx, balanceCancel := context.WithTimeout(egCtx, c.Cfg.Network.TxnTimeout.Duration())
balance, err := c.Client.BalanceAt(ctx, c.Addresses[idx], nil)
balanceCancel()
if err != nil {
L.Error().Err(err).Msg("Error getting balance")
return err
}
var gasLimit int64
//nolint
gasLimitRaw, err := c.EstimateGasLimitForFundTransfer(c.Addresses[idx], common.HexToAddress(toAddr), balance)
if err != nil {
gasLimit = c.Cfg.Network.TransferGasFee
} else {
gasLimit = int64(gasLimitRaw)
}
networkTransferFee := gasPrice.Int64() * gasLimit
fundsToReturn := new(big.Int).Sub(balance, big.NewInt(networkTransferFee))
if fundsToReturn.Cmp(big.NewInt(0)) == -1 {
L.Warn().
Str("Key", c.Addresses[idx].Hex()).
Interface("Balance", balance).
Interface("NetworkFee", networkTransferFee).
Interface("FundsToReturn", fundsToReturn).
Msg("Insufficient funds to return. Skipping.")
return nil
}
L.Info().
Str("Key", c.Addresses[idx].Hex()).
Interface("Balance", balance).
Interface("NetworkFee", c.Cfg.Network.GasPrice*gasLimit).
Interface("GasLimit", gasLimit).
Interface("GasPrice", gasPrice).
Interface("FundsToReturn", fundsToReturn).
Msg("Returning funds from address")
return c.TransferETHFromKey(
egCtx,
idx,
toAddr,
fundsToReturn,
gasPrice,
)
})
}
return eg.Wait()
}