RinCoinの モバイル向け仮想通貨ウォレット を実装してみて、
改めて「仮想通貨ウォレットって思った以上に複雑だな…」と実感しました。
今回は、実装して初めて理解できたポイントを中心にまとめます。
ウォレットは多数の暗号技術の集合体だった
正直、作る前はこう思っていました。
秘密鍵からアドレスを作って送金するだけでは?
実際は全く違いました。
ウォレットは以下のような複数の暗号技術の組み合わせで成り立っています。
- ハッシュ関数
- 公開鍵暗号
- 署名アルゴリズム
- エンコード方式
- チェックサム
内部的には ripemd など複数の暗号処理 が段階的に使われており、
どこか1つでも実装を間違えると、全体が壊れます。
公開鍵と秘密鍵、どちらを間違えてもアウト
ウォレットで一番シビアだと感じたのがここです。
- 秘密鍵 → 公開鍵
- 公開鍵 → アドレス
この変換過程で、
- バイトオーダー
- 圧縮形式
- ハッシュの順番
の どれか1つでも違う と、
見た目は正しそうな
まったく別のアドレス
が生成されます。
署名が間違うと rawtransaction は通らない
送金処理で一番時間を使ったのが 署名 でした。
- トランザクションの組み立て
- 署名対象データの作成
- 署名の付与
このどこかがズレていると、
- ノードに送信できない
- rawtransaction が reject される
- エラー内容が分かりづらい
という問題が発生します。
特に厄介だったのは、
「ほぼ正しいが、1バイトだけ違う署名」
このケースで、見た目では原因が全く分かりません。
とにかく検証、検証、検証
ウォレット開発で一番重要だったのはこれです。
- 公式実装との比較
- 既存ウォレットとの比較
- 自前実装同士のクロスチェック
1回の実装で動くことはまずありません。
- 鍵生成が合っているか
- アドレスが一致するか
- 署名結果が同じか
を 何度も検証 して、
ようやく「これなら大丈夫そうだ」と言える状態になります。
betaを出せるまでが本当に長い
結果として、
beta版を出すだけでも相当な時間がかかりました
理由は単純で、
- バグがあっても資産が失われる
- ミスが即致命傷になる
- 後から修正できない部分が多い
からです。
「とりあえず動くから公開」は、
ウォレットでは絶対にできません。
作ってみて分かったこと
- 仮想通貨ウォレットは簡単ではない
- 暗号技術の積み重ねでできている
- 1つのミスが全てを壊す
- 検証に最も時間をかけるべき
まとめ
- 鍵生成とアドレス生成は超シビア
- 署名ミスは即トランザクション失敗
- 実装より検証が本番
- beta公開までが一番大変
ウォレットを「ただのアプリ」と考えていると、
確実に痛い目を見る分野だと感じました。
この記事が、
これから仮想通貨ウォレットを作ろうとしている人の
参考になれば幸いです。