Skip to content

Commit 8cc2afe

Browse files
author
NullpointerW
committed
refactor
1 parent d05cb48 commit 8cc2afe

File tree

4 files changed

+105
-90
lines changed

4 files changed

+105
-90
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module MintTool
1+
module ethereum-wallet-tool
22

33
go 1.21
44

pkg/tx/transfer.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package tx
2+
3+
import (
4+
"context"
5+
"crypto/ecdsa"
6+
"ethereum-wallet-tool/pkg/util"
7+
"fmt"
8+
"github.com/ethereum/go-ethereum"
9+
"github.com/ethereum/go-ethereum/common"
10+
"github.com/ethereum/go-ethereum/core/types"
11+
"github.com/ethereum/go-ethereum/crypto"
12+
"github.com/ethereum/go-ethereum/ethclient"
13+
"log"
14+
"math/big"
15+
)
16+
17+
func Transfer(pk string, to string, val string, data []byte, ec *ethclient.Client) (txHash string, err error) {
18+
privateKeyHex := pk
19+
privateKey, err := crypto.HexToECDSA(privateKeyHex)
20+
if err != nil {
21+
log.Fatalf("Failed to decode private key: %v", err)
22+
}
23+
24+
// 获取账户地址
25+
publicKey := privateKey.Public()
26+
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
27+
if !ok {
28+
log.Fatal("error casting public key to ECDSA")
29+
}
30+
fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
31+
32+
// 获取账户的nonce
33+
nonce, err := ec.PendingNonceAt(context.Background(), fromAddress)
34+
if err != nil {
35+
log.Fatalf("Failed to get account nonce: %v", err)
36+
}
37+
38+
// 设置转账金额(0.001 ETH)
39+
wei, ok := util.ToWei(val)
40+
if !ok {
41+
fmt.Println("invalid eth value:", val)
42+
return "", err
43+
}
44+
45+
gasTipCap, err := ec.SuggestGasTipCap(context.Background())
46+
if err != nil {
47+
log.Fatalf("Failed to suggest gas tip cap: %v", err)
48+
}
49+
50+
// 设置 maxFeePerGas。这通常是 baseFeePerGas + maxPriorityFeePerGas,但要留有余地以适应 baseFee 的变动
51+
baseFee, err := ec.HeaderByNumber(context.Background(), nil)
52+
if err != nil {
53+
log.Fatalf("Failed to get latest block header: %v", err)
54+
}
55+
maxFeePerGas := new(big.Int).Add(baseFee.BaseFee, gasTipCap)
56+
57+
// 设置接收方地址
58+
toAddress := common.HexToAddress(to)
59+
60+
// 估算 Gas 量
61+
msg := ethereum.CallMsg{
62+
From: fromAddress,
63+
To: &toAddress,
64+
Gas: 0,
65+
GasPrice: maxFeePerGas,
66+
Value: wei,
67+
Data: nil,
68+
}
69+
70+
estimatedGas, err := ec.EstimateGas(context.Background(), msg)
71+
if err != nil {
72+
return "", err
73+
}
74+
fmt.Println("maxPriorityFeePerGas:", gasTipCap, "GasFeeCap:", maxFeePerGas, "Gas:", estimatedGas)
75+
tx := &types.DynamicFeeTx{
76+
ChainID: big.NewInt(1),
77+
Nonce: nonce,
78+
GasTipCap: gasTipCap, // maxPriorityFeePerGas
79+
GasFeeCap: maxFeePerGas, // max Fee
80+
Gas: estimatedGas,
81+
To: &toAddress,
82+
Value: wei,
83+
}
84+
if len(data) > 0 {
85+
tx.Data = data
86+
}
87+
txn := types.NewTx(tx)
88+
// 创建交易
89+
signedTx, err := types.SignTx(txn, types.NewCancunSigner(tx.ChainID), privateKey)
90+
if err != nil {
91+
return "", err
92+
}
93+
err = ec.SendTransaction(context.Background(), signedTx)
94+
return txn.Hash().String(), err
95+
}

wei_util.go renamed to pkg/util/wei_util.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
package main
1+
package util
22

33
import "math/big"
44

5-
// EthToWei converts an Ethereum value in ETH (as a string) to wei (as *big.Int).
6-
func EthToWei(eth string) (*big.Int, bool) {
7-
// Create a big.Float from the ETH string
8-
value, ok := new(big.Float).SetString(eth)
5+
// ToWei converts an Ethereum value in val (as a string) to wei (as *big.Int).
6+
func ToWei(v string) (*big.Int, bool) {
7+
// Create a big.Float from the val string
8+
value, ok := new(big.Float).SetString(v)
99
if !ok {
1010
return nil, false // Could not parse ETH value
1111
}
1212

1313
// Create a big.Float for the conversion factor (1 ETH = 10^18 wei)
1414
multiplier := new(big.Float).SetInt(big.NewInt(1e18))
1515

16-
// Multiply the ETH value by the conversion factor to get wei
16+
// Multiply the value by the conversion factor to get wei
1717
value.Mul(value, multiplier)
1818

1919
// Convert the big.Float result to a big.Int

transfer.go

Lines changed: 3 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,10 @@
11
package main
22

33
import (
4-
"context"
5-
"crypto/ecdsa"
64
"encoding/json"
7-
"errors"
5+
_tx "ethereum-wallet-tool/pkg/tx"
86
"fmt"
9-
"github.com/ethereum/go-ethereum"
10-
"github.com/ethereum/go-ethereum/common"
11-
"github.com/ethereum/go-ethereum/core/types"
12-
"github.com/ethereum/go-ethereum/crypto"
137
"github.com/ethereum/go-ethereum/ethclient"
14-
"log"
15-
"math/big"
168
"os"
179
"strings"
1810
)
@@ -67,81 +59,9 @@ func Transfer(val string) {
6759
}
6860

6961
func transfer(mpk string, w Wallet, val string, ec *ethclient.Client) (TxRecord, error) {
70-
privateKeyHex := mpk
71-
privateKey, err := crypto.HexToECDSA(privateKeyHex)
72-
if err != nil {
73-
log.Fatalf("Failed to decode private key: %v", err)
74-
}
75-
76-
// 获取账户地址
77-
publicKey := privateKey.Public()
78-
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
79-
if !ok {
80-
log.Fatal("error casting public key to ECDSA")
81-
}
82-
fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
83-
84-
// 获取账户的nonce
85-
nonce, err := ec.PendingNonceAt(context.Background(), fromAddress)
86-
if err != nil {
87-
log.Fatalf("Failed to get account nonce: %v", err)
88-
}
89-
90-
// 设置转账金额(0.001 ETH)
91-
wei, ok := EthToWei(val)
92-
if !ok {
93-
fmt.Println("invalid eth value:", val)
94-
return TxRecord{}, errors.New(fmt.Sprintf("invalid eth value: %s", val))
95-
}
96-
97-
gasTipCap, err := ec.SuggestGasTipCap(context.Background())
98-
if err != nil {
99-
log.Fatalf("Failed to suggest gas tip cap: %v", err)
100-
}
101-
102-
// 设置 maxFeePerGas。这通常是 baseFeePerGas + maxPriorityFeePerGas,但要留有余地以适应 baseFee 的变动
103-
baseFee, err := ec.HeaderByNumber(context.Background(), nil)
104-
if err != nil {
105-
log.Fatalf("Failed to get latest block header: %v", err)
106-
}
107-
maxFeePerGas := new(big.Int).Add(baseFee.BaseFee, gasTipCap)
108-
109-
// 设置接收方地址
110-
toAddress := common.HexToAddress(w.Address)
111-
112-
// 估算 Gas 量
113-
msg := ethereum.CallMsg{
114-
From: fromAddress,
115-
To: &toAddress,
116-
Gas: 0,
117-
GasPrice: maxFeePerGas,
118-
Value: wei,
119-
Data: nil,
120-
}
121-
122-
estimatedGas, err := ec.EstimateGas(context.Background(), msg)
123-
if err != nil {
124-
return TxRecord{}, fmt.Errorf("failed to estimate gas: %v", err)
125-
}
126-
fmt.Println("maxPriorityFeePerGas:", gasTipCap, "GasFeeCap:", maxFeePerGas, "Gas:", estimatedGas)
127-
tx := &types.DynamicFeeTx{
128-
ChainID: big.NewInt(1),
129-
Nonce: nonce,
130-
GasTipCap: gasTipCap, // maxPriorityFeePerGas
131-
GasFeeCap: maxFeePerGas, // max Fee
132-
Gas: estimatedGas,
133-
To: &toAddress,
134-
Value: wei,
135-
}
136-
137-
// 创建交易
138-
signedTx, err := types.SignTx(types.NewTx(tx), types.NewCancunSigner(tx.ChainID), privateKey)
139-
if err != nil {
140-
return TxRecord{}, errors.New(fmt.Sprintf("signTx err:%s", err.Error()))
141-
}
142-
err = ec.SendTransaction(context.Background(), signedTx)
62+
txHash, err := _tx.Transfer(mpk, w.Address, val, nil, ec)
14363
txR := TxRecord{
144-
Hash: signedTx.Hash().String(),
64+
Hash: txHash,
14565
Address: w.Address,
14666
PK: w.PrivateKey,
14767
Value: val,

0 commit comments

Comments
 (0)