-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
209 lines (193 loc) · 5.3 KB
/
main.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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
package main
import (
"context"
"crypto/ecdsa"
"encoding/json"
"flag"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"io/ioutil"
"log"
"math/big"
"math/rand"
"strings"
"sync"
"time"
)
type Wallet struct {
Private string `json:"private"`
Address string `json:"address"`
}
type Token struct {
Tick string `json:"tick"`
Amt string `json:"amt"`
Workc string `json:"workc"`
}
type Network struct {
RpcURL string `json:"rpcURL"`
}
type Config struct {
Wallets []Wallet `json:"wallets"`
Tokens []Token `json:"tokens"`
Network Network `json:"network"`
}
var (
transactionSent = false
mu sync.Mutex
)
var (
token = flag.String("token", "", "example: ierc-m4")
address = flag.String("address", "", "example: 0x000000")
count = flag.Int("count", 1, "单账号挖矿次数,默认为1")
thread = flag.Int("thread", 1000, "并发线程数,默认为1000")
gas = flag.Int("gas", 0, "gas价格,默认为0,自动获取")
test = flag.Bool("test", false, "是否为测试模式,默认为false。测试模式只会计算tx、不发送真实的交易")
)
func main() {
//打印开发者信息
fmt.Println("作者: @longtao_eth https://twitter.com/longtao_eth")
fmt.Println("Author: @longtao_eth https://twitter.com/longtao_eth")
flag.Parse()
//读取config.json配置文件
configFile, err := ioutil.ReadFile("config.json")
if err != nil {
fmt.Println("读取config.json配置文件失败")
return
}
//解析config.json配置文件
var config Config
err = json.Unmarshal(configFile, &config)
if err != nil {
fmt.Println("解析config.json配置文件失败")
return
}
//遍历config.json配置文件,获取对应的私钥、地址、token
for _, wallet := range config.Wallets {
if wallet.Address == *address {
for _, mintToken := range config.Tokens {
if mintToken.Tick == *token {
for i := 0; i < *count; i++ {
transactionSent = false
rand.Seed(time.Now().UnixNano())
pow(wallet, mintToken, config.Network, *thread, *gas, *test)
}
}
}
}
}
}
func pow(wallet Wallet, token Token, network Network, thread int, gas int, test bool) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel() // cancel when we are finished
//连接以太坊客户端
client, err := ethclient.Dial(network.RpcURL)
if err != nil {
return
}
//将私钥转换为ECDSA
privateKeyECDSA, err := crypto.HexToECDSA(wallet.Private)
if err != nil {
return
}
//获取公钥
publicKey := privateKeyECDSA.Public()
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
if !ok {
panic("error casting public key to ECDSA")
return
}
//获取地址
fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
//获取待处理的交易数
nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
if err != nil {
return
}
var gasPrice *big.Int
if gas == 0 {
//获取建议的gas价格
gasPrice, err = client.SuggestGasPrice(context.Background())
if err != nil {
return
}
} else {
gasPrice = big.NewInt(int64(gas) * 1e9)
}
//创建交易签名者
auth := types.NewEIP155Signer(big.NewInt(1)) // 1 is the chain ID for the Ethereum mainnet
value := big.NewInt(0) // in wei (1 eth = 10^18 wei)
toAddress := common.HexToAddress("0x0000000000000000000000000000000000000000")
//统计单个计算tx所耗费时间
start := time.Now()
var TrueHash string
//创建x个线程并发计算txhash,若计算成果则发送交易并关闭所有线程
var wg sync.WaitGroup
for i := 0; i < thread; i++ {
wg.Add(1)
go func(nonce uint64) {
defer wg.Done()
for {
select {
case <-ctx.Done():
return
default:
}
mu.Lock()
if transactionSent {
mu.Unlock()
return
}
mu.Unlock()
randomDigits := generateRandomDigits(8)
currentTime := time.Now().Unix()
timer := fmt.Sprintf("%d%s", currentTime, randomDigits)
dataString := fmt.Sprintf(`data:application/json,{"p":"ierc-20","op":"mint","tick":"%s","amt":"%s","nonce":"%s"}`, token.Tick, token.Amt, timer)
//dataHex := hex.EncodeToString([]byte(dataString))
tx := types.LegacyTx{
Nonce: nonce,
GasPrice: gasPrice,
Gas: 28000,
To: &toAddress,
Value: value,
Data: []byte(dataString),
}
transaction := types.NewTx(&tx)
signedTx, err := types.SignTx(transaction, auth, privateKeyECDSA)
if err != nil {
log.Fatalf("Failed to sign transaction: %v", err)
}
hash := signedTx.Hash().Hex()
fmt.Printf("\rFalseHash: %s\n", hash)
if strings.Contains(hash, token.Workc) {
TrueHash = hash
mu.Lock()
transactionSent = true
mu.Unlock()
//发送交易
if test == false {
err = client.SendTransaction(context.Background(), signedTx)
if err != nil {
log.Fatalf("Failed to send transaction: %v", err)
}
}
cancel()
break
}
}
}(nonce)
}
wg.Wait()
fmt.Printf("TrueHash: %s\n", TrueHash)
stop := time.Now()
fmt.Printf("单个txhash所耗费时间: %v\n", stop.Sub(start))
}
func generateRandomDigits(length int) string {
digits := make([]byte, length)
for i := range digits {
digits[i] = '0' + byte(rand.Intn(10))
}
return string(digits)
}