github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/cmd/puppeth/wizard.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2017 Go Ethereum作者 10 //此文件是Go以太坊的一部分。 11 // 12 //Go以太坊是免费软件:您可以重新发布和/或修改它 13 //根据GNU通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊的分布希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU通用公共许可证了解更多详细信息。 21 // 22 //你应该已经收到一份GNU通用公共许可证的副本 23 //一起去以太坊吧。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 package main 26 27 import ( 28 "bufio" 29 "encoding/json" 30 "fmt" 31 "io/ioutil" 32 "math/big" 33 "net" 34 "os" 35 "path/filepath" 36 "sort" 37 "strconv" 38 "strings" 39 "sync" 40 41 "github.com/ethereum/go-ethereum/common" 42 "github.com/ethereum/go-ethereum/core" 43 "github.com/ethereum/go-ethereum/log" 44 "golang.org/x/crypto/ssh/terminal" 45 ) 46 47 //config包含Puppeth需要保存的所有配置 48 // 49 type config struct { 50 path string // 51 bootnodes []string //所有节点始终连接到的引导节点 52 ethstats string //要为节点部署缓存的ethstats设置 53 54 Genesis *core.Genesis `json:"genesis,omitempty"` //用于节点部署的缓存Genesis块 55 Servers map[string][]byte `json:"servers,omitempty"` 56 } 57 58 //服务器检索按字母顺序排序的服务器列表。 59 func (c config) servers() []string { 60 servers := make([]string, 0, len(c.Servers)) 61 for server := range c.Servers { 62 servers = append(servers, server) 63 } 64 sort.Strings(servers) 65 66 return servers 67 } 68 69 //flush将配置的内容转储到磁盘。 70 func (c config) flush() { 71 os.MkdirAll(filepath.Dir(c.path), 0755) 72 73 out, _ := json.MarshalIndent(c, "", " ") 74 if err := ioutil.WriteFile(c.path, out, 0644); err != nil { 75 log.Warn("Failed to save puppeth configs", "file", c.path, "err", err) 76 } 77 } 78 79 type wizard struct { 80 network string //要管理的网络名称 81 conf config //以前运行的配置 82 83 servers map[string]*sshClient //ssh连接到要管理的服务器 84 services map[string][]string //已知正在服务器上运行的以太坊服务 85 86 in *bufio.Reader //包装stdin以允许读取用户输入 87 lock sync.Mutex //锁定以在并发服务发现期间保护配置 88 } 89 90 //读取从stdin中读取一行,如果从空格中删除,则进行剪裁。 91 func (w *wizard) read() string { 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 return strings.TrimSpace(text) 98 } 99 100 //readString reads a single line from stdin, trimming if from spaces, enforcing 101 //非空性。 102 func (w *wizard) readString() string { 103 for { 104 fmt.Printf("> ") 105 text, err := w.in.ReadString('\n') 106 if err != nil { 107 log.Crit("Failed to read user input", "err", err) 108 } 109 if text = strings.TrimSpace(text); text != "" { 110 return text 111 } 112 } 113 } 114 115 //readdefaultstring从stdin读取一行,从空格中剪裁if。如果 116 //输入空行,返回默认值。 117 func (w *wizard) readDefaultString(def string) string { 118 fmt.Printf("> ") 119 text, err := w.in.ReadString('\n') 120 if err != nil { 121 log.Crit("Failed to read user input", "err", err) 122 } 123 if text = strings.TrimSpace(text); text != "" { 124 return text 125 } 126 return def 127 } 128 129 //readint从stdin读取一行,从空格中剪裁if,强制执行 130 // 131 func (w *wizard) readInt() int { 132 for { 133 fmt.Printf("> ") 134 text, err := w.in.ReadString('\n') 135 if err != nil { 136 log.Crit("Failed to read user input", "err", err) 137 } 138 if text = strings.TrimSpace(text); text == "" { 139 continue 140 } 141 val, err := strconv.Atoi(strings.TrimSpace(text)) 142 if err != nil { 143 log.Error("Invalid input, expected integer", "err", err) 144 continue 145 } 146 return val 147 } 148 } 149 150 // 151 // 152 //返回。 153 func (w *wizard) readDefaultInt(def int) int { 154 for { 155 fmt.Printf("> ") 156 text, err := w.in.ReadString('\n') 157 if err != nil { 158 log.Crit("Failed to read user input", "err", err) 159 } 160 if text = strings.TrimSpace(text); text == "" { 161 return def 162 } 163 val, err := strconv.Atoi(strings.TrimSpace(text)) 164 if err != nil { 165 log.Error("Invalid input, expected integer", "err", err) 166 continue 167 } 168 return val 169 } 170 } 171 172 // 173 // 174 // 175 func (w *wizard) readDefaultBigInt(def *big.Int) *big.Int { 176 for { 177 fmt.Printf("> ") 178 text, err := w.in.ReadString('\n') 179 if err != nil { 180 log.Crit("Failed to read user input", "err", err) 181 } 182 if text = strings.TrimSpace(text); text == "" { 183 return def 184 } 185 val, ok := new(big.Int).SetString(text, 0) 186 if !ok { 187 log.Error("Invalid input, expected big integer") 188 continue 189 } 190 return val 191 } 192 } 193 194 /* 195 196 197 198 199 200 201 如果犯错!= nIL{ 202 203 204 如果text=strings.trimspace(text);text=“” 205 持续 206 } 207 val,err:=strconv.parsefloat(strings.trimspace(text),64) 208 如果犯错!= nIL{ 209 log.error(“输入无效,应为float”,“err”,err) 210 持续 211 } 212 返回瓦尔 213 } 214 } 215 **/ 216 217 218 //readdefaultfloat从stdin读取一行,从空格中剪裁if,强制 219 // 220 func (w *wizard) readDefaultFloat(def float64) float64 { 221 for { 222 fmt.Printf("> ") 223 text, err := w.in.ReadString('\n') 224 if err != nil { 225 log.Crit("Failed to read user input", "err", err) 226 } 227 if text = strings.TrimSpace(text); text == "" { 228 return def 229 } 230 val, err := strconv.ParseFloat(strings.TrimSpace(text), 64) 231 if err != nil { 232 log.Error("Invalid input, expected float", "err", err) 233 continue 234 } 235 return val 236 } 237 } 238 239 //readpassword从stdin读取一行,从尾随的new 240 // 241 func (w *wizard) readPassword() string { 242 fmt.Printf("> ") 243 text, err := terminal.ReadPassword(int(os.Stdin.Fd())) 244 if err != nil { 245 log.Crit("Failed to read password", "err", err) 246 } 247 fmt.Println() 248 return string(text) 249 } 250 251 // 252 //发送到以太坊地址。 253 func (w *wizard) readAddress() *common.Address { 254 for { 255 //从用户处读取地址 256 fmt.Printf("> 0x") 257 text, err := w.in.ReadString('\n') 258 if err != nil { 259 log.Crit("Failed to read user input", "err", err) 260 } 261 if text = strings.TrimSpace(text); text == "" { 262 return nil 263 } 264 // 265 if len(text) != 40 { 266 log.Error("Invalid address length, please retry") 267 continue 268 } 269 bigaddr, _ := new(big.Int).SetString(text, 16) 270 address := common.BigToAddress(bigaddr) 271 return &address 272 } 273 } 274 275 // 276 //将其转换为以太坊地址。如果输入空行,则默认 277 // 278 func (w *wizard) readDefaultAddress(def common.Address) common.Address { 279 for { 280 //从用户处读取地址 281 fmt.Printf("> 0x") 282 text, err := w.in.ReadString('\n') 283 if err != nil { 284 log.Crit("Failed to read user input", "err", err) 285 } 286 if text = strings.TrimSpace(text); text == "" { 287 return def 288 } 289 // 290 if len(text) != 40 { 291 log.Error("Invalid address length, please retry") 292 continue 293 } 294 bigaddr, _ := new(big.Int).SetString(text, 16) 295 return common.BigToAddress(bigaddr) 296 } 297 } 298 299 // 300 func (w *wizard) readJSON() string { 301 var blob json.RawMessage 302 303 for { 304 fmt.Printf("> ") 305 if err := json.NewDecoder(w.in).Decode(&blob); err != nil { 306 log.Error("Invalid JSON, please try again", "err", err) 307 continue 308 } 309 return string(blob) 310 } 311 } 312 313 // 314 // 315 //用户输入格式(而不是返回go net.ip)与 316 // 317 func (w *wizard) readIPAddress() string { 318 for { 319 // 320 fmt.Printf("> ") 321 text, err := w.in.ReadString('\n') 322 if err != nil { 323 log.Crit("Failed to read user input", "err", err) 324 } 325 if text = strings.TrimSpace(text); text == "" { 326 return "" 327 } 328 // 329 if ip := net.ParseIP(text); ip == nil { 330 log.Error("Invalid IP address, please retry") 331 continue 332 } 333 return text 334 } 335 }