VIEW THIS AS

Auto mode follows the Route Engine until you choose a viewpoint.

YOU ARE HERE

ROUTE CHECK

CONNECTED TO

WHAT NEXT

Use the canonical route for this room, or HELP if you are unsure.

解码以太坊事件日志:主题、动态数据与模式歧义

Three students in school uniforms work through open books at a classroom table, with textbooks and stationery nearby and study notes on the whiteboard behind them.

English version · 区块链学习导航 · 上一篇

区块链学习 · 延伸文章 BCX013

三名学生在教室桌旁一起阅读书本,身边放有课本和文具。
学习场景配图;不代表照片中的学生正在学习区块链。

解码后的事件标签,是依据某种模式解释字节的结果。要检查它,需要知道哪些参数被索引、未索引元组从哪里开始、动态偏移以哪里为起点,以及长度究竟统计什么字节。单靠签名主题不能回答全部问题。

本课重建一个完整的合成以太坊ABI格式日志。主题哈希和数据字节在本地生成并独立核对。没有编译或部署合约,没有在网络发出事件,也不声称存在真实回执或交易。发出者及区块上下文都是虚构标签。

实际成果是一份范围清晰的解码记录:给定模式下的准确值、对已知索引字符串候选的检查,以及证据变化时拒绝或暂缓解释的明确理由。

选择适合你的阅读路线

本篇目录

第1至3节建立模式和主题包。第4至6节解码数据字与字符串。第7至10节测试替代模式、截断、偏移和含空隙表示。第11至12节形成判断并限定范围。核心练习所需全部十六进制数据字都已列出。

返回目录 · 下一节

1. 固定预期模式与上下文

虚构请求针对上下文B中的发出者E。另有可信资料给出非匿名模式A:Record(uint256 indexed objectId,uint256 revision,string indexed category,string note)。被索引参数为objectId和category,revision与note未索引。

这是独立的模式前提。日志字节不能认证某个已部署发出者使用了这个声明。稍后我们会移除或替换此前提,检查同一个数据包还能建立什么。

规范事件签名是Record(uint256,uint256,string,string)。参数名称及indexed标记不进入该签名,因此由它产生的主题,承诺的模式细节少于读者可能以为的范围。

Solidity 0.8.30 ABI规范定义事件主题与数据的区别。本课使用固定版本格式规则分析这个准确示例,不声称每个事件或解码器都具有相同形状。

返回目录 · 下一节

2. 准确检查三个主题

主题零是对规范签名准确文本字节计算的Keccak-256摘要:

189e8e18e0a27ae847e3f4ddea0407629c5e42dce5c48b20e39b7dee82374ade

主题一是三十二字节无符号整数编码,末尾为十六进制2a:

000000000000000000000000000000000000000000000000000000000000002a

主题二是索引category字符串对应的哈希:

32253903930ef106de3e96ed95ef4e12e41ce0b59bc8b0967f700bd3e9f59213

三个主题都长三十二字节。在模式A下,主题一解码为objectId 42。补齐的数据字是数值编码,而主题二是摘要;不能因为长度相同,就用同一种捷径解释。

本例非匿名,因此有签名主题。不能不检查模式,就把此前提带到匿名事件。单独的Record名称也不够,有序规范类型列表同样属于被哈希签名。

返回目录 · 下一节

3. 检查已知类别,不假装恢复原文

资料提出类别候选展品,其UTF-8字节为e5b195e59381,共六字节。对直接字符串字节计算以太坊Keccak-256,得到给定主题二,因此已知候选匹配。

这里进行的是候选检查,不是从摘要解码任意原始字符串。如果没有候选或其他证据,主题仍是哈希承诺,不是可读文本。候选匹配也不单独证明谁选择标签,或它是否准确描述真实物品。

独立候选展览的摘要不同,应报告“此候选不匹配”。不能声称已经穷尽排除所有其他字符串,也不能声称验证者通过反演恢复了原文。

这里的索引字符串编码,不是普通ABI元组中的字符串编码。对包含偏移、长度和填充的普通字符串编码做哈希,在给定检查中得到不同结果。也不能把Keccak-256暗中换成标准SHA3-256。

这一区别限于指定的顶层索引字符串。数组、结构体和其他索引类型有自己的规则,本课不会从一个例子推导它们的全部编码。

返回目录 · 下一节

4. 把未索引数据分成四个字

模式A下,data编码未索引元组(uint256 revision,string note),前面没有四字节函数选择器。总长128字节,这里分成四个三十二字节数据字。

字零位于字节0至31:

0000000000000000000000000000000000000000000000000000000000000007

字一位于字节32至63:

0000000000000000000000000000000000000000000000000000000000000040

字二位于字节64至95:

0000000000000000000000000000000000000000000000000000000000000006

字三位于字节96至127:

e58c97e9a6860000000000000000000000000000000000000000000000000000

按这个顺序连接四个字,就是完整data字段。字边界只为解释,实际字节序列不含空格、行号或分隔符。十六进制文本每两个字符表示一字节,因此不能把字符位置当成字节偏移。

返回目录 · 下一节

5. 从正确起点跟随动态偏移

字零直接解码revision为7。字一是十六进制40,即十进制64。在此元组模式下,它表示动态note尾部的偏移,起点为未索引元组data的开头。

它不是note字符数,不是存储槽号,也不是从整个回执起算的偏移。从data字节64开始到达字二,其中存储note字节长度。这把头部指针与尾部内容说明分开。

长度字为6。内容在三十二字节长度字之后开始,即字节96,占据96至101。接下来的102至127共二十六字节,在这个生成的严格表示中为零填充。

算术很具体:六十四头部字节、三十二长度字节、六内容字节、二十六填充字节,共128。切片或按不可信长度分配空间前,应检查尾部是否存在、范围是否落在现有data内。

返回目录 · 下一节

6. 解码UTF-8字节,不数显示字符

六个内容字节e58c97e9a686解码为北馆。本例显示两个汉字,但ABI长度为六字节。把长度改成二,会截断编码内容,不是另一种正确解释。

填充不属于note。若把末字全部三十二字节当作文本,会附加声明长度排除的二十六个零字节。反过来,在检查长度之前任意删除尾部字节,也不是有依据的解码政策。

模式A的主要解释为objectId 42、revision 7、note北馆。给定类别候选展品匹配索引摘要。最后一项应保留“候选匹配”标签,不要假装主题二直接包含可读字符串。

这些字段重建的是字节在模式下的含义,不证明真实展览、实际修订更新或机构批准。合成包本来就不用于建立那些主张。

返回目录 · 下一节

7. 相同签名主题可能支持另一种模式解释

考虑独立模式B:Record(uint256 objectId,uint256 indexed revision,string indexed category,string note)。它交换了两个uint256中哪一个被索引,事件名、有序规范类型列表和索引参数数量都不变。

因此规范签名和主题零不变,包仍有三个主题。但主题一现在表示revision 42,首个数据字表示objectId 7。note与类别候选检查仍相同。

这个替代解释在模式B下结构上合理,不是哈希碰撞:两个模式刻意使用相同规范签名文本。不同的indexed标记和参数名称,是该签名哈希没有编码的信息。

两个声明是本课独立替代方案,不声称它们在同一个合约中共同编译为不同事件。要选择预期解释,审查者需要把相关模式绑定到预期发出者及版本、上下文。

缺少这种绑定时,应保留原始包及两种可能解释,作为待解决证据。挑一个更熟悉的数字当objectId,不是验证。主题零比较成功,本身不能在两个方案间作决定。

返回目录 · 下一节

8. 拒绝截断note,不悄悄修补

重置到模式A及原数据字,但只保留前100个data字节。头部和长度字仍声明偏移64、note长度6。内容从96开始,包结束前只剩四个内容字节。

声明六字节,实际可用四字节,放不下。有界检查在尝试呈现完整note之前拒绝截断,不虚构缺失字节,也不把部分解码字符当成声明的完整值。

这不同于错误类别候选。类别检查针对主题摘要,本例针对未索引data缺少字节。主题值可以完全正确,而note数据仍不完整。

无需声称每个钱包或运行时解码器都会怎样显示畸形包。按照自身明确的边界检查,就足以说明完整解码请求没有证据支持。

返回目录 · 下一节

9. 拒绝包外偏移

另一个独立变体把note偏移改为4096,data仍为128字节。声称的尾部起点超过现有数据,因此在该偏移处没有可读长度字。

检查在读取note长度之前失败。解码器不能把大偏移当成读取任意内存或分配无界缓冲区的许可。本固定练习只报告必要范围不可用。

这与截断note不同:前者长度字存在,只是内容不足;这里尾部起点已经在包外。报告第一个失败条件,能让错误对审查者有用。

生产解析器需要这两个例子之外的类型、范围、嵌套和资源检查。通过有效示例、拒绝4096,不等于认证通用ABI实现。

返回目录 · 下一节

10. 区分跟随指针与严格编码配置

再看独立包:把头部偏移从64改为96,在两个字的头部与尾部之间插入一个零字,总长160。长度字现在位于96至127;六个note内容字节从128开始,之后仍为二十六零填充。

有界的教学指针跟随解码器,可以按声明偏移仍恢复北馆。数据足够,选中的内容字节相同。但能解出note,不证明编码是原来规范布局。

另行声明的严格规范编码配置要求,本元组第一个动态尾部紧接64字节头部,所以它拒绝插入空隙及偏移96。这是配置规则结论,不是“所有ABI解码器都拒绝”的普遍说法。

严格编码章节区分编码器限制与解码器强制检查。本课未执行Solidity解码器,也不从教学解析器推断它对所有畸形输入的行为。

在本资料中应同时记录:有界指针解码器恢复同一个note,而规定的严格配置失败。隐藏任何一项,都会让“有效”含糊不清。

返回目录 · 下一节

11. 把发出者身份与字节解码分开

假设相同字节被归到虚构发出者F,而不是预期E。应用模式A仍可产生同样数字和字符串解释,但这些算术不证明E发出了记录。

同样,给定区块标签不是回执包含证明或最终性结果。本包刻意没有真实交易或认证回执上下文。我们在假设下验证格式和解释,不验证网络发生事实。

日志、存储状态和索引器视图的更广泛区别,可参阅存储、事件与索引。该课从已解码事件开始,本课完成字节读取步骤,不重复索引核对练习。

结果应识别原始包、所选模式、发出者及上下文前提、解码值和未解决字段。这让另一个审查者能够复现解释,而不混淆模式来源和数据来源。

返回目录 · 下一节

12. 示范解释记录

“在虚构发出者E、上下文B的给定非匿名模式A下,主题零匹配Record(uint256,uint256,string,string)。主题一解码objectId为42。未索引元组产生revision 7,以及六个UTF-8字节解码的note北馆。已知候选展品匹配主题二,没有进行任意字符串恢复。”

“尽管主题零相同,模式B仍给出另一种结构合理的解释:objectId 7、revision 42。截断包及越界包不通过规定字节范围检查。含空隙包允许有界指针跟随,却不通过声明严格配置。这些计算都不证明真实发出的回执。”

该记录比单独一个解码标签更有信息。它写明选择结果的假设,也把畸形输入发现与模式身份问题分开。

返回目录 · 下一节

练习与详细答案

  1. 主题零哈希的准确文本是什么?Record(uint256,uint256,string,string),不含参数名称、indexed标记或空格。
  2. 主题一在模式A下代表什么?ObjectId 42;模式B下为revision 42。
  3. 偏移字0x40是否表示十进制四十字节?不是。0x40对应十进制64,偏移从本未索引元组起点计算。
  4. 原包note内容位于哪里?字节96至101,含两端,共六字节。
  5. 长度六为何不代表六个显示字符?字段统计UTF-8字节,本例北馆两个字符编码为六字节。
  6. 能直接把类别摘要读成展品吗?不能,是对给定已知候选做哈希比较。
  7. 100字节截断包缺什么?声明六个note内容字节,但只剩四个。
  8. 160字节含空隙包是否满足严格配置?不满足,尽管有界指针解码器能恢复同一个note。

额外长度检查:把note改为单字符ASCII字符串A,保留相同二字段元组形状。头部仍64字节,长度字32字节,一字节内容补三十一个零,共128。可读字符串更短,不一定让按字对齐的数据包更短。

返回目录 · 下一节

常见问题

事件主题零是四字节函数选择器吗?

不是。本非匿名事件使用完整三十二字节签名摘要作为主题零,其data前没有函数选择器。

主题匹配能确定所有indexed标记吗?

不能。替代模式展示了indexed标记可以变化,而规范类型签名不变。仍需相关模式证据。

索引字符串与未索引note用相同方式存储吗?

本例不是。主题保存category直接字节的哈希,data则为未索引note保存偏移、长度和填充字节。

这些字节是真实区块链记录吗?

不是。它们是本地生成核对的实际格式合成字段,没有编译、部署、发出或取回交易。

返回目录 · 下一节

来源与延伸阅读

  • Solidity 0.8.30 ABI规范:事件、索引事件编码、元组与字符串编码及严格编码模式;2026年10月12日核对。具体向量与替代数据包另外为本练习构造。
  • 存储、事件与索引:配套调查,比较正确解码的事件记录、状态与索引证据。

准确日志解释同时遵守字节边界和模式边界:编码了什么,怎样编码,以及哪份有独立依据的声明赋予这些字节名称。

返回目录