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