Skip to content

Commit fdce1bd

Browse files
authored
Merge pull request #10 from bcdevtools/imp/support-mnemonic-as-secret-key
imp: support mnemonic as account secret
2 parents 8bbd8f6 + 7d97653 commit fdce1bd

File tree

5 files changed

+140
-28
lines changed

5 files changed

+140
-28
lines changed

cmd/tx/evm.go

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"crypto/ecdsa"
66
"fmt"
77
"os"
8+
"regexp"
89
"strings"
910

1011
"github.com/bcdevtools/devd/v2/cmd/utils"
@@ -64,17 +65,28 @@ func mustSecretEvmAccount(cmd *cobra.Command) (privKey string, ecdsaPrivateKey *
6465
os.Exit(1)
6566
}
6667

67-
privKey = strings.TrimPrefix(privKey, "0x")
68-
69-
pKeyBytes, err := hexutil.Decode("0x" + privKey)
70-
if err != nil {
71-
utils.PrintlnStdErr("ERR: failed to decode secret key")
72-
os.Exit(1)
73-
}
74-
75-
ecdsaPrivateKey, err = crypto.ToECDSA(pKeyBytes)
76-
if err != nil {
77-
utils.PrintlnStdErr("ERR: failed to convert secret key to ECDSA")
68+
if regexp.MustCompile(`^(0x)?[a-fA-F\d]{64}$`).MatchString(privKey) {
69+
// private key
70+
privKey = strings.TrimPrefix(privKey, "0x")
71+
72+
pKeyBytes, err := hexutil.Decode("0x" + privKey)
73+
if err != nil {
74+
utils.PrintlnStdErr("ERR: failed to decode private key")
75+
os.Exit(1)
76+
}
77+
78+
ecdsaPrivateKey, err = crypto.ToECDSA(pKeyBytes)
79+
if err != nil {
80+
utils.PrintlnStdErr("ERR: failed to convert private key to ECDSA")
81+
os.Exit(1)
82+
}
83+
} else if mnemonicCount := len(strings.Split(privKey, " ")); mnemonicCount == 12 || mnemonicCount == 24 {
84+
// is mnemonic
85+
mnemonic := privKey
86+
ecdsaPrivateKey, err = utils.FromMnemonicToPrivateKey(mnemonic, "" /*no password protected*/)
87+
utils.ExitOnErr(err, "failed to convert mnemonic to private key")
88+
} else {
89+
utils.PrintlnStdErr("ERR: invalid secret key format")
7890
os.Exit(1)
7991
}
8092

cmd/tx/root.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const (
1212

1313
const (
1414
flagEvmRpcDesc = "EVM Json-RPC endpoint, default is " + constants.DEFAULT_EVM_RPC + ", can be set by environment variable " + constants.ENV_EVM_RPC
15-
flagSecretKeyDesc = "Secret key of the account, can be set by environment variable " + constants.ENV_SECRET_KEY
15+
flagSecretKeyDesc = "Secret private key or mnemonic of the account, can be set by environment variable " + constants.ENV_SECRET_KEY
1616
)
1717

1818
// Commands registers a sub-tree of commands

cmd/utils/account_util.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package utils
2+
3+
import (
4+
"crypto/ecdsa"
5+
6+
"github.com/btcsuite/btcd/btcutil/hdkeychain"
7+
"github.com/btcsuite/btcd/chaincfg"
8+
cosmoshd "github.com/cosmos/cosmos-sdk/crypto/hd"
9+
"github.com/cosmos/go-bip39"
10+
"github.com/ethereum/go-ethereum/accounts"
11+
)
12+
13+
func FromMnemonicToPrivateKey(mnemonic, password string) (*ecdsa.PrivateKey, error) {
14+
hdPathStr := cosmoshd.CreateHDPath(60, 0, 0).String()
15+
hdPath, err := accounts.ParseDerivationPath(hdPathStr)
16+
if err != nil {
17+
return nil, err
18+
}
19+
20+
seed, err := bip39.NewSeedWithErrorChecking(mnemonic, password)
21+
if err != nil {
22+
return nil, err
23+
}
24+
25+
// create a BTC-utils hd-derivation key chain
26+
masterKey, err := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams)
27+
if err != nil {
28+
return nil, err
29+
}
30+
31+
key := masterKey
32+
for _, n := range hdPath {
33+
key, err = key.Derive(n)
34+
if err != nil {
35+
return nil, err
36+
}
37+
}
38+
39+
// btc-utils representation of a secp256k1 private key
40+
privateKey, err := key.ECPrivKey()
41+
if err != nil {
42+
return nil, err
43+
}
44+
45+
// cast private key to a convertible form (single scalar field element of secp256k1)
46+
// and then load into ethcrypto private key format.
47+
return privateKey.ToECDSA(), nil
48+
}

go.mod

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@ module github.com/bcdevtools/devd/v2
33
go 1.20
44

55
require (
6+
github.com/btcsuite/btcd v0.24.2
7+
github.com/btcsuite/btcd/btcutil v1.1.5
68
github.com/cometbft/cometbft v0.37.4
79
github.com/cosmos/cosmos-sdk v0.47.10
10+
github.com/cosmos/go-bip39 v1.0.0
811
github.com/ethereum/go-ethereum v1.10.26
912
github.com/pkg/errors v0.9.1
1013
github.com/shirou/gopsutil/v3 v3.24.3
1114
github.com/spf13/cobra v1.7.0
12-
github.com/stretchr/testify v1.9.0
15+
github.com/stretchr/testify v1.10.0
1316
golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb
1417
)
1518

@@ -20,6 +23,7 @@ require (
2023
github.com/VictoriaMetrics/fastcache v1.6.0 // indirect
2124
github.com/beorn7/perks v1.0.1 // indirect
2225
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
26+
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect
2327
github.com/cespare/xxhash v1.1.0 // indirect
2428
github.com/cespare/xxhash/v2 v2.2.0 // indirect
2529
github.com/cometbft/cometbft-db v0.7.0 // indirect
@@ -29,6 +33,7 @@ require (
2933
github.com/cosmos/gogoproto v1.4.10 // indirect
3034
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
3135
github.com/deckarep/golang-set v1.8.0 // indirect
36+
github.com/decred/dcrd/crypto/blake256 v1.1.0 // indirect
3237
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
3338
github.com/dgraph-io/badger/v2 v2.2007.4 // indirect
3439
github.com/dgraph-io/ristretto v0.1.1 // indirect
@@ -90,10 +95,10 @@ require (
9095
github.com/tklauser/numcpus v0.6.1 // indirect
9196
github.com/yusufpapurcu/wmi v1.2.4 // indirect
9297
go.etcd.io/bbolt v1.3.7 // indirect
93-
golang.org/x/crypto v0.22.0 // indirect
98+
golang.org/x/crypto v0.32.0 // indirect
9499
golang.org/x/net v0.21.0 // indirect
95-
golang.org/x/sys v0.19.0 // indirect
96-
golang.org/x/text v0.14.0 // indirect
100+
golang.org/x/sys v0.29.0 // indirect
101+
golang.org/x/text v0.21.0 // indirect
97102
google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 // indirect
98103
google.golang.org/grpc v1.60.1 // indirect
99104
google.golang.org/protobuf v1.32.0 // indirect

0 commit comments

Comments
 (0)