如何从 Solana 的助记词中获取正确的公共地址?

问题描述 投票:0回答:3

我正在尝试在我的react-native测试项目中使用solana-web3.js获取Solana钱包的正确公共地址

import { Keypair} from '@solana/web3.js';
import * as bip39 from 'bip39';
import * as bip32 from 'bip32';

const derivePath = "m/44'/501'/0'/0'";
const mnemonic = "...12 word phrase"

const seed: Buffer = yield bip39.mnemonicToSeed(mnemonic);
// also tried to slice seed.slice(0, 32);
const derivedSeed = bip32.fromSeed(seed).derivePath(derivePath).privateKey;
const keypair = Keypair.fromSeed(derivedSeed);
const publicKey = keypair.publicKey.toString();

我采用了应该用于 Phantom 钱包的派生路径(并且可以在 Solflare 钱包中选择) 但问题是 - 我没有获得与在这些浏览器钱包中获得的相同的公钥。

那么我上面的代码哪里可能出错了?

更新: 当我使用“ed25519-hd-key”lib 而不是“bip32”来获取派生种子时,问题就消失了。

import * as ed25519 from 'ed25519-hd-key';

const derivedSeed = ed25519.derivePath(derivePath, seed.toString('hex')).key;
javascript blockchain seed mnemonics solana
3个回答
3
投票

我的工作变体:

import nacl from 'tweetnacl';
import * as bip39  from 'bip39';
import { derivePath } from 'ed25519-hd-key';

const web3 = require('@solana/web3.js')

const seed = await bip39.mnemonicToSeed(mnemonic);
const seedBuffer = Buffer.from(seed).toString('hex');
const path44Change = `m/44'/501'/0'/0'`;
const derivedSeed = derivePath(path44Change, seedBuffer).key;
keypair = new web3.Account(nacl.sign.keyPair.fromSeed(derivedSeed).secretKey);

0
投票

您应该使用“m/501'/0'/0'”路径


0
投票

除了 @dapp-deep 的答案之外,我还想添加一些更新的答案,因为

Account
中的
@solana/web.js
现在已贬值,我们可以使用
KeyPair

  1. bip39.mnemonicToSeed(mnemonic):此行使用 bip39 库将助记词短语(一系列易于记忆的单词)转换为种子缓冲区(固定长度的二进制值)。

2.Buffer.from(seed).toString('hex'):然后将种子缓冲区转换为十六进制字符串表示形式。

  1. const path44Change = \m/44'/501'/0'/0'
    ;:这一行定义了使用BIP44标准的推导路径。路径 m/44'/501'/0'/0'` 特定于 Solana 加密货币,代表以下内容:

    m
    代表主密钥(派生路径的根)。

    44'
    是目的字段,表示派生密钥将用于硬币类型的目的。

    501'
    是币类型字段,指定加密货币(501 是 Solana 的分配值)。

    0'
    是账户字段,通常用于表示来自同一种子的不同账户。

    0'
    是找零字段,通常用于区分外部和内部/找零地址。

  2. const derivedSeed = derivePath(path44Change, seedBuffer).key;
    :此行使用未指定的
    derivePath
    函数从提供的导出路径和种子缓冲区导出新种子。返回对象的 key 属性被赋值给
    derivedSeed

  3. const kp = Keypair.fromSeed(derivedSeed);
    :最后,使用 Solana 库中的
    Keypair.fromSeed
    方法从派生种子创建新的密钥对对象 (
    kp
    )。

  4. return kp;
    :函数返回生成的keypair对象,其中包含公钥和私钥。

派生路径是必要的,因为它提供了一种标准化的方法,以确定性和可重复的方式从单个种子(助记词短语)派生多个密钥对。这在加密货币钱包中特别有用,其中可以从相同的助记词生成多个地址,从而可以更好地组织和管理资金。

通过遵循BIP44标准,派生路径确保派生密钥与遵循相同标准的其他钱包和工具兼容。它还在不同类型的硬币或账户之间提供一定程度的隔离,降低意外资金转移或密钥重复使用的风险。

以下是所需的代码:

import * as bip39 from "bip39";
import {
  Keypair,
  Connection,
} from "@solana/web3.js";
import { derivePath } from 'ed25519-hd-key';


async function getKeyCreatedBySolanaKeygenFromMnemonic(mnemonic: string) {
  const seed = await bip39.mnemonicToSeed(mnemonic);
    const seedBuffer = Buffer.from(seed).toString('hex');
    const path44Change = `m/44'/501'/0'/0'`;
    const derivedSeed = derivePath(path44Change, seedBuffer).key;
    const kp = Keypair.fromSeed(derivedSeed);
    return kp;
}

© www.soinside.com 2019 - 2024. All rights reserved.