jpskill.com
🛠️ 開発・MCP コミュニティ

pitfalls-blockchain

Blockchain RPC error handling, gas estimation, multi-chain config, and transaction management. Use when interacting with smart contracts, estimating gas, or managing transactions. Triggers on: RPC, contract call, gas, multicall, nonce, transaction, revert.

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o pitfalls-blockchain.zip https://jpskill.com/download/17444.zip && unzip -o pitfalls-blockchain.zip && rm pitfalls-blockchain.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/17444.zip -OutFile "$d\pitfalls-blockchain.zip"; Expand-Archive "$d\pitfalls-blockchain.zip" -DestinationPath $d -Force; ri "$d\pitfalls-blockchain.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して pitfalls-blockchain.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → pitfalls-blockchain フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

Blockchain の落とし穴

Blockchain のインタラクションにおける一般的な落とし穴と正しいパターンについて説明します。

どのような時に使うか

  • RPC 経由でのコントラクト呼び出し
  • トランザクションのガス見積もり
  • リバートとエラーの処理
  • 並行トランザクションの nonce 管理
  • マルチチェーンサポートの設定
  • Blockchain コードのレビュー

ワークフロー

ステップ 1: エラー処理の検証

すべてのコントラクト呼び出しが try/catch でラップされていることを確認します。

ステップ 2: ガス見積もりの確認

送信前に、ガスが見積もりバッファ付きで計算されていることを確認します。

ステップ 3: Multicall の安全性検証

multicall が allowFailure: true を使用していることを確認します。


RPC エラー処理

// ✅ すべてのコントラクト呼び出しをラップする
async function getQuote(tokenIn: Address, tokenOut: Address) {
  try {
    const quote = await quoter.quoteExactInput(...);
    return quote;
  } catch (error) {
    // 流動性の低いトークンは失敗する可能性があります - これは想定内です
    console.warn(`Quote failed for ${tokenIn}->${tokenOut}:`, error.message);
    return null; // 他のトークンの処理を続行する
  }
}

// ✅ コントラクトを呼び出す前に検証する
if (!isAddress(tokenAddress)) {
  throw new Error('Invalid token address');
}

// ✅ "execution reverted" を適切に処理する
if (error.message.includes('execution reverted')) {
  // プールが存在しないか、流動性が不十分
  return null;
}

// ✅ 個別のエラー処理を行う Multicall
const results = await multicall({
  contracts: tokens.map(t => ({ ... })),
  allowFailure: true, // 非常に重要
});
results.forEach((result, i) => {
  if (result.status === 'success') {
    // result.result を使用する
  } else {
    // ログを記録してこのトークンをスキップする
  }
});

ガス見積もり

// ✅ 送信する前に必ずガスを見積もる
const gasEstimate = await contract.estimateGas.swap(...args);

// ✅ ガス見積もりに 10〜20% のバッファを追加する
const gasLimit = gasEstimate.mul(120).div(100);  // 20% バッファ

// ✅ EIP-1559 ガス価格設定
const feeData = await provider.getFeeData();
const tx = {
  maxFeePerGas: feeData.maxFeePerGas,
  maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
  gasLimit,
};

// ✅ 実行前にシミュレーションする
try {
  await contract.callStatic.swap(...args);  // ドライラン
  const tx = await contract.swap(...args);  // 実際の実行
} catch (e) {
  // リバートされる - 送信しない
}

// ✅ ガス価格の急騰を処理する
if (feeData.maxFeePerGas > MAX_ACCEPTABLE_GAS) {
  throw new Error('Gas too high, waiting...');
}

マルチチェーン構成

// ✅ チェーン固有の構成
const CHAIN_CONFIG: Record<ChainId, ChainConfig> = {
  ethereum: {
    chainId: 1,
    rpcUrl: process.env.ETHEREUM_RPC_URL,
    blockTime: 12,
    confirmations: 2,
    nativeToken: 'ETH',
  },
  polygon: {
    chainId: 137,
    rpcUrl: process.env.POLYGON_RPC_URL,
    blockTime: 2,
    confirmations: 5,  // より高速なチェーンではより多くの確認
    nativeToken: 'MATIC',
  },
};

トランザクション管理

// ✅ 確認を待つ
const receipt = await tx.wait(2);  // 2 確認

// ✅ Nonce 管理
class NonceManager {
  private pending = new Map<Address, number>();

  async getNextNonce(address: Address, provider: Provider): Promise<number> {
    const onChain = await provider.getTransactionCount(address, 'pending');
    const local = this.pending.get(address) ?? onChain;
    const next = Math.max(onChain, local);
    this.pending.set(address, next + 1);
    return next;
  }
}

レート制限と再試行

// ✅ 指数バックオフ
async function fetchWithRetry<T>(fn: () => Promise<T>, maxRetries = 3): Promise<T> {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await fn();
    } catch (error) {
      if (error.status === 429) {  // レート制限
        const delay = Math.pow(2, attempt) * 1000;
        await sleep(delay);
        continue;
      }
      throw error;
    }
  }
  throw new Error('Max retries exceeded');
}

// ✅ フォールバック RPC エンドポイント
const RPC_ENDPOINTS = [
  'https://eth-mainnet.alchemyapi.io/v2/KEY',
  'https://mainnet.infura.io/v3/KEY',
  'https://rpc.ankr.com/eth',
];

簡単なチェックリスト

  • [ ] すべてのコントラクト呼び出しが try/catch でラップされている
  • [ ] Multicall が allowFailure: true を使用している
  • [ ] 20% のバッファ付きのガス見積もり
  • [ ] EIP-1559 ガス価格設定が使用されている
  • [ ] 送信前のトランザクションシミュレーション
  • [ ] 並行トランザクションの nonce 管理
  • [ ] チェーンごとに適切な確認数
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

Blockchain Pitfalls

Common pitfalls and correct patterns for blockchain interactions.

When to Use

  • Making contract calls via RPC
  • Estimating gas for transactions
  • Handling reverts and errors
  • Managing nonces for concurrent txs
  • Configuring multi-chain support
  • Reviewing blockchain code

Workflow

Step 1: Verify Error Handling

Check all contract calls are wrapped in try/catch.

Step 2: Check Gas Estimation

Ensure gas is estimated with buffer before sending.

Step 3: Verify Multicall Safety

Confirm multicall uses allowFailure: true.


RPC Error Handling

// ✅ Wrap ALL contract calls
async function getQuote(tokenIn: Address, tokenOut: Address) {
  try {
    const quote = await quoter.quoteExactInput(...);
    return quote;
  } catch (error) {
    // Low-liquidity tokens WILL fail - this is expected
    console.warn(`Quote failed for ${tokenIn}->${tokenOut}:`, error.message);
    return null; // Continue processing other tokens
  }
}

// ✅ Validate before calling contracts
if (!isAddress(tokenAddress)) {
  throw new Error('Invalid token address');
}

// ✅ Handle "execution reverted" gracefully
if (error.message.includes('execution reverted')) {
  // Pool doesn't exist or insufficient liquidity
  return null;
}

// ✅ Multicall with individual error handling
const results = await multicall({
  contracts: tokens.map(t => ({ ... })),
  allowFailure: true, // CRITICAL
});
results.forEach((result, i) => {
  if (result.status === 'success') {
    // Use result.result
  } else {
    // Log and skip this token
  }
});

Gas Estimation

// ✅ Always estimate gas before sending
const gasEstimate = await contract.estimateGas.swap(...args);

// ✅ Add 10-20% buffer to gas estimates
const gasLimit = gasEstimate.mul(120).div(100);  // 20% buffer

// ✅ EIP-1559 gas pricing
const feeData = await provider.getFeeData();
const tx = {
  maxFeePerGas: feeData.maxFeePerGas,
  maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
  gasLimit,
};

// ✅ Simulate before execution
try {
  await contract.callStatic.swap(...args);  // Dry run
  const tx = await contract.swap(...args);  // Real execution
} catch (e) {
  // Would revert - don't send
}

// ✅ Handle gas price spikes
if (feeData.maxFeePerGas > MAX_ACCEPTABLE_GAS) {
  throw new Error('Gas too high, waiting...');
}

Multi-Chain Configuration

// ✅ Chain-specific configuration
const CHAIN_CONFIG: Record<ChainId, ChainConfig> = {
  ethereum: {
    chainId: 1,
    rpcUrl: process.env.ETHEREUM_RPC_URL,
    blockTime: 12,
    confirmations: 2,
    nativeToken: 'ETH',
  },
  polygon: {
    chainId: 137,
    rpcUrl: process.env.POLYGON_RPC_URL,
    blockTime: 2,
    confirmations: 5,  // More confirmations for faster chains
    nativeToken: 'MATIC',
  },
};

Transaction Management

// ✅ Wait for confirmations
const receipt = await tx.wait(2);  // 2 confirmations

// ✅ Nonce management
class NonceManager {
  private pending = new Map<Address, number>();

  async getNextNonce(address: Address, provider: Provider): Promise<number> {
    const onChain = await provider.getTransactionCount(address, 'pending');
    const local = this.pending.get(address) ?? onChain;
    const next = Math.max(onChain, local);
    this.pending.set(address, next + 1);
    return next;
  }
}

Rate Limiting & Retry

// ✅ Exponential backoff
async function fetchWithRetry<T>(fn: () => Promise<T>, maxRetries = 3): Promise<T> {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await fn();
    } catch (error) {
      if (error.status === 429) {  // Rate limited
        const delay = Math.pow(2, attempt) * 1000;
        await sleep(delay);
        continue;
      }
      throw error;
    }
  }
  throw new Error('Max retries exceeded');
}

// ✅ Fallback RPC endpoints
const RPC_ENDPOINTS = [
  'https://eth-mainnet.alchemyapi.io/v2/KEY',
  'https://mainnet.infura.io/v3/KEY',
  'https://rpc.ankr.com/eth',
];

Quick Checklist

  • [ ] All contract calls wrapped in try/catch
  • [ ] Multicall uses allowFailure: true
  • [ ] Gas estimation with 20% buffer
  • [ ] EIP-1559 gas pricing used
  • [ ] Transaction simulation before send
  • [ ] Nonce management for concurrent txs
  • [ ] Confirmations appropriate per chain