你有没有想过,当你把一笔以太坊交易发送出去后,它到底是怎么在区块链上穿梭的呢?今天,就让我带你一探究竟,揭开以太坊交易池的神秘面纱!
交易之旅:从钱包到交易池

想象你打开了以太坊钱包,轻轻一点,交易就发送出去了。其实,这笔交易在踏上区块链的征途之前,要先经过一个重要的中转站——交易池。
交易池,顾名思义,就是一个存放交易的“大仓库”。当你通过钱包发送交易时,它首先会到达一个运行中的以太坊节点,比如geth。经过一系列校验和处理后,交易成功进入交易池,然后向已连接的邻近节点发送此交易。
这个过程就像你把一封信寄出去,信件会经过邮局,然后被送到收信人的手中。在这个例子中,邮局就是交易池,信件就是交易,而收信人就是矿工。
交易池里的“本地”与“远方”

你知道吗?进入交易池的交易,其实是有“本地”和“远方”之分的。本地交易,就像是你亲自送到邮局的信件,而远方交易,则是别人帮你寄来的。
为什么会有这样的区别呢?因为节点对待本地交易和远方交易有所差异。简单来说,本地交易优先级更高,就像是你亲自送的信件,邮局会优先处理。
交易池里的“排队”与“淘汰”

交易池里的交易可不少,它们就像是一群人在排队,等着被矿工选中,打包进区块。但是,交易池的空间是有限的,所以当交易数量过多时,就需要进行“淘汰”。
淘汰的规则是这样的:如果交易提供的gas值低于交易池里当前提供gas最低的那条交易,那么就会被淘汰。这种情况发生之后,往往在etherscan中会观察到正在pending的交易消失了,找不到了。
交易池里的“nonce”值
在交易池里,还有一个非常重要的概念,那就是“nonce”值。nonce值就像是一串密码,用来确保交易顺序的正确性。只有当nonce值连续时,交易才能被成功执行。
举个例子,假设你的账户的nonce值是10,那么txpool中必须存在第10号交易。如果txpool中没有第11~99号交易,那么第100号交易就无法执行。
交易池里的“缓存”与“清理”
交易池除了存放交易,还有两个重要的功能:缓存和清理。
缓存功能的设计,是为了在交易量大的时候,能够及时处理交易。而清理功能,则是为了防止交易池过于拥挤,对系统造成压力。
交易池会定期清理一些过期的交易,就像邮局会清理那些无人领取的信件一样。
交易池里的“pending”与“queue”
交易池里主要有两个缓冲区:pending和queue。
pending缓冲区存放的是可以立即处理的交易,就像邮局里已经准备好投递的信件。
queue缓冲区存放的是nonce-gap交易,也就是nonce值不连续的交易。当nonce-gap消除后,这些交易会被迁移到pending缓冲区。
交易池里的“事件处理”
交易池在符合条件的情况下,会处理以下事件:
- report:统计交易池中pending和queue中交易数量。
- evict:交易失效检查事件,从queue中剔除3小时前的交易。
- journal:本地交易日志,缓存pending和queue队列中属于本地的交易。
- chainHeadEvent:收到新块后交易池的处理,调用reset。
交易池里的“状态重置”
交易池在启动时,会从本地获取当前区块状态,设置pending和queue缓冲区,以及txpool状态db。收到合法块时,会重置交易池状态到新块root,调整pending和queue缓冲区以对应新的区块高度。
交易池里的“交易入池”
当一条交易进入挖矿节点的交易池时,节点会做出以下逻辑:
- 通过判断交易hash,当这条交易已经在节点的交易池里面时,就会丢弃掉当前收到的这一个交易。
- 如果是一个全新的hash,就会根据共识协议,对这一条交易做基本的验证。验证包括:长度、value、是否溢出当前区块的gaslimit、Nonce值、转账提供的gas大小是否太小等。
- 如果验证不通过,就会返回相应的错误代码。
- 如果验证通过,需要根据当前交易池的状态来决定,如果交易池满了的话,那么判断当前的转账交易提供的gas是否高于交易池里当前提供gas最低的那条交易。如果低了,就返回错误ErrUnderpriced。
现在,你对以太坊交易池有了更深入的了解了吧?它就像是一个繁忙的邮局,负责处理大量的交易,确保它们能够顺利地到达目的地。希望这篇文章能让你对区块链技术有更深入的认识!