func main() { // Ensure seed hex was specified. if len(os.Args) < 2 { appName := filepath.Base(os.Args[0]) appName = strings.TrimSuffix(appName, filepath.Ext(appName)) fmt.Fprintf(os.Stderr, "Seed hex argument not specified\n\n") fmt.Fprintln(os.Stderr, "Usage:") fmt.Fprintf(os.Stderr, " %s <seedhex>\n", appName) os.Exit(1) } // Ensure the hex is the appropriate length for a 256-bit seed. seedStr := strings.TrimSpace(os.Args[1]) if len(seedStr) != 64 { fmt.Println("The specified seed must have a length of 64 characters") os.Exit(1) } // Decode hex to bytes. seedBytes, err := hex.DecodeString(seedStr) if err != nil { fmt.Println("Specified seed hex is not valid. It must only " + "contain numbers and letters in the range [a-f]") os.Exit(1) } // Convert bytes to seed words with checksum. seedWords, err := pgpwordlist.ToStringChecksum(seedBytes) if err != nil { fmt.Printf("Unable to encode seed bytes: %v", err) os.Exit(1) } fmt.Println(seedWords) }
// createSimulationWallet is intended to be called from the rpcclient // and used to create a wallet for actors involved in simulations. func createSimulationWallet(cfg *config) error { // Simulation wallet password is 'password'. privPass := wallet.SimulationPassphrase // Public passphrase is the default. pubPass := []byte(wallet.InsecurePubPassphrase) // Generate a random seed. seed, err := hdkeychain.GenerateSeed(hdkeychain.RecommendedSeedLen) if err != nil { return err } netDir := networkDir(cfg.AppDataDir, activeNet.Params) // Write the seed to disk, so that we can restore it later // if need be, for testing purposes. seedStr, err := pgpwordlist.ToStringChecksum(seed) if err != nil { return err } err = ioutil.WriteFile(filepath.Join(netDir, "seed"), []byte(seedStr), 0644) if err != nil { return err } // Create the wallet. dbPath := filepath.Join(netDir, walletDbName) fmt.Println("Creating the wallet...") // Create the wallet database backed by bolt db. db, err := walletdb.Create("bdb", dbPath) if err != nil { return err } defer db.Close() // Create the wallet. err = wallet.Create(db, pubPass, privPass, seed, activeNet.Params, cfg.UnsafeMainNet) if err != nil { return err } fmt.Println("The wallet has been created successfully.") return nil }
// Seed prompts the user whether they want to use an existing wallet generation // seed. When the user answers no, a seed will be generated and displayed to // the user along with prompting them for confirmation. When the user answers // yes, a the user is prompted for it. All prompts are repeated until the user // enters a valid response. The bool returned indicates if the wallet was // restored from a given seed or not. func Seed(reader *bufio.Reader) ([]byte, error) { // Ascertain the wallet generation seed. useUserSeed, err := promptListBool(reader, "Do you have an "+ "existing wallet seed you want to use?", "no") if err != nil { return nil, err } if !useUserSeed { seed, err := hdkeychain.GenerateSeed(hdkeychain.RecommendedSeedLen) if err != nil { return nil, err } seedStr, err := pgpwordlist.ToStringChecksum(seed) if err != nil { return nil, err } seedStrSplit := strings.Split(seedStr, " ") fmt.Println("Your wallet generation seed is:") for i := 0; i < hdkeychain.RecommendedSeedLen+1; i++ { fmt.Printf("%v ", seedStrSplit[i]) if (i+1)%6 == 0 { fmt.Printf("\n") } } fmt.Printf("\n\nHex: %x\n", seed) fmt.Println("IMPORTANT: Keep the seed in a safe place as you\n" + "will NOT be able to restore your wallet without it.") fmt.Println("Please keep in mind that anyone who has access\n" + "to the seed can also restore your wallet thereby\n" + "giving them access to all your funds, so it is\n" + "imperative that you keep it in a secure location.") for { fmt.Print(`Once you have stored the seed in a safe ` + `and secure location, enter "OK" to continue: `) confirmSeed, err := reader.ReadString('\n') if err != nil { return nil, err } confirmSeed = strings.TrimSpace(confirmSeed) confirmSeed = strings.Trim(confirmSeed, `"`) if confirmSeed == "OK" { break } } return seed, nil } for { fmt.Print("Enter existing wallet seed " + "(followed by a blank line): ") // Use scanner instead of buffio.Reader so we can choose choose // more complicated ending condition rather than just a single // newline. var seedStr string scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { line := scanner.Text() if line == "" { break } seedStr += " " + line } seedStrTrimmed := strings.TrimSpace(seedStr) seedStrTrimmed = collapseSpace(seedStrTrimmed) wordCount := strings.Count(seedStrTrimmed, " ") + 1 var seed []byte if wordCount == 1 { if len(seedStrTrimmed)%2 != 0 { seedStrTrimmed = "0" + seedStrTrimmed } seed, err = hex.DecodeString(seedStrTrimmed) if err != nil { fmt.Printf("Input error: %v\n", err.Error()) } } else { seed, err = pgpwordlist.ToBytesChecksum(seedStrTrimmed) if err != nil { fmt.Printf("Input error: %v\n", err.Error()) } } if err != nil || len(seed) < hdkeychain.MinSeedBytes || len(seed) > hdkeychain.MaxSeedBytes { fmt.Printf("Invalid seed specified. Must be a "+ "word seed (usually 33 words) using the PGP wordlist or "+ "hexadecimal value that is at least %d bits and "+ "at most %d bits\n", hdkeychain.MinSeedBytes*8, hdkeychain.MaxSeedBytes*8) continue } fmt.Printf("\nSeed input successful. \nHex: %x\n", seed) return seed, nil } }
// createSimulationWallet is intended to be called from the rpcclient // and used to create a wallet for actors involved in simulations. func createSimulationWallet(cfg *config) error { // Simulation wallet password is 'password'. privPass := []byte("password") // Public passphrase is the default. pubPass := []byte(defaultPubPassphrase) // Generate a random seed. seed, err := hdkeychain.GenerateSeed(hdkeychain.RecommendedSeedLen) if err != nil { return err } netDir := networkDir(cfg.DataDir, activeNet.Params) // Write the seed to disk, so that we can restore it later // if need be, for testing purposes. seedStr, err := pgpwordlist.ToStringChecksum(seed) if err != nil { return err } err = ioutil.WriteFile(filepath.Join(netDir, "seed"), []byte(seedStr), 0644) if err != nil { return err } // Create the wallet. dbPath := filepath.Join(netDir, walletDbName) fmt.Println("Creating the wallet...") // Create the wallet database backed by bolt db. db, err := walletdb.Create("bdb", dbPath) if err != nil { return err } defer db.Close() // Create the address manager. waddrmgrNamespace, err := db.Namespace(waddrmgrNamespaceKey) if err != nil { return err } manager, err := waddrmgr.Create(waddrmgrNamespace, seed, []byte(pubPass), []byte(privPass), activeNet.Params, nil) if err != nil { return err } defer manager.Close() // Create the stake manager/store. wstakemgrNamespace, err := db.Namespace(wstakemgrNamespaceKey) if err != nil { return err } stakeStore, err := wstakemgr.Create(wstakemgrNamespace, manager, activeNet.Params) if err != nil { return err } defer stakeStore.Close() fmt.Println("The wallet has been created successfully.") return nil }