ファクト

ÆTERNITYのセキュリティ監査報告を読んでみる7

更新日:

本稿について

ÆTERNITYのメインネットリリース前から行われているセキュリティ監査報告のv0.5について見ていきます。今回の範囲は「4. Protocol」の「4.4 State Channels」です。

原文はこちらになります。

スポンサードサーチ

今回のまとめ

  • ÆTERNITYのステートチャネル概観
    • オンチェーン(ブロックチェーン上)で行う必要があるのはchannel_createトランザクションとchannel_closeトランザクションだけ。
    • チャネルを開設する双方がチャネルステートツリーを持つ。各ステートはchannel_id、state_hash、round(初期化時0、その後1ずつインクリメント)で特定する。このツリー内にアカウント、コントラクト、コントラクト呼び出しのチャネルデータ全てを持つ。
    • オフチェーンアップデートに双方の署名がなされるとそれが最新のステートとなる。
  • チャネルオープンについて
    • 両者がオフチェーンで条件(initiator_amount、respondent_amount、lock_period、channel_reserve等)に合意し、共同署名付きのchannel_createトランザクションをオンチェーンに送信する。このトランザクションがブロックに取り込まれるとチャネルが開設されたことになる。
  • チャネルアップデートについて
    • オフチェーンの場合
      • 片方がステートに対する操作とその結果のステートをトランザクションに含めて署名をして相手に送信。
      • 相手は結果がOKであれば自身のステートツリーを更新し、トランザクションに署名をして返信。
    • オンチェーンの場合
      • 合意ありの場合
        • 新しいチャネルステート(channel_id、state_hash、round)を含む共同署名付きトランザクション(channel_depositかchannel_withdraw)を送信。このトランザクションがオンチェーンでブロックに取り込まれるとステートが更新される。
      • 合意なしの場合
        • 一方がオフチェーンコントラクトのオンチェーンでの強制執行を要求するchannel_force_progressトランザクションを送信。
          • このトランザクションには双方が署名した最後のステートとPoI(侵害の証明)、執行後のstate_hash、オンチェーンで実行するためのgasなどが含まれる。なお、当然ながらステートのラウンドはオンチェーンのラウンド以上でなくてはならない。
        • オンチェーンでブロックに取り込まれるとコントラクト呼び出しが実行され、結果がstate_hashと一致するかの確認が行われる。
          • 一致すればステートが更新される。一致しなければ更新されない。
        • もう一方はchannel_force_soloとして送信することで、channel_force_progressトランザクションの結果を無効化できる。
          • channel_force_progressトランザクションで指定されている最後のステートのラウンド数以上のステートで共同署名がなされたステートが必要。
        • channel_force_progressトランザクションの連続送信は原則認められない。前のchannel_force_progressトランザクションがlock_periodで定める期間経過後であれば可能である。channel_force_progressトランザクションがオンチェーンでブロックに取り込まれるとステートが更新される。
        • 現在のプロトコルではchannel_force_progressとchannel_snapshot_soloを交互に送信することで不正が可能であるという弱点が存在する。従って、両者が署名したステートは常に片方のみで行ったオペレーションをオーバライドするようにプロトコルを定義すべきである。これはステートチャネルのlock_periodのみにより制限されるべきである。
  • チャネルクローズについて
    • 合意ありの場合
      • 一方が共同署名付きのchannel_close_mutualトランザクションをオンチェーンで送信。channel_close_mutualトランザクションがオンチェーンでブロックに取り込まれるとチャネルは閉じたことになる。
    • 合意なしの場合
      • 一方が自身の署名付きのchannel_close_soloトランザクションを送信。これには双方が署名した最後のステートとPoIが含まれる。
      • もう一方は猶予期間(lock_period)以内にchannel_slashトランザクションを送信できる。これには双方が署名したより新しいステートとPoIが含まれる
      • 上記のトランザクションの有効期限経過後、どちらかがchannel_settleトランザクションを送信。channel_settleトランザクションがオンチェーンでブロックに取り込まれるとチャネルは閉じたことになる。
  • チャネルステートツリーについて
    • ブロックチェーンの各ブロックは開いている複数のチャネルのパトリシアマークルツリーにコミットする。
    • channel_idがチャネルのパスを指定する。
    • リーフノードはチャネルの現在のステートを反映する情報(channel_id、initiator_pubkey、responder_pubkey、channel_amount、initiator_amount、responder_amount、channel_reserve、state_hash(最後にオンチェーンに送られたもの)、round(最後にオンチェーンに送られたもの)、lock_period、closes_at、force_blocked_until)を保存する。
  • その他考察
    • cnlabは、ステートチャネル参加者(特に先手側)のディスアドバンテージを避けるため、インタラクティブな署名プロセスをプロトコルに追加することを推奨する。
      • 後手側の方が、すぐに署名する、拒否する、放置するなど選択肢が多く有利であるため。

※以下、今回まとめた範囲の和訳になりますので詳細をご覧になりたい方は読み進めてください。

4. プロトコル(続き)

4.4 ステートチャネル

ステートチャネルは2ノード間で行われてオフチェーンでの価値の交換を実現するもので、ブロックチェーンは裁定者のようにふるまう。

ブロックチェーンに発行する(そして支払いをする)必要があるのはchannel_createトランザクションとchannel_closeトランザクションだけである。ゆえにステートチャネルにより高速かつ安価でプライベートに取引を行うことができる。

各パーティがチャネルステートツリーを保持する。このツリーは全てのチャネルデータ、すなわち、アカウント、コントラクト、コントラクト呼び出しからなる。チャネルのステートはchannel_id、state_hash(チャネルステートツリーのルートハッシュ)、round(ラウンド。チャネル初期化時に0で始まり、更新ごとに厳密に増える)で表現される。

ステートチャネルは互いに合意したオフチェーンアップデートごとに(オフチェーントランザクションの一部として)共同署名がなされる。このようにして最新のチャネルのステートが証明され、最後のステートをブロックチェーンに送信することで対立を解決できる。

オンチェーンでの対立の解決は高速でもなければ安価でもプライベートでもないが、オンチェーンで対立を解決する可能性があることは予防的に作用しオフチェーンでの不正行為を抑止する。

4.4.1 チャネルを開く

  • ステートチャネルを開くためにイニシエータ(開設しようとする者)とレスポンデント(それを受け入れる者)はオフチェーンの通信(TCPなど)を確立し、条件(initiator_amount(イニシエータの金額)、respondent_amount(レスポンデントの金額)、lock_period(ロック期間)、channel_reserve(チャネルの準備金)など)に合意するためのオフチェーンメッセージを交換し、両者がchannel_createオンチェーントランザクションに署名してからオンチェーンに送信する。
  • 共同署名付きのchannel_createトランザクションがブロックに含まれると(そして最低限の深さに達すると)チャネルが開設されたとみなされる。このトランザクションはイニシエータとレスポンデントが(それぞれのオンチェーンアカウントから)いくらチャネルに預け入れたかを定め、チャネルを閉じる際に問題が起こった場合の対処方法を定める(lock_period、channel_reserve←これは悪意あるふるまいがあった場合には没収される)。

4.4.2 チャネルの更新

a)オフチェーン(2フェーズプロトコル)

  1. 一方が自身の署名付きトランザクションを送信することで変更を提案する。このトランザクションは前ステートに対して行うオペレーションの一覧と(予想されるオペレーションの結果を反映した)新しいチャネルステートからなる。
  2. 受け取った側は新しいステートが提案されたオペレーションの有効な結果であるかを検証し、ローカルのチャネルステートツリーを更新、提案されたトランザクションに署名をして返す。

各ラウンドで厳密にラウンドが増えなくてはならない(チャネル初期化時点で0から始まる)。

ステートチャネルの参加者はステートチャネル内部でローカルに全てのトランザクション(AEVMを介したコントラクトを含む)を評価できる立場にいなくてはならない。

b)オンチェーン

  • お互いの合意による更新の場合(channel_deposit、channel_withdraw):
    お互いの合意を得たオンチェーンの更新は、新しいチャネルステート(channel_id、state_hash、round)を含む共同署名付きのオンチェーントランザクションを送信することで実行される。
  • 合意のない更新の場合(channel_snapshot_solo、force_progress):
    • channel_snapshot_soloは最後の共同署名がされた(と推定される)オフチェーントランザクションを含む一方の署名付きのオンチェーントランザクションで、従って(恐らく)最新のチャネルステート(state_hashとroundで表現される)を反映している。roundはチェーン上にいまあるroundよりも大きくなくてはならない。channel_snapshot_soloがブロックに取り込まれると、古いステートでチャネルを閉じることはできない。
    • channel_force_progressは一方の署名付きのオンチェーントランザクションで、オフチェーンコントラクトに対する有効なコントラクト呼び出しの結果をもう一方に強制的に"承認"させるものである(最後のチャネルステートと推定されるものに適用される)。
      1. 強制する側はオフチェーンコントラクトをオンチェーンで実行できるよう、十分な情報(共同署名がなされた最後のステートと対応する侵害の証明(PoI, Proof of Inclusion))で構成されるchannel_force_progressトランザクションを送信する。
        さらにchannel_force_progressトランザクションはコントラクト呼び出しとオンチェーン実行のためのガスリミットとガス価格、予想される新しいstate_hashを含む。
      2. このトランザクションがブロックに取り込まれると、コントラクト呼び出しが実行され(呼び出しオブジェクトがオンチェーンに追加される)、ガスが消費される(このガスは強制する側のチャネルアカウントから消費)。
        コントラクト呼び出しの結果が予想されるstate_hashと一致する場合、それに従ってチャネルステートツリーは更新され(るとともにこのチャネルの新しいオンチェーンステートとみなされ)、チャネルラウンドは1増える。
        一致しない場合、オンチェーンのチャネルオブジェクトは変更されない(強制する側のチャネルアカウントからガス手数料を差し引くことは除く?)。
      3. 強制される側はより新しい共同署名付きのステート(例えばchannel_snapshot_soloを利用する)を送信することで拒否できる。ラウンド数が同じか大きい共同署名付きのステート(強制する側が送信したchannel_force_progressのあとに送信されたもの)はオンチェーンで生成されたステートを置き換えることができる。
        channel_force_progressトランザクションごとにチャネルラウンドは1増えるので、悪意ある者が次々と膨大なchannel_force_progressトランザクションを送信して古いステートから最新のオフチェーンラウンドを追い抜いてしまうのは防がねばならない。そうできないようにするため、最後のオンチェーントランザクションがchannel_force_progressでないか、channel_force_progressトランザクションがlock_periodで定められる深さに達したかのいずれかの場合にchannel_force_progressトランザクションをブロックに取り込むことができる。

提案されたルールはchannel_force_progressを濫用する潜在的なあらゆる可能性を防ぐには十分とは言えない。以下の例を考えてみよう。

  • AliceとBobの二人はラウンド100のステートsまでステートチャネルを運営している。
  • AliceはBobを騙そうとしてラウンド99のステートに基づいてchannel_force_progressを送信し、ラウンド100でステートs'になった。
  • 現在のプロトコルはAliceが次のchannel_force_progressオペレーションを送信するのを防ぐ。しかし。Aliceはステートs'に対してchannel_close_soloオペレーションを実行できてしまう。
  • この結果、Aliceはステートs'に基づいて次のchannel_force_progressオペレーションを送信でき、ラウンド101のステートtになってしまう。
  • BobはAliceとBobの両者が署名した正しい最後のステートsを送信することはもうできない。なぜなら、ラウンドが100だからだ。

推奨案5:上述の状況を避けるため、両者が署名したステートは常に一人が行ったオペレーションをオーバライドするようにプロトコルを定義すべきである。これはステートチャネルのlock_periodのみにより制限されるべきである。

4.4.3 チャネルを閉じる

  • お互いの合意によりチャネルを閉じる場合:
    どちらか一方が金額の分配方法を定める共同署名付きのchannel_close_mutualオンチェーントランザクションを送信する。
  • 合意なくチャネルを閉じる場合 - オンチェーンでの強制による:
    1. 一方が自身の署名の付いたchannel_close_soloトランザクションを送信する。このトランザクションにはチャネルを閉じるための十分な情報(最後の共同署名付きのステート、対応するPoI)を含んでいなければならない。
    2. もう一方には猶予期間(lock_periodとして定められている)があり、より新しいステート(共同署名付きのオフチェーントランザクションの一部として)と対応するPoI含むchannel_slashトランザクションを送信することで拒否できる。
    3. channel_close_soloとchannel_slashの有効期限経過後:どちらか片方がchannel_settleトランザクションを送信する。channel_settleは最新のオンチェーンステートに応じてチャネル内の金額の分配を決める。

channel_close_mutualトランザクションかchannel_settleトランザクションがブロックに含まれると(そして最低限の深さに達すると)、チャネルは閉じたとみなされる。チャネル内の金額は適宜にイニシエータとレスポンデントのオンチェーンアカウントに分配される。

4.4.4 チャネルステートツリー

ブロックチェーンの各ブロックは開いているチャネルのパトリシアマークルツリーにコミットする(そのルートハッシュに含まれる)(筆者注:マークルパトリシアツリーの記載が一般的なようですが、本文に則ってパトリシアマークルツリーとします)。channel_idがそのパスを指定する。リーフノードは所与のチャネルの現在のステートを反映する情報、すなわちchannel_id、initiator_pubkey、responder_pubkey、channel_amount、initiator_amount、responder_amount、channel_reserve、state_hash(最後に送信されたstate_hash)、round(最後に送信されたround)、lock_period、closes_at(オンチェーンのチャネルを閉じるブロック高)、force_blocked_until(新しいforce progressをブロックに取り込めるようになった後のオンチェーンチャネルのブロック高)を保存する。

4.4.5 追加考察

ステートチャネルはブロックチェーンプロトコルの有益な拡張であると考える。実際にユーザが不誠実なふるまいをしないよう効率的にインセンティブを与えられることが証明されれば、多くのトランザクションをブロックチェーンに保存せずに済むようになることからステートチャネルはブロックチェーンをもっとスケーラブルにしうる可能性を秘めている。

思い浮かぶ問題の一つは、現在のプロトコル設計では二者のうちの片方がまずトランザクションに署名せねばならないという事実である。これではもう一方にアドバンテージがある。というのもいますぐにトランザクションの署名に合意することも拒否することもできるし、ともすれば後で署名することに決めることさえできる。

このステートチャネルは直接通信する二者によって開設されるように作られているので、この非対称な状況を避けるインタラクティブなスキームを使ってトランザクションに署名できるようにすることは大きな改善であろう。

推奨案6:ステートチャネル参加者のディスアドバンテージを避けるため、インタラクティブな署名プロセスをプロトコルに追加することをcnlabは推奨する。

ÆTERNITYのセキュリティ監査報告を読んでみる6 ←← 前)|(次 →→ ÆTERNITYのセキュリティ監査報告を読んでみる8

免責

邦訳には誤りがある場合がございます。予めご承知おき下さい。

確実な情報を知るためには冒頭に示した原文をご参照くださいますようお願いいたします。

-ファクト
-, , ,

Copyright© 暗号通貨界隈のメモ書きなど。 , 2024 All Rights Reserved Powered by STINGER.

%d人のブロガーが「いいね」をつけました。