bitcoin-rubyを使ってBitcoin Coreのウォレットで管理している秘密鍵からから公開鍵を作成する手順。
dumpprivkeyの戻り値
最初、Bitcoin Coreのdumpprivkeyコマンドで秘密鍵を入手できるので、その秘密鍵から公開鍵を再作成するだけと思い、bitcoin-rubyを使って↓のようにすれば公開鍵を生成できると思ってた。
public_key = regenerate_public_key(dumpprivkeyで取得した秘密鍵) address = pubkey_to_address(public_key)
が、こので算出したaddressとBitcoin CoreのウォレットのBitcoinアドレスが全く別のものになる。同じ秘密鍵から生成されてるのに何故公開鍵が違う?と疑問に思う。
で、ちゃんとdumpprivkeyの説明を読むと
https://bitcoin.org/en/developer-reference#dumpprivkey
dumpprivkeyの戻り値は、
The private key encoded as base58check using wallet import format
とある。dumpprivkeyの戻り値はBase58Checkエンコーディングされた値(WIFフォーマット)で秘密鍵の値そのものではない。そのため、公開鍵を作成するには、dumpprivkeyの結果をデコードして秘密鍵そのものを入手する必要がある。
WIFフォーマットの秘密鍵のデコード
まず秘密鍵の表現形式には以下の3パターンがある。
種類 | プレフィックス | 説明 |
---|---|---|
Hex | 無し | 64個の16進数 |
WIF | 5 | Base58Checkエンコーディングされた値でversion prefixである128(プレフィックスの5)と32bitのチェックサムが付いてる。 |
WIF-compressed | KかL | エンコード前にサフィックスとして0x01が付加されてる |
WIF形式のデータから秘密鍵を取得するのは↓の手順でできる。
- データをBase58デコードする。
- デコードしたデータのHexサイズからWIFかWIF-compressedか判定する。
- デコードしたデータのHexデータをversionと秘密鍵、チェックサムに分解する。
というのを実装しようと思ったら既にbitcoin-rubyで実装済み(Bitcoin::Key#from_base58)だったので、↓のようにすれば公開鍵が取得できる。
private_key = Bitcoin::Key.from_base58(dumpprivkeyで取得した秘密鍵) public_key = private_key.pub