# Sourcify 字节码有差异：核对metadata、源码路径与转换记录

整理：链小知（AI 辅助）
资料核对日期：2026-10-12
引用地址：https://lianxiaozhi.com/tools/guides/sourcify-metadata-source-bytecode-difference
难度：进阶
核验方式：官方文档整理，未执行真实账户操作

用本人已有Solidity artifact和验证响应区分编译配置、源码指纹及部署转换，避免把任意字节差异解释成恶意替换。

## 使用工具
- [Sourcify V2](https://lianxiaozhi.com/tools/sourcify) · [官方入口](https://sourcify.dev/)

## 前置条件
- 准备原版本的metadata或编译artifact、sources正文、Sourcify V2响应及采集时间；仅本地查看已有文件。
- 不执行编译、拉链上字节码、修改源码或上传验证；未取得哈希计算证据时保留未核。

## 1. 锁定编译语言与完整合约身份

从已存compilation取language、compiler、compilerVersion、compilerSettings、fullyQualifiedName，完整路径:ContractName与本地artifact配对。相同合约名在不同文件不是相同编译目标。

Solidity metadata机制不自动适用于Vyper；当前lookup schema还列Fe，但不能用Solidity metadata不存在判断其未验证。编译器commit/版本、optimizer等配置未知时标缺口，不拿pragma约束当实际编译版本。

核对结果：已确定语言、目标路径/名称与真实编译版本或明确缺证。
依据：[Sourcify APIv2 2.1.0 lookup方法规范](https://sourcify.dev/server/api-docs/swagger.json)
依据：[Sourcify Solidity metadata 与本地artifact位置](https://docs.sourcify.dev/docs/metadata/)
依据：[Sourcify Exact Match 与 Match](https://docs.sourcify.dev/docs/exact-match-vs-match/)

## 2. 在已有artifact找到正确metadata字段

Foundry官方路径out/CONTRACT_NAME的JSON可含rawMetadata和metadata；Hardhat artifacts/build-info中取output.contracts.<contract-path>.<contract-name>.metadata。先找同一编译目标，不混用另一轮构建文件。

metadata通常含compiler/settings、ABI/NatSpec及sources哈希。字符串形式与对象形式按原artifact解析，只查看已有内容；缺metadata或损坏JSON留为读取问题，不新跑compiler/verify补造结果。

核对结果：metadata绑定同一目标和构建，字符串/对象与缺失情况有记录。
依据：[Sourcify Solidity metadata 与本地artifact位置](https://docs.sourcify.dev/docs/metadata/)
依据：[Sourcify APIv2 2.1.0 lookup方法规范](https://sourcify.dev/server/api-docs/swagger.json)

## 3. 逐文件对应源码内容与指纹

对照metadata.sources的原文件路径、keccak256及urls与已存sources[path].content。文件路径/哈希不是源码正文，urls也不是已经取到文件的证据；没有正文或已有哈希比对记录时标未核。

官方说明单字节改动会改变源码哈希和metadata指纹，注释/变量名/路径也可让exact失配。不要先格式化、扁平化或重命名再声称仍是原文件；match的功能字节码匹配仍不能证明注释或文档原样一致。

核对结果：每个文件有原路径、正文是否取得与哈希比对是否完成，未以名字相同证明相同内容。
依据：[Sourcify Exact Match 与 Match](https://docs.sourcify.dev/docs/exact-match-vs-match/)
依据：[Sourcify APIv2 2.1.0 lookup方法规范](https://sourcify.dev/server/api-docs/swagger.json)
依据：[Sourcify Solidity metadata 与本地artifact位置](https://docs.sourcify.dev/docs/metadata/)

## 4. 分别查看creation与runtime差异层

分别记录creationBytecode/runtimeBytecode的onchainBytecode、recompiledBytecode与已保存匹配状态。runtime是部署后的运行码，creation的constructorArguments附加与runtime immutable替换不能按一个整串直接解释。

查看已有transformations的type/offset/reason/id以及transformationValues。creation可有constructorArguments insert；runtime replace可为library、immutable、cborAuxdata、callProtection。没有转换细节时不能自行删除任意尾部或差异区来凑一致。

核对结果：差异对应具体字节码类型和官方转换理由或待核，未任意截断。
依据：[Sourcify APIv2 2.1.0 lookup方法规范](https://sourcify.dev/server/api-docs/swagger.json)
依据：[Sourcify Exact Match 与 Match](https://docs.sourcify.dev/docs/exact-match-vs-match/)

## 5. 按reason寻找对应值而非套统一键

转换reason中的library/immutable为单数，但values字典是libraries/immutables复数；通过已有id关联条目。callProtection及constructorArguments没有id，不能因缺id就宣称响应错误。

runtime的immutableReferences与linkReferences帮助定位具体区域，cborAuxdata有自身value/offset，transformationValues.cborAuxdata是另一结构。offset保留整数位置，不猜成源码行号；schema不足以让本篇重放转换或证明全部字节已相等。

核对结果：转换条目、相应值及未知映射逐项配对，不同对象外壳未混用。
依据：[Sourcify APIv2 2.1.0 lookup方法规范](https://sourcify.dev/server/api-docs/swagger.json)
依据：[Sourcify 2025 APIv2 lookup历史解释](https://docs.sourcify.dev/blog/apiv2-lookup-endpoints/)

## 6. 将结果写成配置、指纹和转换边界

把差异归到已证实的编译配置/metadata指纹、已有library/immutable等转换或仍缺证；原exact/match/null各自保留，不从一个文件哈希反推出完整部署验证成功。

ABI和NatSpec用于解释接口，不是安全结论；已保存验证也不证明当前代理implementation或权限。材料不含密钥，且未进行验证提交、编译或链上查询，当前状态缺口单独列出。

核对结果：交付原构建—文件—metadata—字节码转换表，匹配与安全/当前部署边界清楚。
依据：[Sourcify Exact Match 与 Match](https://docs.sourcify.dev/docs/exact-match-vs-match/)
依据：[Sourcify Solidity metadata 与本地artifact位置](https://docs.sourcify.dev/docs/metadata/)
依据：[Sourcify APIv2 2.1.0 lookup方法规范](https://sourcify.dev/server/api-docs/swagger.json)

## 常见错误
- 将pragma当实际compilerVersion，或将metadata.sources哈希当已取得文件正文。
- 比较creation/runtime时随意剥离后缀、跳过未知差异会制造匹配错觉。
- library/immutable转换存在不证明真实配置或依赖安全。

## 完成检查
- 形成各编译目标的配置、原文件、指纹、两类字节码与转换证据表。
- 未做哈希/转换重放或编译的部分明确未核，不宣称已重新验证。

## 相关知识
- [合约代码已验证，为什么仍不能直接判断安全？](https://lianxiaozhi.com/learn/verified-contract-boundaries)
- [把数据上链，与只保存数据哈希有什么区别？](https://lianxiaozhi.com/learn/data-onchain-vs-offchain)
- [原始、解码和整理后的链上数据有什么区别？](https://lianxiaozhi.com/learn/raw-decoded-curated-data)

## 官方依据
- [Sourcify APIv2 2.1.0 lookup方法规范](https://sourcify.dev/server/api-docs/swagger.json)
- [Sourcify Solidity metadata 与本地artifact位置](https://docs.sourcify.dev/docs/metadata/)
- [Sourcify Exact Match 与 Match](https://docs.sourcify.dev/docs/exact-match-vs-match/)
- [Sourcify 2025 APIv2 lookup历史解释](https://docs.sourcify.dev/blog/apiv2-lookup-endpoints/)
