// Copyright 2021 Evmos Foundation // This file is part of Evmos' Ethermint library. // // The Ethermint library is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // The Ethermint library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE 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 ethm10jmp6sgh4cc6zt3e8gw05wavvejgr5pw2unfju $ %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 }, } }