一键导入
debug-diff
Debug a failed diffyscan verification run. Analyzes diffs, identifies root causes. Use when diffyscan exits with non-zero or shows unexpected diffs.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Debug a failed diffyscan verification run. Analyzes diffs, identifies root causes. Use when diffyscan exits with non-zero or shows unexpected diffs.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
| name | debug-diff |
| description | Debug a failed diffyscan verification run. Analyzes diffs, identifies root causes. Use when diffyscan exits with non-zero or shows unexpected diffs. |
| argument-hint | ["config-path-or-contract-address"] |
Help debug a failed diffyscan verification. The user may provide a config path, contract address, or describe the failure.
Each run creates a timestamped directory under digest/. The timestamp is int(time.time()) captured at process start (see diffyscan/utils/constants.py):
digest/{timestamp}/logs.txt -- full run log (written by Logger in diffyscan/utils/logger.py)digest/{timestamp}/diffs/{contract_address}/{filename}.html -- per-file HTML source diff reportsFind the most recent run:
ls -lt digest/ | grep "^d" | head -5
Then inspect its contents:
# View the log
cat digest/<timestamp>/logs.txt
# List HTML diff reports for a specific contract
ls digest/<timestamp>/diffs/<contract_address>/
Source code diffs -- files differ between GitHub and the blockchain explorer:
commit in github_repo matches what was actually deployedrelative_root is correct (sources may live in a subdirectory of the repo)dependencies have the right commit hashes and relative_root paths--support-brownie for brownie-verified contracts)digest/{timestamp}/diffs/{address}/*.html) to see exactly which lines differ#, Filename, Found, Diffs, Origin, ReportBytecode diffs -- compiled bytecode does not match on-chain:
constructor_calldata or constructor_args under the bytecode_comparison config keybytecode_comparison.librariesdeep_match_bytecode() in diffyscan/utils/binary_verifier.py compares instruction-by-instruction and tolerates differences that fall within known immutable reference regions. If all diffs are in immutable positions it logs a warning and reports a non-match. To accept it, add a granular allowed_diffs.bytecode rule with the exact on-chain immutables values (diffyscan prints a ready-to-paste suggestion in the final summary) rather than a blanket wildcard. Differences outside immutable regions raise BinVerifierError, which process_config catches and records as a non-match (match=False) — it does not abort the runCompilation errors (raised as CompileError):
relative_root. The error message is: "missing GitHub sources for bytecode compilation; count=N; first=path1, path2..." (from run_bytecode_diff() in diffyscan/diffyscan.py)~/.cache/diffyscan/solc/ or equivalent via XDG_CACHE_HOME)Constructor calldata errors (raised as CalldataError from diffyscan/utils/calldata.py):
"No constructor calldata found for 0x... (not in config and not in explorer metadata)" -- need to add constructor_calldata or constructor_args to the config"Contract 0x... found in both 'constructor_args' and 'constructor_calldata'" -- only one should be specified per contractNetwork/API errors:
--cache-explorer to reuse cached responses (cached in .diffyscan_cache/)REMOTE_RPC_URL env var is valid and the node supports eth_callexplorer_token_env_var names the env var holding the API token; if absent, falls back to ETHERSCAN_EXPLORER_TOKEN| Symptom | Likely fix |
|---|---|
"missing GitHub sources for bytecode compilation" | Add the missing dependency to dependencies in the config with correct url, commit, and relative_root |
| Source diffs in OpenZeppelin or other dependency imports | Check the dependency commit hash matches what was used at deploy time |
| Bytecode mismatch after constructor | Add constructor_calldata (raw hex) or constructor_args (ABI-typed values) for the contract under bytecode_comparison |
"Failed to infer source path for library '...' from explorer metadata" | Add library addresses to bytecode_comparison.libraries keyed by "path/to/File.sol": {"LibName": "0xAddr"} |
| All files show diffs | Wrong commit or relative_root in github_repo |
| Single contract fails | May need a per-contract constructor_calldata or constructor_args entry |
"Failed in binary comparison: Bytecodes have differences not on the immutable reference position" | Real bytecode mismatch -- check compiler version, optimizer settings, EVM version, and library addresses |
"Exiting with non-zero code due to unallowed diffs" | Either fix the diffs or add a granular allowed_diffs rule to the config for known-acceptable diffs (copy the suggestion diffyscan prints in the final summary; prefer immutables/byte_ranges/line_ranges/files/cbor_metadata over any: true) |
"Contract name in config does not match with blockchain explorer ... !=" | Contract not verified on explorer — comment it out or verify it on the explorer first |
"Failed to get calldata: Explorer metadata has empty constructor calldata for 0x..." | Factory-created contract — Etherscan has no constructor args. Add constructor_calldata manually (extract via getsourcecode API ConstructorArguments, debug_traceTransaction trace, or cross-chain reuse) |
"HTTP error: 404 ... contents/<path>.sol" | Missing or wrong dependencies entry — the explorer source uses a path prefix not covered by config dependencies. Add a mapping for that prefix |
"err: intrinsic gas too low" | Chain gas model needs a higher deployment gas cap (known on Mantle) — set deployment_gas_limit in the config (e.g. 30000000000) |
| All proxy bytecode diffs say "immutable reference position" | Normal for TransparentUpgradeableProxy — ProxyAdmin address baked in as immutable. Add an allowed_diffs.bytecode rule with the exact immutables values (from the printed suggestion) to accept it |
After fixing, suggest:
uv run diffyscan <config-path> --yes --cache-explorer --cache-github
--yes (-Y) skips the interactive prompt before each contract--cache-explorer (-E) reuses cached explorer responses from .diffyscan_cache/--cache-github (-G) reuses cached GitHub file fetches--support-brownie enables recursive retrieval for brownie-verified contracts with flattened import pathsTo accept known diffs, use config allowed_diffs rules. (The former --allow-source-diff / --allow-bytecode-diff CLI flags have been removed; they were blanket any: true shorthands.) When a diff is uncovered, diffyscan prints a ready-to-paste allowed_diffs snippet in the final summary — paste it into the config and replace the placeholder reason, tightening any: true to a granular facet (immutables, byte_ranges, cbor_metadata, line_ranges, files) wherever possible. See the "Granular allowlists" section of the README.
If any of these apply, explicitly tell the user — these are inherent constraints of the tool, not bugs to debug.
When a contract was verified on the explorer as a single flattened file (the explorer's SourceCode is a plain string, not JSON wrapped in {{}}), diffyscan cannot reliably reproduce the bytecode. Two problems arise:
ContractName field is used as the solc source file key (e.g. {"sources": {"MyContract": {...}}}). If the explorer does not return ContractName, or the name does not match the actual contract declaration in the Solidity source, the compiled output cannot be remapped and get_target_compiled_contract() will fail.How to detect: check the explorer response or logs — if the solc input has a source key that looks like a contract name (no .sol extension, no path separators) rather than a file path, the contract was flat-verified.
What to tell the user: explain that bytecode comparison is unreliable for this contract due to the flat-source limitation. Recommend accepting the mismatch with an allowed_diffs.bytecode rule (use any: true here only because the bytecode genuinely cannot be reproduced — and say so in the reason), and note that source comparison is still valid.
Create a new diffyscan verification config file for a deployed smart contract. Use when the user wants to verify a new contract or deployment.
Validate a diffyscan config file for correctness before running verification. Checks schema, required fields, type correctness, and common mistakes.
Add support for a new blockchain explorer API to diffyscan. Use when a new chain or explorer type needs to be supported.
基于 SOC 职业分类