diff --git a/cmd/account/derive/input.go b/cmd/account/derive/input.go index 2a0df24..abacafa 100644 --- a/cmd/account/derive/input.go +++ b/cmd/account/derive/input.go @@ -26,7 +26,8 @@ type dataIn struct { mnemonic string path string // Output options. - showKey bool + showPrivateKey bool + showWithdrawalCredentials bool } func input(ctx context.Context) (*dataIn, error) { @@ -47,8 +48,11 @@ func input(ctx context.Context) (*dataIn, error) { } data.path = viper.GetString("path") - // Show key. - data.showKey = viper.GetBool("show-key") + // Show private key. + data.showPrivateKey = viper.GetBool("show-private-key") + + // Show withdrawal credentials. + data.showWithdrawalCredentials = viper.GetBool("show-withdrawal-credentials") return data, nil } diff --git a/cmd/account/derive/output.go b/cmd/account/derive/output.go index 90ebfc9..eae128f 100644 --- a/cmd/account/derive/output.go +++ b/cmd/account/derive/output.go @@ -20,11 +20,13 @@ import ( "github.com/pkg/errors" e2types "github.com/wealdtech/go-eth2-types/v2" + util "github.com/wealdtech/go-eth2-util" ) type dataOut struct { - showKey bool - key *e2types.BLSPrivateKey + showPrivateKey bool + showWithdrawalCredentials bool + key *e2types.BLSPrivateKey } func output(ctx context.Context, data *dataOut) (string, error) { @@ -37,10 +39,15 @@ func output(ctx context.Context, data *dataOut) (string, error) { builder := strings.Builder{} - if data.showKey { + if data.showPrivateKey { builder.WriteString(fmt.Sprintf("Private key: %#x\n", data.key.Marshal())) } builder.WriteString(fmt.Sprintf("Public key: %#x", data.key.PublicKey().Marshal())) + if data.showWithdrawalCredentials { + withdrawalCredentials := util.SHA256(data.key.PublicKey().Marshal()) + withdrawalCredentials[0] = byte(0) // BLS_WITHDRAWAL_PREFIX + builder.WriteString(fmt.Sprintf("\nWithdrawal credentials: %#x", withdrawalCredentials)) + } return builder.String(), nil } diff --git a/cmd/account/derive/output_internal_test.go b/cmd/account/derive/output_internal_test.go index 96d8ca1..2951493 100644 --- a/cmd/account/derive/output_internal_test.go +++ b/cmd/account/derive/output_internal_test.go @@ -36,7 +36,7 @@ func TestOutput(t *testing.T) { tests := []struct { name string dataOut *dataOut - res string + needs []string err string }{ { @@ -53,15 +53,32 @@ func TestOutput(t *testing.T) { dataOut: &dataOut{ key: blsPrivateKey("0x068dce0c90cb428ab37a74af0191eac49648035f1aaef077734b91e05985ec55"), }, - res: "Public key: 0x99b1f1d84d76185466d86c34bde1101316afddae76217aa86cd066979b19858c2c9d9e56eebc1e067ac54277a61790db", + needs: []string{"Public key"}, }, { name: "PrivatKey", dataOut: &dataOut{ key: blsPrivateKey("0x068dce0c90cb428ab37a74af0191eac49648035f1aaef077734b91e05985ec55"), - showKey: true, + showPrivateKey: true, }, - res: "Private key: 0x068dce0c90cb428ab37a74af0191eac49648035f1aaef077734b91e05985ec55\nPublic key: 0x99b1f1d84d76185466d86c34bde1101316afddae76217aa86cd066979b19858c2c9d9e56eebc1e067ac54277a61790db", + needs: []string{"Public key", "Private key"}, + }, + { + name: "WithdrawalCredentials", + dataOut: &dataOut{ + key: blsPrivateKey("0x068dce0c90cb428ab37a74af0191eac49648035f1aaef077734b91e05985ec55"), + showWithdrawalCredentials: true, + }, + needs: []string{"Public key", "Withdrawal credentials"}, + }, + { + name: "All", + dataOut: &dataOut{ + key: blsPrivateKey("0x068dce0c90cb428ab37a74af0191eac49648035f1aaef077734b91e05985ec55"), + showPrivateKey: true, + showWithdrawalCredentials: true, + }, + needs: []string{"Public key", "Private key", "Withdrawal credentials"}, }, } @@ -72,7 +89,9 @@ func TestOutput(t *testing.T) { require.EqualError(t, err, test.err) } else { require.NoError(t, err) - require.Equal(t, test.res, res) + for _, need := range test.needs { + require.Contains(t, res, need) + } } }) } diff --git a/cmd/account/derive/process.go b/cmd/account/derive/process.go index dbe2dbc..89ee75c 100644 --- a/cmd/account/derive/process.go +++ b/cmd/account/derive/process.go @@ -63,8 +63,9 @@ func process(ctx context.Context, data *dataIn) (*dataOut, error) { } results := &dataOut{ - showKey: data.showKey, - key: key, + showPrivateKey: data.showPrivateKey, + showWithdrawalCredentials: data.showWithdrawalCredentials, + key: key, } return results, nil diff --git a/cmd/accountderive.go b/cmd/accountderive.go index 7ab9075..245141d 100644 --- a/cmd/accountderive.go +++ b/cmd/accountderive.go @@ -49,7 +49,8 @@ func init() { accountFlags(accountDeriveCmd) accountDeriveCmd.Flags().String("mnemonic", "", "mnemonic from which to derive the HD seed") accountDeriveCmd.Flags().String("path", "", "path from which to derive the account") - accountDeriveCmd.Flags().Bool("show-key", false, "show key as well as public key") + accountDeriveCmd.Flags().Bool("show-private-key", false, "show private key for derived account") + accountDeriveCmd.Flags().Bool("show-withdrawal-credentials", false, "show withdrawal credentials for derived account") } func accountDeriveBindings() { @@ -59,7 +60,10 @@ func accountDeriveBindings() { if err := viper.BindPFlag("path", accountDeriveCmd.Flags().Lookup("path")); err != nil { panic(err) } - if err := viper.BindPFlag("show-key", accountDeriveCmd.Flags().Lookup("show-key")); err != nil { + if err := viper.BindPFlag("show-private-key", accountDeriveCmd.Flags().Lookup("show-private-key")); err != nil { + panic(err) + } + if err := viper.BindPFlag("show-withdrawal-credentials", accountDeriveCmd.Flags().Lookup("show-withdrawal-credentials")); err != nil { panic(err) } } diff --git a/docs/usage.md b/docs/usage.md index 6e88e15..d4aa091 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -128,7 +128,8 @@ $ ethdo account create --account="Personal wallet/Operations" --wallet-passphras - `mnemonic`: a pre-defined 24-word [BIP-39 seed phrase](https://en.bitcoin.it/wiki/Seed_phrase) to derive the account, along with an additional "seed extension" phrase if required supplied as the 25th word - `path`: the HD path used to derive the account - - `show-key`: show the private key as well as the public key. **Warning** displaying private keys, especially those derived from seeds held on hardware wallets, can expose your Ether to risk of being stolen. Only use this option if you are sure you understand the risks involved + - `show-private-key`: show the private of the derived account. **Warning** displaying private keys, especially those derived from seeds held on hardware wallets, can expose your Ether to risk of being stolen. Only use this option if you are sure you understand the risks involved + - `show-withdrawal-credentials`: show the withdrawal credentials of the derived account ```sh $ ethdo account derive --mnemonic="abandon ... abandon art" --path="m/12381/3600/0/0"