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.
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
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
$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. 下の青いボタンを押して
pitfalls-blockchain.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
pitfalls-blockchainフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
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