diff --git a/CHANGELOG.md b/CHANGELOG.md index 522d15cc..1db2f9e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -71,6 +71,7 @@ the Tracer type used to collect execution traces from the EVM transaction execut ### Improvements +* (client) [tharsis#450](https://github.com/tharsis/ethermint/issues/450) Add EIP55 hex address support on `debug addr` command. * (server) [tharsis#343](https://github.com/tharsis/ethermint/pull/343) Define a wrap tendermint logger `Handler` go-ethereum's `root` logger. * (rpc) [tharsis#457](https://github.com/tharsis/ethermint/pull/457) Configure RPC gas cap through app config. * (evm) [tharsis#434](https://github.com/tharsis/ethermint/pull/434) Support different `Tracer` types for the EVM. diff --git a/client/debug/debug.go b/client/debug/debug.go new file mode 100644 index 00000000..9e89633b --- /dev/null +++ b/client/debug/debug.go @@ -0,0 +1,128 @@ +package debug + +import ( + "encoding/hex" + "fmt" + "strconv" + "strings" + + "github.com/spf13/cobra" + "github.com/tendermint/tendermint/libs/bytes" + + "github.com/ethereum/go-ethereum/common" + + "github.com/cosmos/cosmos-sdk/client" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/version" +) + +// Cmd creates a main CLI command +func Cmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "debug", + Short: "Tool for helping with debugging your application", + RunE: client.ValidateCmd, + } + + cmd.AddCommand(PubkeyCmd()) + cmd.AddCommand(AddrCmd()) + cmd.AddCommand(RawBytesCmd()) + + return cmd +} + +// getPubKeyFromString decodes SDK PubKey using JSON marshaler. +func getPubKeyFromString(ctx client.Context, pkstr string) (cryptotypes.PubKey, error) { + var pk cryptotypes.PubKey + err := ctx.Codec.UnmarshalInterfaceJSON([]byte(pkstr), &pk) + return pk, err +} + +func PubkeyCmd() *cobra.Command { + return &cobra.Command{ + Use: "pubkey [pubkey]", + Short: "Decode a pubkey from proto JSON", + Long: "Decode a pubkey from proto JSON and display it's address", + Example: fmt.Sprintf( + `"$ %s debug pubkey '{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AurroA7jvfPd1AadmmOvWM2rJSwipXfRf8yD6pLbA2DJ"}'`, + version.AppName, + ), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + pk, err := getPubKeyFromString(clientCtx, args[0]) + if err != nil { + return err + } + + addr := pk.Address() + cmd.Printf("Address (EIP-55): %s\n", common.BytesToAddress(addr)) + cmd.Printf("Bech32 Acc: %s\n", sdk.AccAddress(addr)) + cmd.Println("PubKey Hex:", hex.EncodeToString(pk.Bytes())) + return nil + }, + } +} + +func AddrCmd() *cobra.Command { + return &cobra.Command{ + Use: "addr [address]", + Short: "Convert an address between hex and bech32", + Long: "Convert an address between hex encoding and bech32.", + Example: fmt.Sprintf( + `$ %s debug addr eth10jmp6sgh4cc6zt3e8gw05wavvejgr5pw2unfju +$ %s debug addr 0xA588C66983a81e800Db4dF74564F09f91c026351`, version.AppName, version.AppName), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + + addrString := args[0] + cfg := sdk.GetConfig() + + var addr []byte + switch { + case common.IsHexAddress(addrString): + addr = common.HexToAddress(addrString).Bytes() + case strings.HasPrefix(addrString, cfg.GetBech32ValidatorAddrPrefix()): + addr, _ = sdk.ValAddressFromBech32(addrString) + case strings.HasPrefix(addrString, cfg.GetBech32AccountAddrPrefix()): + addr, _ = sdk.AccAddressFromBech32(addrString) + default: + return fmt.Errorf("expected a valid hex or bech32 address (acc prefix %s), got '%s'", cfg.GetBech32AccountAddrPrefix(), addrString) + } + + cmd.Println("Address bytes:", addr) + cmd.Printf("Address (hex): %s\n", bytes.HexBytes(addr)) + cmd.Printf("Address (EIP-55): %s\n", common.BytesToAddress(addr)) + cmd.Printf("Bech32 Acc: %s\n", sdk.AccAddress(addr)) + cmd.Printf("Bech32 Val: %s\n", sdk.ValAddress(addr)) + return nil + }, + } +} + +func RawBytesCmd() *cobra.Command { + return &cobra.Command{ + Use: "raw-bytes [raw-bytes]", + Short: "Convert raw bytes output (eg. [10 21 13 255]) to hex", + Example: fmt.Sprintf(`$ %s debug raw-bytes [72 101 108 108 111 44 32 112 108 97 121 103 114 111 117 110 100]`, version.AppName), + Args: cobra.ExactArgs(1), + RunE: func(_ *cobra.Command, args []string) error { + stringBytes := args[0] + stringBytes = strings.Trim(stringBytes, "[") + stringBytes = strings.Trim(stringBytes, "]") + spl := strings.Split(stringBytes, " ") + + byteArray := []byte{} + for _, s := range spl { + b, err := strconv.ParseInt(s, 10, 8) + if err != nil { + return err + } + byteArray = append(byteArray, byte(b)) + } + fmt.Printf("%X\n", byteArray) + return nil + }, + } +} diff --git a/cmd/ethermintd/root.go b/cmd/ethermintd/root.go index 4d87e9de..8ea1dd4e 100644 --- a/cmd/ethermintd/root.go +++ b/cmd/ethermintd/root.go @@ -16,7 +16,6 @@ import ( "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/config" - "github.com/cosmos/cosmos-sdk/client/debug" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/rpc" sdkserver "github.com/cosmos/cosmos-sdk/server" @@ -33,6 +32,7 @@ import ( "github.com/tharsis/ethermint/app" ethermintclient "github.com/tharsis/ethermint/client" + "github.com/tharsis/ethermint/client/debug" "github.com/tharsis/ethermint/crypto/hd" "github.com/tharsis/ethermint/encoding" "github.com/tharsis/ethermint/server" diff --git a/docs/basics/accounts.md b/docs/basics/accounts.md index 9699ba16..85ca5d19 100644 --- a/docs/basics/accounts.md +++ b/docs/basics/accounts.md @@ -56,24 +56,21 @@ Cosmos `sdk.AccAddress`. The `ethermintd debug addr
` can be used to convert an address between hex and bech32 formats. For example: ```bash -ethermintd debug addr eth12uqc42yj77hk64cdr3vsnpkfs6k0pllln7rudt - Address: [87 1 138 168 146 247 175 109 87 13 28 89 9 134 201 134 172 240 255 255] - Address (hex): 57018AA892F7AF6D570D1C590986C986ACF0FFFF - Bech32 Acc: eth12uqc42yj77hk64cdr3vsnpkfs6k0pllln7rudt - Bech32 Val: ethvaloper12uqc42yj77hk64cdr3vsnpkfs6k0pllldvagr4 +ethermintd debug addr eth10jmp6sgh4cc6zt3e8gw05wavvejgr5pw2unfju + Address bytes: [124 182 29 65 23 174 49 161 46 57 58 28 250 59 172 102 100 129 208 46] + Address (hex): 7CB61D4117AE31A12E393A1CFA3BAC666481D02E + Address (EIP-55): 0x7cB61D4117AE31a12E393a1Cfa3BaC666481D02E + Bech32 Acc: eth10jmp6sgh4cc6zt3e8gw05wavvejgr5pw2unfju + Bech32 Val: ethvaloper10jmp6sgh4cc6zt3e8gw05wavvejgr5pw5wdauz -ethermintd debug addr 57018AA892F7af6D570D1c590986c986aCf0fFff - Address: [87 1 138 168 146 247 175 109 87 13 28 89 9 134 201 134 172 240 255 255] - Address (hex): 57018AA892F7AF6D570D1C590986C986ACF0FFFF - Bech32 Acc: eth12uqc42yj77hk64cdr3vsnpkfs6k0pllln7rudt - Bech32 Val: ethvaloper12uqc42yj77hk64cdr3vsnpkfs6k0pllldvagr4 +ethermintd debug addr 0x7cB61D4117AE31a12E393a1Cfa3BaC666481D02E + Address bytes: [124 182 29 65 23 174 49 161 46 57 58 28 250 59 172 102 100 129 208 46] + Address (hex): 7CB61D4117AE31A12E393A1CFA3BAC666481D02E + Address (EIP-55): 0x7cB61D4117AE31a12E393a1Cfa3BaC666481D02E + Bech32 Acc: eth10jmp6sgh4cc6zt3e8gw05wavvejgr5pw2unfju + Bech32 Val: ethvaloper10jmp6sgh4cc6zt3e8gw05wavvejgr5pw5wdauz ``` -::: tip -Add the `0x` prefix to the returned hex address above to represent the Ethereum hex address format. For example: -`Address (hex): 57018AA892F7AF6D570D1C590986C986ACF0FFFF` implies that `0x57018AA892F7AF6D570D1C590986C986ACF0FFFF` is the Ethereum hex address. -::: - ### Key output ::: tip