Explorar o código

cmd/ethereum: add account commands

Felix Lange %!s(int64=10) %!d(string=hai) anos
pai
achega
a2810c06d7
Modificáronse 2 ficheiros con 93 adicións e 34 borrados
  1. 71 8
      cmd/ethereum/main.go
  2. 22 26
      cmd/utils/flags.go

+ 71 - 8
cmd/ethereum/main.go

@@ -21,6 +21,7 @@
 package main
 
 import (
+	"bufio"
 	"fmt"
 	"os"
 	"runtime"
@@ -34,6 +35,7 @@ import (
 	"github.com/ethereum/go-ethereum/ethutil"
 	"github.com/ethereum/go-ethereum/logger"
 	"github.com/ethereum/go-ethereum/state"
+	"github.com/peterh/liner"
 )
 
 const (
@@ -60,6 +62,23 @@ func init() {
 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,
 			Name:   "dump",
@@ -93,8 +112,6 @@ runtime will execute the file and exit.
 	app.Flags = []cli.Flag{
 		utils.BootnodesFlag,
 		utils.DataDirFlag,
-		utils.KeyRingFlag,
-		utils.KeyStoreFlag,
 		utils.ListenPortFlag,
 		utils.LogFileFlag,
 		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) {
 	if len(ctx.Args()) != 1 {
 		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) {
 	fmt.Printf(`%v %v
 PV=%d
@@ -216,3 +258,24 @@ GOPATH=%s
 GOROOT=%s
 `, 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
+}

+ 22 - 26
cmd/utils/flags.go

@@ -4,8 +4,10 @@ import (
 	"crypto/ecdsa"
 	"path"
 	"runtime"
+	"time"
 
 	"github.com/codegangsta/cli"
+	"github.com/ethereum/go-ethereum/accounts"
 	"github.com/ethereum/go-ethereum/core"
 	"github.com/ethereum/go-ethereum/crypto"
 	"github.com/ethereum/go-ethereum/eth"
@@ -30,16 +32,6 @@ var (
 		Name:  "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{
 		Name:  "datadir",
 		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 {
 	ethereum, err := eth.New(&eth.Config{
-		Name:         p2p.MakeName(clientID, version),
-		KeyStore:     ctx.GlobalString(KeyStoreFlag.Name),
-		DataDir:      ctx.GlobalString(DataDirFlag.Name),
-		LogFile:      ctx.GlobalString(LogFileFlag.Name),
-		LogLevel:     ctx.GlobalInt(LogLevelFlag.Name),
-		LogFormat:    ctx.GlobalString(LogFormatFlag.Name),
-		MinerThreads: ctx.GlobalInt(MinerThreadsFlag.Name),
-
-		MaxPeers:  ctx.GlobalInt(MaxPeersFlag.Name),
-		Port:      ctx.GlobalString(ListenPortFlag.Name),
-		NAT:       GetNAT(ctx),
-		NodeKey:   GetNodeKey(ctx),
-		KeyRing:   ctx.GlobalString(KeyRingFlag.Name),
-		Shh:       true,
-		Dial:      true,
-		BootNodes: ctx.GlobalString(BootnodesFlag.Name),
+		Name:           p2p.MakeName(clientID, version),
+		DataDir:        ctx.GlobalString(DataDirFlag.Name),
+		LogFile:        ctx.GlobalString(LogFileFlag.Name),
+		LogLevel:       ctx.GlobalInt(LogLevelFlag.Name),
+		LogFormat:      ctx.GlobalString(LogFormatFlag.Name),
+		MinerThreads:   ctx.GlobalInt(MinerThreadsFlag.Name),
+		AccountManager: GetAccountManager(ctx),
+		MaxPeers:       ctx.GlobalInt(MaxPeersFlag.Name),
+		Port:           ctx.GlobalString(ListenPortFlag.Name),
+		NAT:            GetNAT(ctx),
+		NodeKey:        GetNodeKey(ctx),
+		Shh:            true,
+		Dial:           true,
+		BootNodes:      ctx.GlobalString(BootnodesFlag.Name),
 	})
 	if err != nil {
 		exit(err)
@@ -176,3 +166,9 @@ func GetChain(ctx *cli.Context) (*core.ChainManager, ethutil.Database) {
 	}
 	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)
+}