cmd/ethereum: add account commands

This commit is contained in:
Felix Lange 2015-03-07 12:39:52 +01:00
parent d66f93cecd
commit a2810c06d7
2 changed files with 93 additions and 34 deletions

View File

@ -21,6 +21,7 @@
package main package main
import ( import (
"bufio"
"fmt" "fmt"
"os" "os"
"runtime" "runtime"
@ -34,6 +35,7 @@ import (
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/state"
"github.com/peterh/liner"
) )
const ( const (
@ -60,6 +62,23 @@ func init() {
The output of this command is supposed to be machine-readable. The output of this command is supposed to be machine-readable.
`, `,
}, },
{
Action: accountList,
Name: "account",
Usage: "manage accounts",
Subcommands: []cli.Command{
{
Action: accountList,
Name: "list",
Usage: "print account addresses",
},
{
Action: accountCreate,
Name: "new",
Usage: "create a new account",
},
},
},
{ {
Action: dump, Action: dump,
Name: "dump", Name: "dump",
@ -93,8 +112,6 @@ runtime will execute the file and exit.
app.Flags = []cli.Flag{ app.Flags = []cli.Flag{
utils.BootnodesFlag, utils.BootnodesFlag,
utils.DataDirFlag, utils.DataDirFlag,
utils.KeyRingFlag,
utils.KeyStoreFlag,
utils.ListenPortFlag, utils.ListenPortFlag,
utils.LogFileFlag, utils.LogFileFlag,
utils.LogFormatFlag, utils.LogFormatFlag,
@ -166,6 +183,37 @@ func startEth(ctx *cli.Context, eth *eth.Ethereum) {
} }
} }
func accountList(ctx *cli.Context) {
am := utils.GetAccountManager(ctx)
accts, err := am.Accounts()
if err != nil {
utils.Fatalf("Could not list accounts: %v", err)
}
for _, acct := range accts {
fmt.Printf("Address: %#x\n", acct)
}
}
func accountCreate(ctx *cli.Context) {
am := utils.GetAccountManager(ctx)
auth, err := readPassword("Passphrase: ", true)
if err != nil {
utils.Fatalf("%v", err)
}
confirm, err := readPassword("Repeat Passphrase: ", false)
if err != nil {
utils.Fatalf("%v", err)
}
if auth != confirm {
utils.Fatalf("Passphrases did not match.")
}
acct, err := am.NewAccount(auth)
if err != nil {
utils.Fatalf("Could not create the account: %v", err)
}
fmt.Printf("Address: %#x\n", acct.Address)
}
func importchain(ctx *cli.Context) { func importchain(ctx *cli.Context) {
if len(ctx.Args()) != 1 { if len(ctx.Args()) != 1 {
utils.Fatalf("This command requires an argument.") utils.Fatalf("This command requires an argument.")
@ -201,12 +249,6 @@ func dump(ctx *cli.Context) {
} }
} }
// hashish returns true for strings that look like hashes.
func hashish(x string) bool {
_, err := strconv.Atoi(x)
return err != nil
}
func version(c *cli.Context) { func version(c *cli.Context) {
fmt.Printf(`%v %v fmt.Printf(`%v %v
PV=%d PV=%d
@ -216,3 +258,24 @@ GOPATH=%s
GOROOT=%s GOROOT=%s
`, ClientIdentifier, Version, eth.ProtocolVersion, runtime.GOOS, runtime.Version(), os.Getenv("GOPATH"), runtime.GOROOT()) `, ClientIdentifier, Version, eth.ProtocolVersion, runtime.GOOS, runtime.Version(), os.Getenv("GOPATH"), runtime.GOROOT())
} }
// hashish returns true for strings that look like hashes.
func hashish(x string) bool {
_, err := strconv.Atoi(x)
return err != nil
}
func readPassword(prompt string, warnTerm bool) (string, error) {
if liner.TerminalSupported() {
lr := liner.NewLiner()
defer lr.Close()
return lr.PasswordPrompt(prompt)
}
if warnTerm {
fmt.Println("!! Unsupported terminal, password will be echoed.")
}
fmt.Print(prompt)
input, err := bufio.NewReader(os.Stdin).ReadString('\n')
fmt.Println()
return input, err
}

View File

@ -4,8 +4,10 @@ import (
"crypto/ecdsa" "crypto/ecdsa"
"path" "path"
"runtime" "runtime"
"time"
"github.com/codegangsta/cli" "github.com/codegangsta/cli"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth"
@ -30,16 +32,6 @@ var (
Name: "vm", Name: "vm",
Usage: "Virtual Machine type: 0 is standard VM, 1 is debug VM", Usage: "Virtual Machine type: 0 is standard VM, 1 is debug VM",
} }
KeyRingFlag = cli.StringFlag{
Name: "keyring",
Usage: "Name of keyring to be used",
Value: "",
}
KeyStoreFlag = cli.StringFlag{
Name: "keystore",
Usage: `Where to store keyrings: "db" or "file"`,
Value: "db",
}
DataDirFlag = cli.StringFlag{ DataDirFlag = cli.StringFlag{
Name: "datadir", Name: "datadir",
Usage: "Data directory to be used", Usage: "Data directory to be used",
@ -145,22 +137,20 @@ func GetNodeKey(ctx *cli.Context) (key *ecdsa.PrivateKey) {
func GetEthereum(clientID, version string, ctx *cli.Context) *eth.Ethereum { func GetEthereum(clientID, version string, ctx *cli.Context) *eth.Ethereum {
ethereum, err := eth.New(&eth.Config{ ethereum, err := eth.New(&eth.Config{
Name: p2p.MakeName(clientID, version), Name: p2p.MakeName(clientID, version),
KeyStore: ctx.GlobalString(KeyStoreFlag.Name), DataDir: ctx.GlobalString(DataDirFlag.Name),
DataDir: ctx.GlobalString(DataDirFlag.Name), LogFile: ctx.GlobalString(LogFileFlag.Name),
LogFile: ctx.GlobalString(LogFileFlag.Name), LogLevel: ctx.GlobalInt(LogLevelFlag.Name),
LogLevel: ctx.GlobalInt(LogLevelFlag.Name), LogFormat: ctx.GlobalString(LogFormatFlag.Name),
LogFormat: ctx.GlobalString(LogFormatFlag.Name), MinerThreads: ctx.GlobalInt(MinerThreadsFlag.Name),
MinerThreads: ctx.GlobalInt(MinerThreadsFlag.Name), AccountManager: GetAccountManager(ctx),
MaxPeers: ctx.GlobalInt(MaxPeersFlag.Name),
MaxPeers: ctx.GlobalInt(MaxPeersFlag.Name), Port: ctx.GlobalString(ListenPortFlag.Name),
Port: ctx.GlobalString(ListenPortFlag.Name), NAT: GetNAT(ctx),
NAT: GetNAT(ctx), NodeKey: GetNodeKey(ctx),
NodeKey: GetNodeKey(ctx), Shh: true,
KeyRing: ctx.GlobalString(KeyRingFlag.Name), Dial: true,
Shh: true, BootNodes: ctx.GlobalString(BootnodesFlag.Name),
Dial: true,
BootNodes: ctx.GlobalString(BootnodesFlag.Name),
}) })
if err != nil { if err != nil {
exit(err) exit(err)
@ -176,3 +166,9 @@ func GetChain(ctx *cli.Context) (*core.ChainManager, ethutil.Database) {
} }
return core.NewChainManager(db, new(event.TypeMux)), db return core.NewChainManager(db, new(event.TypeMux)), db
} }
func GetAccountManager(ctx *cli.Context) *accounts.AccountManager {
dataDir := ctx.GlobalString(DataDirFlag.Name)
ks := crypto.NewKeyStorePassphrase(path.Join(dataDir, "keys"))
return accounts.NewAccountManager(ks, 300*time.Second)
}