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