github.com/core-coin/go-core/v2@v2.1.9/cmd/xcbkey/generate.go (about) 1 // Copyright 2017 by the Authors 2 // This file is part of go-core. 3 // 4 // go-core 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-core 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-core. If not, see <http://www.gnu.org/licenses/>. 16 17 package main 18 19 import ( 20 crand "crypto/rand" 21 "fmt" 22 "io/ioutil" 23 "os" 24 "path/filepath" 25 26 "github.com/pborman/uuid" 27 "gopkg.in/urfave/cli.v1" 28 29 "github.com/core-coin/go-core/v2/accounts/keystore" 30 "github.com/core-coin/go-core/v2/cmd/utils" 31 "github.com/core-coin/go-core/v2/common" 32 "github.com/core-coin/go-core/v2/crypto" 33 ) 34 35 type outputGenerate struct { 36 Address string 37 AddressCIP55 string 38 } 39 40 var commandGenerate = cli.Command{ 41 Name: "generate", 42 Usage: "generate new keyfile", 43 ArgsUsage: "[ <keyfile> ]", 44 Description: ` 45 Generate a new keyfile. 46 47 If you want to encrypt an existing private key, it can be specified by setting 48 --privatekey with the location of the file containing the private key. 49 `, 50 Flags: []cli.Flag{ 51 passphraseFlag, 52 jsonFlag, 53 cli.StringFlag{ 54 Name: "privatekey", 55 Usage: "file containing a raw private key to encrypt", 56 }, 57 cli.BoolFlag{ 58 Name: "lightkdf", 59 Usage: "use less secure scrypt parameters", 60 }, 61 utils.NetworkIdFlag, 62 }, 63 Action: func(ctx *cli.Context) error { 64 if ctx.IsSet(utils.NetworkIdFlag.Name) { 65 common.DefaultNetworkID = common.NetworkID(ctx.Uint64(utils.NetworkIdFlag.Name)) 66 } 67 68 // Check if keyfile path given and make sure it doesn't already exist. 69 keyfilepath := ctx.Args().First() 70 if keyfilepath == "" { 71 keyfilepath = defaultKeyfileName 72 } 73 if _, err := os.Stat(keyfilepath); err == nil { 74 utils.Fatalf("Keyfile already exists at %s.", keyfilepath) 75 } else if !os.IsNotExist(err) { 76 utils.Fatalf("Error checking if keyfile exists: %v", err) 77 } 78 79 var privateKey *crypto.PrivateKey 80 var err error 81 if file := ctx.String("privatekey"); file != "" { 82 // Load private key from file. 83 privateKey, err = crypto.LoadEDDSA(file) 84 if err != nil { 85 utils.Fatalf("Can't load private key: %v", err) 86 } 87 } else { 88 // If not loaded, generate random. 89 privateKey, err = crypto.GenerateKey(crand.Reader) 90 if err != nil { 91 utils.Fatalf("Failed to generate random private key: %v", err) 92 } 93 } 94 95 // Create the keyfile object with a random UUID. 96 id := uuid.NewRandom() 97 key := &keystore.Key{ 98 Id: id, 99 Address: privateKey.Address(), 100 PrivateKey: privateKey, 101 } 102 103 // Encrypt key with passphrase. 104 passphrase := getPassphrase(ctx, true) 105 scryptN, scryptP := keystore.StandardScryptN, keystore.StandardScryptP 106 if ctx.Bool("lightkdf") { 107 scryptN, scryptP = keystore.LightScryptN, keystore.LightScryptP 108 } 109 keyjson, err := keystore.EncryptKey(key, passphrase, scryptN, scryptP) 110 if err != nil { 111 utils.Fatalf("Error encrypting key: %v", err) 112 } 113 114 // Store the file to disk. 115 if err := os.MkdirAll(filepath.Dir(keyfilepath), 0700); err != nil { 116 utils.Fatalf("Could not create directory %s", filepath.Dir(keyfilepath)) 117 } 118 if err := ioutil.WriteFile(keyfilepath, keyjson, 0600); err != nil { 119 utils.Fatalf("Failed to write keyfile to %s: %v", keyfilepath, err) 120 } 121 122 // Output some information. 123 out := outputGenerate{ 124 Address: key.Address.Hex(), 125 } 126 if ctx.Bool(jsonFlag.Name) { 127 mustPrintJSON(out) 128 } else { 129 fmt.Println("Address:", out.Address) 130 } 131 return nil 132 }, 133 }