前言当你在区块链浏览器上查询交易时,你是否只看概述和内部交易?事件日志呢?你是否在一个不起眼的角落忽略了它。
对于用户和开发者来说,事务事件日志实际上非常重要。触发事件不仅可以向外界通知链上智能合约的交易,还可以使智能合约的开发者对合约进行测试,确保合约的安全性。
接下来我会帮你详细了解关于以太坊的事件日志,以及一些关于它的基础知识。
事件1。什么是事件?
Event是一个可以方便调用以太坊虚拟机日志功能的接口。
固体事件是EVM测井函数之上的抽象。应用程序可以通过以太坊客户端的RPC接口订阅和监听这些事件,允许我们在区块链上打印信息。
因此,通过坚实度活动,我们可以做到:
测试智能合约中的特定变量以索引变量,从而重建存储状态。监听事件用于更改前端状态,并创建子图以更快地读取数据。
二。声明和触发事件
以官方的ERC20契约代码为例,我们通过IERC20.sol文件中的event关键字进行声明。
我们可以把一个事件看作一种特殊的类型。在上面的代码中,我们创建了一个名为Transfer的事件,其中有两种类型的参数:索引的和未索引的。from和to参数被索引,而value参数不被索引。
在ERC20.sol的_transfer函数中,相应的事件由emit关键字触发(在以前的版本中不需要使用emit)。
什么是日志?
在以太坊中,日志用于存储事件。当调用该事件时,它将触发存储在事务日志中的参数。它不能被智能协定访问,但是它可以提供关于以块发送的事务和消息的信息。
我们随意点开一个交易(0x 477 ed 7208127 bea 597142622d 52d 46d 3 e 4967835 BD 360995581 EB 5 aaeec 3 e)查看其日志。
通过日志,我们可以将日志分为四个部分:
1.地址:地址。即合同的地址或发布事件的帐户的地址。
2.姓名:姓名。即触发的事件名称及其参数。
3.主题:主题。也就是说,事件中有索引参数。
4.数据:数据。也就是说,事件中没有索引参数。
二、日志记录中的主题
上面我们谈了话题,接下来我们再详细谈话题。
每个日志记录都包含“主题”和“数据”。主题是32字节(256位)来描述事件中发生了什么。不同的操作代码(日志0日志1 LOG2日志3日志4)用于描述日志记录中需要包含的主题数量。
EVM有五个操作码,用于触发事件日志和创建日志记录,分别是LOG0、LOG1、LOG2、LOG3和LOG4。它们用于描述智能合约中的事件,如令牌的转移和所有权的变更。LOG1包含一个主题,单个日志记录中最多可以包含四个LOG4的主题。
Topics0通常是事件名称的签名(keccak256的哈希值),包括其参数的类型(address、uint256等。),其中Topics1是第一个索引参数的值,Topics2是第二个索引参数的值。
本主题Topics0的值为0 xdf 252 ad 1 be 2 c 89 b 69 C2 b 068 fc 378 da 952 ba 7 f 163 C4 a 1628 f 55 a4 df 523 B3 ff,其事件为上一行名称的内容。
我们用keccak256加密事件传送(address,address,uint256),结果和Name的值一样,说明Name的值确实是事件名称的签名。当然,有一个例外是没有事件签名的,那就是当一个匿名事件被触发的时候。
Topics1是第一个索引参数的值,即表单地址的值。Topics2是第二个索引参数的值,它是要寻址的的值。从内部通话分析也可以看出,确实是这样。
一个主题只能包含32个字节的数据,因此可能超过32个字节的内容,如数组和字符串,不能用作主题。如果你想尝试包含超过32个字节的数据,那么主题必须被散列,所以最好在超过32个字节后将其作为数据包含在日志记录中。
第三,日志记录中的数据
除了主题之外,日志记录还有一部分是数据,它是事件的非索引参数的ABI代码或哈希值。我们可以使用Dec或Hex来检查数据data的值。
数据和主题各有利弊:
话题可以搜索,数据不能搜索。数据小于主题要求的气体。因为题目是带索引的参数,我们可以直接在日志中搜索,而数据是ABI码或者哈希值,所以不能直接搜索。
根据黄皮书,我们可以找到相关的天然气成本的日志。日志的基本开销是375气,每个话题也是375气,而数据字节的开销是8气。
我们从黄皮书上可以知道,日志的气费很便宜,一个ERC20令牌转移事件的费用最多只需要1756气(日志基础375气,转移事件三个主题375 * 3=1125气,最大32字节数据8 * 32=256气),而标准以太坊的转移需要21000气。当然,以上只是日志运营本身的成本。在智能合约的开发中,不能简单地用价值来计算测井作业的成本。但是在开发中,我们只能把智能合约需要的数据保存在状态变量中,其余的用事件处理,这样可以节省很多气成本。
触发事件
接下来,举例说明触发事件。下面的代码实现了符合ERC20标准的令牌协定中使用的传输事件。
由于上面不是“匿名事件”,所以第一个主题将包含事件的签名(签名时只需要参数的类型)。
那么我们来看看事件的参数,from和_to地址索引,value值不索引。所以_from和_to地址将被视为主题,而_value值将被视为数据。
3.3节我们说了话题可以搜索,数据不可以,所以可以在日志中搜索from地址和_to地址值的相关转账日志,但是不能搜索转账金额为_value的转账日志。由于事件有三个主题(事件签名、from、_to),日志记录操作将使用LOG3操作码。
如果我们想找到数据的内容呢?这里我们需要知道EVM操作码的参数。尽管LOG3包含三个主题,但在EVM中有五个参数。
如果你想读取数据的内容,你可以用下面的方法从内存中读取事件数据。
钓鱼1。事件在钓鱼中的应用
上面提到的日志事件那么多,那么这些和钓鱼有什么关系呢?攻击者通常会伪装成交易所或名人,通过日志事件向受害者转账(这些钱没有实际交易价值,只是一个钓鱼令牌)。当受害者看到是交易所或名人转让的信物,就会放松警惕。这时,袭击者会把受害者引到一个有钓鱼令牌的水池边。当受害者看到代币价值极高时,他们会立即授权交易。这时,他们就会落入攻击者设置的陷阱,攻击者会让受害者授权他们去偷受害者钱包里的钱。
下图是之前发生的一起钓鱼事件。攻击者伪装成硬币安全钱包向他人转移钓鱼令牌。
我们可以通过BSC浏览器上的标签找到官方地址。
通过查询,发现币安热钱包6的地址是0x 8894 e 0 a 0 c 962 CB 723 c 1976 a 4421 c 95949 be 2d 4 e 3。
因为浏览器记录是基于事件的,所以topics1的值,即sender的值是0x 8894 e 0 a 0 c 962 CB 723 c 1976 a 4421 c 95949 be 2d 4 E3。
第二,再现
下面是BEP20的伪代码,以BNB链主网为例进行转载。攻击者创建一个名为“钓鱼令牌”的钓鱼令牌。
如下图所示,新的币安参数为0x 8894 E0 a0c 962 CB 723 c 1976 a 4421 c 95949 be 2d 4 E3。
然后,我们需要修改红色标志代码,如下所示,并将发出触发事件中的发件人地址更改为币安。
部署契约(https://bbscscan.com/address/0x7c08a19b 8d2c 14591506d 7d 3 c 385 fc 702 e 0630)后,调用转移函数将钓鱼令牌转发给受害者。
查看交易信息发现,这里的from地址并不是攻击者的地址0x 95 e 2 ea 34 deb 5c 91 a 47 f 459770d 20568 a 15 b,而是币安:热钱包6的地址0x 8894 e 0 a 0 c 962 CB 723 c 1976 a 4421 c 95949 be 2d 4 e 3。
查看Logs日志,Topics1记录的发件人地址也是币安热钱包6地址,Topics2记录的收件人是受害者地址。
总结细节决定成败。不要认为事件日志是沧海一粟。在区块链世界,越细致的地方越容易被黑客攻击和利用,往往需要更加谨慎。同时需要注意的是,不要因为日志中显示的内容而落入骗子设计的骗局。再次提醒大家,不要随意点击不熟悉的链接,更不要随意授权他人。当我们对事件日志有了更深入的了解,就能更好的防止自己上当受骗。
参考《Solidity 中文文档》755-7900《Solidity 中的事件和日志》755-79000来自https://www . freebuf . com/articles/区块链-articles/349885.html