ethers.jsが最近人気とのことで使ってみます。ethers.jsはweb3.jsに近しい、node.jsでethereumを用いることができるライブラリです。みた感じ、web3.jsにはbip39のニーモニックフレーズ(文字列から秘密鍵を作成する機能)が見当たりませんでしたが、ethers.jsでは簡単に作れました。
予備知識となるBIP39、BIP44の話はこちらに丁寧な説明があるためご参照ください。
バージョン
node.js v10.16.3 npm 6.10.3 ethers.js 4.0.45
ethers.jsの特徴
公式のFeaturesには以下のように書いています。 What is ethers.js — ethers.js 4.0.0 documentation
- 秘密キーをクライアントサイドに安全かつ確実に保管する
- JSONウォレットのインポートとエクスポート(Geth、Parity、crowdsale)
- BIP39ニーモニックフレーズ(12ワードのバックアップフレーズ)およびHDウォレット(英語、イタリア語、日本語、韓国語、簡体字中国語、繁体字中国語 etc)のインポートとエクスポート
- ABIv2やHuman-Readable ABIなど、任意のコントラクトABIからJavaScriptオブジェクトを作成する
- JSON-RPC、INFURA、Etherscan、またはMetaMaskを介してEthereumノードに接続する
- Ethereum Name Service(ENS)の名前解決(ENS はこちら参照 https://note.com/akira_19/n/na1459f4c83e8?magazine_key=md88688a3936b )
- 小さなサイズ(圧縮で~88kb;非圧縮で284kb)
- Ethereum機能に対応する包括的な機能
- 広範なドキュメント
- 広範なテストケース
- 完全なTypeScript対応
- MITライセンス(全ての依存関係を含む)で自由に使える完全なオープンソースである
今回は「BIP39ニーモニックフレーズ(12ワードのバックアップフレーズ)およびHDウォレット(英語、イタリア語、日本語、韓国語、簡体字中国語、繁体字中国語 etc)のインポートとエクスポート」に焦点をあてます。
ethers.jsのインストール
npm install ethers
$ npm install ethers npm WARN saveError ENOENT: no such file or directory, open '/Users/nao/experiments/ethersjs/package.json' npm notice created a lockfile as package-lock.json. You should commit this file. npm WARN enoent ENOENT: no such file or directory, open '/Users/nao/experiments/ethersjs/package.json' npm WARN ethersjs No description npm WARN ethersjs No repository field. npm WARN ethersjs No README data npm WARN ethersjs No license field. + ethers@4.0.45 added 15 packages from 11 contributors and audited 26 packages in 1.794s found 0 vulnerabilities
ニーモニックフレーズと、秘密鍵とアドレスを作成する
ethers.jsでニーモニックフレーズとprivatekey, addressを作成します。
const ethers = require('ethers'); // randomなニーモニックフレーズを作成する const wallet = ethers.Wallet.createRandom(); console.log("mnemonic:" + wallet.mnemonic) console.log("privateKey:" + wallet.privateKey) console.log("address:" + wallet.address)
上記をmnemonic.js として保存。実行します。
$ node mnemonic.js mnemonic:maze noodle finish dinosaur flight demise double whisper cycle token curve erosion privateKey:0xe93cea93c2e27672ebdb6b5e69031ffc0302ee025fe82751ef5f2978a977128c address:0x3CbDbAfE2585F4991CEf5A5D2870F68D661b3943
BIP44準拠のHDWalletを作成する
作成したニーモニックフレーズからBIP44準拠のHDWalletを作成します。
BIP44準拠のHDWalletは、拡張秘密鍵(秘密鍵とチェーンコード)からHDWalletのパスを指定して一意な秘密鍵を作成する機能です。 HDWalletのパスとして
"m/44'/60'/0'/0"
などを指定して秘密鍵を作成します。以下コードで鍵を作成します。
const ethers = require('ethers'); // 先ほど作成したニーモニックフレーズ const mnemonic = "maze noodle finish dinosaur flight demise double whisper cycle token curve erosion" const hdnode = ethers.utils.HDNode.fromMnemonic(mnemonic); const nodeA = hdnode.derivePath("m/44'/60'/0'/0"); const nodeB = hdnode.derivePath("m/44'/60'/0'/1"); console.log(nodeA) console.log(nodeB)
上記をhdwallet.js として保存。 実行します。
$ node hdwallet.js HDNode { privateKey: '0xfea15e2e0cff04bcb0c54de19e617a5e6178c551e343433c1a6f84f7f6c01790', publicKey: '0x023f0cae7ce16a571097b709aa5a229892d74295721b84b96077c29c55495b48d7', parentFingerprint: '0x912096c1', fingerprint: '0x8e1a6902', address: '0x88216E17AE29A05895A5DbC97296e65B4A85AFdF', chainCode: '0x3b483d38512ccba9ba949e50c1f98a020bcd38340721c3380d112ffefac6fea9', index: 0, depth: 4, mnemonic: 'maze noodle finish dinosaur flight demise double whisper cycle token curve erosion', path: 'm/44\'/60\'/0\'/0' } HDNode { privateKey: '0x85c212b45a45a31b9eec2a46ade91d83454fa33bb2b4c5a70822f6e0ef9069cb', publicKey: '0x0206d41e7f2db2c35a682d9cfb1d4df5ff6a62b922719b7af5238056eb38a704b7', parentFingerprint: '0x912096c1', fingerprint: '0xd537fbb6', address: '0x3Ec831F1bD67483B8CddAE3EE7de87B49c69E032', chainCode: '0x1546ec7f08949daf1b8714e26ff5c178a13f46aaf5f84e25ced903d96e583efc', index: 1, depth: 4, mnemonic: 'maze noodle finish dinosaur flight demise double whisper cycle token curve erosion', path: 'm/44\'/60\'/0\'/1' }
秘密鍵、アドレス、チェーンコード、Walletpathなどの一式が簡単に出力できました。
まとめ
EthereumでNode.jsを用いた鍵管理系はethers.jsで簡単に実現できそうです。( ethereumjs-wallet などもあるようですが)
web3.jsとtruffle-hdwallet-provideなどを組み合わせて使う場合、少し相性が悪い時もあったのでこちらをweb3.jsの代替として使う選択肢もありそうです。