mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-06 03:53:47 +00:00
Add account commands
This commit is contained in:
parent
8fe5c5a329
commit
74d384b6a4
8 changed files with 316 additions and 2 deletions
32
command/account.go
Normal file
32
command/account.go
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
package main
|
||||
|
||||
import "github.com/mitchellh/cli"
|
||||
|
||||
type Account struct {
|
||||
UI cli.Ui
|
||||
}
|
||||
|
||||
// Help implements the cli.Command interface
|
||||
func (a *Account) Help() string {
|
||||
return `Usage: bor account <subcommand>
|
||||
|
||||
This command groups actions to interact with accounts.
|
||||
|
||||
List the running deployments:
|
||||
|
||||
$ bor account new
|
||||
|
||||
Display the status of a specific deployment:
|
||||
|
||||
$ bor account import`
|
||||
}
|
||||
|
||||
// Synopsis implements the cli.Command interface
|
||||
func (a *Account) Synopsis() string {
|
||||
return "Interact with accounts"
|
||||
}
|
||||
|
||||
// Run implements the cli.Command interface
|
||||
func (a *Account) Run(args []string) int {
|
||||
return cli.RunResultHelp
|
||||
}
|
||||
74
command/account_import.go
Normal file
74
command/account_import.go
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||
"github.com/ethereum/go-ethereum/command/flagset"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
)
|
||||
|
||||
type AccountImportCommand struct {
|
||||
*Meta
|
||||
}
|
||||
|
||||
// Help implements the cli.Command interface
|
||||
func (a *AccountImportCommand) Help() string {
|
||||
return `Usage: bor account import
|
||||
|
||||
Import a private key into a new account.
|
||||
|
||||
Import an account:
|
||||
|
||||
$ bor account import key.json
|
||||
|
||||
` + a.Flags().Help()
|
||||
}
|
||||
|
||||
func (a *AccountImportCommand) Flags() *flagset.Flagset {
|
||||
return a.NewFlagSet("account import")
|
||||
}
|
||||
|
||||
// Synopsis implements the cli.Command interface
|
||||
func (a *AccountImportCommand) Synopsis() string {
|
||||
return "Import a private key into a new account"
|
||||
}
|
||||
|
||||
// Run implements the cli.Command interface
|
||||
func (a *AccountImportCommand) Run(args []string) int {
|
||||
flags := a.Flags()
|
||||
if err := flags.Parse(args); err != nil {
|
||||
a.UI.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
|
||||
args = flags.Args()
|
||||
if len(args) != 1 {
|
||||
a.UI.Error("Expected one argument")
|
||||
return 1
|
||||
}
|
||||
key, err := crypto.LoadECDSA(args[0])
|
||||
if err != nil {
|
||||
a.UI.Error(fmt.Sprintf("Failed to load the private key '%s': %v", args[0], err))
|
||||
return 1
|
||||
}
|
||||
|
||||
keystore, err := a.GetKeystore()
|
||||
if err != nil {
|
||||
a.UI.Error(fmt.Sprintf("Failed to get keystore: %v", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
password, err := a.AskPassword()
|
||||
if err != nil {
|
||||
a.UI.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
|
||||
acct, err := keystore.ImportECDSA(key, password)
|
||||
if err != nil {
|
||||
utils.Fatalf("Could not create the account: %v", err)
|
||||
}
|
||||
a.UI.Output(fmt.Sprintf("Account created: %s", acct.Address.String()))
|
||||
return 0
|
||||
}
|
||||
62
command/account_list.go
Normal file
62
command/account_list.go
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts"
|
||||
"github.com/ethereum/go-ethereum/command/flagset"
|
||||
)
|
||||
|
||||
type AccountListCommand struct {
|
||||
*Meta
|
||||
}
|
||||
|
||||
// Help implements the cli.Command interface
|
||||
func (a *AccountListCommand) Help() string {
|
||||
return `Usage: bor account list
|
||||
|
||||
List the local accounts.
|
||||
|
||||
` + a.Flags().Help()
|
||||
}
|
||||
|
||||
func (a *AccountListCommand) Flags() *flagset.Flagset {
|
||||
return a.NewFlagSet("account list")
|
||||
}
|
||||
|
||||
// Synopsis implements the cli.Command interface
|
||||
func (a *AccountListCommand) Synopsis() string {
|
||||
return "List the local accounts"
|
||||
}
|
||||
|
||||
// Run implements the cli.Command interface
|
||||
func (a *AccountListCommand) Run(args []string) int {
|
||||
flags := a.Flags()
|
||||
if err := flags.Parse(args); err != nil {
|
||||
a.UI.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
|
||||
keystore, err := a.GetKeystore()
|
||||
if err != nil {
|
||||
a.UI.Error(fmt.Sprintf("Failed to get keystore: %v", err))
|
||||
return 1
|
||||
}
|
||||
a.UI.Output(formatAccounts(keystore.Accounts()))
|
||||
return 0
|
||||
}
|
||||
|
||||
func formatAccounts(accts []accounts.Account) string {
|
||||
if len(accts) == 0 {
|
||||
return "No accounts found"
|
||||
}
|
||||
|
||||
rows := make([]string, len(accts)+1)
|
||||
rows[0] = "Index|Address"
|
||||
for i, d := range accts {
|
||||
rows[i+1] = fmt.Sprintf("%d|%s",
|
||||
i,
|
||||
d.Address.String())
|
||||
}
|
||||
return formatList(rows)
|
||||
}
|
||||
62
command/account_new.go
Normal file
62
command/account_new.go
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/ethereum/go-ethereum/command/flagset"
|
||||
)
|
||||
|
||||
type AccountNewCommand struct {
|
||||
*Meta
|
||||
}
|
||||
|
||||
// Help implements the cli.Command interface
|
||||
func (a *AccountNewCommand) Help() string {
|
||||
return `Usage: bor account new
|
||||
|
||||
Create a new local account.
|
||||
|
||||
` + a.Flags().Help()
|
||||
}
|
||||
|
||||
func (a *AccountNewCommand) Flags() *flagset.Flagset {
|
||||
return a.NewFlagSet("account new")
|
||||
}
|
||||
|
||||
// Synopsis implements the cli.Command interface
|
||||
func (a *AccountNewCommand) Synopsis() string {
|
||||
return "Create a new local account"
|
||||
}
|
||||
|
||||
// Run implements the cli.Command interface
|
||||
func (a *AccountNewCommand) Run(args []string) int {
|
||||
flags := a.Flags()
|
||||
if err := flags.Parse(args); err != nil {
|
||||
a.UI.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
|
||||
keystore, err := a.GetKeystore()
|
||||
if err != nil {
|
||||
a.UI.Error(fmt.Sprintf("Failed to get keystore: %v", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
password, err := a.AskPassword()
|
||||
if err != nil {
|
||||
a.UI.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
|
||||
account, err := keystore.NewAccount(password)
|
||||
if err != nil {
|
||||
a.UI.Error(fmt.Sprintf("Failed to create new account: %v", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
a.UI.Output("\nYour new key was generated")
|
||||
a.UI.Output(fmt.Sprintf("Public address of the key: %s", account.Address.Hex()))
|
||||
a.UI.Output(fmt.Sprintf("Path of the secret key file: %s", account.URL.Path))
|
||||
|
||||
return 0
|
||||
}
|
||||
|
|
@ -4,8 +4,12 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts/keystore"
|
||||
"github.com/ethereum/go-ethereum/command/flagset"
|
||||
"github.com/ethereum/go-ethereum/command/server"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/ryanuber/columnize"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
|
@ -35,6 +39,10 @@ func commands() map[string]cli.CommandFactory {
|
|||
Writer: os.Stdout,
|
||||
ErrorWriter: os.Stderr,
|
||||
}
|
||||
|
||||
meta := &Meta{
|
||||
UI: ui,
|
||||
}
|
||||
return map[string]cli.CommandFactory{
|
||||
"server": func() (cli.Command, error) {
|
||||
return &server.Command{
|
||||
|
|
@ -46,5 +54,78 @@ func commands() map[string]cli.CommandFactory {
|
|||
UI: ui,
|
||||
}, nil
|
||||
},
|
||||
"account": func() (cli.Command, error) {
|
||||
return &Account{
|
||||
UI: ui,
|
||||
}, nil
|
||||
},
|
||||
"account new": func() (cli.Command, error) {
|
||||
return &AccountNewCommand{
|
||||
Meta: meta,
|
||||
}, nil
|
||||
},
|
||||
"account import": func() (cli.Command, error) {
|
||||
return &AccountImportCommand{
|
||||
Meta: meta,
|
||||
}, nil
|
||||
},
|
||||
"account list": func() (cli.Command, error) {
|
||||
return &AccountListCommand{
|
||||
Meta: meta,
|
||||
}, nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Meta is a helper utility for the commands
|
||||
type Meta struct {
|
||||
UI cli.Ui
|
||||
|
||||
dataDir string
|
||||
keyStoreDir string
|
||||
}
|
||||
|
||||
func (m *Meta) NewFlagSet(n string) *flagset.Flagset {
|
||||
f := flagset.NewFlagSet(n)
|
||||
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "datadir",
|
||||
Value: &m.dataDir,
|
||||
Usage: "Path of the data directory to store information",
|
||||
})
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
Name: "keystore",
|
||||
Value: &m.keyStoreDir,
|
||||
Usage: "Path of the data directory to store information",
|
||||
})
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func (m *Meta) AskPassword() (string, error) {
|
||||
return m.UI.AskSecret("Your new account is locked with a password. Please give a password. Do not forget this password")
|
||||
}
|
||||
|
||||
func (m *Meta) GetKeystore() (*keystore.KeyStore, error) {
|
||||
cfg := node.DefaultConfig
|
||||
cfg.DataDir = m.dataDir
|
||||
cfg.KeyStoreDir = m.keyStoreDir
|
||||
|
||||
stack, err := node.New(&cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
keydir := stack.KeyStoreDir()
|
||||
scryptN := keystore.StandardScryptN
|
||||
scryptP := keystore.StandardScryptP
|
||||
|
||||
keys := keystore.NewKeyStore(keydir, scryptN, scryptP)
|
||||
return keys, nil
|
||||
}
|
||||
|
||||
func formatList(in []string) string {
|
||||
columnConf := columnize.DefaultConfig()
|
||||
columnConf.Empty = "<none>"
|
||||
return columnize.Format(in, columnConf)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ type VersionCommand struct {
|
|||
|
||||
// Help implements the cli.Command interface
|
||||
func (c *VersionCommand) Help() string {
|
||||
return `Usage: ensemble version
|
||||
return `Usage: bor version
|
||||
|
||||
Display the Ensemble version`
|
||||
Display the Bor version`
|
||||
}
|
||||
|
||||
// Synopsis implements the cli.Command interface
|
||||
|
|
|
|||
1
go.mod
1
go.mod
|
|
@ -58,6 +58,7 @@ require (
|
|||
github.com/prometheus/tsdb v0.7.1
|
||||
github.com/rjeczalik/notify v0.9.1
|
||||
github.com/rs/cors v1.7.0
|
||||
github.com/ryanuber/columnize v2.1.2+incompatible
|
||||
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible
|
||||
github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4
|
||||
github.com/stretchr/testify v1.7.0
|
||||
|
|
|
|||
2
go.sum
2
go.sum
|
|
@ -393,6 +393,8 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
|||
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
|
||||
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v2.1.2+incompatible h1:C89EOx/XBWwIXl8wm8OPJBd7kPF25UfsK2X7Ph/zCAk=
|
||||
github.com/ryanuber/columnize v2.1.2+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo=
|
||||
github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
|
|
|
|||
Loading…
Reference in a new issue