github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/signer/core/api_test.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 //版权所有2018 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 core 26 27 import ( 28 "bytes" 29 "context" 30 "fmt" 31 "io/ioutil" 32 "math/big" 33 "os" 34 "path/filepath" 35 "testing" 36 "time" 37 38 "github.com/ethereum/go-ethereum/accounts/keystore" 39 "github.com/ethereum/go-ethereum/cmd/utils" 40 "github.com/ethereum/go-ethereum/common" 41 "github.com/ethereum/go-ethereum/common/hexutil" 42 "github.com/ethereum/go-ethereum/core/types" 43 "github.com/ethereum/go-ethereum/internal/ethapi" 44 "github.com/ethereum/go-ethereum/rlp" 45 ) 46 47 //用于测试 48 type HeadlessUI struct { 49 controller chan string 50 } 51 52 func (ui *HeadlessUI) OnSignerStartup(info StartupInfo) { 53 } 54 55 func (ui *HeadlessUI) OnApprovedTx(tx ethapi.SignTransactionResult) { 56 fmt.Printf("OnApproved called") 57 } 58 59 func (ui *HeadlessUI) ApproveTx(request *SignTxRequest) (SignTxResponse, error) { 60 61 switch <-ui.controller { 62 case "Y": 63 return SignTxResponse{request.Transaction, true, <-ui.controller}, nil 64 case "M": //修改 65 old := big.Int(request.Transaction.Value) 66 newVal := big.NewInt(0).Add(&old, big.NewInt(1)) 67 request.Transaction.Value = hexutil.Big(*newVal) 68 return SignTxResponse{request.Transaction, true, <-ui.controller}, nil 69 default: 70 return SignTxResponse{request.Transaction, false, ""}, nil 71 } 72 } 73 func (ui *HeadlessUI) ApproveSignData(request *SignDataRequest) (SignDataResponse, error) { 74 if "Y" == <-ui.controller { 75 return SignDataResponse{true, <-ui.controller}, nil 76 } 77 return SignDataResponse{false, ""}, nil 78 } 79 func (ui *HeadlessUI) ApproveExport(request *ExportRequest) (ExportResponse, error) { 80 81 return ExportResponse{<-ui.controller == "Y"}, nil 82 83 } 84 func (ui *HeadlessUI) ApproveImport(request *ImportRequest) (ImportResponse, error) { 85 86 if "Y" == <-ui.controller { 87 return ImportResponse{true, <-ui.controller, <-ui.controller}, nil 88 } 89 return ImportResponse{false, "", ""}, nil 90 } 91 func (ui *HeadlessUI) ApproveListing(request *ListRequest) (ListResponse, error) { 92 93 switch <-ui.controller { 94 case "A": 95 return ListResponse{request.Accounts}, nil 96 case "1": 97 l := make([]Account, 1) 98 l[0] = request.Accounts[1] 99 return ListResponse{l}, nil 100 default: 101 return ListResponse{nil}, nil 102 } 103 } 104 func (ui *HeadlessUI) ApproveNewAccount(request *NewAccountRequest) (NewAccountResponse, error) { 105 106 if "Y" == <-ui.controller { 107 return NewAccountResponse{true, <-ui.controller}, nil 108 } 109 return NewAccountResponse{false, ""}, nil 110 } 111 func (ui *HeadlessUI) ShowError(message string) { 112 //stdout用于通信 113 fmt.Fprint(os.Stderr, message) 114 } 115 func (ui *HeadlessUI) ShowInfo(message string) { 116 //stdout用于通信 117 fmt.Fprint(os.Stderr, message) 118 } 119 120 func tmpDirName(t *testing.T) string { 121 d, err := ioutil.TempDir("", "eth-keystore-test") 122 if err != nil { 123 t.Fatal(err) 124 } 125 d, err = filepath.EvalSymlinks(d) 126 if err != nil { 127 t.Fatal(err) 128 } 129 return d 130 } 131 132 func setup(t *testing.T) (*SignerAPI, chan string) { 133 134 controller := make(chan string, 10) 135 136 db, err := NewAbiDBFromFile("../../cmd/clef/4byte.json") 137 if err != nil { 138 utils.Fatalf(err.Error()) 139 } 140 var ( 141 ui = &HeadlessUI{controller} 142 api = NewSignerAPI( 143 1, 144 tmpDirName(t), 145 true, 146 ui, 147 db, 148 true) 149 ) 150 return api, controller 151 } 152 func createAccount(control chan string, api *SignerAPI, t *testing.T) { 153 154 control <- "Y" 155 control <- "apassword" 156 _, err := api.New(context.Background()) 157 if err != nil { 158 t.Fatal(err) 159 } 160 //允许传播更改的一段时间 161 time.Sleep(250 * time.Millisecond) 162 } 163 func failCreateAccount(control chan string, api *SignerAPI, t *testing.T) { 164 control <- "N" 165 acc, err := api.New(context.Background()) 166 if err != ErrRequestDenied { 167 t.Fatal(err) 168 } 169 if acc.Address != (common.Address{}) { 170 t.Fatal("Empty address should be returned") 171 } 172 } 173 func list(control chan string, api *SignerAPI, t *testing.T) []Account { 174 control <- "A" 175 list, err := api.List(context.Background()) 176 if err != nil { 177 t.Fatal(err) 178 } 179 return list 180 } 181 182 func TestNewAcc(t *testing.T) { 183 184 api, control := setup(t) 185 verifyNum := func(num int) { 186 if list := list(control, api, t); len(list) != num { 187 t.Errorf("Expected %d accounts, got %d", num, len(list)) 188 } 189 } 190 //测试创建和创建拒绝 191 createAccount(control, api, t) 192 createAccount(control, api, t) 193 failCreateAccount(control, api, t) 194 failCreateAccount(control, api, t) 195 createAccount(control, api, t) 196 failCreateAccount(control, api, t) 197 createAccount(control, api, t) 198 failCreateAccount(control, api, t) 199 verifyNum(4) 200 201 //测试列表: 202 //列出一个帐户 203 control <- "1" 204 list, err := api.List(context.Background()) 205 if err != nil { 206 t.Fatal(err) 207 } 208 if len(list) != 1 { 209 t.Fatalf("List should only show one Account") 210 } 211 //拒绝上市 212 control <- "Nope" 213 list, err = api.List(context.Background()) 214 if len(list) != 0 { 215 t.Fatalf("List should be empty") 216 } 217 if err != ErrRequestDenied { 218 t.Fatal("Expected deny") 219 } 220 } 221 222 func TestSignData(t *testing.T) { 223 224 api, control := setup(t) 225 //创建两个帐户 226 createAccount(control, api, t) 227 createAccount(control, api, t) 228 control <- "1" 229 list, err := api.List(context.Background()) 230 if err != nil { 231 t.Fatal(err) 232 } 233 a := common.NewMixedcaseAddress(list[0].Address) 234 235 control <- "Y" 236 control <- "wrongpassword" 237 h, err := api.Sign(context.Background(), a, []byte("EHLO world")) 238 if h != nil { 239 t.Errorf("Expected nil-data, got %x", h) 240 } 241 if err != keystore.ErrDecrypt { 242 t.Errorf("Expected ErrLocked! %v", err) 243 } 244 245 control <- "No way" 246 h, err = api.Sign(context.Background(), a, []byte("EHLO world")) 247 if h != nil { 248 t.Errorf("Expected nil-data, got %x", h) 249 } 250 if err != ErrRequestDenied { 251 t.Errorf("Expected ErrRequestDenied! %v", err) 252 } 253 254 control <- "Y" 255 control <- "apassword" 256 h, err = api.Sign(context.Background(), a, []byte("EHLO world")) 257 258 if err != nil { 259 t.Fatal(err) 260 } 261 if h == nil || len(h) != 65 { 262 t.Errorf("Expected 65 byte signature (got %d bytes)", len(h)) 263 } 264 } 265 func mkTestTx(from common.MixedcaseAddress) SendTxArgs { 266 to := common.NewMixedcaseAddress(common.HexToAddress("0x1337")) 267 gas := hexutil.Uint64(21000) 268 gasPrice := (hexutil.Big)(*big.NewInt(2000000000)) 269 value := (hexutil.Big)(*big.NewInt(1e18)) 270 nonce := (hexutil.Uint64)(0) 271 data := hexutil.Bytes(common.Hex2Bytes("01020304050607080a")) 272 tx := SendTxArgs{ 273 From: from, 274 To: &to, 275 Gas: gas, 276 GasPrice: gasPrice, 277 Value: value, 278 Data: &data, 279 Nonce: nonce} 280 return tx 281 } 282 283 func TestSignTx(t *testing.T) { 284 285 var ( 286 list Accounts 287 res, res2 *ethapi.SignTransactionResult 288 err error 289 ) 290 291 api, control := setup(t) 292 createAccount(control, api, t) 293 control <- "A" 294 list, err = api.List(context.Background()) 295 if err != nil { 296 t.Fatal(err) 297 } 298 a := common.NewMixedcaseAddress(list[0].Address) 299 300 methodSig := "test(uint)" 301 tx := mkTestTx(a) 302 303 control <- "Y" 304 control <- "wrongpassword" 305 res, err = api.SignTransaction(context.Background(), tx, &methodSig) 306 if res != nil { 307 t.Errorf("Expected nil-response, got %v", res) 308 } 309 if err != keystore.ErrDecrypt { 310 t.Errorf("Expected ErrLocked! %v", err) 311 } 312 313 control <- "No way" 314 res, err = api.SignTransaction(context.Background(), tx, &methodSig) 315 if res != nil { 316 t.Errorf("Expected nil-response, got %v", res) 317 } 318 if err != ErrRequestDenied { 319 t.Errorf("Expected ErrRequestDenied! %v", err) 320 } 321 322 control <- "Y" 323 control <- "apassword" 324 res, err = api.SignTransaction(context.Background(), tx, &methodSig) 325 326 if err != nil { 327 t.Fatal(err) 328 } 329 parsedTx := &types.Transaction{} 330 rlp.Decode(bytes.NewReader(res.Raw), parsedTx) 331 //用户界面不应修改Tx 332 if parsedTx.Value().Cmp(tx.Value.ToInt()) != 0 { 333 t.Errorf("Expected value to be unchanged, expected %v got %v", tx.Value, parsedTx.Value()) 334 } 335 control <- "Y" 336 control <- "apassword" 337 338 res2, err = api.SignTransaction(context.Background(), tx, &methodSig) 339 if err != nil { 340 t.Fatal(err) 341 } 342 if !bytes.Equal(res.Raw, res2.Raw) { 343 t.Error("Expected tx to be unmodified by UI") 344 } 345 346 //Tx由用户界面修改 347 control <- "M" 348 control <- "apassword" 349 350 res2, err = api.SignTransaction(context.Background(), tx, &methodSig) 351 if err != nil { 352 t.Fatal(err) 353 } 354 355 parsedTx2 := &types.Transaction{} 356 rlp.Decode(bytes.NewReader(res.Raw), parsedTx2) 357 //用户界面应修改Tx 358 if parsedTx2.Value().Cmp(tx.Value.ToInt()) != 0 { 359 t.Errorf("Expected value to be unchanged, got %v", parsedTx.Value()) 360 } 361 362 if bytes.Equal(res.Raw, res2.Raw) { 363 t.Error("Expected tx to be modified by UI") 364 } 365 366 } 367 368 /* 369 func测试同步响应(t*testing.t) 370 371 //设置一个帐户 372 API,控件:=设置(T) 373 创建帐户(控件、API、T) 374 375 //两个事务,第二个事务的值大于第一个事务的值 376 tx1:=mktestx()。 377 newval:=big.newint(0).add((*big.int)(tx1.value),big.newint(1)) 378 tx2:=mktestx()。 379 tx2.value=(*hexUtil.big)(newval) 380 381 控件<-“w”//等待 382 控制<-“Y”// 383 控件<-“apassword” 384 控制<-“Y”// 385 控件<-“apassword” 386 387 无功误差 388 389 h1,err:=api.signTransaction(context.background(),common.hextoAddress(“1111”),tx1,nil) 390 h2,错误:=api.signTransaction(context.background(),common.hextoAddress(“2222”),tx2,nil) 391 392 393 } 394 **/ 395