17
17
package main
18
18
19
19
import (
20
+ "errors"
20
21
"fmt"
21
22
"os"
23
+ "strings"
22
24
23
25
"github.com/ethereum/go-ethereum/accounts"
24
26
"github.com/ethereum/go-ethereum/accounts/keystore"
25
27
"github.com/ethereum/go-ethereum/cmd/utils"
28
+ "github.com/ethereum/go-ethereum/common"
26
29
"github.com/ethereum/go-ethereum/crypto"
27
- "github.com/ethereum/go-ethereum/log"
28
30
"github.com/urfave/cli/v2"
29
31
)
30
32
@@ -191,7 +193,7 @@ nodes.
191
193
// makeAccountManager creates an account manager with backends
192
194
func makeAccountManager (ctx * cli.Context ) * accounts.Manager {
193
195
cfg := loadBaseConfig (ctx )
194
- am := accounts .NewManager (& accounts. Config { InsecureUnlockAllowed : cfg . Node . InsecureUnlockAllowed } )
196
+ am := accounts .NewManager (nil )
195
197
keydir , isEphemeral , err := cfg .Node .GetKeyStoreDir ()
196
198
if err != nil {
197
199
utils .Fatalf ("Failed to get the keystore directory: %v" , err )
@@ -219,60 +221,22 @@ func accountList(ctx *cli.Context) error {
219
221
return nil
220
222
}
221
223
222
- // tries unlocking the specified account a few times.
223
- func unlockAccount (ks * keystore.KeyStore , address string , i int , passwords []string ) (accounts.Account , string ) {
224
- account , err := utils .MakeAddress (ks , address )
225
- if err != nil {
226
- utils .Fatalf ("Could not list accounts: %v" , err )
227
- }
228
- for trials := 0 ; trials < 3 ; trials ++ {
229
- prompt := fmt .Sprintf ("Unlocking account %s | Attempt %d/%d" , address , trials + 1 , 3 )
230
- password := utils .GetPassPhraseWithList (prompt , false , i , passwords )
231
- err = ks .Unlock (account , password )
232
- if err == nil {
233
- log .Info ("Unlocked account" , "address" , account .Address .Hex ())
234
- return account , password
235
- }
236
- if err , ok := err .(* keystore.AmbiguousAddrError ); ok {
237
- log .Info ("Unlocked account" , "address" , account .Address .Hex ())
238
- return ambiguousAddrRecovery (ks , err , password ), password
239
- }
240
- if err != keystore .ErrDecrypt {
241
- // No need to prompt again if the error is not decryption-related.
242
- break
243
- }
244
- }
245
- // All trials expended to unlock account, bail out
246
- utils .Fatalf ("Failed to unlock account %s (%v)" , address , err )
247
-
248
- return accounts.Account {}, ""
249
- }
250
-
251
- func ambiguousAddrRecovery (ks * keystore.KeyStore , err * keystore.AmbiguousAddrError , auth string ) accounts.Account {
252
- fmt .Printf ("Multiple key files exist for address %x:\n " , err .Addr )
253
- for _ , a := range err .Matches {
254
- fmt .Println (" " , a .URL )
255
- }
256
- fmt .Println ("Testing your password against all of them..." )
257
- var match * accounts.Account
258
- for i , a := range err .Matches {
259
- if e := ks .Unlock (a , auth ); e == nil {
260
- match = & err .Matches [i ]
261
- break
262
- }
224
+ // readPasswordFromFile reads the first line of the given file, trims line endings,
225
+ // and returns the password and whether the reading was successful.
226
+ func readPasswordFromFile (path string ) (string , bool ) {
227
+ if path == "" {
228
+ return "" , false
263
229
}
264
- if match == nil {
265
- utils . Fatalf ( "None of the listed files could be unlocked." )
266
- return accounts. Account {}
230
+ text , err := os . ReadFile ( path )
231
+ if err != nil {
232
+ utils . Fatalf ( "Failed to read password file: %v" , err )
267
233
}
268
- fmt .Printf ("Your password unlocked %s\n " , match .URL )
269
- fmt .Println ("In order to avoid this warning, you need to remove the following duplicate key files:" )
270
- for _ , a := range err .Matches {
271
- if a != * match {
272
- fmt .Println (" " , a .URL )
273
- }
234
+ lines := strings .Split (string (text ), "\n " )
235
+ if len (lines ) == 0 {
236
+ return "" , false
274
237
}
275
- return * match
238
+ // Sanitise DOS line endings.
239
+ return strings .TrimRight (lines [0 ], "\r " ), true
276
240
}
277
241
278
242
// accountCreate creates a new account into the keystore defined by the CLI flags.
@@ -292,8 +256,10 @@ func accountCreate(ctx *cli.Context) error {
292
256
scryptP = keystore .LightScryptP
293
257
}
294
258
295
- password := utils .GetPassPhraseWithList ("Your new account is locked with a password. Please give a password. Do not forget this password." , true , 0 , utils .MakePasswordList (ctx ))
296
-
259
+ password , ok := readPasswordFromFile (ctx .Path (utils .PasswordFileFlag .Name ))
260
+ if ! ok {
261
+ password = utils .GetPassPhrase ("Your new account is locked with a password. Please give a password. Do not forget this password." , true )
262
+ }
297
263
account , err := keystore .StoreKey (keydir , password , scryptN , scryptP )
298
264
299
265
if err != nil {
@@ -323,10 +289,23 @@ func accountUpdate(ctx *cli.Context) error {
323
289
ks := backends [0 ].(* keystore.KeyStore )
324
290
325
291
for _ , addr := range ctx .Args ().Slice () {
326
- account , oldPassword := unlockAccount (ks , addr , 0 , nil )
327
- newPassword := utils .GetPassPhraseWithList ("Please give a new password. Do not forget this password." , true , 0 , nil )
328
- if err := ks .Update (account , oldPassword , newPassword ); err != nil {
329
- utils .Fatalf ("Could not update the account: %v" , err )
292
+ if ! common .IsHexAddress (addr ) {
293
+ return errors .New ("address must be specified in hexadecimal form" )
294
+ }
295
+ account := accounts.Account {Address : common .HexToAddress (addr )}
296
+ newPassword := utils .GetPassPhrase ("Please give a NEW password. Do not forget this password." , true )
297
+ updateFn := func (attempt int ) error {
298
+ prompt := fmt .Sprintf ("Please provide the OLD password for account %s | Attempt %d/%d" , addr , attempt + 1 , 3 )
299
+ password := utils .GetPassPhrase (prompt , false )
300
+ return ks .Update (account , password , newPassword )
301
+ }
302
+ // let user attempt unlock thrice.
303
+ err := updateFn (0 )
304
+ for attempts := 1 ; attempts < 3 && errors .Is (err , keystore .ErrDecrypt ); attempts ++ {
305
+ err = updateFn (attempts )
306
+ }
307
+ if err != nil {
308
+ return fmt .Errorf ("could not update account: %w" , err )
330
309
}
331
310
}
332
311
return nil
@@ -347,10 +326,12 @@ func importWallet(ctx *cli.Context) error {
347
326
if len (backends ) == 0 {
348
327
utils .Fatalf ("Keystore is not available" )
349
328
}
329
+ password , ok := readPasswordFromFile (ctx .Path (utils .PasswordFileFlag .Name ))
330
+ if ! ok {
331
+ password = utils .GetPassPhrase ("" , false )
332
+ }
350
333
ks := backends [0 ].(* keystore.KeyStore )
351
- passphrase := utils .GetPassPhraseWithList ("" , false , 0 , utils .MakePasswordList (ctx ))
352
-
353
- acct , err := ks .ImportPreSaleKey (keyJSON , passphrase )
334
+ acct , err := ks .ImportPreSaleKey (keyJSON , password )
354
335
if err != nil {
355
336
utils .Fatalf ("%v" , err )
356
337
}
@@ -373,9 +354,11 @@ func accountImport(ctx *cli.Context) error {
373
354
utils .Fatalf ("Keystore is not available" )
374
355
}
375
356
ks := backends [0 ].(* keystore.KeyStore )
376
- passphrase := utils .GetPassPhraseWithList ("Your new account is locked with a password. Please give a password. Do not forget this password." , true , 0 , utils .MakePasswordList (ctx ))
377
-
378
- acct , err := ks .ImportECDSA (key , passphrase )
357
+ password , ok := readPasswordFromFile (ctx .Path (utils .PasswordFileFlag .Name ))
358
+ if ! ok {
359
+ password = utils .GetPassPhrase ("Your new account is locked with a password. Please give a password. Do not forget this password." , true )
360
+ }
361
+ acct , err := ks .ImportECDSA (key , password )
379
362
if err != nil {
380
363
utils .Fatalf ("Could not create the account: %v" , err )
381
364
}
0 commit comments