Implement the generation of HD Wallet

Ryota Kogaenzawa
3 min readOct 13, 2018

--

m / purpose' / coin_type' / account' / change / address_index

この記事では、シード・フレーズを使い、階層的決定性ウォレットを生成するところまでを簡単にまとめておく。また、Golangのbtcsuiteライブラリーを使用する

  1. シード 生成
seed, err := hdkeychain.GenerateSeed(hdkeychain.RecommendedSeedLen)
if err != nil {
return err
}

基本的にHD Walletの実装では、hdkeychainパッケージに用意されている、シードの生成もこのパッケージにあるGenerateSeedファンクションを使えばよい。また、シードの長さはBIP-0032で推奨されているバイト単位の長さ(256bits)も定数として定義されているので、それを使う

2. マスター鍵

master, err := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams)
if err != nil {
return err
}
master.ECPrivKey() // マスターの秘密鍵
  1. で生成したシードを利用してマスター鍵を生成する、またテストネットの場合、第二引数に渡すものはchaincfgパッケージに用意されているchaincfg.TestNet3Paramsをセットすればよい

3. Purpose

// m/49'
purpose, err := master.Child(49 + hdkeychain.HardenedKeyStart)
if err != nil {
return err
}

ここではどの仕様(BIP)に従っているかを示す。また、強化鍵導出のためインデックス値に2³¹を加算する

4. Coin Type

// m/49'/1'
coinType, err := purpose.Child(1 + hdkeychain.HardenedKeyStart)
if err != nil {
return err
}

ここではどの通貨に従っているかを示す。また、強化鍵導出のためインデックス値に2³¹を加算する。Coin Type のインデックスについては、こちらに記載されている

4. Account

// m/49'/1'/0'
account, err := coinType.Child(1 + hdkeychain.HardenedKeyStart)
if err != nil {
return err
}

ここではアカウントを示すインデックスを指定する。また、強化鍵導出のためインデックス値に2³¹を加算する

5. エクスターナル/インターナル

// m/49'/1'/0'/0
change, err := account.Child(0)
if err != nil {
return err
}

ここでは支払い=0、おつり用=1のいづれかを示す

6. アドレス

// m/49'/1'/0'/0/0
addressIndex, err := change.Child(0)
if err != nil {
return err
}
addressIndex.ECPubKey() // 公開鍵

ここが末端となりここで生成された公開鍵を使ってアドレスを生成する、次回はこの公開鍵利用し P2SH アドレスを生成するところを纏める

--

--