ソース: Starknet Chinese Community
Selected Quick Takes
Deep dive into building demo bridge contracts on Bitcoin, laying the foundation for the Starknet?
入出金アグリゲーター、ブリッジ、出金エクステンダーのための4つのスマートコントラクトの実装
ユーザーアカウントの整合性とセキュリティを維持しながら、入出金リクエストを効率的にバッチ処理するための再帰的コントラクトとMerkleツリーの使用
はじめに
本稿では、sCryptがどのようにビットコイン上でデモブリッジコントラクトを構築するかについて掘り下げます。この概念実証の実装は、Starknetレイヤー2(L2)ネットワーク用のプロダクショングレードのブリッジの基礎を築くことを目的としています。ブリッジは、複数の入金または出金要求トランザクションを単一のルートトランザクションにマージできるように設計されており、このトランザクションはメインのブリッジ契約に組み込まれ、メルケルツリーで編成されたアカウントセットで構成される状態を更新します。
ブリッジ契約のスクリプトは複雑であるため、sCryptではその実装を書くためにsCrypt固有のドメイン言語(DSL)を利用しました。
概要
ブリッジは再帰的なコントラクトBitcoinスクリプトで構成されています。この文脈では、「コントラクト」は、ロッキングスクリプトが支出トランザクションに条件を課すことができることを意味し、「再帰的」は、上記のルールがチェーン上で永続的なロジックと状態を可能にするのに十分堅牢であることを意味します(任意のオンチェーンスマートコントラクトの基本要件)。
スクリプトは一連のトランザクションの中に存在し、各トランザクションは後続のトランザクションの構造に制約を課し、現在のトランザクションの出力をアンロックする。新しいトランザクションがこのチェーンに追加されるたびに、それはブリッジ状態の更新を意味する。したがって、このチェーンの終わりは現在のブリッジ状態を保持する。
契約状態(具体的にはハッシュ値)は、消費不可能なOP_RETURN出力に格納される。このUTXOを使用することはありませんが、そのデータは契約スクリプトを実行するときに調べることができます。
Merkleツリーは、アカウントスロットの固定セットのデータを保持しています。リーフノードには、住所と残高を含むそれぞれの口座データのハッシュが格納されています。空のアカウントスロットを示すために、これらのスロットはゼロバイトでマークされます。
ブリッジが更新されるたびに、アカウントツリーが変更されます。この更新を容易にするために、ビットコインスクリプトで検証が非常に効率的であるMerkle証明に依存します。更新は主に2つのステップで構成されます。まず、メルクル証明を検証して、証明メルクルツリーに特定のアカウントの現在の状態が含まれていることを示します。次に、そのアカウントの新しい状態を計算した後、前述のメルクル証明と同じ補助ノードを使用して、新しいルートハッシュを導出します。
更新には入金や出金があります。ブリッジは単一のトランザクションでこれらの更新のバッチ操作を実行することができます。
入金
私たちの目標は、ユーザーが独立して入金や出金リクエストを提出できるようにすることです。これを実現するために、ユーザーは入出金アグリゲーション契約に別々に支払われる個別のトランザクションを作成します。コントラクトはこれらのリクエストをメルクルツリーに集約する。このツリーのルートハッシュはメインブリッジコントラクトにマージされ、メインブリッジコントラクトは各入金または引き出しを処理する。
預金データをハッシュ化し、預け入れトランザクションでメルクルツリーを構築することに加え、コントラクトは、コントラクト出力にロックされた預け入れサトシが正しくツリーのルートノードに蓄積されるようにする。集約コントラクトは、正しいオンチェーン・スマートコントラクトのみがこれらの資金を使用できることを保証する。(もちろん、本番環境では、ユーザーがデポジット取引をキャンセルすることもできるようにします)。
このツリー構造の設計は、コントラクトスクリプト構築の制約に由来しており、あまりに多くの入力と出力を含むトランザクションを許可していません。ツリー構造により、潜在的に任意のスループットまで拡張することができます。
出金リクエスト
出金リクエストは入金と同様に集約されますが、いくつかの違いがあります。まず、ユーザーが自分の口座からお金を引き出すことができるように、認証方法が必要です。これは入金とは異なり、誰でもどの口座にも入金でき、ビットコインアドレスが使用される方法と似ている。認証は集約ツリーのリーフノードレベルで行われる。引き出し要求集約契約は、引き出しアドレスがリーフトランザクションで入力された最初のP2WPKHアドレスと一致するかどうかをチェックします。
これにより、アドレスの所有者が引き出しを要求するトランザクションに署名しているため、引き出しを承認していることが保証されます。入金集計と比べたもう一つの微妙な違いは、中間累積額をハッシュ化し、ツリー構造の上方に渡すことである。これは後で詳しく説明するが、出金を拡張するときにこのデータが必要になるからである。
勘のいい読者は、この出金要求認証モデルの潜在的な問題に気づくかもしれません。もしあるオペレーターが不正を決行し、ルートトランザクションの集約ツリーを作成し、その集約ツリーのデータが認証されていない偽の出金リクエストによってローカルで偽造されたとしたらどうなるでしょうか?ルートトランザクションが有効なリーフトランザクションから来ていることを検証する効率的な方法が必要です。
この問題を解決するために、私たちは「ジェネシス・チェック」と呼ばれるものを実行します。基本的に、集計コントラクトにその前のトランザクションと最初の2つのトランザクション、すなわち「祖先トランザクション」をチェックさせる。コントラクトは、これらのトランザクションに同じコントラクトスクリプトが含まれていることを確認し、同じチェックを実行する。このようにして、帰納的トランザクション履歴チェックを実装する。最初の2つのトランザクションは現在のコントラクトと同じチェックを実行するので、これらのトランザクションの「祖先」も、リーフノード(すなわち、作成トランザクション)まで遡って同じチェックを実行することを確認できる。
もちろん、ツリーの両方の枝で検証を実行します。したがって、各集約ノードトランザクションは、合計で最大6つのトランザクションをチェックする。
出金拡張
さて、ソリューションの最後の部分、出金拡張に移りましょう。出金要求のバッチを処理した後、メインブリッジの契約は出金総額を延長契約に支払う出力を強制する。このコントラクトは、フェッチリクエスト集計コントラクトが行った処理の逆プロセスと考えることができる。これはフェッチツリーのルートノードから始まり、それを2つのブランチに展開し、それぞれがそのブランチに支払われるべき対応するフェッチ量を含む。このプロセスはフェッチツリーのリーフノードまで続く。リーフ・トランザクションは、引き落としを要求された金額について、口座所有者のアドレスへの単純な支払い出力を強制する。
Implementation
ブリッジコントラクトを実装するために、私たちは4つのsCryptスマートコントラクトを開発しました。システムの異なる側面を処理します。このセクションでは、各コントラクトの機能の概要を説明します。
DepositAggregatorコントラクト
DepositAggregatorコントラクトは、個々のデポジットをメルケルツリーに集約し、それをメインのブリッジコントラクトにマージします。この集約により、一括入金処理が可能になり、ブリッジが個別に処理する必要のあるトランザクションの数を減らすことができます。さらに、利用者が個別に預金を提出し、それを後でオペレーターが処理することも可能になる。
契約ビルダー関数には次のものがあります。2つのパラメータ:
預金アグリゲーターの中核機能は、「aggregate」メソッドにカプセル化されています。このメソッドは以下のステップを実行します:
Sighash原本およびオペレーターの署名の検証:取引がブリッジオペレーターによって承認され、sighash原本が正しくフォーマットされ、実行される取引に属していることを確認します。sighash原本の検証についてはこちらの記事をご覧ください。
先行トランザクションIDの構築と検証:集約された先行トランザクションが有効で、正しく参照されていることをチェックします。
先行トランザクションIDの構築:集計された先行トランザクションが正しく参照されているかチェックする。
Merkle Tree Aggregation: ウィットネスハッシュとして渡されたデポジットデータが、先行トランザクションに保存された状態と一致することを検証します。
Merkle Tree Aggregation:証人ハッシュとして渡された預託データが、先行する取引に保存されている状態と一致することを検証する。
金額検証:事前出力の金額が指定された入金額と一致するかどうかを確認し、集計で資金が正しく計算されるようにします。
ステータス更新:先行トランザクションのハッシュ値をつなげて新しいハッシュ値を計算し、OP_RETURN出力のステータスを更新する。
再入力攻撃防止:厳格な出力スクリプトと金額を強制し、無許可の変更や二重支出を防ぎます。
再入力攻撃防止:厳格な出力スクリプトを実施し、不正な修正や二重支出を防ぎます。
預託金が集約されたら、メインのブリッジ証書にマージされなければならない。このプロセスは「finalise」メソッドで処理され、そのステップには次のようなものがあります:
前任者取引の検証:「集約」メソッドと同様に、前任者取引は統合されたデータの整合性を確保するために検証されます。
ブリッジ契約との統合:ブリッジのトランザクションIDとスクリプト公開キーを参照することで、集約された預金がメインのブリッジ契約に正しくマージされることを確認します。
Deposit Aggregationコントラクトの全ソースコードはGitHubで見ることができます。
Withdrawal Aggregatorコントラクト
WithdrawalAggregatorコントラクトは、個々の引き出しリクエストをMerkleツリーに集約するように設計されています。ツリーに集約するように設計されています。しかし、引き出し操作では、正当な口座所有者だけが口座から資金を引き出せるようにするために、追加の認証が必要になる。
出金アグリゲーターのコア機能は「aggregate」メソッドにカプセル化されており、以下のステップを実行します:
先行トランザクションIDの構築と検証:このプロセスは、集約された先行トランザクションが有効であり、正しく参照されていることを検証します。
所有権証明の検証: 所有権証明取引を検証することで、正当な所有者だけが口座から資金を引き出せるようにします。
Genesis checking via 'Ancestral Transactions': 預金アグリゲーターと同様に、契約は先祖代々の取引を検証することで帰納的チェックを行います。これにより、取引履歴の完全性が保証され、オペレーターが未承認の引き出し要求を挿入することを防ぎます。
金額の検証と合計金額の計算:このメソッドは、引き出しリクエストまたは以前の集計から金額を合計して、引き出す合計金額を計算します。
ステータス更新:先行取引のハッシュと引き出し額の合計を含む新しいハッシュを計算する。このハッシュはOP_RETURN出力に格納され、ステータスを更新する。
再侵入攻撃防止と出力強制: 無許可の変更や再侵入攻撃を防ぐために、出力が厳密に定義されていることを確認します。
出金集約コントラクトの完全なソースコードはGitHubで見ることができます。
ブリッジコントラクト
ブリッジコントラクトは私たちのシステムのコアコンポーネントで、メルケルツリーで整理された口座とその残高を含むブリッジの状態を維持するメインコントラクトです。先に説明したアグリゲーター・コントラクトと統合することで、入出金オペレーションを処理します。
契約ビルダー関数には2つのパラメータがあります。br>
入金メソッドは、集約された入金トランザクションを処理し、それに応じて口座残高を更新する責任があります。
預金方法は、以下を実行する。ステップには以下が含まれます:
入金を処理し、口座を更新する:
ブリッジのステータスを更新し、出力する。
預金を処理した後、新しい口座Merkel Rootを計算する。
更新されたブリッジ状態を表す新しい状態ハッシュを作成します。
ブリッジの残高にデポジット総額を追加するためにコントラクト出力を構築する。
データの整合性を維持するために、出力が期待される形式であることを確認します。
出金メソッドは、集約された出金トランザクションを処理し、口座残高を更新し、出金エクステンダを通して割り当てられた資金を準備します。
引き出し方法によって実行されるステップには、以下が含まれる:
引き出し方法によって実行されるステップには、以下が含まれる。br>
出金リクエストを処理し、口座を更新する。
出金処理後に新しい口座メルケルートを計算します。
更新されたブリッジ状態を表す新しい状態ハッシュを作成します。
ブリッジの残高から引き出し総額を差し引くために、コントラクト出力を構築する。
合計引き出し額を含む引き出しエクステンダー契約の拡張出力を作成します。
データの整合性を維持するために、出力が期待される形式であることを確認します。
完全なソースコードはGitHubで入手可能です。
Withdrawal Expander Contract
WithdrawalExpanderはブリッジシステムの最後のコンポーネントであり、ユーザーの引き出し要求に基づいて集計された引き出し額を個々のユーザーに分配する役割を担っています。各ユーザーに分配する役割を担っています。WithdrawalExpanderは、WithdrawalAggregatorによって実行された集約プロセスを逆転させ、集約された引き出しデータを個々のユーザーの支払いにまで拡張します。
出金エキスパンダーのコア機能は'expand'メソッドにカプセル化されています。このメソッドは、集約された出金データを受け取り、ユーザーに適切な金額を支払う個々の出金トランザクションに再帰的に展開します。
リーフノードへの展開:メソッドがリーフノード(個々のフェッチ)に展開する場合、フェッチデータを検証し、ユーザーのアドレスに直接支払う出力を構築します。
さらなる拡張:メソッドがまだリーフノードレベルに達していない場合、集約されたデータを2つのブランチに分割し、さらに拡張されたトランザクションによって消費される出力を作成することによって拡張を続けます。
結論
この概念実証の実装では、sCrypt組み込みドメイン固有言語(DSL)を使用して、OP_CATサポートに基づくビットコインのブリッジ契約を開発しました。このブリッジは、再帰的コントラクトとMerkleツリーを利用して、ユーザーアカウントの整合性とセキュリティを維持しながら、入出金要求を効率的にバッチ処理します。WithdrawalExpanderの4つのスマートコントラクトにより、ビットコイン上のステートフルなやり取りを管理する方法を提供し、Starknetのような第2層のネットワークとの相互運用性を促進する。この研究は、ビットコインエコシステムにおけるスケーラビリティと機能性を高める可能性のあるプロダクショングレードのブリッジを構築するための技術的基盤を提供します。
すべてのコードの実装とエンドツーエンドのテストは、GitHubで利用可能です。
[記事全文終わり]
Original link: https://starkware.co/blog/implementing-a-bridge-covenant-on-op-cat-bitcoin/
Mirror: https://mirror.xyz/starknet-zh.eth/zFbhQB7gfmSTV4CcTv5MRqJBUnKuwMLTNOgZ6jUgDK8