You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Golang中从助记词派生以太坊账户的公私钥?

解决Golang从助记词派生以太坊公私钥的问题

你当前的代码只生成了master密钥,还没按照BIP-44路径m/44'/60'/0'/0/0派生出对应以太坊账户的子密钥。下面是完整的实现步骤和修改后的代码:

关键步骤说明

  1. 解析派生路径:将BIP路径拆分为多个层级,区分普通索引和hardened索引(带'的索引需要加上0x80000000)。
  2. 逐层派生子密钥:从masterKey开始,依次派生每个层级的子密钥。
  3. 生成以太坊地址:用派生后的公钥(去掉开头的0x04字节)计算Keccak256哈希,取最后20字节作为地址并添加0x前缀。
  4. 格式化公私钥:将私钥和公钥转换为十六进制字符串,添加0x前缀。

修改后的完整代码

package generator

import (
	"encoding/hex"
	"fmt"
	"strconv"
	"strings"

	"github.com/tyler-smith/go-bip32"
	"github.com/tyler-smith/go-bip39"
	"golang.org/x/crypto/sha3"
)

type HDWallet struct{}

const BIP_PATH = "m/44'/60'/0'/0/0"

func (wallet *HDWallet) GenerateAddressAndPrivateKey(seedPhrase string) (string, string, error) {
	// 从助记词生成seed
	seed, err := bip39.NewSeedWithErrorChecking(seedPhrase, "")
	if err != nil {
		return "", "", err
	}

	// 生成master密钥
	masterKey, err := bip32.NewMasterKey(seed)
	if err != nil {
		return "", "", err
	}

	// 解析BIP路径并派生子密钥
	parts := strings.Split(BIP_PATH, "/")
	currentKey := masterKey
	// 跳过第一个"m"部分
	for _, part := range parts[1:] {
		// 处理hardened索引(带')
		isHardened := strings.HasSuffix(part, "'")
		if isHardened {
			part = strings.TrimSuffix(part, "'")
		}

		// 转换为整数索引
		index, err := strconv.ParseUint(part, 10, 32)
		if err != nil {
			return "", "", fmt.Errorf("invalid path part: %s, err: %w", part, err)
		}

		// hardened索引需要加上0x80000000
		if isHardened {
			index += 0x80000000
		}

		// 派生子密钥
		currentKey, err = currentKey.Child(uint32(index))
		if err != nil {
			return "", "", fmt.Errorf("failed to derive child key: %w", err)
		}
	}

	// 获取私钥并格式化为十六进制字符串(带0x前缀)
	privateKeyHex := "0x" + hex.EncodeToString(currentKey.Key)

	// 获取公钥(去掉开头的0x04字节,以太坊用非压缩公钥)
	publicKey := currentKey.PublicKey().Key[1:]
	// 计算Keccak256哈希
	hash := sha3.NewLegacyKeccak256()
	hash.Write(publicKey)
	hashBytes := hash.Sum(nil)
	// 取最后20字节作为以太坊地址,添加0x前缀
	address := "0x" + hex.EncodeToString(hashBytes[12:])

	return address, privateKeyHex, nil
}

代码说明

  • 路径解析:通过拆分路径字符串,逐个处理每个层级的索引,区分hardened类型并转换为正确的索引值。
  • 子密钥派生:使用currentKey.Child()方法逐层派生,最终得到对应以太坊账户的子密钥。
  • 地址生成:以太坊地址基于公钥的Keccak256哈希生成,需去掉公钥开头的0x04标识位,再取哈希的后20字节。
  • 公私钥格式化:将原始字节数组转换为十六进制字符串,并添加以太坊标准的0x前缀。

内容的提问来源于stack exchange,提问作者Gervasius Twinklewinkleson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 08:53:13