主页 > imtoken钱包下载2.0版本 > 科普|深入理解以太坊交易处理机制

科普|深入理解以太坊交易处理机制

imtoken钱包下载2.0版本 2023-05-04 06:59:18

本地提交,第三方应用通过调用本地以太坊节点的RPC服务提交交易;

远程同步,通过广播同步的形式,将其他以太坊节点的交易数据同步到本地节点。

交易池中数据的去向:由矿工(miner)获取并验证,用于挖矿,挖矿成功后写入区块并广播,写入后交易将从交易池中删除规范链,如果交易写入后进入分叉,交易池中的交易不会减少,然后等待重新打包。

数据结构

首先查看TxPoolConfig的配置信息:

以太坊挖矿能赚钱吗_以太坊挖矿机制_购买以太坊挖矿机

默认配置如下:

以太坊挖矿能赚钱吗_购买以太坊挖矿机_以太坊挖矿机制

TxPool数据结构如下:

以太坊挖矿机制_购买以太坊挖矿机_以太坊挖矿能赚钱吗

基本配置

在分析交易执行时,我们首先需要看一些基本的配置,比如:交易手续费是否有最大上限/下限、交易池配置、交易信息检索的最大数量等。这里我们只看一些要点:

01 交易手续费

以太坊挖矿机制_以太坊挖矿能赚钱吗_购买以太坊挖矿机

02 交易池配置

购买以太坊挖矿机_以太坊挖矿能赚钱吗_以太坊挖矿机制

03 交易检索数量

初始化池

交易池的初始化是通过NewTxPool实现的,具体代码如下:

购买以太坊挖矿机_以太坊挖矿能赚钱吗_以太坊挖矿机制

以太坊挖矿机制_以太坊挖矿能赚钱吗_购买以太坊挖矿机

这里首先调用sanitize函数来验证配置参数,避免设置不合理的gas prices。

以太坊挖矿能赚钱吗_购买以太坊挖矿机_以太坊挖矿机制

以太坊挖矿能赚钱吗_购买以太坊挖矿机_以太坊挖矿机制

然后使用默认配置初始化交易池( txpool ):

购买以太坊挖矿机_以太坊挖矿能赚钱吗_以太坊挖矿机制

然后初始化本地账户,将配置好的本地账户地址添加到交易池中:

然后创建一个更多的 gasprices 有序交易:

具体实现代码如下:

以太坊挖矿能赚钱吗_以太坊挖矿机制_购买以太坊挖矿机

然后调用 reset 更新交易池:

reset的具体实现如下:

以太坊挖矿能赚钱吗_以太坊挖矿机制_购买以太坊挖矿机

以太坊挖矿能赚钱吗_以太坊挖矿机制_购买以太坊挖矿机

购买以太坊挖矿机_以太坊挖矿机制_以太坊挖矿能赚钱吗

然后启动重组循环,以便它可以处理日志加载期间产生的请求:

scheduleReorgLoop的具体实现代码如下所示。 该函数主要用于reset和promoteExecutable的执行计划。

购买以太坊挖矿机_以太坊挖矿能赚钱吗_以太坊挖矿机制

购买以太坊挖矿机_以太坊挖矿机制_以太坊挖矿能赚钱吗

此时如果启用了本地事务,则从本地磁盘加载本地事务。

购买以太坊挖矿机_以太坊挖矿能赚钱吗_以太坊挖矿机制

然后订阅相关的事务事件并启动主循环:

主循环loop的具体实现代码如下。 它是 txPool 的 goroutine,也是主事件循环。 主要用于等待和响应外部区块链事件以及各种上报和交易驱逐事件:

购买以太坊挖矿机_以太坊挖矿能赚钱吗_以太坊挖矿机制

以太坊挖矿机制_以太坊挖矿能赚钱吗_购买以太坊挖矿机

购买以太坊挖矿机_以太坊挖矿机制_以太坊挖矿能赚钱吗

建立交易

交易由用户发起,使资产从一方转移到另一方,即所谓的价值转移。 我们最直观的交易构造就是通过钱包转账。 这里我们直接以eth_sendTransaction的RPC为例来分析交易的构建过程,一个eth_sendTransaction请求的例子如下:

示例参数:

from: DATA, 20 bytes - 发送交易的源地址

to: DATA, 20 bytes - 交易的目标地址,创建新合约时可选

gas: QUANTITY - 交易执行可用的gas量,可选整数,默认值90000,未使用的gas将被返还

gasPrice: QUANTITY - gas价格,可选,默认:待定

value: QUANTITY - 交易发送的数量,可选整数

data: DATA——合约编译或调用方法的签名和编码参数

nonce: QUANTITY - nonce,可选,同一个nonce可以用来重写挂起的交易

购买以太坊挖矿机_以太坊挖矿能赚钱吗_以太坊挖矿机制

示例响应:

下面跟踪一下eth_sendTransaction这个RPC的执行过程。 这里先检查账户是否存在,再检查Nonce是否为空,然后调用SingTx进行签名操作,再调用SubmitTransaction提交交易:

以太坊挖矿机制_以太坊挖矿能赚钱吗_购买以太坊挖矿机

SignTx的实现代码如下。 这里会继续调用SignTx进行签名操作。 我不会在这里深入。 后续的“交易签名”会详细分析:

以太坊挖矿机制_以太坊挖矿能赚钱吗_购买以太坊挖矿机

以太坊挖矿能赚钱吗_购买以太坊挖矿机_以太坊挖矿机制

签名后返回SendTransaction调用SubmitTransaction提交签名。 在这里,它会先检查交易费用是否足够,然后调用 SendTx 发送交易:

以太坊挖矿能赚钱吗_以太坊挖矿机制_购买以太坊挖矿机

SendTx的具体实现如下。 这里会调用AddLocal将交易添加到交易池中。 这里不深入会有一个“Add Transaction”的分析单元模块:

然后检查接收地址是否为空,如果为空,则创建一个地址(一般在创建合约时出现),然后打印一份完整的TX详情的log,供后续人工排查分析,然后返回该地址的hash值交易:

以太坊挖矿能赚钱吗_购买以太坊挖矿机_以太坊挖矿机制

交易入池

我们知道交易的来源有两种:一种是本地提交,一种是远程提交。 这两个的具体实现代码分别是AddLocals和AddRemotes。 这两个函数在向交易池中添加交易时使用。 这是通过调用 addTxs 实现的:

以太坊挖矿机制_购买以太坊挖矿机_以太坊挖矿能赚钱吗

addTxs 代码如下所示:

购买以太坊挖矿机_以太坊挖矿能赚钱吗_以太坊挖矿机制

以太坊挖矿能赚钱吗_以太坊挖矿机制_购买以太坊挖矿机

首先会对交易进行过滤,检查是否为已知交易(即添加或广播),然后调用send函数通过secp256k1椭圆曲线验证签名(v,r,s)导出的地址, 如果 derived 失败或签名不正确,则返回错误:

以太坊挖矿能赚钱吗_购买以太坊挖矿机_以太坊挖矿机制

然后将交易添加到交易池中(注意:这里有交易锁)

addTxsLocked的具体实现如下,它将有效的交易排队,并调用pool.add函数将交易添加到交易队列中:

以太坊挖矿机制_购买以太坊挖矿机_以太坊挖矿能赚钱吗

add函数的具体实现如下:

以太坊挖矿机制_购买以太坊挖矿机_以太坊挖矿能赚钱吗

以太坊挖矿机制_以太坊挖矿能赚钱吗_购买以太坊挖矿机

以太坊挖矿能赚钱吗_以太坊挖矿机制_购买以太坊挖矿机

在这里以太坊挖矿机制,它会先检查当前交易是否已经被知道(即是否被广播或添加到池中),如果知道,则直接丢弃:

然后识别交易是本地提交还是远程提交以太坊挖矿机制,调用函数validateTx对交易进行验证。 如果验证失败,则直接丢弃:

以太坊挖矿能赚钱吗_以太坊挖矿机制_购买以太坊挖矿机

然后检查交易池是否已满,如果已满,则丢弃交易队列中被低估的交易。 GlobalSlots和GlobalQueue是pending和queue的最大容量:

以太坊挖矿能赚钱吗_以太坊挖矿机制_购买以太坊挖矿机

然后判断当前交易的pending队列中是否有相同nonce值的交易。 如果存在,判断当前交易所设置的gasprice是否超过设置的PriceBump百分比。 如果超过,则替换并覆盖现有事务。 否则会返回错误,替换交易的 Gasprice 过低。 ,并将其放入队列(enqueueTx):

以太坊挖矿能赚钱吗_购买以太坊挖矿机_以太坊挖矿机制

调用enqueueTx后会加入到交易队列中,同时检查from账户是否为本地地址,如果是则加入到交易池的本地地址中:

以太坊挖矿机制_购买以太坊挖矿机_以太坊挖矿能赚钱吗

enqueueTx代码如下,该函数主要是向交易队列中插入新的交易:

购买以太坊挖矿机_以太坊挖矿能赚钱吗_以太坊挖矿机制

以太坊挖矿机制_购买以太坊挖矿机_以太坊挖矿能赚钱吗

最后会到addTx函数,这里会调用requestPromoteExecutables函数进行交易提升请求操作,主要是将交易从队列中放入pending:

交易签名

交易签名主要通过函数SignTx实现。 首先检查钱包是否关闭,然后检查钱包账户是否包含发情交易请求的账户,然后调用SignTx进行签名处理:

以太坊挖矿机制_购买以太坊挖矿机_以太坊挖矿能赚钱吗

购买以太坊挖矿机_以太坊挖矿能赚钱吗_以太坊挖矿机制

SignTx的具体实现代码如下:

以太坊挖矿能赚钱吗_以太坊挖矿机制_购买以太坊挖矿机

在验证了账户的合法性后,我们可以使用keystore通过SignTx进行签名处理,然后在这里调用LatestSignerForChainID进行签名:

以太坊挖矿机制_以太坊挖矿能赚钱吗_购买以太坊挖矿机

然后使用私钥登录SignTx函数:

以太坊挖矿能赚钱吗_以太坊挖矿机制_购买以太坊挖矿机

使用ECDSA(椭圆曲线加密算法)进行签名,然后返回签名结果:

购买以太坊挖矿机_以太坊挖矿能赚钱吗_以太坊挖矿机制

交易验证

交易验证是整个交易环节中最重要的环节。 对于用户而言,交易验证是保障用户财产安全的重要手段。 对于整个以太坊来说,交易验证是保证以太坊稳定运行和可持续发展的重要途径。 ,交易验证主要发生在以下场景:

当用户完成一笔交易的签名后,需要将交易提交到区块链网络,以便尽快确认交易,而节点需要在提交交易前对交易进行验证,以确认交易的合法性。交易;

当节点收到其他节点广播的交易时,节点需要验证该交易是否合法,合法的交易将被添加到节点的交易池中;

当挖矿节点成功计算出满足要求的哈希值后,该节点会将交易池中的交易打包到区块中,打包交易时需要验证交易的合法性;

当一个节点收到一个由其他节点同步的区块时,它也需要验证这个区块中包含的交易。

交易验证由validateTx函数完成,其逻辑代码如下。 这里会检查eip2718是否启用,交易类型,然后检查交易的大小,交易转账的金额,交易的gas,交易签名的正确性,确保交易遵循Nonce订单,交易者资产是否充足,保证交易gas价格。 基本交易费用高:

以太坊挖矿机制_购买以太坊挖矿机_以太坊挖矿能赚钱吗

以太坊挖矿机制_购买以太坊挖矿机_以太坊挖矿能赚钱吗

交易升级

交易升级主要是指将交易放入待定列表。 该方法与add方法的区别在于add函数是将获取到的新交易插入到pending中,而PromoteExecutables是将可执行文件放入给定的账户地址列表中。 交易从队列列表中插入到pending中,检查无效交易,然后发送交易池更新事件。 实现代码如下:

购买以太坊挖矿机_以太坊挖矿能赚钱吗_以太坊挖矿机制

以太坊挖矿机制_购买以太坊挖矿机_以太坊挖矿能赚钱吗

这里用一个for循环遍历所有账户,升级交易。 这里首先删除队列中nonce低于账户当前nonce的所有交易:

以太坊挖矿能赚钱吗_以太坊挖矿机制_购买以太坊挖矿机

然后移除队列中所有消费大于账户持有余额或gas大于最大gas limit的交易:

以太坊挖矿能赚钱吗_购买以太坊挖矿机_以太坊挖矿机制

然后将队列中的所有可执行事务添加到待处理状态,其中将调用 promoteTx 方法将队列中的事务( Txs )放入待处理状态:

以太坊挖矿机制_购买以太坊挖矿机_以太坊挖矿能赚钱吗

promoteTx的实现代码如下。 此函数首先将事务插入挂起队列。 如果旧交易更好(交易Gasprice大于或等于原始交易价值的110%,标准与pricebump设置有关),则删除当前交易。 这个事务,如果当前事务比旧事务好删除旧事务,则更新列表:

购买以太坊挖矿机_以太坊挖矿能赚钱吗_以太坊挖矿机制

然后返回 promoteExecutables 函数,如果非本地账户队列小于限制( AccountQueue ),则将其移除:

购买以太坊挖矿机_以太坊挖矿机制_以太坊挖矿能赚钱吗

最后,记录被移除的条目并更新queuedGauge。 如果队列中该账户的交易为空,则删除该账户:

以太坊挖矿机制_以太坊挖矿能赚钱吗_购买以太坊挖矿机

交易降级

交易降级是指当出现新区块时,打包的交易将从padding降级到queue,或者当另一笔交易的Gas price更高时,将其从padding降级到queue。 降级操作关键实现函数是demoteUnexecutables,事务降级主要发生在以下三种情况:

分叉导致Account的Nonce值下降:如果原规范链A上的交易号m花费20,已经上链,但是新规范链上的交易号m在新规范链上不在链上分叉,导致规范链上记录的交易编号m 账户的Nonce减少,因此必须将交易m回滚到交易池中,放入队列;

分叉后的缺口:这种问题一般是交易余额问题造成的。 如果原标准链上一笔交易m的费用为100,分叉后账户又发送了一笔费用为200的交易m,这会导致账户余额为原标准链上的某笔交易支付,但不一定在新的规范链上就足够了。 如果余额不足的交易是m+3,那么交易m+2和m+4之间就会出现gap,导致从m+3开始的所有交易都被降级;

分叉导致待处理交易的 nonce 值与状态的 nonce 值不同。

demoteUnexecutables的代码如下。 这里首先遍历pending list得到每个addr的最新Nonce值,然后删除Nonce小于上一次查询得到的Nonce值的交易,然后账户余额不够支付交易手续费和一些暂时无效的交易被退回。 交易,并将暂时无效的交易放入队列。 如果此时有空档,将后面的事务移到待办列表中。 如果进行上述降级,如果pending中某个addr没有交易,则该交易会被删除。 要删除的帐户:

以太坊挖矿机制_购买以太坊挖矿机_以太坊挖矿能赚钱吗

以太坊挖矿能赚钱吗_以太坊挖矿机制_购买以太坊挖矿机

池重置

我们可以通过reset来重置交易池,该方法具体代码如下:

购买以太坊挖矿机_以太坊挖矿能赚钱吗_以太坊挖矿机制

以太坊挖矿能赚钱吗_购买以太坊挖矿机_以太坊挖矿机制

以太坊挖矿能赚钱吗_以太坊挖矿机制_购买以太坊挖矿机

如果旧块不为空且旧块不是新块的父块,则检查旧块与新块的差值是否大于64,如果超过64则不进行重组,否则获取old header和new header Block的最新更新,如果old header为null,检查新header的高度是否小于旧header的高度,然后打印log直接返回,继续不满意向下执行;

如果旧头不为空,则重组开始。 此时,如果旧链的头部区块大于新链头部区块的高度,则旧链将回滚,回收所有回滚的交易。 如果新链的头部区块大于旧链的头​​部区块,则新链会后退并回收交易。 当新链和旧链到达相同的高度时,它们会同时后退,直到找到一个共同的父节点,然后找出所有存储在discard中但没有包含在included中的交易。 值,然后将这些交易重新插入池中:

以太坊挖矿能赚钱吗_以太坊挖矿机制_购买以太坊挖矿机

以太坊挖矿机制_以太坊挖矿能赚钱吗_购买以太坊挖矿机

购买以太坊挖矿机_以太坊挖矿能赚钱吗_以太坊挖矿机制

然后设置最新的世界状态,设置新链头区块的状态,然后将旧链支持的交易放入交易池:

购买以太坊挖矿机_以太坊挖矿能赚钱吗_以太坊挖矿机制

文末总结

区块链由链式结构中相互链接的块组成。 每个区块由区块头和区块体组成。 区块体存储交易记录,因此“交易”成为链上数据的关键。 ,也是链上价值传递的主要方式。 在公链系统中,交易构建过程、交易验证、交易签名、Gas费设计等方面都存在值得考虑的安全风险。 例如:当交易手续费(GasPrice)被恶意DOS攻击,交易签名伪造,双花攻击,交易签名数据长度未验证,导致签名时节点OOM等。

本文从源代码的角度分析以太坊交易池数据结构、交易手续费设置、交易构建、交易签名、交易入池、交易验证、交易升级、交易降级、交易池重置等功能模块。 以太坊交易处理的流程和安全设计已经探索,但公链安全体系的建设还有很长的路要走,需要进一步探索。

参考链接: