如何使用 Hedera JS SDK 基于 BIP-39 种子短语和自定义派生路径生成一组 ECDSA 密钥对?

bgu*_*uiz 3 javascript mnemonics ecdsa hedera-hashgraph hedera

我目前正在使用 Hedera JS SDK 直接使用私钥作为输入来生成单个 ECDSA 密钥对,如下所示:

const privateKey = PrivateKey.fromStringECDSA(process.env.TARGET_HEX_PRIVATE_KEY);
    
Run Code Online (Sandbox Code Playgroud)

相反,我想做这样的事情,我使用 BIP-39 种子短语和派生路径作为输入:

const mnemonic = Mnemonic.fromString(process.env.TARGET_SEED_PHRASE);
const privateKey = await mnemonic.toEcdsaPrivateKey('', "m/44'/60'/0'/0/0");

Run Code Online (Sandbox Code Playgroud)

然而,根据其 JsDoc 注释,MnemonictoEcdsaPrivateKey函数似乎接受一个数字数组作为派生路径的输入@param,复制如下:

    /**
     * Recover an ECDSA private key from this mnemonic phrase, with an
     * optional passphrase.
     *
     * @param {string} [passphrase]
     * @param {number[]} [path]
     * @returns {Promise<PrivateKey>}
     */
    async toEcdsaPrivateKey(passphrase = "", path) {
        return CACHE.privateKeyConstructor(
            await this._mnemonic.toEcdsaPrivateKey(passphrase, path)
        );
    }
Run Code Online (Sandbox Code Playgroud)

在我的用例中,我想使用 MetaMask,不幸的是,它还不支持每个网络配置的自定义派生路径,而是硬编码了以太坊派生路径m/44'/60'/0'/0/0。请注意,前 3 个段已“硬化”,而其余 2 个则未“硬化”。

我如何指定这个派生路径?

bgu*_*uiz 5

在最新版本 v2.24.1 中,该类Mnemonic已更新为弃用 toEcdsaPrivateKey

    /**
     * @deprecated - Use `toStandardEd25519PrivateKey()` or `toStandardECDSAsecp256k1PrivateKey()` instead
     * Recover an ECDSA private key from this mnemonic phrase, with an
     * optional passphrase.
     * @param {string} [passphrase]
     * @param {number[]} [path]
     * @returns {Promise<PrivateKey>}
     */
Run Code Online (Sandbox Code Playgroud)

...所以使用@Topaco在评论中建议的方法,其中每个硬化段都是二进制OR0x80000000,是行不通的。...因此仅使用 Hedera JS SDK不可能实现我的预期结果。

因此,这里有一个解决方法,将 EthersJs 与 Hedera JS SDK 结合使用来实现预期结果:

import { PrivateKey } from "@hashgraph/sdk";
import { utils as ethersUtils } from "ethers";

// init a hierarchically deterministic wallet's node using a seed phrase
const hdNodeRoot = ethersUtils.HDNode.fromMnemonic(process.env.TARGET_SEED_PHRASE);

// apply the derivation path, `accountIdx` starts at `0`
const hdNodeX = hdNodeRoot.derivePath(`m/44'/60'/0'/0/${accountIdx}`);

// convert from ethersjs private key to hedera js sdk private key
const privateKeyX = PrivateKey.fromStringECDSA(hdNodeX.privateKey);

// extract the `0x...` address from the private key
const addressX = privateKeyX.publicKey.toEvmAddress();

Run Code Online (Sandbox Code Playgroud)

重要的一点是utils.HDNode.fromMnemonic使用 EthersJs 代替Mnemonic.toEcdsaPrivateKeyHedera JS SDK。


这是一个更完整的示例,我使用上述方法创建了多个帐户,并从 ED22519 帐户(最初在Hedera Testnet Portal上生成并由其资助,其功能类似于水龙头)为它们提供资金。