HiddenWallet:鍵の管理(HD ウォレット)

(nopara73)私はHiddenWalletというプライバシー重視のビットコインウォレットを開発している。HiddenBitcoinのライブラリーはNBitcoinとユーザーインターフェースの間の抽象化レイヤーの導入となっている。

ビットコインウォレットには3つの重要な機能があり、このケーススタディーはその3つで構成するつもりだ。

  1. 安全に鍵を保管し、鍵へのアクセスを管理する

  2. ビットコインブロックチェーン上のこれらの鍵や他の鍵を監視する

  3. トランザクションを生成し、それらをブロードキャストする

このレッスンでは鍵のストレージ機能に取り組むつもりだ。 もしより広い範囲でコードを確かめてみたければ、GitHubにソリューションがあるので見てほしい。 ただ早くウォレットをセットアップして使う方法を知りたければ、CodeProjectによりハイレベルなチュートリアルがある。

どのくらいハイレベルか?私見では、GUIディベロッパーやデザイナーでもそんなに多くのミスは起こさないはずだ。彼らはインプット、アウトプットやscriptPubKeyについて知らないかもしれない。ただ彼らはビットコインアドレス、秘密鍵とウォレットのレベルはしっかり理解しているはずだ。NBitcoinも十分に抽象化されるようにしている。

鍵を保管するデザインの決定

秘密鍵を保管するときになにを決めなければならないかと、それらを作るときになにを気に留めるべきかについての、テンプレートを提示するのにとても良いタイミングだ。

1つの鍵しか使わないケース

これが手っ取り早い。ただ、僕がこの道を行くのが正しいと思うシチュエーションはそんなに多くはない。しかし、あなたのニーズに最も適していることもありえなくはないだろう。 悪い例としてここに私が作った、1つしか鍵を使わないビットコインウォレットのイラストレーションを示そう。結論を考えるために残しておこう。

JBOKウォレット

JBOKウォレットはひと束の鍵(Just a Bunch Of Keys)をまとめるものだ。リファレンスを書いている時点で、鍵を保管するためにクライアントでこのメソッドを使っている。 これの問題はユーザーが定期的にバックアップをとらなければならないということだ。しかしもし鍵をインポートしたり、鍵を紙にメモしたり、パスワードを変えたりすることをできるようにしたいなら、この機能を使うか、この機能と決定性ウォレットをあわせて使うようなことをする必要がある。私はこれを使わないと決めた。というのは私のHiddenWalletをプライバシー向上のために改良しようとしていたということと、これではなくてより良いウォレット構造を持ち得るからだ。

BIP38 (Part 2) - 信頼できないサードパーティーの鍵生成

何度も言うことになるが、これは鍵の生成機構のためにパスフレーズを生成するという思想だ。パスフレーズを使えば、パスワードや知らなかったりまったく秘密鍵を知らなかったりしても、暗号化された鍵を生成することができる。 HiddenWalletはデスクトップウォレットだ(そしておそらく、しばらく変えるつもりはない)。ということで鍵の生成や鍵を保管する目的で信頼できないサードパーティーを使う必要がない。だからまだこの機能は実装しないことに決めた。

SHDウォレット

これは私が組み込んだウォレット構造だ。そう、降参だ。SHDウォレットとは私がたった今思いついた言葉だ。この言葉は標準的な言葉としては存在していないし誰も使っていない。では私の中でこれは何を表しているかというと、不可視な階層的決定性ウォレット(Stealth and Hierarchical Deterministic wallet)だ。これが私が作成したものを表現するのに最適な言葉だ。 コードに入っていく前に不可視にする機能だけ実装したことを注釈しておきたい。なぜならばそれが低いところに成っているフルーツだからだ。ステルスアドレスがビットコイン業界において将来的にどんな使用法にしても使われるかどうかは私は確信を持てていない。

ステルスアドレスとはこのようなものだ。 waPXAvDCDGv8sXYRY6XDEymDGscYeepXBV5tgSDF1JHn61rzNk4EXTuBfx22J2W9rPAszXFmPXwD2m52psYhXQe5Yu1cG26A7hkPxs

ブラックボックス

Safeというクラスを実装した。ブラックボックスとしてこのクラスは直感的に使える。

このNetworkNBitcoin.Networkではない。というのはGUIディベロッパーはNBitcoinを使っているとは知らないはずだからだ。また、NBitcoinではより多くのネットワークの選択肢があるが、HiddenBitcoinではそれらを扱うことはできない。現時点でHiddenBitcoinはMainNetTestNetをサポートしている。 ネットワークはenumとなっていて、HiddenBitcoin.DataClassesのネームスペースで見つけることができる。

また、safeクラスをロードしたり復元したりすることができる。

safeクラスから文字列で鍵を取得することもできる。

注釈:理想的にはシードは決して使わないこと。safeクラスの鍵を生成するメソッド(後述)を使って鍵生成を繰り返すことを始めるほうがよりよいプラクティスだ。

ホワイトボックス

Safe.Create

safe.SetSeedによってmnemonic codeを作り、_seedPrivateKeyをセットできる。最後にmnemonic codeをリターンし、クラスを使っているユーザーに示すことができる。

safe.Save

ウォレットのファイルを保存する。問題はその中に何を保存するかだ。

ウォレットファイルはJSONフォーマットだ。 拡張鍵からチェーンコードと秘密鍵を取得することができるし、逆もできる。

最後に秘密鍵を暗号化する。

Safe.Load

保存するプロセスを逆方向にたどってみよう。

ここにSafeクラスのコンストラクタの中で何をしているかを示す。

SetNetwork

このクラスの中ではNBitcoin.Networkを使いたい。だからそれをprivateのメンバーとしてセットしよう。

Safe.Recover

これを動かすために、コンストラクタを拡張しなければならない。

Getters

ここにはどのようにして鍵を引き出すかを示してある。私の目的としては複雑なキーパスを使うことはあまり意味をなさない。

Stealth

Last updated