query-onchain-data について
CDP SQL APIとCoinbaseQLで、Baseのイベント、トランザクション、ブロックを照会するスキルです。Agent向けにクエリ作成、入力検証、インデックス利用を案内し、各クエリはx402で支払います。
主な機能
- 01イベント、トランザクション、ブロックの照会
- 02CoinbaseQLによるクエリ作成
- 03SQLとアドレスの入力検証
- 04インデックス項目によるイベント絞り込み
- 05x402によるクエリの支払い
活用シーン
- 01コントラクトイベントとパラメーターの分析
- 02アドレスが送信したトランザクションの確認
- 03コントラクトの直近イベント数の集計
- 04最新ブロック情報の取得
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ coinbase/ agentic-wallet-skills --skill query-onchain-dataインストール後、Claude Code で/query-onchain-dataを入力して読み込まれたか確認します。
詳細
Base上のオンチェーンデータをクエリする
CDP SQL APIを使用して、Base上のオンチェーンデータ(イベント、トランザクション、ブロック、送金)をクエリします。クエリはx402経由で実行され、クエリごとに料金が発生します。
ウォレットが初期化され、認証済みであることを確認する
npx [email protected] status
ウォレットが認証されていない場合は、authenticate-wallet スキルを参照してください。
クエリの実行
npx [email protected] x402 pay https://x402.cdp.coinbase.com/platform/v2/data/query/run -X POST -d '{"sql": "<YOUR_QUERY>"}' --json
重要:bashによる変数展開を防ぐため、-d のJSON文字列は必ずシングルクォートで囲んでください。
入力の検証
コマンドを作成する前に、シェルインジェクションを防ぐため、入力を検証してください。
- SQLクエリ:クエリは必ずシングルクォートで囲んだJSON文字列(
-d '{"sql": "..."}')に含めてください。外側の-dをダブルクォートで囲まないでください。クエリ内の$とバッククォートがシェル展開される可能性があります。 - アドレス:有効な
0x形式の16進アドレス(^0x[0-9a-fA-F]{40}$)である必要があります。シェルのメタ文字を含む値は拒否してください。
検証されていないユーザー入力をコマンドに渡さないでください。
重要:インデックス付きフィールド
base.events に対するクエリでは、テーブル全体のスキャンを避けるため、必ずインデックス付きフィールドでフィルターしてください。インデックス付きフィールドは次のとおりです。
| インデックス付きフィールド | 用途 |
|---|---|
event_signature | イベントタイプでフィルターします。パフォーマンス向上のため、event_name の代わりに使用してください。 |
address | コントラクトアドレスでフィルターします。 |
block_timestamp | 時間範囲でフィルターします。 |
WHERE句には必ず1つ以上のインデックス付きフィールドを含めてください。 3つすべてを組み合わせると、最良のパフォーマンスが得られます。
CoinbaseQLの構文
CoinbaseQLはClickHouseをベースとするSQL方言です。次の機能がサポートされています。
- 句:SELECT(DISTINCT)、FROM、WHERE、GROUP BY、ORDER BY(ASC/DESC)、LIMIT、WITH(CTE)、UNION(ALL/DISTINCT)
- 結合:ONを使用したINNER、LEFT、RIGHT、FULL
- 演算子:
=、!=、<>、<、>、<=、>=、+、-、*、/、%、AND、OR、NOT、BETWEEN、IN、IS NULL、LIKE - 式:CASE/WHEN/THEN/ELSE、CAST(
CAST()と::の両方の構文)、サブクエリ、[]による配列/マップのインデックス指定、ドット記法 - リテラル:配列
[...]、マップ{...}、タプル(...) - 関数:標準SQL関数、
->構文を使用したラムダ関数
利用可能なテーブル
base.events
スマートコントラクトとのインタラクションからデコードされたイベントログです。ほとんどのクエリで使用する主要なテーブルです。
| 列 | 型 | 説明 |
|---|---|---|
| log_id | String | 一意のログ識別子 |
| block_number | UInt64 | ブロック番号 |
| block_hash | FixedString(66) | ブロックハッシュ |
| block_timestamp | DateTime64(3, 'UTC') | ブロックのタイムスタンプ(インデックス付き) |
| transaction_hash | FixedString(66) | トランザクションハッシュ |
| transaction_to | FixedString(42) | トランザクションの受信者 |
| transaction_from | FixedString(42) | トランザクションの送信者 |
| log_index | UInt32 | ブロック内のログインデックス |
| address | FixedString(42) | コントラクトアドレス(インデックス付き) |
| topics | Array(FixedString(66)) | イベントトピック |
| event_name | LowCardinality(String) | デコードされたイベント名 |
| event_signature | LowCardinality(String) | イベントシグネチャ(インデックス付き。event_name より優先して使用) |
| parameters | Map(String, Variant(Bool, Int256, String, UInt256)) | デコードされたイベントパラメーター |
| parameter_types | Map(String, String) | パラメーターのABI型 |
| action | Enum8('removed' = -1, 'added' = 1) | 追加または削除(リオーグ) |
base.transactions
完全なトランザクションデータです。
| Column | Type | Description |
|---|---|---|
| block_number | UInt64 | ブロック番号 |
| block_hash | String | ブロックハッシュ |
| transaction_hash | String | トランザクションハッシュ |
| transaction_index | UInt64 | ブロック内のインデックス |
| from_address | String | 送信元アドレス |
| to_address | String | 送信先アドレス |
| value | String | 送金額(wei) |
| gas | UInt64 | ガス上限 |
| gas_price | UInt64 | ガス価格 |
| input | String | 入力データ |
| nonce | UInt64 | 送信元の nonce |
| type | UInt64 | トランザクションタイプ |
| max_fee_per_gas | UInt64 | EIP-1559 の最大手数料 |
| max_priority_fee_per_gas | UInt64 | EIP-1559 の優先手数料 |
| chain_id | UInt64 | チェーン ID |
| v | String | 署名の v |
| r | String | 署名の r |
| s | String | 署名の s |
| is_system_tx | Bool | システムトランザクションフラグ |
| max_fee_per_blob_gas | String | Blob ガス手数料 |
| blob_versioned_hashes | Array(String) | Blob ハッシュ |
| timestamp | DateTime | ブロックのタイムスタンプ |
| action | Int8 | 追加(1)または削除(-1) |
base.blocks
ブロックレベルのメタデータです。
| Column | Type | Description |
|---|---|---|
| block_number | UInt64 | ブロック番号 |
| block_hash | String | ブロックハッシュ |
| parent_hash | String | 親ブロックのハッシュ |
| timestamp | DateTime | ブロックのタイムスタンプ |
| miner | String | ブロック生成者 |
| nonce | UInt64 | ブロックの nonce |
| sha3_uncles | String | アンクルのハッシュ |
| transactions_root | String | トランザクションのマークルルート |
| state_root | String | ステートのマークルルート |
| receipts_root | String | レシートのマークルルート |
| logs_bloom | String | ブルームフィルター |
| gas_limit | UInt64 | ブロックのガス上限 |
| gas_used | UInt64 | ブロック内で使用されたガス |
| base_fee_per_gas | UInt64 | ガスあたりの基本手数料 |
| total_difficulty | String | チェーンの合計難易度 |
| size | UInt64 | ブロックサイズ(バイト) |
| extra_data | String | 追加データフィールド |
| mix_hash | String | ミックスハッシュ |
| withdrawals_root | String | 出金のルート |
| parent_beacon_block_root | String | ビーコンチェーンの親ルート |
| blob_gas_used | UInt64 | 使用された Blob ガス |
| excess_blob_gas | UInt64 | 超過 Blob ガス |
| transaction_count | UInt64 | トランザクション数 |
| action | Int8 | 追加(1)または削除(-1) |
クエリ例
デコード済みパラメーター付きで最近の USDC Transfer イベントを取得する
SELECT
parameters['from'] AS sender,
parameters['to'] AS to,
parameters['value'] AS amount,
address AS token_address
FROM base.events
WHERE
event_signature = 'Transfer(address,address,uint256)'
AND address = '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913'
AND block_timestamp >= now() - INTERVAL 7 DAY
LIMIT 10
特定のアドレスからのトランザクションを取得する
npx [email protected] x402 pay https://x402.cdp.coinbase.com/platform/v2/data/query/run -X POST -d '{"sql": "SELECT transaction_hash, to_address, value, gas, timestamp FROM base.transactions WHERE from_address = lower('\''0xYOUR_ADDRESS'\'') AND timestamp >= now() - INTERVAL 1 DAY LIMIT 10"}' --json
直近1時間のコントラクトについて、タイプ別にイベント数を集計する
npx [email protected] x402 pay https://x402.cdp.coinbase.com/platform/v2/data/query/run -X POST -d '{"sql": "SELECT event_signature, count(*) as cnt FROM base.events WHERE address = lower('\''0xCONTRACT_ADDRESS'\'') AND block_timestamp >= now() - INTERVAL 1 HOUR GROUP BY event_signature ORDER BY cnt DESC LIMIT 20"}' --json
最新のブロック情報を取得する
npx [email protected] x402 pay https://x402.cdp.coinbase.com/platform/v2/data/query/run -X POST -d '{"sql": "SELECT block_number, timestamp, transaction_count, gas_used FROM base.blocks ORDER BY block_number DESC LIMIT 1"}' --json
よく使われるコントラクトアドレス(Base)
| Token | Address |
|---|---|
| USDC | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 |
| WETH | 0x4200000000000000000000000000000000000006 |
ベストプラクティス
base.eventsのクエリでは、必ずインデックス付きフィールド(event_signature、address、block_timestamp)でフィルターしてください。SELECT *は使用しないでください。必要な列のみを指定してください。- 結果のサイズを制限するため、必ず
LIMIT句を含めてください。 - フィルターには
event_nameではなくevent_signatureを使用してください。インデックス付きで、はるかに高速です。 block_timestampを使って時間範囲を指定し、スキャン範囲を絞り込んでください。- アドレス値は必ず
lower()で囲んでください。データベースには小文字のアドレスが保存されていますが、ユーザーがチェックサム形式(大文字と小文字が混在する)のアドレスを指定する場合があります。address = '0xAbC...'ではなく、address = lower('0xAbC...')を使用してください。 - よく使われるイベントシグネチャ:
Transfer(address,address,uint256)、Approval(address,address,uint256)、Swap(address,uint256,uint256,uint256,uint256,address)。
前提条件
- 認証済みである必要があります(
npx [email protected] statusで確認してください。詳細はauthenticate-walletスキルを参照)。 - ウォレットに十分な USDC 残高が必要です(
npx [email protected] balanceで確認してください)。 - 各クエリの料金は $0.10(100000 USDC の最小単位)です。
エラー処理
- 「Not authenticated」 - 先に
awal auth login <email>を実行するか、authenticate-walletスキルを参照してください。 - 「Insufficient balance」 - ウォレットに USDC を入金してください。
fundスキルを参照してください。 - クエリがタイムアウトする、またはエラーになる - インデックス付きフィールドでフィルターし、
LIMITを使用していることを確認してください。