github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/cmd/puppeth/wizard.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 12:09:31</date> 10 //</624342604082843648> 11 12 13 package main 14 15 import ( 16 "bufio" 17 "encoding/json" 18 "fmt" 19 "io/ioutil" 20 "math/big" 21 "net" 22 "os" 23 "path/filepath" 24 "sort" 25 "strconv" 26 "strings" 27 "sync" 28 29 "github.com/ethereum/go-ethereum/common" 30 "github.com/ethereum/go-ethereum/core" 31 "github.com/ethereum/go-ethereum/log" 32 "golang.org/x/crypto/ssh/terminal" 33 ) 34 35 //config包含Puppeth需要保存的所有配置 36 // 37 type config struct { 38 path string // 39 bootnodes []string //所有节点始终连接到的引导节点 40 ethstats string //要为节点部署缓存的ethstats设置 41 42 Genesis *core.Genesis `json:"genesis,omitempty"` //用于节点部署的缓存Genesis块 43 Servers map[string][]byte `json:"servers,omitempty"` 44 } 45 46 //服务器检索按字母顺序排序的服务器列表。 47 func (c config) servers() []string { 48 servers := make([]string, 0, len(c.Servers)) 49 for server := range c.Servers { 50 servers = append(servers, server) 51 } 52 sort.Strings(servers) 53 54 return servers 55 } 56 57 //flush将配置的内容转储到磁盘。 58 func (c config) flush() { 59 os.MkdirAll(filepath.Dir(c.path), 0755) 60 61 out, _ := json.MarshalIndent(c, "", " ") 62 if err := ioutil.WriteFile(c.path, out, 0644); err != nil { 63 log.Warn("Failed to save puppeth configs", "file", c.path, "err", err) 64 } 65 } 66 67 type wizard struct { 68 network string //要管理的网络名称 69 conf config //以前运行的配置 70 71 servers map[string]*sshClient //ssh连接到要管理的服务器 72 services map[string][]string //已知正在服务器上运行的以太坊服务 73 74 in *bufio.Reader //包装stdin以允许读取用户输入 75 lock sync.Mutex //锁定以在并发服务发现期间保护配置 76 } 77 78 //读取从stdin中读取一行,如果从空格中删除,则进行剪裁。 79 func (w *wizard) read() string { 80 fmt.Printf("> ") 81 text, err := w.in.ReadString('\n') 82 if err != nil { 83 log.Crit("Failed to read user input", "err", err) 84 } 85 return strings.TrimSpace(text) 86 } 87 88 //readString reads a single line from stdin, trimming if from spaces, enforcing 89 //非空性。 90 func (w *wizard) readString() string { 91 for { 92 fmt.Printf("> ") 93 text, err := w.in.ReadString('\n') 94 if err != nil { 95 log.Crit("Failed to read user input", "err", err) 96 } 97 if text = strings.TrimSpace(text); text != "" { 98 return text 99 } 100 } 101 } 102 103 //readdefaultstring从stdin读取一行,从空格中剪裁if。如果 104 //输入空行,返回默认值。 105 func (w *wizard) readDefaultString(def string) string { 106 fmt.Printf("> ") 107 text, err := w.in.ReadString('\n') 108 if err != nil { 109 log.Crit("Failed to read user input", "err", err) 110 } 111 if text = strings.TrimSpace(text); text != "" { 112 return text 113 } 114 return def 115 } 116 117 //readint从stdin读取一行,从空格中剪裁if,强制执行 118 // 119 func (w *wizard) readInt() int { 120 for { 121 fmt.Printf("> ") 122 text, err := w.in.ReadString('\n') 123 if err != nil { 124 log.Crit("Failed to read user input", "err", err) 125 } 126 if text = strings.TrimSpace(text); text == "" { 127 continue 128 } 129 val, err := strconv.Atoi(strings.TrimSpace(text)) 130 if err != nil { 131 log.Error("Invalid input, expected integer", "err", err) 132 continue 133 } 134 return val 135 } 136 } 137 138 // 139 // 140 //返回。 141 func (w *wizard) readDefaultInt(def int) int { 142 for { 143 fmt.Printf("> ") 144 text, err := w.in.ReadString('\n') 145 if err != nil { 146 log.Crit("Failed to read user input", "err", err) 147 } 148 if text = strings.TrimSpace(text); text == "" { 149 return def 150 } 151 val, err := strconv.Atoi(strings.TrimSpace(text)) 152 if err != nil { 153 log.Error("Invalid input, expected integer", "err", err) 154 continue 155 } 156 return val 157 } 158 } 159 160 // 161 // 162 // 163 func (w *wizard) readDefaultBigInt(def *big.Int) *big.Int { 164 for { 165 fmt.Printf("> ") 166 text, err := w.in.ReadString('\n') 167 if err != nil { 168 log.Crit("Failed to read user input", "err", err) 169 } 170 if text = strings.TrimSpace(text); text == "" { 171 return def 172 } 173 val, ok := new(big.Int).SetString(text, 0) 174 if !ok { 175 log.Error("Invalid input, expected big integer") 176 continue 177 } 178 return val 179 } 180 } 181 182 /* 183 184 185 186 187 188 189 如果犯错!= nIL{ 190 191 192 如果text=strings.trimspace(text);text=“” 193 持续 194 } 195 val,err:=strconv.parsefloat(strings.trimspace(text),64) 196 如果犯错!= nIL{ 197 log.error(“输入无效,应为float”,“err”,err) 198 持续 199 } 200 返回瓦尔 201 } 202 } 203 **/ 204 205 206 //readdefaultfloat从stdin读取一行,从空格中剪裁if,强制 207 // 208 func (w *wizard) readDefaultFloat(def float64) float64 { 209 for { 210 fmt.Printf("> ") 211 text, err := w.in.ReadString('\n') 212 if err != nil { 213 log.Crit("Failed to read user input", "err", err) 214 } 215 if text = strings.TrimSpace(text); text == "" { 216 return def 217 } 218 val, err := strconv.ParseFloat(strings.TrimSpace(text), 64) 219 if err != nil { 220 log.Error("Invalid input, expected float", "err", err) 221 continue 222 } 223 return val 224 } 225 } 226 227 //readpassword从stdin读取一行,从尾随的new 228 // 229 func (w *wizard) readPassword() string { 230 fmt.Printf("> ") 231 text, err := terminal.ReadPassword(int(os.Stdin.Fd())) 232 if err != nil { 233 log.Crit("Failed to read password", "err", err) 234 } 235 fmt.Println() 236 return string(text) 237 } 238 239 // 240 //发送到以太坊地址。 241 func (w *wizard) readAddress() *common.Address { 242 for { 243 //从用户处读取地址 244 fmt.Printf("> 0x") 245 text, err := w.in.ReadString('\n') 246 if err != nil { 247 log.Crit("Failed to read user input", "err", err) 248 } 249 if text = strings.TrimSpace(text); text == "" { 250 return nil 251 } 252 // 253 if len(text) != 40 { 254 log.Error("Invalid address length, please retry") 255 continue 256 } 257 bigaddr, _ := new(big.Int).SetString(text, 16) 258 address := common.BigToAddress(bigaddr) 259 return &address 260 } 261 } 262 263 // 264 //将其转换为以太坊地址。如果输入空行,则默认 265 // 266 func (w *wizard) readDefaultAddress(def common.Address) common.Address { 267 for { 268 //从用户处读取地址 269 fmt.Printf("> 0x") 270 text, err := w.in.ReadString('\n') 271 if err != nil { 272 log.Crit("Failed to read user input", "err", err) 273 } 274 if text = strings.TrimSpace(text); text == "" { 275 return def 276 } 277 // 278 if len(text) != 40 { 279 log.Error("Invalid address length, please retry") 280 continue 281 } 282 bigaddr, _ := new(big.Int).SetString(text, 16) 283 return common.BigToAddress(bigaddr) 284 } 285 } 286 287 // 288 func (w *wizard) readJSON() string { 289 var blob json.RawMessage 290 291 for { 292 fmt.Printf("> ") 293 if err := json.NewDecoder(w.in).Decode(&blob); err != nil { 294 log.Error("Invalid JSON, please try again", "err", err) 295 continue 296 } 297 return string(blob) 298 } 299 } 300 301 // 302 // 303 //用户输入格式(而不是返回go net.ip)与 304 // 305 func (w *wizard) readIPAddress() string { 306 for { 307 // 308 fmt.Printf("> ") 309 text, err := w.in.ReadString('\n') 310 if err != nil { 311 log.Crit("Failed to read user input", "err", err) 312 } 313 if text = strings.TrimSpace(text); text == "" { 314 return "" 315 } 316 // 317 if ip := net.ParseIP(text); ip == nil { 318 log.Error("Invalid IP address, please retry") 319 continue 320 } 321 return text 322 } 323 } 324