【Golang】go语言批量生成5W地址

基于go语言编写批量生成用户地址

1、执行二进制

2、切分数据

3、创建goroutine并发执行

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
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
package main

import (
"encoding/csv"
"gopkg.in/yaml.v3"

"fmt"
//"gopkg.in/yaml.v3"
"log"
"os"
"os/exec"
"strings"
"sync"
"time"
)

var (
// Execute binary file
binaryPath = "/home/wang/code/pressure-me/me-chaind"
userChan = make(chan User, 100000)
outputMutex sync.Mutex
dirPath = "--home=./me-chain"
csvName = "users.csv"
)

type User struct {
Id string
Address string
PrivateKey string
Mnemonic string
}

type addResponse struct {
Name string
Type string
Address string
Pubkey string
Mnemonic string
}

func NewUser(id uint64) (User, error) {
addRes, err := add(id)
if err != nil {
return User{}, err
}
pk, _, err := export(id)
if err != nil {
return User{}, err
}
userInfo := User{Id: addRes.Name, Address: addRes.Address, PrivateKey: pk, Mnemonic: addRes.Mnemonic}
return userInfo, nil
}

// 添加一个用户 传入用户id
func add(id uint64) (addResponse, error) {
formattedNumber := fmt.Sprintf("u-%06d", id)

args := []string{"keys", "add", formattedNumber, "--keyring-backend=test", dirPath}

cmd := exec.Command(binaryPath, args...) // 执行二进制文件,传入参数
cmd.Stdin = strings.NewReader("y\n") // y回车

stdout, stderr := &strings.Builder{}, &strings.Builder{}
cmd.Stdout, cmd.Stderr = stdout, stderr

err := cmd.Run()

outputMutex.Lock()
defer outputMutex.Unlock()

var data []addResponse
if err := yaml.Unmarshal([]byte(stdout.String()), &data); err != nil {
log.Fatalf("Error parsing YAML: %v", err)
}

if len(data) <= 0 {
log.Fatalf("Data is nil: %v", err)
return addResponse{}, err
}

// handle Mnemonic
text := strings.Join([]string{stderr.String()}, "\n")
splitText := strings.SplitAfter(text, "It is the only way to recover your account if you ever forget your password.")
if len(splitText) < 2 {
fmt.Println("Could not find 'It is the only way to recover your account if you ever forget your password.'")
return addResponse{}, err
}
// Extract the mnemonic phrase
mnemonic := strings.TrimSpace(splitText[1])
data[0].Mnemonic = mnemonic
return data[0], nil
}

// Export private key
func export(id uint64) (string, string, error) {
formattedNumber := fmt.Sprintf("u-%06d", id)

args := []string{"keys", "export", formattedNumber, "--unsafe", "--unarmored-hex", "--keyring-backend=test", dirPath}

cmd := exec.Command(binaryPath, args...)
cmd.Stdin = strings.NewReader("y\n")

stdout, stderr := &strings.Builder{}, &strings.Builder{}
cmd.Stdout, cmd.Stderr = stdout, stderr

err := cmd.Run()

return strings.TrimRight(stdout.String(), "\n"), stderr.String(), err
}

func Batch() {
start := time.Now()
goroutineNum := 30
totalUsers := 50000

wg := sync.WaitGroup{}
for i := 0; i < goroutineNum; i++ {
wg.Add(1)
go func(startID int) {
defer wg.Done()

for j := startID; j <= totalUsers; j += goroutineNum {
user, err := NewUser(uint64(j))
if err != nil {
return
}
userChan <- user
}
}(i + 1)
}
// Close the channel after all goroutines finish
wg.Wait()
elapsed := time.Since(start)
fmt.Printf("创造数据执行耗时:%v \n", elapsed.Seconds())
close(userChan)

start1 := time.Now()
// Collect the generated users
var users []User
for user := range userChan {
users = append(users, user)
}

// Write users to CSV file
err := writeUsersToCSV(users, csvName)
if err != nil {
fmt.Println("Error writing to CSV file:", err)
} else {
fmt.Printf("Users written to [%s] file successfully. \n", csvName)
}
elapsed2 := time.Since(start1)
fmt.Printf("写入数据执行耗时:%v \n", elapsed2.Seconds())

}
func writeUsersToCSV(users []User, filename string) error {
// Create the CSV file
file, err := os.Create(filename)
if err != nil {
return err
}
defer file.Close()

// Create the CSV writer
writer := csv.NewWriter(file)
defer writer.Flush()

// Write the header row
header := []string{"ID", "Address", "PrivateKey", "Mnemonic"}
err = writer.Write(header)
if err != nil {
return err
}

// Write the user data rows
for _, user := range users {
row := []string{user.Id, user.Address, user.PrivateKey, user.Mnemonic}
err := writer.Write(row)
if err != nil {
return err
}
}
return nil
}

/*
PrivFromAddrString
@Description: 私钥转地址, gea/cosmos-sdk/types/address.go 要更改默认地址前缀
@param privStr
@return string
@return error
*/
//func PrivFromAddrString(privStr string) (string, error) {
// priBytes, err := hex.DecodeString(privStr)
// if err != nil {
// return "", err
// }
// priv := &secp256k1.PrivKey{Key: priBytes}
// accAddr := sdk.AccAddress(priv.PubKey().Address().Bytes())
// return accAddr.String(), nil
//}

func main() {
//s, err := add(001)
//s, s2, err := export(001)
//if err != nil {
// return
//}
//fmt.Println(s)
//fmt.Println(s2)

//addrString, err := PrivFromAddrString("108c7ca3d2bdf462c4af5504fcbda1c1ffec3213ef9b02f39edbafc20bc068a2")
//if err != nil {
// return
//}
////gea1adezarkjat6gz79sh2svr66k2ltf0ks052256v
//fmt.Println(addrString)
//if addrString != "gea1adezarkjat6gz79sh2svr66k2ltf0ks052256v" {
// fmt.Println("Fail")
//}

//user, err := NewUser(2)
//if err != nil {
// return
//}
//fmt.Println(user)

start := time.Now()

Batch()

elapsed := time.Since(start)
fmt.Printf("程序执行耗时:%v \n", elapsed.Seconds())
}


【Golang】go语言批量生成5W地址
http://example.com/2023/12/07/808go语言批量生成5W地址/
作者
Wangxiaowang
发布于
2023年12月7日
许可协议