btc: libwally-core を使う (1)
2025/01/26
はじめに
P2TR のトランザクションを作るシリーズ。
前回まで TypeScript で bitcoinjs-lib を使っていた。
今回から C言語で libwally-core を使う。
- ElementsProject/libwally-core: Useful primitives for wallets
- libwally-core documentation — libwally-core 1.3.1 documentation
インストール
git clone https://github.com/ElementsProject/libwally-core.git
cd libwally-core
git checkout -b v1.3.1 release_1.3.1
普通に使う場合、初回は submodule の処理がいる。
もしシステムにインストールした libsecp256k1
を使う(--
)ならやらなくてもよかった。
その代わりというか、libsecp256k1
のビルドには ./configure --enable-module-recovery
のようにして recovery module を有効にしておかないと libwally-core の ./configure
でエラーになる。
submodule では BlockstreamResearch/secp256k1-zkp を持ってきている。
以前は ElementsProject だったが BlockstreamResearch に移動したようである。
git submodule init
git submodule sync --recursive
git submodule update --init --recursive
あとは configure してビルドするだけなのだが、オプションがいろいろある。
Recommended development configure options もあるが “development” は libwally-core を使った開発だろうか。
あるいは libwally-core そのものの開発だろうか。
今回は組み込み用っぽく仕立てることにした。
であれば MbedTLS を使うようにするべきだろうが、そこは面倒だったので以前インストールした libsecp256k1
を使う。
前述のように libsecp256k1
のビルドに --enable-module-recovery
しておかないとエラーになる。
Elements で使うわけでは無いのでなるべく最小限にしておく。
./tools/autogen.sh
./configure --enable-minimal --disable-elements --enable-standard-secp --with-system-secp256k1 --disable-shared
make
make install
はせずに別の場所に include ファイルと static ライブラリをコピーすることにした。
ディレクトリを作って ./configure --prefix
で場所を教えて make install
するのもよいかも。
pkgconfig
を作ってくれるようだが、私は使ったことが無いのでよくわからん。
cd ..
mkdir -p libs/libwally-core
cp -r libwally-core/include libwally-core/src/.libs/libwallycore.a libs/libwally-core/
ディレクトリ構成はこんな感じでやっていく。
+-- libs/
| +-- libwally-core/
| +-- include/*.h
| +-- libwallycore.a
|
+-- c-keypath/
+-- main.c
+-- ...
関数の数
nm libwallycore.a | grep " T "
として関数の数・・・リンクできるシンボルの数を数えた。
1000個ちょっとある。
“wally_” が付くシンボルが 818個。
“elements” が入ったシンボルが 24個。
“confidential” は 15個。
“liquid” は無い。
それ以外は、いろいろだ。
bip32/38/39/85、AES128/192/256、sha256、sha512、ripemd160、base64、push/pull、…
アドレス生成
データは bitcoinjs-lib のサンプルでも使った learnmeabitcoin を使う。
どうにかこうにかアドレスを作ることはできた。
$ ./tst 1
internal pubkey: 03924c163b385af7093440184af6fd6244936d1288cbb41cc3812286d3f83a3329
tweak pubkey: 020f0c8db753acbd17343a39c2f3f4e35e4be6da749f9e35137ab220e7b238a667
tweak privkey: 37f0f35933e8b52e6210dca589523ea5b66827b4749c49456e62fae4c89c6469
witness program: 51200f0c8db753acbd17343a39c2f3f4e35e4be6da749f9e35137ab220e7b238a667
address: bc1ppuxgmd6n4j73wdp688p08a8rte97dkn5n70r2ym6kgsw0v3c5ensrytduf
wally_ec_public_key_bip341_tweak()
での tweaked public key が 33バイトなので
wally_witness_program_from_bytes_and_version()
に与えるときに先頭バイトを外す処理を自分でやっている。
X only にする方法が他にあるんだろうか。
c-lightning でも自分で先頭をスキップさせているので、この使い方で良いのか。
それだったらコメントアウトしているが自分で witness program を作ってしまってもよいかも、と考えたりもする。
どこまで知識がある前提で使うのかというのは難しいね。
おわりに
トランザクションを作る方も一緒にやろうとしたのだが、どこから手を付けて良いのかがわからない。
Users of libwally-core で参考にできそうなプロジェクトを探すしかないのか。