aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Lange <fjl@twurst.com>2015-03-07 19:39:52 +0800
committerFelix Lange <fjl@twurst.com>2015-03-07 19:39:52 +0800
commita2810c06d7cfc64e1636fe4ecfd5e35cc52b0d2b (patch)
treef9219d79707ce4a65177c5292478f971faa1d7c9
parentd66f93cecdbae6a88bfb710e0d95d62340bf2460 (diff)
downloaddexon-a2810c06d7cfc64e1636fe4ecfd5e35cc52b0d2b.tar.gz
dexon-a2810c06d7cfc64e1636fe4ecfd5e35cc52b0d2b.tar.zst
dexon-a2810c06d7cfc64e1636fe4ecfd5e35cc52b0d2b.zip
cmd/ethereum: add account commands
-rw-r--r--cmd/ethereum/main.go79
-rw-r--r--cmd/utils/flags.go48
2 files changed, 93 insertions, 34 deletions
diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go
index 1133bd6f7..f12616e17 100644
--- a/cmd/ethereum/main.go
+++ b/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 (
@@ -61,6 +63,23 @@ 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",
Usage: `dump a specific block from storage`,
@@ -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
+}
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index fb80ac708..4f3ecd2b2 100644
--- a/cmd/utils/flags.go
+++ b/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)
+}