Wallet creation: Make mnemonic length configurable, default to 24 words. (#1697)
## Issue Addressed Fixes #1665. ## Proposed Changes `lighthouse account_manager wallet create` now generates a 24-word mnemonic. The user can override this by passing `--mnemonic-length 12` (or another legal bip39 length). ## Additional Info CLI `--help`: ``` --mnemonic-length <MNEMONIC_LENGTH> The number of words to use for the mnemonic phrase. [default: 24] ``` In case of an invalid argument: ``` % lighthouse account_manager wallet create --mnemonic-length 25 error: Invalid value for '--mnemonic-length <MNEMONIC_LENGTH>': Mnemonic length must be one of 12, 15, 18, 21, 24 ```
This commit is contained in:
parent
b56dbc3ba0
commit
2cc20101d4
@ -23,6 +23,14 @@ pub const PASSWORD_FLAG: &str = "password-file";
|
|||||||
pub const TYPE_FLAG: &str = "type";
|
pub const TYPE_FLAG: &str = "type";
|
||||||
pub const MNEMONIC_FLAG: &str = "mnemonic-output-path";
|
pub const MNEMONIC_FLAG: &str = "mnemonic-output-path";
|
||||||
pub const STDIN_INPUTS_FLAG: &str = "stdin-inputs";
|
pub const STDIN_INPUTS_FLAG: &str = "stdin-inputs";
|
||||||
|
pub const MNEMONIC_LENGTH_FLAG: &str = "mnemonic-length";
|
||||||
|
pub const MNEMONIC_TYPES: &[MnemonicType] = &[
|
||||||
|
MnemonicType::Words12,
|
||||||
|
MnemonicType::Words15,
|
||||||
|
MnemonicType::Words18,
|
||||||
|
MnemonicType::Words21,
|
||||||
|
MnemonicType::Words24,
|
||||||
|
];
|
||||||
pub const NEW_WALLET_PASSWORD_PROMPT: &str =
|
pub const NEW_WALLET_PASSWORD_PROMPT: &str =
|
||||||
"Enter a password for your new wallet that is at least 12 characters long:";
|
"Enter a password for your new wallet that is at least 12 characters long:";
|
||||||
pub const RETYPE_PASSWORD_PROMPT: &str = "Please re-enter your wallet's new password:";
|
pub const RETYPE_PASSWORD_PROMPT: &str = "Please re-enter your wallet's new password:";
|
||||||
@ -78,6 +86,20 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
.long(STDIN_INPUTS_FLAG)
|
.long(STDIN_INPUTS_FLAG)
|
||||||
.help("If present, read all user inputs from stdin instead of tty."),
|
.help("If present, read all user inputs from stdin instead of tty."),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name(MNEMONIC_LENGTH_FLAG)
|
||||||
|
.long(MNEMONIC_LENGTH_FLAG)
|
||||||
|
.value_name("MNEMONIC_LENGTH")
|
||||||
|
.help("The number of words to use for the mnemonic phrase.")
|
||||||
|
.takes_value(true)
|
||||||
|
.validator(|len| {
|
||||||
|
match len.parse::<usize>().ok().and_then(|words| MnemonicType::for_word_count(words).ok()) {
|
||||||
|
Some(_) => Ok(()),
|
||||||
|
None => Err(format!("Mnemonic length must be one of {}", MNEMONIC_TYPES.iter().map(|t| t.word_count().to_string()).collect::<Vec<_>>().join(", "))),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.default_value("24"),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cli_run(matches: &ArgMatches, base_dir: PathBuf) -> Result<(), String> {
|
pub fn cli_run(matches: &ArgMatches, base_dir: PathBuf) -> Result<(), String> {
|
||||||
@ -86,7 +108,11 @@ pub fn cli_run(matches: &ArgMatches, base_dir: PathBuf) -> Result<(), String> {
|
|||||||
// Create a new random mnemonic.
|
// Create a new random mnemonic.
|
||||||
//
|
//
|
||||||
// The `tiny-bip39` crate uses `thread_rng()` for this entropy.
|
// The `tiny-bip39` crate uses `thread_rng()` for this entropy.
|
||||||
let mnemonic = Mnemonic::new(MnemonicType::Words12, Language::English);
|
let mnemonic_length = clap_utils::parse_required(matches, MNEMONIC_LENGTH_FLAG)?;
|
||||||
|
let mnemonic = Mnemonic::new(
|
||||||
|
MnemonicType::for_word_count(mnemonic_length).expect("Mnemonic length already validated"),
|
||||||
|
Language::English,
|
||||||
|
);
|
||||||
|
|
||||||
let wallet = create_wallet_from_mnemonic(matches, &base_dir.as_path(), &mnemonic)?;
|
let wallet = create_wallet_from_mnemonic(matches, &base_dir.as_path(), &mnemonic)?;
|
||||||
|
|
||||||
@ -95,7 +121,7 @@ pub fn cli_run(matches: &ArgMatches, base_dir: PathBuf) -> Result<(), String> {
|
|||||||
.map_err(|e| format!("Unable to write mnemonic to {:?}: {:?}", path, e))?;
|
.map_err(|e| format!("Unable to write mnemonic to {:?}: {:?}", path, e))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Your wallet's 12-word BIP-39 mnemonic is:");
|
println!("Your wallet's {}-word BIP-39 mnemonic is:", mnemonic_length);
|
||||||
println!();
|
println!();
|
||||||
println!("\t{}", mnemonic.phrase());
|
println!("\t{}", mnemonic.phrase());
|
||||||
println!();
|
println!();
|
||||||
|
@ -97,9 +97,9 @@ lighthouse --testnet medalla account wallet create
|
|||||||
You will be prompted for a wallet name and a password. The output will look like this:
|
You will be prompted for a wallet name and a password. The output will look like this:
|
||||||
|
|
||||||
```
|
```
|
||||||
Your wallet's 12-word BIP-39 mnemonic is:
|
Your wallet's 24-word BIP-39 mnemonic is:
|
||||||
|
|
||||||
thank beach essence clerk gun library key grape hotel wise dutch segment
|
glad marble art pelican nurse large guilt response brave affair kite essence welcome gauge peace once picnic debris devote ticket blood bike solar junk
|
||||||
|
|
||||||
This mnemonic can be used to fully restore your wallet, should
|
This mnemonic can be used to fully restore your wallet, should
|
||||||
you lose the JSON file or your password.
|
you lose the JSON file or your password.
|
||||||
@ -114,12 +114,12 @@ a piece of paper and storing it in a safe place would be prudent.
|
|||||||
|
|
||||||
Your wallet's UUID is:
|
Your wallet's UUID is:
|
||||||
|
|
||||||
e762671a-2a33-4922-901b-62a43dbd5227
|
1c8c13d5-d065-4ef7-bad3-14e9d8146140
|
||||||
|
|
||||||
You do not need to backup your UUID or keep it secret.
|
You do not need to backup your UUID or keep it secret.
|
||||||
```
|
```
|
||||||
|
|
||||||
**Don't forget to make a backup** of the 12-word BIP-39 mnemonic. It can be
|
**Don't forget to make a backup** of the 24-word BIP-39 mnemonic. It can be
|
||||||
used to restore your validator if there is a data loss.
|
used to restore your validator if there is a data loss.
|
||||||
|
|
||||||
### 4.2 Create a Validator from the Wallet
|
### 4.2 Create a Validator from the Wallet
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
Lighthouse uses a _hierarchical_ key management system for producing validator
|
Lighthouse uses a _hierarchical_ key management system for producing validator
|
||||||
keys. It is hierarchical because each validator key can be _derived_ from a
|
keys. It is hierarchical because each validator key can be _derived_ from a
|
||||||
master key, making the validators keys _children_ of the master key. This
|
master key, making the validators keys _children_ of the master key. This
|
||||||
scheme means that a single 12-word mnemonic can be used to backup all of your
|
scheme means that a single 24-word mnemonic can be used to backup all of your
|
||||||
validator keys without providing any observable link between them (i.e., it is
|
validator keys without providing any observable link between them (i.e., it is
|
||||||
privacy-retaining). Hierarchical key derivation schemes are common-place in
|
privacy-retaining). Hierarchical key derivation schemes are common-place in
|
||||||
cryptocurrencies, they are already used by most hardware and software wallets
|
cryptocurrencies, they are already used by most hardware and software wallets
|
||||||
@ -13,8 +13,10 @@ to secure BTC, ETH and many other coins.
|
|||||||
|
|
||||||
We defined some terms in the context of validator key management:
|
We defined some terms in the context of validator key management:
|
||||||
|
|
||||||
- **Mnemonic**: a string of 12-words that is designed to be easy to write down
|
- **Mnemonic**: a string of 24 words that is designed to be easy to write down
|
||||||
and remember. E.g., _"enemy fog enlist laundry nurse hungry discover turkey holiday resemble glad discover"_.
|
and remember. E.g., _"radar fly lottery mirror fat icon bachelor sadness
|
||||||
|
type exhaust mule six beef arrest you spirit clog mango snap fox citizen
|
||||||
|
already bird erase"_.
|
||||||
- Defined in BIP-39
|
- Defined in BIP-39
|
||||||
- **Wallet**: a wallet is a JSON file which stores an
|
- **Wallet**: a wallet is a JSON file which stores an
|
||||||
encrypted version of a mnemonic.
|
encrypted version of a mnemonic.
|
||||||
@ -49,7 +51,7 @@ In step (1), we created a wallet in `~/.lighthouse/wallets` with the name
|
|||||||
|
|
||||||
Thanks to the hierarchical key derivation scheme, we can delete all of the
|
Thanks to the hierarchical key derivation scheme, we can delete all of the
|
||||||
aforementioned directories and then regenerate them as long as we remembered
|
aforementioned directories and then regenerate them as long as we remembered
|
||||||
the 12-word mnemonic (we don't recommend doing this, though).
|
the 24-word mnemonic (we don't recommend doing this, though).
|
||||||
|
|
||||||
Creating another validator is easy, it's just a matter of repeating step (2).
|
Creating another validator is easy, it's just a matter of repeating step (2).
|
||||||
The wallet keeps track of how many validators it has generated and ensures that
|
The wallet keeps track of how many validators it has generated and ensures that
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
# Create a wallet
|
# Create a wallet
|
||||||
|
|
||||||
A wallet allows for generating practically unlimited validators from an
|
A wallet allows for generating practically unlimited validators from an
|
||||||
easy-to-remember 12-word string (a mnemonic). As long as that mnemonic is
|
easy-to-remember 24-word string (a mnemonic). As long as that mnemonic is
|
||||||
backed up, all validator keys can be trivially re-generated.
|
backed up, all validator keys can be trivially re-generated.
|
||||||
|
|
||||||
The 12-word string is randomly generated during wallet creation and printed out
|
The 24-word string is randomly generated during wallet creation and printed out
|
||||||
to the terminal. It's important to **make one or more backups of the mnemonic**
|
to the terminal. It's important to **make one or more backups of the mnemonic**
|
||||||
to ensure your ETH is not lost in the case of data loss. It very important to
|
to ensure your ETH is not lost in the case of data loss. It very important to
|
||||||
**keep your mnemonic private** as it represents the ultimate control of your
|
**keep your mnemonic private** as it represents the ultimate control of your
|
||||||
|
Loading…
Reference in New Issue
Block a user