我基本上是尝试使用 Golang 通过从以太坊帐户的种子短语派生路径来获取公钥和私钥。我有这个:
package generator
import (
"fmt"
"github.com/tyler-smith/go-bip32"
"github.com/tyler-smith/go-bip39"
)
type HDWallet struct{}
const BIP_PATH = "m/44'/60'/0'/0/0"
func (wallet *HDWallet) GenerateAddressAndPrivateKey(seedPhrase string) (string, string, error) {
seed, err := bip39.NewSeedWithErrorChecking(seedPhrase, "")
if err != nil {
return "", "", err
}
masterKey, err := bip32.NewMasterKey(seed)
if err != nil {
return "", "", err
}
publicKey := masterKey.PublicKey()
if err != nil {
return "", "", err
}
return ???, ???, nil
}
我有主密钥,但如何获得派生帐户(公钥和私钥)?
为了检索公钥和私钥作为其众所周知的十六进制字符串(帐户密钥),您需要将生成的主私钥和公钥转换为 ECDSA 十六进制字符串,如下所示。顺便说一句,通常您不会使用主私钥和公钥。
package main
import (
"crypto/ecdsa"
"encoding/hex"
"fmt"
"github.com/ethereum/go-ethereum/crypto"
"github.com/tyler-smith/go-bip32"
"github.com/tyler-smith/go-bip39"
)
func main() {
// Generate a mnemonic
entropy, _ := bip39.NewEntropy(256)
mnemonic, _ := bip39.NewMnemonic(entropy)
fmt.Println("Mnemonic (gen): ", mnemonic)
// Generate a Bip32 HD wallet for the mnemonic and a user supplied passphrase
seed := bip39.NewSeed(mnemonic, "Secret Passphrase")
masterPrivateKey, _ := bip32.NewMasterKey(seed)
masterPublicKey := masterPrivateKey.PublicKey()
fmt.Println("Master private key (gen): ", masterPrivateKey)
fmt.Println("Master public key (gen): ", masterPublicKey)
// Use Unsafe to suppress error, otherwise use crypto.ToECDSA
ecdaPrivateKey := crypto.ToECDSAUnsafe(masterPrivateKey.Key)
ecdaPublicKey := ecdaPrivateKey.Public().(*ecdsa.PublicKey)
fmt.Println("ECDA Private key: ", ecdaPrivateKey.D)
fmt.Println("ECDA Public key: ", ecdaPublicKey.X)
privateKeyHex := fmt.Sprintf("%x", ecdaPrivateKey.D)
publicKeyHex := fmt.Sprintf("%x", crypto.CompressPubkey(ecdaPublicKey)) // Encode a public key to the 33-byte compressed format
fmt.Println("Private key (hex):", privateKeyHex)
fmt.Println("Public key (hex):", publicKeyHex)
}
您可以检查生成的公钥十六进制字符串是否属于私钥十六进制字符串,如下所示。
// Decode the private key and public key from hex strings
privateKey, err := crypto.HexToECDSA(privateKeyHex)
if err != nil {
fmt.Println("Invalid private key:", err)
return
}
publicKeyBytes, err := hex.DecodeString(publicKeyHex)
if err != nil {
fmt.Println("Invalid public key:", err)
return
}
// Use crypto.DecompressPubkey to decode the public key bytes
givenPublicKey, err := crypto.DecompressPubkey(publicKeyBytes)
if err != nil {
fmt.Println("Invalid public key:", err)
return
}
// Derive the public key from the private key
derivedPublicKey := privateKey.Public().(*ecdsa.PublicKey)
// Compare the derived public key with the given public key
if derivedPublicKey.X.Cmp(givenPublicKey.X) == 0 && derivedPublicKey.Y.Cmp(givenPublicKey.Y) == 0 {
fmt.Println("The private key matches the public key.")
} else {
fmt.Println("The private key does not match the public key.")
}
--编辑--
不能保证,但请尝试这种方法。
// BIP44 derivation path format: m / purpose' / coin_type' / account' / change / address_index
// Example: m/44'/0'/0'/0/0
purposeKey, _ := masterKey.NewChildKey(bip32.FirstHardenedChild + 44)
coinTypeKey, _ := purposeKey.NewChildKey(bip32.FirstHardenedChild)
accountKey, _ := coinTypeKey.NewChildKey(bip32.FirstHardenedChild)
changeKey, _ := accountKey.NewChildKey(0)
addressKey, _ := changeKey.NewChildKey(0)
要使用 Golang 从助记词获取以太坊账户的公钥和私钥,您需要:
使用 Go 以太坊库,例如 go-ethereum。 将助记词转换为种子。 使用以太坊的适当派生路径派生密钥(对于第一个帐户,通常为 m/44'/60'/0'/0/0)。 从派生路径中提取私钥和公钥。 确保妥善保管钥匙。