暗号資産におけるイベントログとは?
イベントログは、ブロックチェーントランザクションの実行中にスマートコントラクトが作成する構造化された記録です。スマートコントラクトから情報を公開することで、ウォレット、分散型アプリケーション、ブロックチェーンエクスプローラー、分析プラットフォームなどのオフチェーンシステムが、その情報を検索して処理できるようになります。EthereumやほかのEVMベースのネットワークでは、開発者は通常、Solidityでイベントを宣言し、関連する操作が発生したときにemitキーワードを使ってイベントログを作成します。たとえば、トークンコントラクトは、トークンの送金、ミント、バーン、使用承認時にイベントを出力する場合があります。分散型金融プロトコルは、ユーザーが担保を預け入れる、暗号資産を借りる、債務を返済する、報酬を受け取る、ポジションを決済するといった際にログを出力することがあります。公式のイベントに関するSolidityドキュメントでは、イベントはEVMのログ機能を抽象化したものと説明されています。
イベントログは通常、コントラクトの状態を制御したり、出力後に追加のビジネスロジックを実行したりするものではありません。外部ソフトウェアがトランザクション中に何が起きたかを把握するために利用できる、効率的な記録を提供します。このため、イベントログはオンチェーンのスマートコントラクトと、ブロックチェーン上の活動をユーザーに表示するオフチェーンアプリケーションをつなぐ重要な役割を果たします。イベントログの仕組み
イベントログは、トランザクション内の正常な実行経路をEthereum Virtual Machineが処理する間に作成されます。まずスマートコントラクトで、名前とパラメーターの一覧を含むイベントを宣言します。その後、コードが該当する命令に到達すると、コントラクトがイベントを出力します。Solidityコンパイラーは、イベントの出力をEVMのログ命令のいずれかに変換します。生成されるログには、出力元コントラクトのアドレス、検索可能なトピックの一覧、追加のエンコード済み情報を格納するデータフィールドが含まれます。トランザクションがブロックに含まれると、ログはトランザクションレシートの一部になります。アプリケーションはEthereumノード、RPCプロバイダー、ブロックチェーンエクスプローラー、専用のブロックチェーンインデクサーを通じてログを取得できます。スマートコントラクトのイベントログに関するEthereumガイドでは、分散型アプリケーションがイベントの出力を検知し、その情報を基にオフチェーンで処理できると説明されています。
トランザクションがリバートされた場合、リバートされた実行中に作成されたログも最終的なトランザクション結果から削除されます。そのため、シミュレーションや実行トレースに表示されたログが、全体の呼び出しに失敗した場合、確定後のレシートに現れないことがあります。イベントとイベントログの違い
イベントは、コントラクトが公開できる情報を定義するために開発者が宣言するものです。イベントログは、トランザクション中にコントラクトがイベントを出力したときに作成される実際の記録です。たとえば、コントラクトはソースコード内でTransferイベントを定義できます。完了した送金ごとに、そのイベント定義に基づく個別のログが作成されます。イベントがテンプレートだとすれば、各ログはそのテンプレートに基づいて記録された1回の発生事例です。1つのトランザクションで、ログが0件、1件、または複数件作成される場合があります。複数のスマートコントラクトとやり取りするトランザクションでは、実行に関与した各コントラクトがログを出力することがあります。アプリケーションは、コントラクトのApplication Binary Interface(ABI)を使い、未加工のログをイベント定義と照合して値をデコードします。イベントログに記録される情報
EVMのイベントログには、出力元コントラクトのアドレス、0~4個のトピック、可変長のデータフィールドが含まれます。出力元アドレスは、どのコントラクトの実行によってログが作成されたかを示します。トピックには、効率的なフィルタリングや検索に適した値が含まれます。データフィールドには、indexedとして指定されていないイベントパラメーターが格納されます。一般的なRPCインターフェースでは、ログとともにトランザクションやブロックのメタデータも返されます。このメタデータには、トランザクションハッシュ、トランザクションインデックス、ブロックハッシュ、ブロック番号、ログインデックスなどが含まれる場合があります。ログインデックスは、同じブロック内のほかのログと比べたログの位置を示します。アプリケーションで一意の記録IDを作成する際は、通常、チェーンID、ブロックハッシュ、トランザクションハッシュ、ログインデックスを組み合わせて使います。1つのトランザクションで同じイベントが複数回出力されることがあるため、イベント名やトランザクションハッシュだけでは不十分な場合があります。イベントトピックとは?
トピックは、EVMログ内の専用の検索可能領域に置かれる32バイトの値です。アプリケーションはこれを使い、イベントデータフィールドを個別にすべてデコードせずに、ブロックチェーンの履歴をフィルタリングできます。通常の非匿名Solidityイベントでは、最大4つのトピックを使用できます。最初のトピックは通常、イベントの種類を識別し、最大3つの追加トピックはindexedに指定されたパラメーターを表します。トピックには順序があるため、2番目のトピック位置にある値を検索する場合と、同じ値を3番目の位置で検索する場合では異なります。公式のeth_getLogsに関するEthereum JSON-RPCドキュメントでは、トピックフィルターは順序に依存し、同じ位置に複数の候補値を指定できると説明されています。
ウォレットアドレス、トークンID、市場、提案、その他よく検索される値に関連するイベントを探す際、トピックは特に便利です。indexedパラメーターの選定が適切でないと、アプリケーションの過去データを検索しにくくなったり、検索コストが高くなったりする場合があります。Topic 0とは?
Topic 0には通常、イベントの正規シグネチャのKeccak-256ハッシュが格納されます。正規シグネチャは、イベント名と順序付けられたパラメーター型を組み合わせたものです。パラメーター名とindexedキーワードは、イベントシグネチャのハッシュには含まれません。たとえば、Transferという名前で、型がaddress、address、uint256のパラメーターを持つイベントは、予測可能なイベントシグネチャを持ちます。アプリケーションはTopic 0を既知のシグネチャハッシュと比較し、未加工ログがどのイベントを表すか識別できます。イベント名やパラメーターの順序または型を変更すると、別のイベントシグネチャになります。そのため、名前が同じでもパラメーター型が異なる2つのイベントは、Topic 0の値も異なります。イベントに関するSolidity ABI仕様では、イベントシグネチャとイベント引数がトピックおよびデータにエンコードされる方法が説明されています。
indexedイベントパラメーター
indexedパラメーターとは、外部システムが効率的にフィルタリングできるよう、トピックに保存されるイベント引数です。Solidityの通常の非匿名イベントでは、最大3つのパラメーターをindexedにできます。残りのトピック位置はイベントシグネチャ用に確保されます。アドレス、整数、ブール値など、32バイトのワードに収まる値は、ABI互換のエンコードを用いてトピックに直接保存できます。動的な値である文字列、バイト配列、動的配列、複雑な構造体は、異なる方法で扱われます。動的な値をindexedにすると、元の読みやすい値ではなく、エンコードした値のKeccak-256ハッシュがトピックに保存されます。検索対象の値がすでに分かっている場合、アプリケーションはそのハッシュでフィルタリングできます。ただし、ハッシュだけから、未知の元の文字列やバイト配列を復元することはできません。開発者は、ハッシュ化した値をindexedパラメーターに、読み取り可能な値を非indexedパラメーターに置き、同じ情報を二重に含める場合があります。この設計では、元の値をデコードできる状態に保ちながら、検索性を高められます。非indexedイベントパラメーター
indexedキーワードのないパラメーターは、ログのデータフィールドに保存されます。これらの値はEthereum ABIのルールに従ってエンコードされます。未加工のログデータには、各値の人間が読める名前や型が付いていないため、デコードにはABIが必要です。データを正確にデコードするには、アプリケーションが正しいイベント定義を使う必要があります。非indexedパラメーターには、個々のトピックより大きく複雑な値を含めることができます。金額、詳細な設定値、配列、文字列など、トピックによる直接のフィルタリングが不要な情報に適しています。通常、eth_getLogsを使ってデータフィールド内の任意の値を基準にフィルタリングすることはできません。まずコントラクトアドレスとトピックを使ってログを取得し、その後、データをローカルでデコードして確認する必要があります。匿名イベント
Solidityのイベントは匿名として宣言できます。匿名イベントでは、イベントシグネチャのハッシュがTopic 0に自動で格納されません。これにより、indexedパラメーターに4つすべてのトピック位置を使用できます。ただし、シグネチャトピックがないと、外部ソフトウェアがイベントの種類を自動的に識別しにくくなります。似たトピック構造やデータ構造を持つ複数の匿名イベントは、見分けるのが難しくなる場合があります。匿名イベントは特殊な低水準設計で適切な場合もありますが、通常のアプリケーションイベントは、匿名にしない方がインデックス化やデコードが容易です。開発者は、追加のindexedトピックによる利点が、イベント識別の難しさを上回る場合に限り、匿名イベントを使用する必要があります。EVMのログオペコード
EVMにはLOG0からLOG4まで、5種類のログオペコードがあります。オペコード名の数字は、ログに含まれるトピックの数を示します。LOG0はトピックなしのログを作成し、LOG4は4つのトピックを持つログを作成します。各ログ命令は、EVMメモリ内の指定された範囲も読み取り、ログのデータフィールドとして保存します。Solidityのイベントは、コンパイル時にこれらの低水準ログ命令へ変換されます。コントラクトアドレスは通常のイベントパラメーターとして渡されるのではなく、実行環境によってログに付加されます。ログ命令のガス消費量は、トピックの数や記録されるデータ量などの要素に応じて変わります。公式のEthereumオペコードのリファレンスには、EVMのログ命令と実行コストが記載されています。
イベントログとトランザクションレシート
トランザクションレシートは、トランザクションがブロックに含まれた後に生成される実行記録です。レシートには、実行ステータス、累積ガス使用量、ログブルーム、トランザクションが出力したログなどが含まれます。RPCの応答には、コントラクト作成アドレス、実効ガス価格、個々のトランザクションのガス使用量など、ほかの有用なフィールドが追加される場合があります。logs配列は、実行中にイベントが出力された順序を保持します。コントラクトがイベントを出力しなければ、トランザクションが成功してもlogs配列が空の場合があります。失敗したトランザクションでは、状態変更とログがリバートされるため、通常、イベントログは残りません。トランザクションハッシュが存在することを実行成功の証拠とみなさず、アプリケーションはレシートのステータスを確認する必要があります。トランザクションレシートを取得するEthereum JSON-RPCメソッドでは、実行クライアントが返すレシートのフィールドが説明されています。
イベントログとブロックレシート
トランザクションレシートは、ブロックのreceipts rootを通じて暗号学的にコミットされます。このコミットメントによって、ブロックチェーン参加者はレシートが特定のブロック履歴に属することを検証できます。各レシートには、そのトランザクションが生成したログが含まれます。現行の実行ブロック形式では、ブロックヘッダーに、そのブロックのトランザクションから出力されたログのアドレスとトピックを要約するブルームフィルターも含まれます。ブルームフィルターは、検索条件に一致するログがブロックに含まれる可能性があるかをクライアントが判断するのに役立ちます。ブルームフィルターでは偽陽性が起こるため、一致判定が出ても、実際に該当するログが存在するとは限りません。否定判定の場合、検索したアドレスやトピックはそのブルームフィルターに含まれていません。正確なイベント値を確認するには、アプリケーションが実際のレシートログを確認する必要があります。イベントログとコントラクトストレージ
イベントログとスマートコントラクトのストレージは、異なる目的で使われます。コントラクトストレージには、将来のスマートコントラクト実行で直接読み取れる永続データが保存されます。イベントログは主に、外部からの監視と過去データのインデックス化を目的としています。Solidityコントラクトは、同じコントラクトが出力したものを含め、過去のイベントログを直接読み取ることはできません。Solidityのイベントリファレンスでは、ログやイベントデータをコントラクト内から参照できないとされています。
将来のオンチェーン判断に必要なデータを、過去のイベントだけに依存させてはいけません。将来のコントラクトロジックで値を使用する必要がある場合、その値は通常、コントラクトの状態に保存するか、検証可能な仕組みを通じて提供する必要があります。オフチェーンのユーザーだけが利用する情報であれば、ログへの保存は通常、永続ストレージより低コストです。ただし、ストレージの代わりにログを使うと、スマートコントラクトが後から検証または取得できる情報が変わります。イベントログと関数の返却データ
関数の返却データは、コントラクト実行中に直接の呼び出し元へ返されます。イベントログはトランザクションレシートに保存され、後からオフチェーンで取得できます。状態を変更するトランザクションでは、イベントログと同じような履歴形式で、ユーザーインターフェースに返却データを提供することは簡単ではありません。そのため、アプリケーションは送信済みトランザクションの結果を把握する際、レシートやイベントを利用することがよくあります。読み取り専用の呼び出しでは、イベントログの作成やブロックチェーンの状態変更を行わずに値を返せます。開発者は、即時のコントラクト呼び出しには返却値を、永続的なオフチェーン通知にはイベントを使う必要があります。1つのトランザクションで複数のコントラクトがログを出力する場合があるため、イベントを直接の関数応答として扱うべきではありません。アプリケーションによるイベントログの検索
アプリケーションは、eth_getLogs JSON-RPCメソッドを通じて過去のイベントログを検索することがよくあります。検索では、開始ブロック、終了ブロック、コントラクトアドレス、ブロックハッシュ、トピックフィルターを指定できます。このメソッドは、フィルターに一致するログの配列を返します。非常に広いブロック範囲のすべてのログを要求するより、範囲を絞った検索の方が一般に信頼性と効率に優れます。RPCプロバイダーは、ブロック範囲、応答サイズ、処理時間、リクエスト頻度に制限を設けている場合があります。アプリケーションは大規模な過去データ検索を小さなブロック範囲に分割し、処理の進捗を保存する必要があります。また、失敗したリクエストは制御されたバックオフで再試行し、空の応答や失敗した応答を、イベントが存在しない証拠とみなさないようにする必要があります。EIP-234で定義されたblockHashフィルターを使うと、特定のブロックに属するログを要求できます。
ポーリングとイベントサブスクリプション
アプリケーションは、ポーリングまたはサブスクリプションによって新しいイベントログを検知できます。ポーリングでは、ノードに対して定期的にログやフィルターの変更を問い合わせます。サブスクリプションでは接続を維持し、ブロックが到着するとノードが新しいログの通知を送信します。サブスクリプションは迅速な更新を提供できますが、障害時に接続が切れたり、情報を取りこぼしたりする可能性があります。ポーリングは、アプリケーションが既知のブロック範囲を再取得できるため、復旧しやすい場合があります。本番環境の堅牢なシステムでは、リアルタイムのサブスクリプションと、ブロック単位での定期的な照合作業を組み合わせることがよくあります。これにより、ネットワークの切断やノードの再起動中に取りこぼしたログを検出できます。公式のEthereum JSON-RPC APIドキュメントには、前回のポーリング以降に出現したログを取得するフィルターメソッドが説明されています。
イベントログとチェーンの再編成
チェーンの再編成とは、アクティブチェーンの一部とみなされていたブロックが、別のブロック履歴に置き換えられることです。置き換えられたブロックのログは、正規のブロックチェーンに含まれなくなります。そのログにすぐ反応したアプリケーションは、ローカルデータベースの変更を取り消す必要がある場合があります。一部のRPCサブスクリプション応答では、再編成によって以前に通知されたログが削除されたことが示されます。ただし、ネットワーク接続の切断によって、アプリケーションが削除通知を受信できない場合があります。信頼性の高いインデクサーは、ブロックハッシュと親ブロックとの関係を追跡し、置き換えられたブロックを独自に検出します。ブロックハッシュに基づくログフィルタリングの背景には、再編成や接続障害への慎重な対応が必要であることが示されています。
金融システムでは通常、イベントを取り消し不能として扱う前に、適切な承認数またはファイナリティの基準を待つ必要があります。必要な基準は、チェーン、アプリケーションで扱う価値、早期に処理した場合の影響によって異なります。イベントログとファイナリティ
新しく出力されたイベントは、ブロックがより強いコンセンサス上のファイナリティに達する前に、提案中のブロックに表示される場合があります。接続先のクライアントが対応していれば、latest、safe、finalizedなどのブロックタグを使ってログを検索できます。latestタグは情報をすばやく取得できますが、再編成のリスクが比較的高いブロックを含む場合があります。finalizedタグはより高い確度を提供する一方、時間がかかります。ポートフォリオ画面は表示用にlatestのイベントを採用する一方、ブリッジや高額な資金移転では、より強い確認を必要とする場合があります。すべてのイベントに同じルールを適用せず、経済的リスクに基づいて確認方針を選ぶ必要があります。トークンコントラクトのイベントログ
トークン標準は、送金や承認をウォレットやブロックチェーンデータシステムから確認できるように、イベントログを使用します。代替可能トークンは通常、アドレス間で価値が移転した際にTransferイベントを出力します。所有者が別のアドレスの使用許可額を変更すると、Approvalイベントも出力する場合があります。NFTコントラクトは、トークンIDを含む送金イベントや承認イベントを一般に出力します。マルチトークンコントラクトは、単一送金イベントや一括送金イベントを出力する場合があります。イベント構造の標準化により、外部ツールは共通のデコードロジックを使って多くのトークンコントラクトに対応できます。ただし、誤解を招くイベントを出力したり、標準に正しく従わなかったりするトークンもあります。イベントだけで、コントラクトの正当性、価値、安全性が証明されるわけではありません。分散型金融におけるイベントログ
分散型金融プロトコルは、複雑な金融操作を示すためにイベントログを利用します。一般的な例には、入金、出金、スワップ、借入、返済、強制決済、利息の更新、報酬請求、ガバナンス変更などがあります。ユーザーインターフェースは、これらのイベントを監視して残高や取引履歴を更新する場合があります。分析システムは、イベントを集計して取引高、流動性、借入活動、プロトコル収益などを計算する場合があります。リスク監視サービスは、強制決済や担保に関するイベントを追跡し、リスクが高まったポジションを検知する場合があります。1つのDeFiトランザクションで複数のコントラクトを呼び出すことがあるため、レシートに関連するログが多数含まれる場合があります。アプリケーションは、使い慣れたイベントシグネチャをすべて主要なプロトコルコントラクトから出たものとしてデコードせず、出力元アドレスとログの順序を考慮する必要があります。ウォレットとブロックチェーンエクスプローラーにおけるイベントログ
ウォレットはイベントログを使い、スマートコントラクトの生のトランザクションを読みやすい履歴に変換します。トークン送金は、トランザクションの基本フィールドにネイティブ資産の移動として表示されない場合があります。ウォレットはトークンコントラクトのTransferイベントをデコードし、資産、送信者、受信者、数量を表示できます。ブロックチェーンエクスプローラーも、検証済みコントラクトのABIや既知のイベントシグネチャを使ってログをデコードします。ソースコードやABI情報を利用できない場合、エクスプローラーは未加工のトピックやデータ値を表示することがあります。デコードされたラベルは、コントラクトの意図を独立して保証するものではなく、未加工ログの解釈として扱う必要があります。イベントの説明を信頼する前に、出力元コントラクトのアドレスを確認してください。イベントログとブロックチェーンインデクサー
ブロックチェーンインデクサーはブロックやレシートを読み取り、選択したイベントデータを検索しやすいデータベースに保存します。インデクサーを利用すると、直接のRPCリクエストでは処理しにくい質問に答えやすくなります。例として、あるウォレットのすべてのトークン送金を取得する、プロトコルの活動を時系列で計算する、レンディング市場で開設されたすべてのポジションを追跡することなどが挙げられます。インデクサーは通常、指定したブロックから順番に新しいブロックを処理します。関連するログをデコードしてデータベースの記録を作成し、再編成への対応に必要なブロック情報を保存します。インデクサーは、クラッシュ後にイベントを飛ばしたり重複させたりせずに処理を再開できる必要があります。デコード用スキーマやアプリケーションロジックが変わったときに、過去データを再処理できることも重要です。Ethereumのデータと分析に関するドキュメントでは、ブロックチェーンデータシステムがログ、レシート、トレースなどの実行情報を扱う方法が説明されています。
イベントログとオフチェーン自動化
オフチェーンサービスはイベントログを監視し、ブロックチェーン外の処理を開始できます。入金後に通知を送る、取引後に内部データベースを更新する、ガバナンス投票後に別のワークフローを開始するといった処理が可能です。ログ自体がオフチェーンサービスに処理を強制するわけではありません。サービスは稼働し、イベントを受信して検証したうえで、何を行うか判断する必要があります。オフチェーンの自動化では、重要な処理を行う前にチェーンID、コントラクトアドレス、ブロックの状態、デコード済みの値を検証する必要があります。同じイベントを二度処理しても誤った重複結果が生じない、冪等性も備える必要があります。再試行、再接続、再編成によって同じログが複数回検知される場合があるため、この保護は重要です。スマートコントラクトはイベントログを読み取れますか?
スマートコントラクトは、通常のEVM実行を通じて過去のイベントログを直接検索できません。ログはコントラクトが読み取る状態ではなく、外部アプリケーション向けに設計されています。過去のイベント情報が必要なコントラクトは、別の仕組みを通じてその情報を受け取る必要があります。仕組みの例として、コントラクトストレージ、暗号学的証明、オラクル、クロスチェーンメッセージングプロトコルがあります。コントラクトは、提供された情報を利用する前に、その信頼性を検証する必要があります。この制約により、オフチェーンのRPC応答をオンチェーンで自動的に有効なデータとして扱うことを防げます。イベントログは変更できますか?
確定したログを、それを生成したトランザクションやブロックから切り離して編集することはできません。ログを変更するには、そのレシートを含むブロックチェーンの履歴を置き換えるか無効にする必要があります。強いファイナリティに達する前であれば、チェーンの再編成によってアクティブな履歴からログが削除される場合があります。新しいトランザクションで訂正イベントや取り消しイベントを出力することはできますが、過去の正規ログを消去するわけではありません。アプリケーションは過去のイベントを保持し、元のブロックチェーンデータをひそかに書き換えるのではなく、後続の記録として訂正内容を表す必要があります。イベントログは偽造できますか?
どのスマートコントラクトでも、よく知られた名前やシグネチャを持つイベントを定義し、出力できます。そのため、悪意のあるコントラクトが、正規のトークンコントラクトのものに似たTransferイベントを出力することも可能です。イベントシグネチャだけでは、資産を特定したり、信頼できるコントラクトで実際に残高が変化したことを証明したりできません。アプリケーションは出力元コントラクトのアドレスを確認し、そのコードと状態を理解する必要があります。詐欺トークンが誤解を招く値を出力したり、資産を受け取っていないウォレットに受領したように見せるイベントを作成したりすることもあります。ウォレットやエクスプローラーは、見慣れたイベントシグネチャをすべて同じように信頼できるものとして扱わないようにする必要があります。取引履歴に予期しない送金イベントが表示されても、そのトークンを操作しないでください。イベントログとスマートコントラクトのセキュリティ
監視システムは正確なログに依存するため、イベント設計はスマートコントラクトのセキュリティの一部です。権限、手数料、オラクルアドレス、アップグレード実装、緊急時設定が変更された際、重要な管理操作を明確なイベントとして出力する必要があります。イベントが欠落すると、ユーザーやセキュリティチームが危険な変更を検知しにくくなる場合があります。イベントの値が誤っていると、オフチェーンシステムがコントラクトの状態と異なる結果を表示する可能性があります。関連するチェックと状態変更が成功した後にのみ、コントラクトはイベントを出力する必要があります。開発者は、重要なすべての実行経路で、想定されるログが正確に1回出力されることをテストする必要があります。また、トランザクションがリバートされた場合に、誤解を招くログが最終結果に残らないことも確認する必要があります。イベントは、コントラクトコード内で権限や残高のルールを適用することの代わりにはなりません。イベントログのガスコスト
EVMがログ命令を処理し、トランザクションレシートに情報を追加するため、イベントの出力にはガスが必要です。トピックが増えたり、データフィールドが大きくなったりすると、一般にログのコストも増加します。そのため、大きな値を複数含むイベントは、最小限のイベントよりコストが高くなる場合があります。オフチェーンで利用する情報を保存する場合、ログは同じ情報を永続コントラクトストレージに保存するより低コストであることがよくあります。ただし、不要なログもユーザーのトランザクションコストとブロックチェーン履歴のデータ量を増やします。開発者は、インデックス化、監視、監査、ユーザーインターフェースなどで実際に必要な情報を出力する必要があります。外部システムが必要としない内部計算を、すべて個別のイベントに複製することは避けてください。ガス最適化のために、プロトコル活動の安全な監視に必要な透明性を損なってはいけません。イベント設計のベストプラクティス
イベント名は、発生した操作を明確に示すものにします。開発者や分析者が意味を理解できるよう、パラメーター名は具体的にします。ユーザーが頻繁に検索する値は、indexedパラメーターにすることを検討します。よくindexedにする値には、アカウントアドレス、トークンID、市場ID、提案IDがあります。直接フィルタリングする必要がない場合、金額や詳細な設定値は通常、データフィールドに格納できます。ハッシュによるフィルタリングが特に有用な場合を除き、開発者は動的な値のindexed指定を避ける必要があります。イベントには、トランザクションの順序に関する不安定な前提に頼らずに解釈できるだけの情報を含めます。複数の資産や市場に対応するコントラクトでは、関連する資産IDまたは市場IDを含める必要があります。アップグレードイベントでは、監視に役立つ場合、変更前と変更後の両方の値を識別できるようにします。外部アプリケーションがイベントシグネチャやパラメーターレイアウトに依存している場合、イベント宣言は安定させる必要があります。イベントログを読み取る際のベストプラクティス
アプリケーションは、想定するイベントシグネチャだけでなく、想定するコントラクトアドレスでもフィルタリングする必要があります。コントラクト実装がそのブロックで使用していた正しいABIバージョンを使ってログをデコードします。アップグレード可能なコントラクトは、実装のアップグレード後に利用可能なイベントが変わる場合があります。インデクサーには、ブロックハッシュ、ブロック番号、トランザクションハッシュ、トランザクションインデックス、ログインデックスを保存する必要があります。ログを正規ブロックの順序で処理し、再編成後にロールバックできるようにします。大規模な過去データ検索は、処理可能なブロック範囲に分割します。正真正銘の空の応答と、失敗、切り捨て、レート制限による応答を区別する必要があります。金融上の処理は、その価値とリスクに応じた確認レベルに達するまで待つ必要があります。特に正確性が重要な場合、イベントから算出した値をコントラクトの状態と照合します。Layer 2ネットワークのイベントログ
EVMベースのLayer 2ネットワークでは、Ethereumのログと似た構造のイベントログが一般に使われます。開発者は多くの場合、使い慣れたSolidityイベント、トピック、ABI、JSON-RPC検索を利用できます。ただし、Layer 2システムでは、ブロック時間、確認ルール、シーケンサー、手数料体系、最終決済プロセスが異なる場合があります。Layer 2のシーケンサーによって確認されたログでも、Ethereum上で最も強い決済ステータスに達していないことがあります。ブリッジ関連のイベントは、送金の異なる段階で送信元と送信先の両ネットワークに表示される場合があります。アプリケーションは正しいチェーンを追跡し、別々のネットワークのイベントを共有された1つのログ履歴として扱わないようにする必要があります。同じコントラクトアドレスやイベントシグネチャでも、チェーンによって異なるコントラクトや資産を表すことがあります。クロスチェーン送金におけるイベントログ
クロスチェーンシステムでは、資産がロック、バーン、解放、ミントされたことを示すためにイベントが使われることがよくあります。オフチェーンのリレイヤーや送信先チェーンのプロトコルは、送金処理を続ける前に送信元チェーンのイベントを確認する場合があります。送信先での処理には、ブリッジの証明方式またはバリデーター設計を通じた送信元イベントの検証が必要です。通常のRPCプロバイダーを通じてログを確認しただけでは、トラストレスなスマートコントラクトがイベントの有効性を証明するには不十分です。ブリッジは、送信元チェーンの再編成とファイナリティも考慮する必要があります。処理が早すぎるブリッジは、後に正規の送信元履歴から削除されるイベントを処理する可能性があります。ブリッジイベントは、送金の開始を示しているだけで、最終的な完了を意味するとは限らないことを理解してください。イベントログの例
ユーザーが代替可能トークンを別のウォレットに500単位送金するとします。ユーザーはトークンコントラクトのtransfer関数を呼び出すトランザクションを送信します。コントラクトは送信者の残高を確認し、送信者と受信者の残高を更新します。その後、送信者アドレス、受信者アドレス、送金額を含むTransferイベントを出力します。送信者と受信者はindexedトピックに保存され、金額はABIに従ってデータフィールドにエンコードされる場合があります。イベントシグネチャのハッシュはTopic 0に表示されます。トランザクションがブロックに含まれると、ログはトランザクションレシートに表示されます。ウォレットはログを取得してデコードし、トークンの移動を読みやすい取引履歴として表示します。インデクサーもイベントを記録し、ユーザーがいずれかのアドレスに関係するすべての送金を検索できるようにします。この例は、1つのイベントログがコントラクト実行とウォレット、エクスプローラー、ブロックチェーン分析をどのようにつなぐかを示しています。イベントログに関するよくある誤り
よくある誤りの1つは、別のスマートコントラクトがイベントを読み取れると思い込むことです。また、見慣れたイベントシグネチャを、その出力元コントラクトが正規である証拠として扱うのも誤りです。コントラクトアドレスを確認せずにログをデコードするのも問題です。indexed文字列をトピックのハッシュから直接復元できると思い込むのも誤りです。ログの識別にトランザクションハッシュだけを使うのも不十分です。チェーンの再編成に対応しないこともよくある誤りです。RPCの再試行やアプリケーションの再起動後に、同じログを二度処理することにも注意が必要です。極端に広いブロック範囲を検索し、タイムアウトしたリクエストを空の結果とみなすのも誤りです。将来のスマートコントラクトロジックで同じデータが必要なのに、イベントだけに依存することも避けてください。イベントを正常にデコードできたことを、意図したすべての状態変更が正しく行われた証拠とみなすのも誤りです。FAQ
暗号資産におけるイベントログとは何ですか?
イベントログは、ブロックチェーントランザクションの実行中に起きた操作を示すため、スマートコントラクトが出力する構造化された記録です。Ethereumのイベントログはどこに保存されますか?
Ethereumのイベントログはトランザクションレシートに含まれ、ブロックの実行履歴の一部としてコミットされます。イベントとログの違いは何ですか?
イベントはスマートコントラクトコード内の宣言であり、ログはそのイベントが出力されたときに作成される実際の記録です。スマートコントラクトは過去のイベントログを読み取れますか?
いいえ。スマートコントラクトは通常のEVM実行を通じて過去のログを直接検索したり読み取ったりできません。EthereumのイベントログにおけるTopic 0とは何ですか?
Topic 0には通常、イベント名と正規パラメーター型のKeccak-256ハッシュが含まれます。イベントログにはいくつのトピックを含められますか?
EVMログには最大4つのトピックを含められます。通常のSolidityイベントでは、そのうち1つをイベントシグネチャ用に確保します。Solidityイベントのindexedとは何ですか?
indexedパラメーターはトピックに保存され、外部アプリケーションがその値を基にログをフィルタリングできます。イベントログで文字列をindexedにできますか?
はい。ただし、indexed文字列は元の読みやすい文字列ではなく、Keccak-256ハッシュとして表されます。トランザクションがリバートされるとイベントログはどうなりますか?
リバートされた実行中に生成されたログは、最終的なトランザクション結果から削除されます。イベントログにはガスがかかりますか?
はい。ログの出力には、そのトピック数やデータ量などに応じたガスがかかります。イベントログはトークンの正当性を証明できますか?
いいえ。どのコントラクトでも見慣れたイベントを出力できるため、出力元コントラクトと実際の状態を確認する必要があります。開発者はイベントログを取得するにはどうすればよいですか?
eth_getLogsなどのメソッド、レシート検索、フィルター、サブスクリプション、ブロックチェーンエクスプローラー、インデックスサービスを利用できます。ブロックチェーンの再編成でイベントログが削除されることはありますか?
あります。置き換えられたブロックのログは、正規チェーンの履歴から削除されます。すべてのEVMチェーンでイベントログは同じですか?
基本的な構造は通常似ていますが、チェーンID、コントラクト、ブロック履歴、ファイナリティ、RPCの動作は異なる場合があります。イベントログはコントラクトストレージより低コストですか?
オフチェーンで利用する過去情報にはログの方が低コストであることがよくありますが、将来のスマートコントラクト実行で読み取る必要があるストレージの代わりにはなりません。ウォレットがイベントログを使うのはなぜですか?
ウォレットはイベントログを使い、トークン送金、承認、スワップなど、トランザクションの基本フィールドだけでは分かりにくいスマートコントラクト操作を特定します。まとめ
イベントログは、スマートコントラクトの実行をウォレット、分散型アプリケーション、ブロックチェーンエクスプローラー、分析システムなどのオフチェーンサービスにつなぐ構造化された記録です。EVMのログ命令を通じて作成され、トランザクションが正常に実行されるとトランザクションレシートに保存されます。ログには、出力元コントラクトのアドレス、検索可能なトピック、ABIエンコードされたイベントデータが含まれます。Topic 0は通常、イベントシグネチャを識別し、indexedパラメーターは追加のフィルタリング手段を提供します。非indexedパラメーターはデータフィールドに保存され、デコードには正しいABIが必要です。イベントログはコントラクトストレージとは異なり、スマートコントラクトが過去のログを直接読み取ることはできません。また、ログはオフチェーンでの過去データ処理を目的とするため、関数の返却データとも異なります。アプリケーションは、JSON-RPCフィルター、サブスクリプション、トランザクションレシート、ブロックチェーンエクスプローラー、専用インデクサーを通じてログを取得できます。信頼性の高いシステムでは、重複処理、RPCの制限、チェーンの再編成、コントラクトのアップグレード、確認レベルの違いに対応する必要があります。見慣れたイベント名があっても、出力元コントラクトが信頼できることや、トークンが正規のものであることを証明するわけではありません。開発者は、明確な名前、有用なindexedパラメーター、十分な文脈、安定したスキーマを備えたイベントを設計する必要があります。イベントログを理解すると、暗号資産ユーザーや開発者は、トークン送金、DeFi活動、スマートコントラクトの変更、トランザクションレシート、オンチェーンアプリケーションのデータをより正確に解釈できます。関連コンテンツ
WhatsMiner M30S++
Web3ドメイン
Web3プロジェクト
ホット
現在、市場で大きな注目を集めているトレンドの暗号資産
トップ取引高
取引高が最も多い暗号資産

