English version · 区块链学习导航 · 上一篇
区块链学习 · 延伸文章 BCX008

可读源代码和已部署合约是不同的证据对象。要把两者连接起来,审查者需要正确构建输入、正确输出产物,以及与已识别链上下文中代码的明确比较。熟悉的函数名或成功退出的编译器进程,都不能代替这条联系。
本课通过一份静态、可核对的资料解释调查过程。你将区分创建代码与运行时代码,分类仅标记区域不同和正文区域无法解释的差异,并在不掩盖任意不一致的前提下,应用明确声明的库引用和不可变量替换。
下述字节数组是刻意构造的比较对象,不是真实Solidity编译器输出,不声称能作为合约执行,也没有部署或提交验证服务。它们让偏移、范围和结论可以复核,而不需要真实目标、钱包、凭据或金融操作。
选择适合你的阅读路线
本篇目录
- 1. 识别被验证的对象
- 2. 先重建输入,再解释差异
- 3. 选择运行时输出,而不是部署输入
- 4. 定义完整的合成比较对象
- 5. 资料包A:解释替换,再比较全部内容
- 6. 资料包B:只有标记不同
- 7. 资料包C与D:无法解释的正文变化,以及设置变化
- 8. 资料包E:缺少不可变量值,属于未解决证据
- 9. 结合范围理解Exact Match和Match
- 10. 检查构建结果并保留调查记录
- 11. 本资料的示范判断
- 练习与答案
- 常见问题
- 来源与延伸阅读
第1至3节建立身份与构建记录。第4至8节逐项比较字节案例。第9至11节解释标签,并形成有边界的判断。练习提供数值答案。关于区块浏览器标记能证明什么,可阅读阅读区块浏览器证据。
1. 识别被验证的对象
源码验证说法应识别网络、地址、观察所在区块上下文,以及拿来比较的运行时字节。合约名称不是全球唯一标识符。来自身份不明端点的代码响应,也不能证明链上观察的真实性或最终性。
本题给定一个正确识别的非代理目标T,位于虚构上下文N的区块B。资料提供已获取的比较对象R和拟用构建资料包P。目标身份及观察真实性是练习假设;我们调查的是下一条联系,即资料包与对象之间的对应。
如果目标是代理,还需要另行识别相关实现与执行路径。匹配代理自身代码,本身不等于匹配所有应用实现代码。存储状态升级课程处理这一问题的另一个部分。
用一句话限定主张:“在这些明确转换之下,声明的构建资料是否能解释这个已识别上下文中的运行时对象?”这比“合约是否已验证且安全”更窄,也更容易检验。
2. 先重建输入,再解释差异
真实复现记录需要准确源文件字节、源码单元路径、全部导入依赖、编译器身份及相关设置。还应记录编译中选择的合约、优化器配置、EVM目标、中间表示流水线设置和元数据选项。仓库分支名本身不能固定这些输入。
Solidity 0.8.30编译器接口描述结构化输入输出,包括不同字节码产物和引用区间。优化器runs设置涉及优化时考虑的预期使用次数,不是字面意义上的优化遍数。同一编译器版本采用不同设置,也不是同一个声明构建。
概念资料包P标记源集合S7、源码单元路径contracts/Catalogue.sol、编译器产物C7,并声明启用优化、runs为200、目标为shanghai、viaIR为false。S7和C7是资料标签,不是公开源文件哈希,也不表示这里实际运行了编译器。虚构调查假定完整输入记录已提供。
真实工作中,未解决的导入、缺失源字节或含糊的编译器身份,都会阻止可复现性结论。一份看起来合理的源文件,不能代替缺失的依赖关系。应记录缺少什么,不能随手用当前能编译的包补齐。
3. 选择运行时输出,而不是部署输入
创建代码执行后建立合约,并返回部署后的代码。运行时产物是后续调用所使用的保留代码。Solidity合约文档解释,构造函数代码并不会简单地作为最终可调用代码的一部分保留下来。
因此,直接拿创建产物与获取的运行时字节比较,是选错测试对象。构造参数和部署时效果需要分别处理。不同产物类型不匹配,并不能说明提交的源码恶意或编译器失败。
为了给出直观比较,题目还提供一个合成的“创建形状”对象C:四个前置标记字节,随后是90字节对象R,最后是两个参数标记字节,总长96。这只是虚构封装示意,不模拟真实EVM创建代码结构,也不是让人从真实部署中删掉六字节的规则。
课堂运行时比较应使用R的90字节。选择C的96字节,会在元数据或库分析之前就出现产物选择错误。真实构建记录应靠适当输出字段及来源证明产物类型,不能只凭外观。
4. 定义完整的合成比较对象
所有偏移都从0开始,以字节计数,不是十六进制文本中的字符位置。R包含80字节正文、8字节教学CBOR标记和2字节长度字段,因此总长90字节。
先把正文全部80个位置设为0x10。把位置8至27替换成二十个0x22。把位置32至63替换成整数7的32字节大端表示,即三十一个零字节,最后一个为0x07。把位置70改成0x77。其余正文字节仍为0x10。
位置80至87的标记字节是a1 61 74 44 01 02 03 04。在这个模型中,它们编码一个只有一项的CBOR映射:键为t,值为四字节序列01 02 03 04。该标记不是IPFS哈希,不是Solidity元数据文件,也不是真实源码指纹证据。
最后两个字节位于88和89,值为00 08,声明标记长度为八。其起点计算为90减2再减8,等于80。每个字节都有规定,因此读者可以独立重建和比较数组。
真实Solidity元数据有自己的结构和构建设置。固定版本元数据文档说明尾部长度与CBOR解析,并提醒不要假定固定起始前缀。追加CBOR元数据也可以禁用。本题只演示边界算术,不是任意合约代码的通用解析器。
5. 资料包A:解释替换,再比较全部内容
拟用模板与R具有相同正文和标记,但位置8至27、32至63填为零占位。资料包另外声明,第一个区间是库引用范围,第二个是不可变量引用范围。
给定转换记录只列出两个动作:在库区间放入二十个0x22,在不可变量区间放入7的32字节编码。它把两项值都关联到虚构资料中给定的部署证据。没有其他允许的替换、排除区间或推测值。
完成这两个动作后,全部90字节与R相等。声明区间覆盖20+32=52个互不重叠的字节,外部剩余38字节,包括其余正文、完整标记和长度字段。它们也必须匹配;记录合法转换不代表可以忽略其他内容。
结论是:在两个声明的值填入之后,这个给定合成对象实现完整比较匹配。这不是Sourcify验证已部署合约的报告,也没有建立实际源码与编译器输出的联系,因为资料包及输出都是教学模型。
真实调查中的引用范围应来自相关编译器输出及验证器的文档流程。值和来源必须保持可见。“忽略所有不同字节”会把验证目的颠倒过来。
6. 资料包B:只有标记不同
从资料包A已经填好值的对象开始,把字节87从0x04改为0x05。全部80个正文字节及最后长度字段不变。对象仍长90,标记仍占位置80至87。
完整字节数组不匹配。正文完全匹配,而给定标记值不同。报告应同时保留这两个发现,不能压缩成“全部相同”或“没有任何有用对应”。
真实Solidity构建中,源码路径、注释或空白可能改变元数据,而相关正文比较结果不变。这是调查元数据差异的理由,不是把所有靠近尾部的不匹配都视为无害的许可。实际边界、解析结构和构建记录必须支持分类。
资料包B只是教学标记。因此我们称结果为“正文匹配,标记存在差异”,不称为服务实际给出的Match状态。真实验证器可以根据其文档规则与证据分类真实构建;仅凭本题算术不能授予该标签。
7. 资料包C与D:无法解释的正文变化,以及设置变化
资料包C从填好值且匹配的对象开始,把正文字节70从0x77改为0x78。这个位置在两个替换区间之外,也在标记之外。完整比较失败,删除标记也不能解决。
正确发现是:按照给定比较规则,正文存在尚未解释的差异。不能看到不匹配后,就扩大不可变量范围,把位置70也包进去。也不能在本课不可执行模型中猜测这个字节的准确行为效果。发现差异需要解释,但不需要虚构攻击或无害证明。
资料包D另外声称使用同一个源集合标签S7,却把优化器runs从200改为1000。其给定输出在字节70处为0x79,标记也不同。这是题目明确提供的假设结果,不声称实际编译器改变该设置时总会准确改变这个字节。
D既没有复现P的声明输入,也没有在允许转换下匹配R。应保留“设置变化”作为需要用正确可复现构建检验的解释假说。仅知道设置不同,不能得出每个输出差异的完整原因。
EVM目标变化同样需要自身输入及输出证据。没有规则说每种设置变化必定改变每个合约的正文。复现意味着检验规定输入,而不是凭直觉认为两种配置大概行为相同。
8. 资料包E:缺少不可变量值,属于未解决证据
再次从尚未填值的模板开始。库区间和其中二十个0x22已有文档,但缺少建立不可变量值的证据。捕获对象R在该区间恰好包含7的编码。
审查者可以记录观察到的字节,并识别尚未解决的引用。但如果从目标抄出7填进拟用产物,再宣布部署输入得到独立确认,就是循环论证。观察到一个匹配值,与独立重建这个值,是不同证据主张。
按照本课更严格的重建标准,在提供所需值来源或明确缩窄结论前,资料包E仍不完整。服务可以记录排除或转换不可变量的匹配流程;报告应准确反映其实际范围,不能暗中升级成更强的重建结论。
这不表示合约一定错误,而是说资料包不能支持拟定判断中的全部主张。当缺失证据具体、下一步核查明确时,“尚未解决”就是有用结论。
9. 结合范围理解Exact Match和Match
Sourcify当前文档使用Exact Match和Match,取代过去的perfect和partial术语。它区分元数据指纹相同的匹配,以及允许元数据哈希不同的匹配,并明确考虑库和不可变量差异。
因此,应结合文档转换范围阅读Exact Match标签,不能把它改述成部署前后每个原始字节无条件相同。也不应自动把Match说成任意片段匹配或验证失败。
真实报告应保留验证器版本或所核对文档日期、产物身份、源码设置记录、元数据结果,以及库和不可变量处理方式。本课于2026年10月12日核对当前定义;固定Solidity文档描述0.8.30,不是未指定的最新版本。
任何一种标签本身,都不证明某个人确实编写源码,不证明逻辑安全、库可信,也不证明初始化及当前存储满足预期政策。这些是额外证据任务,不是范围明确的代码对应结果有缺陷。
10. 检查构建结果并保留调查记录
真实复现应检查编译器诊断和所需产物。Solidity Standard JSON接口在输出中报告编译错误,因此进程成功退出不够。运行时对象缺失时,不能为了继续流程,就用方便取得的创建对象顶替。
保留准确输入集合、编译器身份、设置、输出产物、观察目标上下文及每项转换。先记录长度和差异偏移,再判断原因。源码获取或编译失败应如实说明。本课只进行了本地数组检查,不声称实际编译。
实用审查记录至少容纳四种结果:在明确范围下完整对应;有依据的较窄对应,例如仅标记不同;无法解释的差异;证据不足。它们指向不同下一步,不应全部简化成绿色或红色标记。
在代码身份建立之后,若要应用审计发现,可阅读如何阅读区块链审计资料。该课询问评估是否覆盖相关实现和假设;本课检查此类评估常常作为已知条件的对应联系。
11. 本资料的示范判断
“资料包A经过两个明确且有给定证据支持的替换后,解释了完整90字节合成目标。资料包B保留80字节正文,却改变教学标记,所以完整相同不成立。资料包C在偏移70存在无法解释的正文差异。资料包D改变声明编译器设置,并提供不匹配正文,因此没有复现P。”
“资料包E缺少规定的不可变量值证据,不能支持更强的重建主张。96字节的创建形状对象,不是直接运行时比较所需产物。上述课堂结果都不是实际编译、部署、验证服务结果或安全审计。”
这样的判断保留有用发现,也明确限制。它不隐藏不匹配证据,不猜测作者动机,也不把字节对应与应用行为可接受性混为一谈。
练习与答案
- 总长90字节、尾部长两字节、标记长八字节时,标记从哪里开始?偏移80,因为90−2−8=80。
- 两个声明替换区间共多少字节?52,即二十个库引用字节加三十二个不可变量引用字节,互不重叠。
- 区间外还有多少字节?38,仍需比较。
- 改变字节87,是否保留完整相同?没有。它保留给定80字节正文,却改变标记。
- 仅排除标记,能解释偏移70的差异吗?不能。70位于正文,也在声明引用区间之外。
- 96字节创建形状对象与90字节运行时对象直接匹配吗?不匹配;对这个测试而言,产物类型也选错了。
- 编译器进程退出,能证明JSON输出没有错误吗?不能。要检查诊断和所需产物。
- 复现字节能建立当前登记状态正确吗?不能。存储、初始化、权限和行为需要各自证据。
再检查一个边界:如果最后两字节声明标记长度100,而对象总长只有90,计算出的起点就会是负数。应拒绝这种解析,不是删除102字节或猜测标记前缀。边界格式成立,是判断仅元数据差异的前提。
常见问题
相同源文本会有不同比较结果吗?
会。构建输入不止可见文本;设置、编译器身份、依赖、路径和部署替换都需要明确记录。实际输出比较决定发现。
审查者可以直接删除每份运行时产物的尾部吗?
不可以。应先确定是否追加元数据,按文档解析边界,并说明得到的比较范围。任意截断可能掩盖差异。
库和不可变量是忽略差异的理由吗?
不是。它们需要已识别区间与有文档的处理。合法转换有界且可复核;未解释的不同字节仍然未解释。
这是安装或部署教程吗?
不是。这是静态证据阅读和数组比较练习,不需要安装编译器、建立账户、上传、寻找部署目标或提交交易。
来源与延伸阅读
- Solidity 0.8.30元数据:源码与设置指纹背景、CBOR长度解析及可选追加元数据;2026年10月12日核对。
- Solidity 0.8.30编译器接口:结构化输入、诊断、运行时输出和引用范围;2026年10月12日核对。
- Solidity 0.8.30合约文档:创建与运行时区别、部署上下文;2026年10月12日核对。
- Sourcify Exact Match与Match:当前术语及库、不可变量范围;2026年10月12日核对,本练习没有执行服务验证。
经得起核查的源码验证结果,应解释哪个产物在什么输入和转换之下匹配,以及哪些重要问题仍在结果范围之外。
