From 241fb2fe839ce078f15607814ff055898dd896b9 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Tue, 4 Aug 2020 20:52:32 +0200 Subject: [PATCH] export funcs for AragonChain (#423) * export funcs for AragonChain * update comments --- client/config.go | 63 ++++++++++++++++++++++++ client/export.go | 80 ++++++++++++++++++++++++++++++ {cmd/emintcli => client}/keys.go | 37 +++++++------- {cmd/emintd => client}/testnet.go | 7 ++- cmd/emintcli/export.go | 82 ------------------------------- cmd/emintcli/main.go | 49 +++++------------- cmd/emintd/main.go | 57 +++++++-------------- 7 files changed, 196 insertions(+), 179 deletions(-) create mode 100644 client/config.go create mode 100644 client/export.go rename {cmd/emintcli => client}/keys.go (90%) rename {cmd/emintd => client}/testnet.go (98%) delete mode 100644 cmd/emintcli/export.go diff --git a/client/config.go b/client/config.go new file mode 100644 index 00000000..05914624 --- /dev/null +++ b/client/config.go @@ -0,0 +1,63 @@ +package client + +import ( + "fmt" + "math/big" + "os" + "path" + + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/tendermint/tendermint/libs/cli" +) + +// InitConfig adds the chain-id, encoding and output flags to the persistent flag set. +func InitConfig(cmd *cobra.Command) error { + home, err := cmd.PersistentFlags().GetString(cli.HomeFlag) + if err != nil { + return err + } + + configFile := path.Join(home, "config", "config.toml") + if _, err := os.Stat(configFile); err == nil { + viper.SetConfigFile(configFile) + + if err := viper.ReadInConfig(); err != nil { + return err + } + } + + if err := viper.BindPFlag(flags.FlagChainID, cmd.PersistentFlags().Lookup(flags.FlagChainID)); err != nil { + return err + } + + if err := viper.BindPFlag(cli.EncodingFlag, cmd.PersistentFlags().Lookup(cli.EncodingFlag)); err != nil { + return err + } + + return viper.BindPFlag(cli.OutputFlag, cmd.PersistentFlags().Lookup(cli.OutputFlag)) +} + +// ValidateChainID wraps a cobra command with a RunE function with base 10 integer chain-id verification. +func ValidateChainID(baseCmd *cobra.Command) *cobra.Command { + // Copy base run command to be used after chain verification + baseRunE := baseCmd.RunE + + // Function to replace command's RunE function + validateFn := func(cmd *cobra.Command, args []string) error { + chainIDFlag := viper.GetString(flags.FlagChainID) + + // Verify that the chain-id entered is a base 10 integer + _, ok := new(big.Int).SetString(chainIDFlag, 10) + if !ok { + return fmt.Errorf("invalid chainID: %s, must be base-10 integer format", chainIDFlag) + } + + return baseRunE(cmd, args) + } + + baseCmd.RunE = validateFn + return baseCmd +} diff --git a/client/export.go b/client/export.go new file mode 100644 index 00000000..37e1ee62 --- /dev/null +++ b/client/export.go @@ -0,0 +1,80 @@ +package client + +import ( + "bufio" + "fmt" + "strings" + + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "github.com/ethereum/go-ethereum/common/hexutil" + ethcrypto "github.com/ethereum/go-ethereum/crypto" + + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/input" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + sdk "github.com/cosmos/cosmos-sdk/types" + + emintcrypto "github.com/cosmos/ethermint/crypto" +) + +// UnsafeExportEthKeyCommand exports a key with the given name as a private key in hex format. +func UnsafeExportEthKeyCommand() *cobra.Command { + return &cobra.Command{ + Use: "unsafe-export-eth-key [name]", + Short: "**UNSAFE** Export an Ethereum private key", + Long: `**UNSAFE** Export an Ethereum private key unencrypted to use in dev tooling`, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + inBuf := bufio.NewReader(cmd.InOrStdin()) + + kb, err := keyring.NewKeyring( + sdk.KeyringServiceName(), + viper.GetString(flags.FlagKeyringBackend), + viper.GetString(flags.FlagHome), + inBuf, + ) + if err != nil { + return err + } + + decryptPassword := "" + conf := true + keyringBackend := viper.GetString(flags.FlagKeyringBackend) + switch keyringBackend { + case keyring.BackendFile: + decryptPassword, err = input.GetPassword( + "**WARNING this is an unsafe way to export your unencrypted private key**\nEnter key password:", + inBuf) + case keyring.BackendOS: + conf, err = input.GetConfirmation( + "**WARNING** this is an unsafe way to export your unencrypted private key, are you sure?", + inBuf) + } + if err != nil || !conf { + return err + } + + // Exports private key from keybase using password + privKey, err := kb.ExportPrivateKeyObject(args[0], decryptPassword) + if err != nil { + return err + } + + // Converts key to Ethermint secp256 implementation + emintKey, ok := privKey.(emintcrypto.PrivKeySecp256k1) + if !ok { + return fmt.Errorf("invalid private key type, must be Ethereum key: %T", privKey) + } + + // Formats key for output + privB := ethcrypto.FromECDSA(emintKey.ToECDSA()) + keyS := strings.ToUpper(hexutil.Encode(privB)[2:]) + + fmt.Println(keyS) + + return nil + }, + } +} diff --git a/cmd/emintcli/keys.go b/client/keys.go similarity index 90% rename from cmd/emintcli/keys.go rename to client/keys.go index fd14a34a..eca31248 100644 --- a/cmd/emintcli/keys.go +++ b/client/keys.go @@ -1,27 +1,27 @@ -package main +package client import ( "bufio" "io" + "github.com/spf13/cobra" + "github.com/spf13/viper" + "github.com/cosmos/cosmos-sdk/client/flags" clientkeys "github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/crypto/keyring" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/ethermint/crypto" - - "github.com/spf13/cobra" - "github.com/spf13/viper" ) const ( flagDryRun = "dry-run" ) -// keyCommands registers a sub-tree of commands to interact with +// KeyCommands registers a sub-tree of commands to interact with // local private key storage. -func keyCommands() *cobra.Command { +func KeyCommands() *cobra.Command { cmd := &cobra.Command{ Use: "keys", Short: "Add or view local private keys", @@ -31,8 +31,11 @@ func keyCommands() *cobra.Command { used by light-clients, full nodes, or any other application that needs to sign with a private key.`, } + + // support adding Ethereum supported keys addCmd := clientkeys.AddKeyCommand() addCmd.RunE = runAddCmd + cmd.AddCommand( clientkeys.MnemonicKeyCommand(), addCmd, @@ -45,11 +48,21 @@ func keyCommands() *cobra.Command { clientkeys.ParseKeyStringCommand(), clientkeys.MigrateCommand(), flags.LineBreak, - unsafeExportEthKeyCommand(), + UnsafeExportEthKeyCommand(), ) return cmd } +func runAddCmd(cmd *cobra.Command, args []string) error { + inBuf := bufio.NewReader(cmd.InOrStdin()) + kb, err := getKeybase(viper.GetBool(flagDryRun), inBuf) + if err != nil { + return err + } + + return clientkeys.RunAddCmd(cmd, args, kb, inBuf) +} + func getKeybase(transient bool, buf io.Reader) (keyring.Keybase, error) { if transient { return keyring.NewInMemory(keyring.WithKeygenFunc(crypto.EthermintKeygenFunc)), nil @@ -62,13 +75,3 @@ func getKeybase(transient bool, buf io.Reader) (keyring.Keybase, error) { buf, keyring.WithKeygenFunc(crypto.EthermintKeygenFunc)) } - -func runAddCmd(cmd *cobra.Command, args []string) error { - inBuf := bufio.NewReader(cmd.InOrStdin()) - kb, err := getKeybase(viper.GetBool(flagDryRun), inBuf) - if err != nil { - return err - } - - return clientkeys.RunAddCmd(cmd, args, kb, inBuf) -} diff --git a/cmd/emintd/testnet.go b/client/testnet.go similarity index 98% rename from cmd/emintd/testnet.go rename to client/testnet.go index 8190ebb1..1e14d3f4 100644 --- a/cmd/emintd/testnet.go +++ b/client/testnet.go @@ -1,4 +1,4 @@ -package main +package client // DONTCOVER @@ -52,11 +52,10 @@ var ( const nodeDirPerm = 0755 -// get cmd to initialize all files for tendermint testnet and application -func testnetCmd(ctx *server.Context, cdc *codec.Codec, +// TestnetCmd initializes all files for tendermint testnet and application +func TestnetCmd(ctx *server.Context, cdc *codec.Codec, mbm module.BasicManager, genBalIterator banktypes.GenesisBalancesIterator, ) *cobra.Command { - cmd := &cobra.Command{ Use: "testnet", Short: "Initialize files for a Ethermint testnet", diff --git a/cmd/emintcli/export.go b/cmd/emintcli/export.go deleted file mode 100644 index b06ebd56..00000000 --- a/cmd/emintcli/export.go +++ /dev/null @@ -1,82 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - "strings" - - "github.com/spf13/cobra" - "github.com/spf13/viper" - - "github.com/ethereum/go-ethereum/common/hexutil" - ethcrypto "github.com/ethereum/go-ethereum/crypto" - - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/client/input" - "github.com/cosmos/cosmos-sdk/crypto/keyring" - sdk "github.com/cosmos/cosmos-sdk/types" - - emintcrypto "github.com/cosmos/ethermint/crypto" -) - -func unsafeExportEthKeyCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "unsafe-export-eth-key [name]", - Short: "**UNSAFE** Export an Ethereum private key", - Long: `**UNSAFE** Export an Ethereum private key unencrypted to use in dev tooling`, - Args: cobra.ExactArgs(1), - RunE: runExportCmd, - } - return cmd -} - -func runExportCmd(cmd *cobra.Command, args []string) error { - inBuf := bufio.NewReader(cmd.InOrStdin()) - - kb, err := keyring.NewKeyring( - sdk.KeyringServiceName(), - viper.GetString(flags.FlagKeyringBackend), - viper.GetString(flags.FlagHome), - inBuf, - ) - if err != nil { - return err - } - - decryptPassword := "" - conf := true - keyringBackend := viper.GetString(flags.FlagKeyringBackend) - switch keyringBackend { - case keyring.BackendFile: - decryptPassword, err = input.GetPassword( - "**WARNING this is an unsafe way to export your unencrypted private key**\nEnter key password:", - inBuf) - case keyring.BackendOS: - conf, err = input.GetConfirmation( - "**WARNING** this is an unsafe way to export your unencrypted private key, are you sure?", - inBuf) - } - if err != nil || !conf { - return err - } - - // Exports private key from keybase using password - privKey, err := kb.ExportPrivateKeyObject(args[0], decryptPassword) - if err != nil { - return err - } - - // Converts key to Ethermint secp256 implementation - emintKey, ok := privKey.(emintcrypto.PrivKeySecp256k1) - if !ok { - return fmt.Errorf("invalid private key type, must be Ethereum key: %T", privKey) - } - - // Formats key for output - privB := ethcrypto.FromECDSA(emintKey.ToECDSA()) - keyS := strings.ToUpper(hexutil.Encode(privB)[2:]) - - fmt.Println(keyS) - - return nil -} diff --git a/cmd/emintcli/main.go b/cmd/emintcli/main.go index 6e4a9a8b..e8f3acee 100644 --- a/cmd/emintcli/main.go +++ b/cmd/emintcli/main.go @@ -2,21 +2,13 @@ package main import ( "fmt" - "os" - "path" "github.com/spf13/cobra" - "github.com/spf13/viper" - - "github.com/cosmos/ethermint/app" - "github.com/cosmos/ethermint/codec" - emintcrypto "github.com/cosmos/ethermint/crypto" - "github.com/cosmos/ethermint/rpc" tmamino "github.com/tendermint/tendermint/crypto/encoding/amino" "github.com/tendermint/tendermint/libs/cli" - "github.com/cosmos/cosmos-sdk/client" + sdkclient "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" clientkeys "github.com/cosmos/cosmos-sdk/client/keys" clientrpc "github.com/cosmos/cosmos-sdk/client/rpc" @@ -28,6 +20,12 @@ import ( authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" "github.com/cosmos/cosmos-sdk/x/bank" bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli" + + "github.com/cosmos/ethermint/app" + "github.com/cosmos/ethermint/client" + "github.com/cosmos/ethermint/codec" + "github.com/cosmos/ethermint/crypto" + "github.com/cosmos/ethermint/rpc" ) var ( @@ -38,8 +36,8 @@ func main() { // Configure cobra to sort commands cobra.EnableCommandSorting = false - tmamino.RegisterKeyType(emintcrypto.PubKeySecp256k1{}, emintcrypto.PubKeyAminoName) - tmamino.RegisterKeyType(emintcrypto.PrivKeySecp256k1{}, emintcrypto.PrivKeyAminoName) + tmamino.RegisterKeyType(crypto.PubKeySecp256k1{}, crypto.PubKeyAminoName) + tmamino.RegisterKeyType(crypto.PrivKeySecp256k1{}, crypto.PrivKeyAminoName) keyring.CryptoCdc = cdc clientkeys.KeysCdc = cdc @@ -59,18 +57,18 @@ func main() { // Add --chain-id to persistent flags and mark it required rootCmd.PersistentFlags().String(flags.FlagChainID, "", "Chain ID of tendermint node") rootCmd.PersistentPreRunE = func(_ *cobra.Command, _ []string) error { - return initConfig(rootCmd) + return client.InitConfig(rootCmd) } // Construct Root Command rootCmd.AddCommand( clientrpc.StatusCommand(), - client.ConfigCmd(app.DefaultCLIHome), + sdkclient.ConfigCmd(app.DefaultCLIHome), queryCmd(cdc), txCmd(cdc), rpc.EmintServeCmd(cdc), flags.LineBreak, - keyCommands(), + client.KeyCommands(), flags.LineBreak, version.Cmd, flags.NewCompletionCmd(rootCmd, true), @@ -140,26 +138,3 @@ func txCmd(cdc *sdkcodec.Codec) *cobra.Command { return txCmd } - -func initConfig(cmd *cobra.Command) error { - home, err := cmd.PersistentFlags().GetString(cli.HomeFlag) - if err != nil { - return err - } - - cfgFile := path.Join(home, "config", "config.toml") - if _, err := os.Stat(cfgFile); err == nil { - viper.SetConfigFile(cfgFile) - - if err := viper.ReadInConfig(); err != nil { - return err - } - } - if err := viper.BindPFlag(flags.FlagChainID, cmd.PersistentFlags().Lookup(flags.FlagChainID)); err != nil { - return err - } - if err := viper.BindPFlag(cli.EncodingFlag, cmd.PersistentFlags().Lookup(cli.EncodingFlag)); err != nil { - return err - } - return viper.BindPFlag(cli.OutputFlag, cmd.PersistentFlags().Lookup(cli.OutputFlag)) -} diff --git a/cmd/emintd/main.go b/cmd/emintd/main.go index da19b2d5..22cf50ed 100644 --- a/cmd/emintd/main.go +++ b/cmd/emintd/main.go @@ -2,9 +2,17 @@ package main import ( "encoding/json" - "fmt" "io" - "math/big" + + "github.com/spf13/cobra" + "github.com/spf13/viper" + + abci "github.com/tendermint/tendermint/abci/types" + tmamino "github.com/tendermint/tendermint/crypto/encoding/amino" + "github.com/tendermint/tendermint/libs/cli" + "github.com/tendermint/tendermint/libs/log" + tmtypes "github.com/tendermint/tendermint/types" + dbm "github.com/tendermint/tm-db" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client/flags" @@ -19,19 +27,10 @@ import ( genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" "github.com/cosmos/cosmos-sdk/x/staking" - "github.com/spf13/cobra" - "github.com/spf13/viper" - "github.com/cosmos/ethermint/app" + "github.com/cosmos/ethermint/client" "github.com/cosmos/ethermint/codec" - emintcrypto "github.com/cosmos/ethermint/crypto" - - abci "github.com/tendermint/tendermint/abci/types" - tmamino "github.com/tendermint/tendermint/crypto/encoding/amino" - "github.com/tendermint/tendermint/libs/cli" - "github.com/tendermint/tendermint/libs/log" - tmtypes "github.com/tendermint/tendermint/types" - dbm "github.com/tendermint/tm-db" + "github.com/cosmos/ethermint/crypto" ) const flagInvCheckPeriod = "inv-check-period" @@ -44,8 +43,8 @@ func main() { cdc := codec.MakeCodec(app.ModuleBasics) appCodec := codec.NewAppCodec(cdc) - tmamino.RegisterKeyType(emintcrypto.PubKeySecp256k1{}, emintcrypto.PubKeyAminoName) - tmamino.RegisterKeyType(emintcrypto.PrivKeySecp256k1{}, emintcrypto.PrivKeyAminoName) + tmamino.RegisterKeyType(crypto.PubKeySecp256k1{}, crypto.PubKeyAminoName) + tmamino.RegisterKeyType(crypto.PrivKeySecp256k1{}, crypto.PrivKeyAminoName) keyring.CryptoCdc = cdc genutil.ModuleCdc = cdc @@ -67,7 +66,9 @@ func main() { } // CLI commands to initialize the chain rootCmd.AddCommand( - withChainIDValidation(genutilcli.InitCmd(ctx, cdc, app.ModuleBasics, app.DefaultNodeHome)), + client.ValidateChainID( + genutilcli.InitCmd(ctx, cdc, app.ModuleBasics, app.DefaultNodeHome), + ), genutilcli.CollectGenTxsCmd(ctx, cdc, bank.GenesisBalancesIterator{}, app.DefaultNodeHome), genutilcli.MigrateGenesisCmd(ctx, cdc), genutilcli.GenTxCmd( @@ -75,7 +76,7 @@ func main() { app.DefaultNodeHome, app.DefaultCLIHome, ), genutilcli.ValidateGenesisCmd(ctx, cdc, app.ModuleBasics), - testnetCmd(ctx, cdc, app.ModuleBasics, bank.GenesisBalancesIterator{}), + client.TestnetCmd(ctx, cdc, app.ModuleBasics, bank.GenesisBalancesIterator{}), // AddGenesisAccountCmd allows users to add accounts to the genesis file AddGenesisAccountCmd(ctx, cdc, appCodec, app.DefaultNodeHome, app.DefaultCLIHome), flags.NewCompletionCmd(rootCmd, true), @@ -116,25 +117,3 @@ func exportAppStateAndTMValidators( return emintApp.ExportAppStateAndValidators(forZeroHeight, jailWhiteList) } - -// Wraps cobra command with a RunE function with integer chain-id verification -func withChainIDValidation(baseCmd *cobra.Command) *cobra.Command { - // Copy base run command to be used after chain verification - baseRunE := baseCmd.RunE - - // Function to replace command's RunE function - chainIDVerify := func(cmd *cobra.Command, args []string) error { - chainIDFlag := viper.GetString(flags.FlagChainID) - - // Verify that the chain-id entered is a base 10 integer - _, ok := new(big.Int).SetString(chainIDFlag, 10) - if !ok { - return fmt.Errorf("invalid chainID: %s, must be base-10 integer format", chainIDFlag) - } - - return baseRunE(cmd, args) - } - - baseCmd.RunE = chainIDVerify - return baseCmd -}