暗号資産の取引をする際に必要な財布を作成するとき、ニーモニックコードというものを使います。
12文字からなる単語の並びで、これをもとにウォレットを表すアドレスを生成します。
下記BitlifeCoinの記事を書いているとき、ウォレットのアドレスが同じニーモニックコードから生成しているにもかかわらずアドレスが一致しなかったことから、Hierarchical Deterministic Pathというものがあることを知りました。
(一つのキーから階層的にアドレスを決定するしくみ)
http://bitlife.me/bc/2022/08/18/
m/44’/60’/0’/0/{account_index}
このような文字列で表せれ、最後のaccount_indexによって複数のアドレスを生成できます。
こちらのサイトにとても詳しく書かれています。
https://techblog.recochoku.jp/8227
このサイトにあるコードで実際にBitlifeCoinの環境のニーモニックから生成されるアドレスが正しいか試してみました。(ニーモニックはカレントディレクトにある.secretファイルに記載)
環境) WSL / Windows 11
インストール
pip install hdwallet
1 2 3 4 5 6 7 8 9 |
from hdwallet import HDWallet from hdwallet.symbols import ETH from pprint import pprint mnemonic = '' hd_wallet_account = HDWallet(symbol=ETH).from_mnemonic(mnemonic=mnemonic).from_path(path="m/44'/60'/0'/0/1") hd_wallet_account_info = hd_wallet_account.dumps() pprint(hd_wallet_account_info) |
PATHは、コードではaccount_indexは1となっています。これを0から順に変えてgoerliの環境の複数のアドレスが正しいか確認したところ一致しました。
あとニーモニックを作成するわかりやすいコードが下記にありましたので、それを動かしてみました。
https://qiita.com/yamaguchi3/items/2c216eee5593ee0f66db
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
const fs = require('fs'); const crypto = require('crypto'); const words = fs.readFileSync('english.txt').toString().trim().split('\n'); const ent = Buffer.from('7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f', 'hex'); const checksum = crypto.createHash('sha256').update(ent).digest().slice(0, ent.length/4); const data = Buffer.concat([ent, checksum]); let bin = ''; for(let d of data) { bin += ('00000000' + d.toString(2)).slice(-8); } let mnemonic = []; for(var i=0; i<3*ent.length/4; i++) { var idx = parseInt(bin.slice(11*i, 11*(i+1)), 2); mnemonic.push(words[idx]); } console.log(mnemonic.join(' ')); |
https://github.com/bitcoin/bips/blob/master/bip-0039/english.txt
ここから取得するenglish.txtには、2048の英単語が書かれており、この中からニーモニックにつかわれる単語が選ばれるようです。
最初にウォレットを作ったとき、たった12文字の並び替えだけで衝突しないアドレスが生成できるのか、と思いましたが2048の候補から選んだうえ並び変えているのですね。
ブロックチェーン界隈では、このようないろいろなしくみが考えられていてとても興味深いです。