Javascript

使用路徑獲取地址會導致錯誤:無法派生強化子密鑰

  • January 15, 2020

我正在使用ethereumjs-walletnpm 包為每個使用者生成一個唯一的錢包地址。然而,不是使用助記符/種子,而是使用公共擴展密鑰xpub來保證私鑰的安全。

但是,我使用的以下程式碼引發了錯誤

斷言錯誤

$$ ERR_ASSERTION $$: 無法派生強化子密鑰

如果我們要替換,程式碼可以正常工作

const hdWallet = hdkey.fromExtendedKey("xpub...")

const hdWallet = hdkey.fromSeed("seed or mnemonic ...")

這似乎是一個問題hdPath,但究竟是哪個問題?我們該如何解決呢?

JS程式碼

var hdkey = require('ethereumjs-wallet/hdkey')

const hdWallet = hdkey.fromExtendedKey("xpub...")
const hdPath  = "m/44'/60'/0'/1/0"
const node = hdWallet.derivePath(hdPath)
const nodeWallet = node.getWallet()
const address = nodeWallet.getAddressString()
return address

我知道它不完全是你所追求的,但你可以得到非硬化的形式:

var hdkey = require('ethereumjs-wallet/hdkey')

const hdWallet = hdkey.fromExtendedKey("xpub6Cy7dUR4ZKF22HEuVq7epRgRsoXfL2MK1RE81CSvp1ZySySoYGXk5PUY9y9Cc5ExpnSwXyimQAsVhyyPDNDrfj4xjDsKZJNYgsHXoEPNCYQ")
const hdPath  = "m/44/60/0/1/0"
const node = hdWallet.derivePath(hdPath)
const nodeWallet = node.getWallet()
const address = nodeWallet.getAddressString()
console.log(address)

強化子鍵是使用撇號 ( m/44'/60'/0') 的子鍵。按照設計,強化的子密鑰不能從擴展公鑰派生,只能從私有 (xprv) 派生。

為了解決這個問題,您直接從您的私鑰派生包含強化子項的部分,並將路徑的最後一個非強化部分留給每個使用者派生。

var privateRoot = hdkey.fromMasterSeed("0x0bad5eed")
var publicParentExtendedKey = privateRoot
     .derivePath("m/44'/60'/0'/1") //missing the final 0
     .publicExtendedKey()

console.log(publicParentExtendedKey) //xpub6Eaz...M6tmjr7t

您可以將其儲存在publicParentExtendedKey生成使用者地址的機器上。然後,為每個使用者生成一個地址,如下所示:

var userIndex = 0
var derivedRoot = hdkey.fromExtendedKey(publicParentExtendedKey)
var derivedChild = derivedRoot.deriveChild(userIndex)
console.log(derivedChild.getWallet().getChecksumAddressString())
//0x345e0aDfc2ABf06C0B1dEf36CD556089Cd0c76fC

然後要實際訪問資金,您從您的私人根目錄開始並獲取完整路徑。

var userPrivKey = privateRoot
     .derivePath(`m/44'/60'/0'/1/${userIndex}`)
     .getWallet()
     .getPrivateKey()

編輯:這基本上是@dalton-hsu 的回答,但帶有程式碼範例。

引用自:https://ethereum.stackexchange.com/questions/60139