github.com/luckypickle/go-ethereum-vet@v1.14.2/cmd/ethkey/generate.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of go-ethereum. 3 // 4 // go-ethereum is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // go-ethereum is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. 16 17 package main 18 19 import ( 20 "crypto/ecdsa" 21 "fmt" 22 "io/ioutil" 23 "os" 24 "path/filepath" 25 26 "github.com/luckypickle/go-ethereum-vet/accounts/keystore" 27 "github.com/luckypickle/go-ethereum-vet/cmd/utils" 28 "github.com/luckypickle/go-ethereum-vet/crypto" 29 "github.com/pborman/uuid" 30 "gopkg.in/urfave/cli.v1" 31 ) 32 33 type outputGenerate struct { 34 Address string 35 AddressEIP55 string 36 } 37 38 var commandGenerate = cli.Command{ 39 Name: "generate", 40 Usage: "generate new keyfile", 41 ArgsUsage: "[ <keyfile> ]", 42 Description: ` 43 Generate a new keyfile. 44 45 If you want to encrypt an existing private key, it can be specified by setting 46 --privatekey with the location of the file containing the private key. 47 `, 48 Flags: []cli.Flag{ 49 passphraseFlag, 50 jsonFlag, 51 cli.StringFlag{ 52 Name: "privatekey", 53 Usage: "file containing a raw private key to encrypt", 54 }, 55 }, 56 Action: func(ctx *cli.Context) error { 57 // Check if keyfile path given and make sure it doesn't already exist. 58 keyfilepath := ctx.Args().First() 59 if keyfilepath == "" { 60 keyfilepath = defaultKeyfileName 61 } 62 if _, err := os.Stat(keyfilepath); err == nil { 63 utils.Fatalf("Keyfile already exists at %s.", keyfilepath) 64 } else if !os.IsNotExist(err) { 65 utils.Fatalf("Error checking if keyfile exists: %v", err) 66 } 67 68 var privateKey *ecdsa.PrivateKey 69 var err error 70 if file := ctx.String("privatekey"); file != "" { 71 // Load private key from file. 72 privateKey, err = crypto.LoadECDSA(file) 73 if err != nil { 74 utils.Fatalf("Can't load private key: %v", err) 75 } 76 } else { 77 // If not loaded, generate random. 78 privateKey, err = crypto.GenerateKey() 79 if err != nil { 80 utils.Fatalf("Failed to generate random private key: %v", err) 81 } 82 } 83 84 // Create the keyfile object with a random UUID. 85 id := uuid.NewRandom() 86 key := &keystore.Key{ 87 Id: id, 88 Address: crypto.PubkeyToAddress(privateKey.PublicKey), 89 PrivateKey: privateKey, 90 } 91 92 // Encrypt key with passphrase. 93 passphrase := promptPassphrase(true) 94 keyjson, err := keystore.EncryptKey(key, passphrase, keystore.StandardScryptN, keystore.StandardScryptP) 95 if err != nil { 96 utils.Fatalf("Error encrypting key: %v", err) 97 } 98 99 // Store the file to disk. 100 if err := os.MkdirAll(filepath.Dir(keyfilepath), 0700); err != nil { 101 utils.Fatalf("Could not create directory %s", filepath.Dir(keyfilepath)) 102 } 103 if err := ioutil.WriteFile(keyfilepath, keyjson, 0600); err != nil { 104 utils.Fatalf("Failed to write keyfile to %s: %v", keyfilepath, err) 105 } 106 107 // Output some information. 108 out := outputGenerate{ 109 Address: key.Address.Hex(), 110 } 111 if ctx.Bool(jsonFlag.Name) { 112 mustPrintJSON(out) 113 } else { 114 fmt.Println("Address:", out.Address) 115 } 116 return nil 117 }, 118 }