github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/signer/core/cliui.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:46</date>
    10  //</624342666540224512>
    11  
    12  
    13  package core
    14  
    15  import (
    16  	"bufio"
    17  	"fmt"
    18  	"os"
    19  	"strings"
    20  
    21  	"sync"
    22  
    23  	"github.com/davecgh/go-spew/spew"
    24  	"github.com/ethereum/go-ethereum/common"
    25  	"github.com/ethereum/go-ethereum/internal/ethapi"
    26  	"github.com/ethereum/go-ethereum/log"
    27  	"golang.org/x/crypto/ssh/terminal"
    28  )
    29  
    30  type CommandlineUI struct {
    31  	in *bufio.Reader
    32  	mu sync.Mutex
    33  }
    34  
    35  func NewCommandlineUI() *CommandlineUI {
    36  	return &CommandlineUI{in: bufio.NewReader(os.Stdin)}
    37  }
    38  
    39  //readstring从stdin读取一行,从空格中剪裁if,强制
    40  //非空性。
    41  func (ui *CommandlineUI) readString() string {
    42  	for {
    43  		fmt.Printf("> ")
    44  		text, err := ui.in.ReadString('\n')
    45  		if err != nil {
    46  			log.Crit("Failed to read user input", "err", err)
    47  		}
    48  		if text = strings.TrimSpace(text); text != "" {
    49  			return text
    50  		}
    51  	}
    52  }
    53  
    54  //readpassword从stdin读取一行,从尾随的new
    55  //行并返回它。输入将不会被回送。
    56  func (ui *CommandlineUI) readPassword() string {
    57  	fmt.Printf("Enter password to approve:\n")
    58  	fmt.Printf("> ")
    59  
    60  	text, err := terminal.ReadPassword(int(os.Stdin.Fd()))
    61  	if err != nil {
    62  		log.Crit("Failed to read password", "err", err)
    63  	}
    64  	fmt.Println()
    65  	fmt.Println("-----------------------")
    66  	return string(text)
    67  }
    68  
    69  //readpassword从stdin读取一行,从尾随的new
    70  //行并返回它。输入将不会被回送。
    71  func (ui *CommandlineUI) readPasswordText(inputstring string) string {
    72  	fmt.Printf("Enter %s:\n", inputstring)
    73  	fmt.Printf("> ")
    74  	text, err := terminal.ReadPassword(int(os.Stdin.Fd()))
    75  	if err != nil {
    76  		log.Crit("Failed to read password", "err", err)
    77  	}
    78  	fmt.Println("-----------------------")
    79  	return string(text)
    80  }
    81  
    82  //如果用户输入“是”,则confirm返回true,否则返回false
    83  func (ui *CommandlineUI) confirm() bool {
    84  	fmt.Printf("Approve? [y/N]:\n")
    85  	if ui.readString() == "y" {
    86  		return true
    87  	}
    88  	fmt.Println("-----------------------")
    89  	return false
    90  }
    91  
    92  func showMetadata(metadata Metadata) {
    93  	fmt.Printf("Request context:\n\t%v -> %v -> %v\n", metadata.Remote, metadata.Scheme, metadata.Local)
    94  }
    95  
    96  //approvetx提示用户确认请求签署交易
    97  func (ui *CommandlineUI) ApproveTx(request *SignTxRequest) (SignTxResponse, error) {
    98  	ui.mu.Lock()
    99  	defer ui.mu.Unlock()
   100  	weival := request.Transaction.Value.ToInt()
   101  	fmt.Printf("--------- Transaction request-------------\n")
   102  	if to := request.Transaction.To; to != nil {
   103  		fmt.Printf("to:    %v\n", to.Original())
   104  		if !to.ValidChecksum() {
   105  			fmt.Printf("\nWARNING: Invalid checksum on to-address!\n\n")
   106  		}
   107  	} else {
   108  		fmt.Printf("to:    <contact creation>\n")
   109  	}
   110  	fmt.Printf("from:  %v\n", request.Transaction.From.String())
   111  	fmt.Printf("value: %v wei\n", weival)
   112  	if request.Transaction.Data != nil {
   113  		d := *request.Transaction.Data
   114  		if len(d) > 0 {
   115  			fmt.Printf("data:  %v\n", common.Bytes2Hex(d))
   116  		}
   117  	}
   118  	if request.Callinfo != nil {
   119  		fmt.Printf("\nTransaction validation:\n")
   120  		for _, m := range request.Callinfo {
   121  			fmt.Printf("  * %s : %s", m.Typ, m.Message)
   122  		}
   123  		fmt.Println()
   124  
   125  	}
   126  	fmt.Printf("\n")
   127  	showMetadata(request.Meta)
   128  	fmt.Printf("-------------------------------------------\n")
   129  	if !ui.confirm() {
   130  		return SignTxResponse{request.Transaction, false, ""}, nil
   131  	}
   132  	return SignTxResponse{request.Transaction, true, ui.readPassword()}, nil
   133  }
   134  
   135  //ApproveSignData提示用户确认请求签署数据
   136  func (ui *CommandlineUI) ApproveSignData(request *SignDataRequest) (SignDataResponse, error) {
   137  	ui.mu.Lock()
   138  	defer ui.mu.Unlock()
   139  
   140  	fmt.Printf("-------- Sign data request--------------\n")
   141  	fmt.Printf("Account:  %s\n", request.Address.String())
   142  	fmt.Printf("message:  \n%q\n", request.Message)
   143  	fmt.Printf("raw data: \n%v\n", request.Rawdata)
   144  	fmt.Printf("message hash:  %v\n", request.Hash)
   145  	fmt.Printf("-------------------------------------------\n")
   146  	showMetadata(request.Meta)
   147  	if !ui.confirm() {
   148  		return SignDataResponse{false, ""}, nil
   149  	}
   150  	return SignDataResponse{true, ui.readPassword()}, nil
   151  }
   152  
   153  //approveexport提示用户确认导出加密帐户json
   154  func (ui *CommandlineUI) ApproveExport(request *ExportRequest) (ExportResponse, error) {
   155  	ui.mu.Lock()
   156  	defer ui.mu.Unlock()
   157  
   158  	fmt.Printf("-------- Export Account request--------------\n")
   159  	fmt.Printf("A request has been made to export the (encrypted) keyfile\n")
   160  	fmt.Printf("Approving this operation means that the caller obtains the (encrypted) contents\n")
   161  	fmt.Printf("\n")
   162  	fmt.Printf("Account:  %x\n", request.Address)
   163  //fmt.printf(“keyfile:\n%v\n”,request.file)
   164  	fmt.Printf("-------------------------------------------\n")
   165  	showMetadata(request.Meta)
   166  	return ExportResponse{ui.confirm()}, nil
   167  }
   168  
   169  //approveImport提示用户确认导入账号json
   170  func (ui *CommandlineUI) ApproveImport(request *ImportRequest) (ImportResponse, error) {
   171  	ui.mu.Lock()
   172  	defer ui.mu.Unlock()
   173  
   174  	fmt.Printf("-------- Import Account request--------------\n")
   175  	fmt.Printf("A request has been made to import an encrypted keyfile\n")
   176  	fmt.Printf("-------------------------------------------\n")
   177  	showMetadata(request.Meta)
   178  	if !ui.confirm() {
   179  		return ImportResponse{false, "", ""}, nil
   180  	}
   181  	return ImportResponse{true, ui.readPasswordText("Old password"), ui.readPasswordText("New password")}, nil
   182  }
   183  
   184  //批准提示用户确认列出帐户
   185  //用户界面可以修改要列出的科目列表
   186  func (ui *CommandlineUI) ApproveListing(request *ListRequest) (ListResponse, error) {
   187  
   188  	ui.mu.Lock()
   189  	defer ui.mu.Unlock()
   190  
   191  	fmt.Printf("-------- List Account request--------------\n")
   192  	fmt.Printf("A request has been made to list all accounts. \n")
   193  	fmt.Printf("You can select which accounts the caller can see\n")
   194  	for _, account := range request.Accounts {
   195  		fmt.Printf("\t[x] %v\n", account.Address.Hex())
   196  	}
   197  	fmt.Printf("-------------------------------------------\n")
   198  	showMetadata(request.Meta)
   199  	if !ui.confirm() {
   200  		return ListResponse{nil}, nil
   201  	}
   202  	return ListResponse{request.Accounts}, nil
   203  }
   204  
   205  //ApproveWaccount提示用户确认创建新帐户,并显示给调用方
   206  func (ui *CommandlineUI) ApproveNewAccount(request *NewAccountRequest) (NewAccountResponse, error) {
   207  
   208  	ui.mu.Lock()
   209  	defer ui.mu.Unlock()
   210  
   211  	fmt.Printf("-------- New Account request--------------\n")
   212  	fmt.Printf("A request has been made to create a new. \n")
   213  	fmt.Printf("Approving this operation means that a new Account is created,\n")
   214  	fmt.Printf("and the address show to the caller\n")
   215  	showMetadata(request.Meta)
   216  	if !ui.confirm() {
   217  		return NewAccountResponse{false, ""}, nil
   218  	}
   219  	return NewAccountResponse{true, ui.readPassword()}, nil
   220  }
   221  
   222  //ShowError向用户显示错误消息
   223  func (ui *CommandlineUI) ShowError(message string) {
   224  
   225  	fmt.Printf("ERROR: %v\n", message)
   226  }
   227  
   228  //ShowInfo向用户显示信息消息
   229  func (ui *CommandlineUI) ShowInfo(message string) {
   230  	fmt.Printf("Info: %v\n", message)
   231  }
   232  
   233  func (ui *CommandlineUI) OnApprovedTx(tx ethapi.SignTransactionResult) {
   234  	fmt.Printf("Transaction signed:\n ")
   235  	spew.Dump(tx.Tx)
   236  }
   237  
   238  func (ui *CommandlineUI) OnSignerStartup(info StartupInfo) {
   239  
   240  	fmt.Printf("------- Signer info -------\n")
   241  	for k, v := range info.Info {
   242  		fmt.Printf("* %v : %v\n", k, v)
   243  	}
   244  }
   245