Skip to main content

Bitcoin 統合の仕組み ー 技術的背景

Bitcoin を IC 内で統合するには、(1)IC と Bitcoin ネットワークのプロトコルレベルでの統合、(2)新しい閾値 ECDSA プロトコルの開発という、2つの高度な技術的課題を解決する必要がありました。

IC と Bitcoin ネットワークのプロトコルレベルでの統合

IC と Bitcoin ネットワークのプロトコルレベルでの統合により、IC は Bitcoin ブロックを Bitcoin ネットワークから直接取得し、含まれるトランザクションを処理することができます。これにより、IC 上で完全な Bitcoin UTXO セットをオンチェーンに維持することができます。Canister は、完全な Bitcoin UTXO セットに対してクエリーを実行することができます。これにより、Canister は自分自身のアドレスを含む任意の Bitcoin アドレスの保有する UTXO、すなわち残高について知ることができます。

革新的な ECDSA プロトコル

Canister 自身は、新しい閾値 ECDSA プロトコルを用いて ECDSA 鍵を持つことができるため、Bitcoin を受け取り、保持できます。また、Canister は Bitcoin のトランザクションを作成し、Bitcoin API を介して Bitcoin ネットワークに送信することができます。Canister は閾値 ECDSA の機能を利用して、Bitcoin ネットワークに送信する取引で閾値 ECDSA の署名をリクエストして UTXO を消費することができます。閾値 ECDSA は、IC の Chain Key 暗号のツールボックスのプロトコルを拡張したものです。IC の閾値 ECDSA プロトコルの詳細は、こちらの 閾値 ECDSA のドキュメントページで見ることができます。

プロトコルレベルの Bitcoin 統合と閾値 ECDSA プロトコルは、それぞれマネージメント Canister 上で API を公開しています。それらの API はエンジニアが IC 上で Bitcoin のスマートコントラクトを記述するために使用するシステムレベルの API です。Bitcoin の UTXO とトランザクションの概念を中心に設計された低レベルの API であり、その使用は簡単なものではなく、Bitcoin の仕組みについて深い理解が必要とされます。

次に、Bitcoin との直接統合の背後にある上記の技術の大まかな概要を説明します。詳細は、Bitcoin page on the Internet Computer Wiki および 閾値 ECDSA documentation page を参照してください。

プロトコルレベルでの IC と Bitcoin ネットワークとの統合

Internet Computer プロトコルと Bitcoin プロトコルを統合し、2つのネットワーク間の直接的な技術統合が可能になりました。この統合は、任意の数の Internet Computer サブネットでアクティブにすることができます。まず最初は 1つの専用の Bitcoin-activated サブネットのみが存在することになり、任意のサブネット上の Canister からの Bitcoin API へのリクエストは、この単一の Bitcoin-activated サブネットにルーティングされることになります。この統合は、2つの重要な目的を果たすものです:

  • Bitcoin の UTXO セットを取得し、Internet Computer の複製されたステートに含めてチェーン上に保持し、Canister が発行した Bitcoin アカウントが行う UTXO セットと残高の問い合わせにレスポンスができるようにすること。
  • Canister の署名付き Bitcoin トランザクションを受け入れ、Bitcoin ネットワークに送信すること。

Bitcoin Integration

コンポーネント

Bitcoin が有効なサブネットでは、マネージメント Canister の API を介して、マネージメント Canister の一部として、すなわちレプリカの一部として実装された BTC Canister(Bitcoin Canister)が、Canister にアクセスできるようにされています。BTC Canister は、オンチェーンの Bitcoin 関連のステート、すなわち UTXO セット、フォークの解決を可能にする最新の Bitcoin ブロック、および外に出ていくトランザクションを保持します。

ネットワーク層の Bitcoin アダプターは、通常の Bitcoin ノードと同じように、Bitcoin ネットワークのノードに接続します。

Bitcoin UTXO セットの維持管理

BTC Canister とアダプターは統合されており、IC のプロトコルスタックを介して相互に通信します。BTC Canister は、受け取った最新の Bitcoin ブロックの後継ブロックを Bitcoin アダプターに要求します。サブネットの各レプリカのアダプターは、要求されたブロックを Bitcoin ネットワークから取得し、ブロック作成レプリカのアダプターは、要求されたブロックをコンセンサスを経て BTC Canister に提供します。BTC Canister は、プルーフ・オブ・ワークを検証し、ブロックのトランザクションを抽出し、トランザクションから UTXO を抽出し、複製されたステートに維持されている UTXO セットを更新するという形式でブロックを処理して、消費された UTXO とトランザクションによって作成された UTXO らを反映させます。UTXO セットと、まだ UTXO セットに吸収されていない最近のブロックのセットは、UTXO と残高に対するリクエストに応答するために使用されます。

フォークを安全に解決したり様々な種類の攻撃から保護するために、セキュリティの領域において非常に複雑な実装になっています。例えば、フォークを解決できるようにするために、BTC Canister は UTXO セットにまだ吸収されていない Bitcoin ブロックを一定数維持する必要があります。しかし、与えられたアドレスの UTXO を計算するためには、UTXO セット内のものに加えて、吸収させずに維持しているブロック内にある UTXO を効率的に考慮しなければなりません。

トランザクションを送信する

Canister は、対応するマネージメント Canister API を使用して、Bitcoin トランザクションを送信することができます。そうすることで、Bitcoin ネットワークに送信されるためのトランザクションをキューに入れます。すべてのサブネットラウンドで、アダプターは BTC Canister から保留中のトランザクションを取得し、Bitcoin ネットワークに送信するために非同期にキューに入れます。サブネットの各レプリカが Bitcoin ネットワークの複数の接続されたノードを介してトランザクションを送信するので、Bitcoin ネットワーク内のトランザクションの効率的で迅速なディストリビューションに繋がります。

革新的な閾値 ECDSA プロトコル

閾値 ECDSA とは、閾値暗号を用いた ECDSA 署名プロトコルの実装のことです。閾値 ECDSA プロトコルでは、ECDSA 秘密鍵は複数の当事者間で秘密共有され、当事者のうち適格な定足数のみがそれぞれの秘密鍵シェアを使って署名を生成することができます。秘密鍵は復元された形では決して存在せず、秘密共有された形でのみ存在します。鍵の生成により、各当事者の秘密鍵シェアが生成されます。

Internet Computer の Chain Key 暗号ツールボックスの一部として実装された閾値 ECDSA プロトコルは、単一のマスター秘密鍵を使用し、そこから BIP-32 ライクな鍵派生を使用して Canister の鍵を派生させることができます。各 Canister は、Canister ID を使用して導き出された1つのルート鍵を持っており、BIP-32 の後方互換性のある拡張を使用して任意の数の追加の Canister 鍵を導き出すことができます。

Internet Computer 上の閾値 ECDSA が最初にデプロイされるのは、Canister の署名要求に答える1つの署名サブネットです。署名サブネットでは鍵を管理する Canister のみがこの鍵での署名を要求できます。すべての API コールは、ECDSA サブネットに到達するために Xnet トラフィックを通過する必要があり、それに応じて余分なレイテンシーが発生します。

Canister は、自分または他の Canister の公開鍵(Canister のさらなる派生公開鍵を含む)を問い合わせることができます。Canister は自身が管理する秘密鍵、すなわちルート秘密鍵や派生秘密鍵による署名を要求できます。公開鍵や派生鍵による署名の要求には、それぞれの API で派生パスを指定するか、BIP-32 を使用して派生させることができます。閾値 ECDSA の詳細は こちら に記載されています。

デプロイメント・アーキテクチャ

Bitcoin 機能は IC の単一サブネット上で起動され、Canister から Bitcoin API への API コールは Xnet 通信を経由するため、余分なレイテンシーが発生します。将来的には、Xnet のレイテンシーを回避し、時間単位でより多くのリクエストに対応するために、必要に応じてアプリケーションのサブネットでもこの機能が有効になる可能性があります。

閾値 ECDSA の要求には、1つのアクティブなサブネットが等しく答え、別のサブネットはディザスタリカバリのために秘密鍵シェア形式で秘密鍵をバックアップします。

API

Bitcoin 統合により、以下のマネージメント Canister の API が利用可能になります(閾値 ECDSA APIについては、そのドキュメントページインターフェース仕様で説明しています)。Bitcoin 関連の各メソッドは、Bitcoin mainnettestnet のどちらを使用するかを指定する必要があります。

  • bitcoin_get_utxos: get_utxos_request が与えられると(Bitcoin アドレスと Bitcoin ネットワーク(メインネットまたはテストネット)を指定する必要があります)、Bitcoin コンポーネントで有効になっている Bitcoin ブロックチェーンの現在のビューに基づいて、この関数は指定した Bitcoin ネットワーク内の指定したアドレスに関するすべての未使用トランザクションアウトプット(UTXOs)を返します。UTXO はブロックの高さの降順でソートされて返されます。
    オプションのフィルターパラメータを使用して、返される UTXO のセットを制限することができます。パラメータに最小の承認数を指定するか、または多くの UTXO を持つアドレスに対してページ分割されている場合はページへの参照を指定することができます。前者のケースでは、指定された数以上の承認数を持つ UTXO のみが返されます。つまり、承認数がこの回数より少ないトランザクションは考慮されません。言い換えれば、承認数が c の場合、少なくとも c 回承認されているトランザクションによって生じたアウトプットのうち、消費されてないものが返されます。ただし、返されたアウトプットは承認回数が c 回未満のトランザクションにはすでに消費されている可能性があります。
    オプションのフィルターなしの get_utxos_request は、ブロックチェーン全体を考慮したリクエストになり、これは min_confirmations を 0 に設定することと同じです。

  • bitcoin_get_balance: Bitcoin アドレスと Bitcoin ネットワーク (メインネットまたはテストネット) を指定する get_balance_request を受け取ると、この関数は、指定した Bitcoin ネットワークにおけるこのアドレスの現在の残高を Satoshi (108 Satoshi = 1 Bitcoin) で返します。bitcoin_get_utxos と同じアドレス形式がサポートされています。

  • bitcoin_send_transaction: send_transaction_request を与えると(Bitcoin トランザクション の Blob と Bitcoin ネットワーク(メインネットまたはテストネット)を指定する必要があります)、いくつかのチェックが行われ、成功すればトランザクションは Bitcoin ネットワークに転送されます。

  • bitcoin_get_current_fee_percentiles:Bitcoin ネットワークの取引手数料は、保留中の取引数に基づいて動的に変化します。Bitcoin 取引を作成する際に、Canister が適切な手数料を決定することが可能でなければなりません。
    この関数は、過去10,000件の取引、つまり過去約4~10ブロックの取引について、millisatoshi/byte (103 millisatoshi = 1 satoshi) で測定した手数料のパーセンタイルを返します。これは通常、支払われるべき手数料の確かな指標となりますが、手数料のパーセンタイルの計算では Bitcoin mempool を考慮しないことに注意してください。

    Bitcoin 連携 API の詳細については、インタフェイス仕様 を参照してください。

開発環境・プレプロダクション環境・プロダクション環境

閾値 ECDSA を含む Bitcoin の機能は、IC 上の開発ライフサイクルに必要なすべてのステージで利用可能です:

  • Canister をローカルに開発するための SDK
  • Bitcoin テストネットでの最終テストのためのプレプロダクション環境としての IC サポート。
  • Bitcoin メインネットを使用したリリースのためのプロダクション環境としての IC サポート。

ローカル SDK

一般的な Canister の開発ワークフローでは、IC 上の Canister は、開発時に Motoko または Rust の Canister SDK を使ってローカル環境でコンパイル・実行されます。このように、SDK は開発ワークフローの最初のステージ、あるいは環境となります。この SDK は Bitcoin 統合 Canister API と閾値 ECDSA マネージメント Canister API の両方に対応できるようになっています。

それぞれ Bitcoin テストネットと Bitcoin メインネットと統合する機能の IC デプロイとは対照的に、SDK はリグレッションテスト(regtest)モードでローカルに動作する bitcoind ノードと統合されています。regtest モードで bitcoind を使用することは、Bitcoin の開発において好ましい方法です。開発者をできる限り手助けするために、私たちは SDK を regtest モードの bitcoind と統合し、IC に最高の Bitcoin 開発体験をもたらしました。このセットアップにより、スマートコントラクトの開発と自動テストの両方が、まずローカル環境で行われます。

ローカル SDK 環境を実行しているシングルレプリカの Bitcoin アダプターは、Bitcoin テストネットまたはメインネットの複数のノードではなく、ローカルの bitcoind ノードに接続します。dfx の関連フラグを確認するには、dfx start —help の出力を見てください。

IC テストネット上の Bitcoin

スマートコントラクトが受け入れテストの準備ができると、IC 上にデプロイされます(パブリックな IC テストネットがないことを思い出してください)。Bitcoin テストネットに接続するために Bitcoin API セットを使用します。これはローカル開発で使用するのと同じ設定です。この設定では Dapp の受け入れテストを実行するために Bitcoin テストネットを使用します。つまり、実際に価値のあるものは危険にさらされません。

IC メインネット上の Bitcoin

Bitcoinのスマートコントラクトの開発の最終段階は、Bitcoin API が設定された IC 上で Bitcoin メインネットを使用するデプロイメントです。これがスマートコントラクトの最終的な本番環境となります。これはまだ利用できませんが、GA リリースで有効化される予定です。

機能を利用する

Bitcoin を使って独自のアプリを作り始めるには、以下のチュートリアルをご覧ください:

はじめてのビットコイン Dapp をデプロイする

Local Development