mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
cmd/clef: add newaccount command
This commit is contained in:
parent
8d7aa9078f
commit
ff7e053a28
3 changed files with 66 additions and 4 deletions
|
|
@ -187,6 +187,21 @@ The setpw command stores a password for a given address (keyfile).
|
||||||
Description: `
|
Description: `
|
||||||
The delpw command removes a password for a given address (keyfile).
|
The delpw command removes a password for a given address (keyfile).
|
||||||
`}
|
`}
|
||||||
|
newAccountCommand = cli.Command{
|
||||||
|
Action: utils.MigrateFlags(newAccount),
|
||||||
|
Name: "newaccount",
|
||||||
|
Usage: "Create a new account",
|
||||||
|
ArgsUsage: "",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
logLevelFlag,
|
||||||
|
keystoreFlag,
|
||||||
|
utils.LightKDFFlag,
|
||||||
|
},
|
||||||
|
Description: `
|
||||||
|
The newaccount command creates a new keystore-backed account. It is a convenience-method
|
||||||
|
which can be used in lieu of an external UI.`,
|
||||||
|
}
|
||||||
|
|
||||||
gendocCommand = cli.Command{
|
gendocCommand = cli.Command{
|
||||||
Action: GenDoc,
|
Action: GenDoc,
|
||||||
Name: "gendoc",
|
Name: "gendoc",
|
||||||
|
|
@ -222,7 +237,12 @@ func init() {
|
||||||
advancedMode,
|
advancedMode,
|
||||||
}
|
}
|
||||||
app.Action = signer
|
app.Action = signer
|
||||||
app.Commands = []cli.Command{initCommand, attestCommand, setCredentialCommand, delCredentialCommand, gendocCommand}
|
app.Commands = []cli.Command{initCommand,
|
||||||
|
attestCommand,
|
||||||
|
setCredentialCommand,
|
||||||
|
delCredentialCommand,
|
||||||
|
newAccountCommand,
|
||||||
|
gendocCommand}
|
||||||
cli.CommandHelpTemplate = utils.OriginCommandHelpTemplate
|
cli.CommandHelpTemplate = utils.OriginCommandHelpTemplate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -382,6 +402,31 @@ func removeCredential(ctx *cli.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newAccount(c *cli.Context) error {
|
||||||
|
if err := initialize(c); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// The newaccount is meant for users using the CLI, since 'real' external
|
||||||
|
// UIs can use the UI-api instead. So we'll just use the native CLI UI here.
|
||||||
|
var (
|
||||||
|
ui = core.NewCommandlineUI()
|
||||||
|
pwStorage storage.Storage = &storage.NoStorage{}
|
||||||
|
ksLoc = c.GlobalString(keystoreFlag.Name)
|
||||||
|
lightKdf = c.GlobalBool(utils.LightKDFFlag.Name)
|
||||||
|
)
|
||||||
|
log.Info("Starting clef", "keystore", ksLoc, "light-kdf", lightKdf)
|
||||||
|
am := core.StartClefAccountManager(ksLoc, true, lightKdf, "")
|
||||||
|
// This gives is us access to the external API
|
||||||
|
apiImpl := core.NewSignerAPI(am, 0, true, ui, nil, false, pwStorage)
|
||||||
|
// This gives us access to the internal API
|
||||||
|
internalApi := core.NewUIServerAPI(apiImpl)
|
||||||
|
addr, err := internalApi.New(context.Background())
|
||||||
|
if err == nil {
|
||||||
|
fmt.Printf("Generated account %v\n", addr.String())
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func initialize(c *cli.Context) error {
|
func initialize(c *cli.Context) error {
|
||||||
// Set up the logger to print everything
|
// Set up the logger to print everything
|
||||||
logOutput := os.Stdout
|
logOutput := os.Stdout
|
||||||
|
|
@ -457,7 +502,6 @@ func signer(c *cli.Context) error {
|
||||||
api core.ExternalAPI
|
api core.ExternalAPI
|
||||||
pwStorage storage.Storage = &storage.NoStorage{}
|
pwStorage storage.Storage = &storage.NoStorage{}
|
||||||
)
|
)
|
||||||
|
|
||||||
configDir := c.GlobalString(configdirFlag.Name)
|
configDir := c.GlobalString(configdirFlag.Name)
|
||||||
if stretchedKey, err := readMasterKey(c, ui); err != nil {
|
if stretchedKey, err := readMasterKey(c, ui); err != nil {
|
||||||
log.Warn("Failed to open master, rules disabled", "err", err)
|
log.Warn("Failed to open master, rules disabled", "err", err)
|
||||||
|
|
|
||||||
|
|
@ -395,8 +395,7 @@ func (api *SignerAPI) List(ctx context.Context) ([]common.Address, error) {
|
||||||
// the given password. Users are responsible to backup the private key that is stored
|
// the given password. Users are responsible to backup the private key that is stored
|
||||||
// in the keystore location thas was specified when this API was created.
|
// in the keystore location thas was specified when this API was created.
|
||||||
func (api *SignerAPI) New(ctx context.Context) (common.Address, error) {
|
func (api *SignerAPI) New(ctx context.Context) (common.Address, error) {
|
||||||
be := api.am.Backends(keystore.KeyStoreType)
|
if be := api.am.Backends(keystore.KeyStoreType); len(be) == 0 {
|
||||||
if len(be) == 0 {
|
|
||||||
return common.Address{}, errors.New("password based accounts not supported")
|
return common.Address{}, errors.New("password based accounts not supported")
|
||||||
}
|
}
|
||||||
if resp, err := api.UI.ApproveNewAccount(&NewAccountRequest{MetadataFromContext(ctx)}); err != nil {
|
if resp, err := api.UI.ApproveNewAccount(&NewAccountRequest{MetadataFromContext(ctx)}); err != nil {
|
||||||
|
|
@ -404,7 +403,16 @@ func (api *SignerAPI) New(ctx context.Context) (common.Address, error) {
|
||||||
} else if !resp.Approved {
|
} else if !resp.Approved {
|
||||||
return common.Address{}, ErrRequestDenied
|
return common.Address{}, ErrRequestDenied
|
||||||
}
|
}
|
||||||
|
return api.newAccount()
|
||||||
|
}
|
||||||
|
|
||||||
|
// newAccount is the internal method to create a new account. It should be used
|
||||||
|
// _after_ user-approval has been obtained
|
||||||
|
func (api *SignerAPI) newAccount() (common.Address, error) {
|
||||||
|
be := api.am.Backends(keystore.KeyStoreType)
|
||||||
|
if len(be) == 0 {
|
||||||
|
return common.Address{}, errors.New("password based accounts not supported")
|
||||||
|
}
|
||||||
// Three retries to get a valid password
|
// Three retries to get a valid password
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
resp, err := api.UI.OnInputRequired(UserInputRequest{
|
resp, err := api.UI.OnInputRequired(UserInputRequest{
|
||||||
|
|
|
||||||
|
|
@ -195,6 +195,16 @@ func (api *UIServerAPI) Import(ctx context.Context, keyJSON json.RawMessage, old
|
||||||
return be[0].(*keystore.KeyStore).Import(keyJSON, oldPassphrase, newPassphrase)
|
return be[0].(*keystore.KeyStore).Import(keyJSON, oldPassphrase, newPassphrase)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// New creates a new password protected Account. The private key is protected with
|
||||||
|
// the given password. Users are responsible to backup the private key that is stored
|
||||||
|
// in the keystore location thas was specified when this API was created.
|
||||||
|
// This method is the same as New on the external API, the difference being that
|
||||||
|
// this implementation does not ask for confirmation, since it's initiated by
|
||||||
|
// the user
|
||||||
|
func (api *UIServerAPI) New(ctx context.Context) (common.Address, error) {
|
||||||
|
return api.extApi.newAccount()
|
||||||
|
}
|
||||||
|
|
||||||
// Other methods to be added, not yet implemented are:
|
// Other methods to be added, not yet implemented are:
|
||||||
// - Ruleset interaction: add rules, attest rulefiles
|
// - Ruleset interaction: add rules, attest rulefiles
|
||||||
// - Store metadata about accounts, e.g. naming of accounts
|
// - Store metadata about accounts, e.g. naming of accounts
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue