以太坊bloom和logs及代码解析

本文介绍了以太坊如何使用Bloom过滤器来提高日志查询效率,详细阐述了Bloom Filter的工作原理及其在以太坊交易收据中的应用。通过eth_getTransactionReceipt和eth_getLogs方法,分析了Bloom过滤器在日志过滤和检索过程中的作用,以及源码中的实现逻辑。
摘要由CSDN通过智能技术生成

一. 以太坊中的Bloom filter 的使用

以太坊中,通过eth_getTransactionReceipt方法获取交易收据。

eth_getTransactionReceipt 得到的结果如下:

{
   
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
   
        "blockHash": "0x04099d9fff6403bf6518ccc94a1d4ed19e5e00f61a1fa43b1ef528e97a8c2ad4",
        "blockNumber": "0x260",
        "contractAddress": "0xdbd3c12200b337791eaa7acf28fce3ab96dedab9",
        "cumulativeGasUsed": "0x408a89",
        "from": "0x385df4353966d91fbad2d287c46d4e89c4934c7e",
        "gasUsed": "0x408a89",
        "logs": [
            {
   
                "address": "0xdbd3c12200b337791eaa7acf28fce3ab96dedab9",
                "topics": [
                    "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
                    "0x0000000000000000000000000000000000000000000000000000000000000000",
                    "0x000000000000000000000000385df4353966d91fbad2d287c46d4e89c4934c7e"
                ],
                "data": "0x",
                "blockNumber": "0x260",
                "transactionHash": "0x7462fc45f454ccdac2fc166ae05f91e800c5d2bfa5a65d3a6c3732eefdbc94d9",
                "transactionIndex": "0x0",
                "blockHash": "0x04099d9fff6403bf6518ccc94a1d4ed19e5e00f61a1fa43b1ef528e97a8c2ad4",
                "logIndex": "0x0",
                "removed": false
            }
        ],
        "logsBloom": "0x00000000000000000000200000000800000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000080000000040000000000000000000000000000000000040",
        "status": "0x1",
        "to": null,
        "transactionHash": "0x7462fc45f454ccdac2fc166ae05f91e800c5d2bfa5a65d3a6c3732eefdbc94d9",
        "transactionIndex": "0x0"
    }
}

在reciept中会为日志数据生成一个Bloom过滤器,在func (pre *Prestate) Apply 方法中:
在这里插入图片描述

CreateBloom方法:

// CreateBloom creates a bloom filter out of the give Receipts (+Logs)
func CreateBloom(receipts Receipts) Bloom {
   
	buf := make([]byte, 6)
	var bin Bloom
	for _, receipt := range receipts {
   
		for _, log := range receipt.Logs {
   
			bin.add(log.Address.Bytes(), buf)
			for _, b := range log.Topics {
   
				bin.add(b[:], buf)
			}
		}
	}
	return bin
}

那么,bloom的作用是什么呢?
布隆过滤器并不是以太坊的专属,Bloom Filter是1970年由布隆提出的,特点是非常节省空间的概率数据结构,运行速度快,占用内存小,缺点是有一定的误判率。

很多场景中,都存在判断一个元素是否存在的需求,比较熟知的方法是采用 HashMap的数据结构,使用put方法存储数据,然后通过取值或者判断存在等方式来确定,在区块链中,在链式结构存储了大量数据以后,采用这种方式需要大量查询,就会非常耗费资源,检索的速度会越来越慢。所以以太坊使用了bloom过滤器来快速查询日志。

我们来看一下以太坊中Bloom:

// Bloom represents a 2048 bit bloom filter.
type Bloom [BloomByteLength]byte

它实际上是一个很长的二进制向量和一系列随机映射函数组成,主要用于判断一个元素是否在一个集合中。

需要注意的是,以太坊的bloom过滤器适合大量数据中高效判断元素是否存在,但是并不存储数据本身,仅存储hash结果取模运算后的位标记。过滤结果如果是存在于,实际情况不一定存在,但是判断结果为不存在时,则一定不存在,基于这个特点,以太坊中的判断逻辑是,根据bloom和过滤的参数判定是否存在,不存在则直接返回。

// blockLogs returns the logs matching the filter criteria within a single block.
func (f *Filter) blockLo
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值