villagerHの日記

勉強したことや苦労した事などを書き綴ります

トランザクションインプット

トランザクションのインプットは自身のUTXO(bitcoinの塊)から選択される。
1つのUTXOでのbitcoinの量は送付された時点で決まっている。


1bitcoinを受け取るとそのUTXOは1bitcoinの塊として生成される。
その後支払い等で他人に0.5bitcoinを送付するといった場合、自身は0.5bitcoinのUTXOを所持していないため
1bitcoinを持ったUTXOが選択される。
0.5bitcoinを送付するためには1bitcoinだと多すぎるためお釣りという形で自身に新しいUTXOが返ってくる。

この辺りは現実の紙幣や通貨と同じイメージ。

VanityAddress

ビットコインアドレスの頭N文字を人の読める単語(意味のある単語)で表しているもの。(1Cat~とか1Dog~とか)

基本的にあまり深い意味はない。
セールスで使用するなどの場合に頭文字に意味を持たせることでその団体の所有しているアドレスだとわかりやすくするために使用したりする。

アドレスの生成方法は基本的にランダムで引き当てるまでの力技。
そのため単語の文字列が増えれば増えるほど検索までの時間も増える。

意味を持たせることで所有者をわかりやすくするメリットもあるが、逆に言えば他の誰かが似た文字列を偽装することで悪用可能なデメリットでもある。

文字列を長くすれば検索にかかる時間も長くなるため、偽装するためのコストが増えてしまうので文字列によっては結果としてセキュリティが上がることもある。


用は使い方次第というところでしょうか。

ウォレット

bitcoinでのウォレットはコインを直接管理しているのでなく秘密鍵のみを管理している。

鍵をいくつも持つことが可能なので、ランダムに鍵を生成して持つことも可能ではあるがウォレットを移動するなどの必要が出た場合に
すべての鍵を移動しないといけない、鍵を紛失してしまうとその鍵に関連したbitcoinは失ってしまうなどの問題がある。

そのため1つのシードからツリー形式で派生していく階層的決定性ウォレットを採用している。

自由度が高い反面、そのままだと無数のツリーが出来てしまい管理が大変なことになるため
階層毎に意味を持たせて使いやすくしている。

第3階層はアカウント(講座)を指示しているため
3階層目が0の場合は1番目の口座に対する鍵、3階層目が3の場合は4番目の口座に対する鍵といった感じ

秘密鍵の表現パターン

関連
villagerh.hatenablog.com
villagerh.hatenablog.com

秘密鍵から公開鍵を作る際に
非圧縮(yが含まれている)ものと圧縮(yが含まれていない)ものの2つの公開鍵を作ることができる。

ビットコインアドレスは公開鍵をハッシュ化することで生成するため上記2つの公開鍵からアドレスを生成すると別のアドレスが生成できる。(1つの秘密鍵から公開鍵とアドレスが2個生成できる)

新しいウォレットに秘密鍵を移すなどした場合に
ウォレットはその秘密鍵の生成したアドレスに対するトランザクション情報をブックチェーンから探し出す必要があるが
圧縮と非圧縮どちらの方法で作られたアドレスを対象にすればよいのかわからなくなってしまうということが起きる。

このため、秘密鍵の表現方法にも公開鍵(アドレス)を圧縮で作るのか非圧縮で作るのかを判断できるようにいくつかのパターンがある。

公開鍵

公開鍵は楕円曲線上の点なのでx,yの形で構成されている。

04のプレフィックス+x+yの形で表現。

yについてはxだけわかれば求められるため、yを省略した形での表現が可能。

圧縮(yを省略)した場合は圧縮されているのを判断するためプレフィックスを02or03に変更する。

xからyを求めると正負2つの点が求まってしまうため、どちらの点かを判断するためにプレフィックスが2つある。

楕円曲線上の点を2進数表現すると偶数と奇数に分かれるため、偶数=02、奇数=03といった形で使い分けている。

ビットコインアドレス表示のサンプルコードで詰まった話

ビットコインとブロックチェーン:暗号通貨を支える技術

ビットコインとブロックチェーン:暗号通貨を支える技術

こちらの本を読み進めていて、サンプルコードを実際に打ってみたら詰まったので解決までのお話。
※記事を書いている時点で使用したlibbitcoinは3.5.0_4です。

とりあえず実行するためにlibbitcoinライブラリが必要なのでインストールしておきます。
villagerh.hatenablog.com

本に書いてあるサンプルコードを入力してコンパイルを実行します。
※コードに関しては実際に本を購入してそちらを参照ください。

$ g++ -o addr main.cpp $(pkg-config --cflags --libs libbitcoin)
Package libsecp256k1 was not found in the pkg-config search path.
Perhaps you should add the directory containing `libsecp256k1.pc'
to the PKG_CONFIG_PATH environment variable
Package 'libsecp256k1', required by 'libbitcoin', not found
(略)


libbitcoin内でlibsecp256k1を使用しているものの見つからないようです。
brewだとインストールされていないみたいなのでlibsecp256k1を直接インストールします。(ソースからlibbitcoinを入れる方法だとどうなんでしょうね?)
https://github.com/libbitcoin/secp256k1

任意の場所にsecp256k1をcloneしてくる。

$ git clone https://github.com/bitcoin-core/secp256k1.git
$ cd secp256k1

あとは公式の手順に沿って実行するだけ。

$ ./autogen.sh
$ ./configure
$ make
$ sudo make install

何事も起こらなければこれでインストールが完了するので再びmakeしてみます!

$ g++ -o addr main.cpp $(pkg-config --cflags --libs libbitcoin)
/usr/local/Cellar/libbitcoin/3.5.0_4/include/bitcoin/bitcoin/utility/data.hpp:36:20: warning: alias declarations are a C++11 extension [-Wc++11-extensions]
using byte_array = std::array<uint8_t, Size>;
/usr/local/Cellar/libbitcoin/3.5.0_4/include/bitcoin/bitcoin/utility/data.hpp:51:14: error: no type named 'initializer_list' in namespace 'std'
typedef std::initializer_list<data_slice> loaf;

んーまだエラーが出ました。
警告とかの内容を見る感じlibbitcoinはC++11を使用いるけどそれがmakeできていない模様。
どうすればいいんだろうと調べたところこちらのサイトさんにたどり着きました。
https://marycore.jp/prog/xcode/warning-cpp-extension/

オプションを追加すればよいようなのでオプションを加えて再度実行。

$ g++ -o addr main.cpp -std=c++0x $(pkg-config --cflags --libs libbitcoin)
main.cpp:11:6: error: no type named 'ec_point' in namespace 'libbitcoin'
        bc::ec_point public_key = bc::secret_to_public_key(success);
main.cpp:11:32: error: no member named 'secret_to_public_key' in namespace 'libbitcoin'
        bc::ec_point public_key = bc::secret_to_public_key(success);

だいぶエラーが減りましたが、まだ残ってます。
ec_pointとかでエラーになっていたので打ち間違いか?と思って本と見比べたものの間違いは見つからず。
とりあえずググってみたところec_pointとかはいつからかのバージョンで使用しなくなったっぽいです。
ご丁寧に変更後のコードを載せてくれてる場所がgitのIssuesにあったのでそのまま載せます。

bc::ec_point public_key = bc::secret_to_public_key(secret);
std::cout << "Public key: " << bc::encode_hex(public_key) << std::endl;

上記の箇所を以下の形式に変更。

bc::ec_compressed public_key;
bc::secret_to_public(public_key, secret);
std::cout << "Public key: " << bc::encode_base16(public_key) << std::endl;

これでmakeしたところようやく通りました!

本が出てから時間が経ってしまっているので仕方がないことですがサンプルのコードが使えなくなってたりすると大変ですね^^;

libbitcoinインストール

c++環境での開発に使用するlibbitcoinライブラリのインストール。

 

mac 環境を使用しているためmac環境でのインストール方法となります。

 

$ brew install bx

以上でインストール完了!
brewについてはそのうちまとめます。たぶん。