github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/cmd/u2u/launcher/validatorcmd.go (about) 1 package launcher 2 3 import ( 4 "crypto/ecdsa" 5 "crypto/rand" 6 "fmt" 7 "path" 8 "strings" 9 10 "gopkg.in/urfave/cli.v1" 11 12 "github.com/unicornultrafoundation/go-u2u/cmd/utils" 13 "github.com/unicornultrafoundation/go-u2u/common" 14 "github.com/unicornultrafoundation/go-u2u/crypto" 15 "github.com/unicornultrafoundation/go-u2u/native/validatorpk" 16 "github.com/unicornultrafoundation/go-u2u/valkeystore" 17 "github.com/unicornultrafoundation/go-u2u/valkeystore/encryption" 18 ) 19 20 var ( 21 validatorCommand = cli.Command{ 22 Name: "validator", 23 Usage: "Manage validators", 24 Category: "VALIDATOR COMMANDS", 25 Description: ` 26 27 Create a new validator private key. 28 29 It supports interactive mode, when you are prompted for password as well as 30 non-interactive mode where passwords are supplied via a given password file. 31 Non-interactive mode is only meant for scripted use on test networks or known 32 safe environments. 33 34 Make sure you remember the password you gave when creating a new validator key. 35 Without it you are not able to unlock your validator key. 36 37 Note that exporting your key in unencrypted format is NOT supported. 38 39 Keys are stored under <DATADIR>/keystore/validator. 40 It is safe to transfer the entire directory or the individual keys therein 41 between u2u nodes by simply copying. 42 43 Make sure you backup your keys regularly.`, 44 Subcommands: []cli.Command{ 45 { 46 Name: "new", 47 Usage: "Create a new validator key", 48 Action: utils.MigrateFlags(validatorKeyCreate), 49 Flags: []cli.Flag{ 50 DataDirFlag, 51 utils.KeyStoreDirFlag, 52 utils.PasswordFileFlag, 53 }, 54 Description: ` 55 u2u validator new 56 57 Creates a new validator private key and prints the public key. 58 59 The key is saved in encrypted format, you are prompted for a passphrase. 60 61 You must remember this passphrase to unlock your key in the future. 62 63 For non-interactive use the passphrase can be specified with the --validator.password flag: 64 65 Note, this is meant to be used for testing only, it is a bad idea to save your 66 password to file or expose in any other way. 67 `, 68 }, 69 { 70 Name: "convert", 71 Usage: "Convert an account key to a validator key", 72 Action: utils.MigrateFlags(validatorKeyConvert), 73 Flags: []cli.Flag{ 74 DataDirFlag, 75 utils.KeyStoreDirFlag, 76 }, 77 ArgsUsage: "<account address> <validator pubkey>", 78 Description: ` 79 u2u validator convert 80 81 Converts an account private key to a validator private key and saves in the validator keystore. 82 `, 83 }, 84 }, 85 } 86 ) 87 88 // validatorKeyCreate creates a new validator key into the keystore defined by the CLI flags. 89 func validatorKeyCreate(ctx *cli.Context) error { 90 cfg := makeAllConfigs(ctx) 91 utils.SetNodeConfig(ctx, &cfg.Node) 92 93 password := getPassPhrase("Your new validator key is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx)) 94 95 privateKeyECDSA, err := ecdsa.GenerateKey(crypto.S256(), rand.Reader) 96 if err != nil { 97 utils.Fatalf("Failed to create account: %v", err) 98 } 99 privateKey := crypto.FromECDSA(privateKeyECDSA) 100 publicKey := validatorpk.PubKey{ 101 Raw: crypto.FromECDSAPub(&privateKeyECDSA.PublicKey), 102 Type: validatorpk.Types.Secp256k1, 103 } 104 105 valKeystore := valkeystore.NewDefaultFileRawKeystore(path.Join(getValKeystoreDir(cfg.Node), "validator")) 106 err = valKeystore.Add(publicKey, privateKey, password) 107 if err != nil { 108 utils.Fatalf("Failed to create account: %v", err) 109 } 110 111 // Sanity check 112 _, err = valKeystore.Get(publicKey, password) 113 if err != nil { 114 utils.Fatalf("Failed to decrypt the account: %v", err) 115 } 116 117 fmt.Printf("\nYour new key was generated\n\n") 118 fmt.Printf("Public key: %s\n", publicKey.String()) 119 fmt.Printf("Path of the secret key file: %s\n\n", valKeystore.PathOf(publicKey)) 120 fmt.Printf("- You can share your public key with anyone. Others need it to validate messages from you.\n") 121 fmt.Printf("- You must NEVER share the secret key with anyone! The key controls access to your validator!\n") 122 fmt.Printf("- You must BACKUP your key file! Without the key, it's impossible to operate the validator!\n") 123 fmt.Printf("- You must REMEMBER your password! Without the password, it's impossible to decrypt the key!\n\n") 124 return nil 125 } 126 127 // validatorKeyConvert converts account key to validator key. 128 func validatorKeyConvert(ctx *cli.Context) error { 129 if len(ctx.Args()) < 2 { 130 utils.Fatalf("This command requires 2 arguments.") 131 } 132 cfg := makeAllConfigs(ctx) 133 utils.SetNodeConfig(ctx, &cfg.Node) 134 135 _, _, keydir, _ := cfg.Node.AccountConfig() 136 137 pubkeyStr := ctx.Args().Get(1) 138 pubkey, err := validatorpk.FromString(pubkeyStr) 139 if err != nil { 140 utils.Fatalf("Failed to decode the validator pubkey: %v", err) 141 } 142 143 var acckeypath string 144 if strings.HasPrefix(ctx.Args().First(), "0x") { 145 acckeypath, err = FindAccountKeypath(common.HexToAddress(ctx.Args().First()), keydir) 146 if err != nil { 147 utils.Fatalf("Failed to find the account: %v", err) 148 } 149 } else { 150 acckeypath = ctx.Args().First() 151 } 152 153 valkeypath := path.Join(keydir, "validator", common.Bytes2Hex(pubkey.Bytes())) 154 err = encryption.MigrateAccountToValidatorKey(acckeypath, valkeypath, pubkey) 155 if err != nil { 156 utils.Fatalf("Failed to migrate the account key: %v", err) 157 } 158 fmt.Println("\nYour key was converted and saved to " + valkeypath) 159 return nil 160 }