Go语言 获取助记符的地址和私钥

vwkv1x7d  于 10个月前  发布在  Go
关注(0)|答案(1)|浏览(173)

我基本上是试图通过使用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
}

字符串
我有主密钥,但我如何获得派生帐户(公钥和私钥)?

new9mtju

new9mtju1#

为了将公钥和私钥作为已知的十六进制字符串(帐户密钥)检索,您需要将生成的主私钥和公钥转换为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)

相关问题