マルチシグ
複数の公開鍵と必要な署名の数を設定したアドレスを作り送金時に複数の署名を要する仕組み
ここでは2of3をベースに記載
複数の公開鍵からビットコインアドレスを生成する流れ
Pubkeys -> Redeem Script -> Locking Script -> Script Pubkey -> Bitcoin Address
- アドレスが3から始まるのはBIP13で決めているから。
base58-encode: [one-byte version][20-byte hash][4-byte checksum]
The leading version bytes are chosen so that, after base58 encoding, the leading character is consistent: for the main network, byte 5 becomes the character '3'. For the testnet, byte 196 is encoded into '2'.
Pubkeys
- マルチシグアドレスを生成するために用意する公開鍵のリスト
- ソートされている必要がある
Redeem Script
- 最大15個まで公開鍵を設定できる
- 公開鍵の数だけスクリプトのサイズが大きくなる
- (3 + (34 * n)) byte -> 2of3なら105byte
OP_2(0x52) pubkey1 pubkey2 pubkey3 OP_3(0x53) OP_CHECKMULTISIG(0xae)
Locking Script (scriptPubKey)
- アドレスに含まれる公開鍵に代わるスクリプト(scriptPubKey)
- P2SHとして扱うのでハッシュ化している
- 23byte 固定
OP_HASH160 HASH160(Redeem Script) OP_EQUAL
Unlock Script
- トランザクションに含まれる実際の署名
- 実際にトランザクションをブロードキャストしない限りRedeemScriptは外部に公開されない
- つまり一度も送金したことがないマルチシグアドレスは外部からいくつの鍵を設定しているかわからない
OP_0(0x50) Sig1 Sig2 Redeem Script
参考資料
- ビットコインにおける「マルチシグ」とは
- https://en.bitcoin.it/wiki/Transaction
- BIP13, Address Format for pay-to-script-hash
- BIP16, Pay to Script Hash
個人的な所感
- マルチシグはスクリプトの仕様はシンプルなのだが運用にたくさん課題があり大変
- 自前の仕組みでウォレットを作った場合は未署名トランザクションをincomplete状態で署名を追記してほかの人に渡す必要があるがそれをどう受け渡すか、どう知らせるか、どう承認してもらうか、いつビットコインネットワークにながすか。
- 受け手のトランザクション手数料が高いので手数料以下のスパム攻撃を受けやすい(inputがたくさんあると引き出す時に不利な仕様のため)
実装や利用例
- copay
- bitgo
- lightning network