github.com/kivutar/go-ethereum@v1.7.4-0.20180117074026-6fdb126e9630/cmd/ethkey/generate.go (about) 1 package main 2 3 import ( 4 "crypto/ecdsa" 5 "crypto/rand" 6 "fmt" 7 "io/ioutil" 8 "os" 9 "path/filepath" 10 11 "github.com/ethereum/go-ethereum/accounts/keystore" 12 "github.com/ethereum/go-ethereum/cmd/utils" 13 "github.com/ethereum/go-ethereum/crypto" 14 "github.com/pborman/uuid" 15 "gopkg.in/urfave/cli.v1" 16 ) 17 18 type outputGenerate struct { 19 Address string 20 AddressEIP55 string 21 } 22 23 var commandGenerate = cli.Command{ 24 Name: "generate", 25 Usage: "generate new keyfile", 26 ArgsUsage: "[ <keyfile> ]", 27 Description: ` 28 Generate a new keyfile. 29 If you want to use an existing private key to use in the keyfile, it can be 30 specified by setting --privatekey with the location of the file containing the 31 private key.`, 32 Flags: []cli.Flag{ 33 passphraseFlag, 34 jsonFlag, 35 cli.StringFlag{ 36 Name: "privatekey", 37 Usage: "the file from where to read the private key to " + 38 "generate a keyfile for", 39 }, 40 }, 41 Action: func(ctx *cli.Context) error { 42 // Check if keyfile path given and make sure it doesn't already exist. 43 keyfilepath := ctx.Args().First() 44 if keyfilepath == "" { 45 keyfilepath = defaultKeyfileName 46 } 47 if _, err := os.Stat(keyfilepath); err == nil { 48 utils.Fatalf("Keyfile already exists at %s.", keyfilepath) 49 } else if !os.IsNotExist(err) { 50 utils.Fatalf("Error checking if keyfile exists: %v", err) 51 } 52 53 var privateKey *ecdsa.PrivateKey 54 55 // First check if a private key file is provided. 56 privateKeyFile := ctx.String("privatekey") 57 if privateKeyFile != "" { 58 privateKeyBytes, err := ioutil.ReadFile(privateKeyFile) 59 if err != nil { 60 utils.Fatalf("Failed to read the private key file '%s': %v", 61 privateKeyFile, err) 62 } 63 64 pk, err := crypto.HexToECDSA(string(privateKeyBytes)) 65 if err != nil { 66 utils.Fatalf( 67 "Could not construct ECDSA private key from file content: %v", 68 err) 69 } 70 privateKey = pk 71 } 72 73 // If not loaded, generate random. 74 if privateKey == nil { 75 pk, err := ecdsa.GenerateKey(crypto.S256(), rand.Reader) 76 if err != nil { 77 utils.Fatalf("Failed to generate random private key: %v", err) 78 } 79 privateKey = pk 80 } 81 82 // Create the keyfile object with a random UUID. 83 id := uuid.NewRandom() 84 key := &keystore.Key{ 85 Id: id, 86 Address: crypto.PubkeyToAddress(privateKey.PublicKey), 87 PrivateKey: privateKey, 88 } 89 90 // Encrypt key with passphrase. 91 passphrase := getPassPhrase(ctx, true) 92 keyjson, err := keystore.EncryptKey(key, passphrase, 93 keystore.StandardScryptN, keystore.StandardScryptP) 94 if err != nil { 95 utils.Fatalf("Error encrypting key: %v", err) 96 } 97 98 // Store the file to disk. 99 if err := os.MkdirAll(filepath.Dir(keyfilepath), 0700); err != nil { 100 utils.Fatalf("Could not create directory %s", filepath.Dir(keyfilepath)) 101 } 102 if err := ioutil.WriteFile(keyfilepath, keyjson, 0600); err != nil { 103 utils.Fatalf("Failed to write keyfile to %s: %v", keyfilepath, err) 104 } 105 106 // Output some information. 107 out := outputGenerate{ 108 Address: key.Address.Hex(), 109 } 110 if ctx.Bool(jsonFlag.Name) { 111 mustPrintJSON(out) 112 } else { 113 fmt.Println("Address: ", out.Address) 114 } 115 return nil 116 }, 117 }