当前位置: 首页 > news >正文

ETH 交易流程深度技术详解

1@2x-3.jpg

1.png

概述

在前面对 PolkaVM 和 Revive 的文章中,我们介绍了很多技术细节,开发工具。还对比 EVM,知道了 PolkaVM 的优势。很多同学还是对 Polkadot SDK 为什么可以运行 EVM 兼容的智能合约,以及交易处理的整个流程不太清楚。这篇文章将会带着大家梳理一下整个过程,在熟悉它之后,对于今后 Debug 代码,找到出错原因都会有很大好处。

整个处理的流程主要有下面几个模块组成,我们来逐一分析

  • RPC Server 接收交易,并转发到节点

  • Runtime 定义交易的格式扩展

  • Revive 做交易的转换,从 Eth 交易转成 Polkadot SDK 的 extrinsic

  • 最终的 bytecode 在 PolkaVM 中的执行

2.png

RPC Server

和普通的 Extrinsic 不同,也有别于之前在 Polkadot SDK 上出现的Frontier,Ink 的支持。在提交 Solidity 的交易的时候,我们会启动一个单独的RPC Server来接收交易。因此我们在配置本地的测试环境或者 Passet Hub 的时候,都需要这个 URL。

那么这个 Server 是怎么工作的呢?它的代码也在 Revive Pallet下,package 名字是 pallet-revive-eth-rpc。它主要有三个组件,一个 subxt 的客户端,一个 RPC 服务器,还有一个用来缓存数据的 sqlite 内存数据库。

subxt 主要是和 node 来交互,比如向区块链提交交易,查询数据等。 RPC 服务器来实现以太坊的 Web3 服务接口,大部分函数定义都在 EthRpc 这个 Trait 可以找到。其他还有 debug api 和 health api。

当 server 收到请求,都会转换成对区块链的请求,通过 subxt 的客户端发出,收到结果后返回给调用者。

这里分别举二个例子,一个是查询余额,一个提交交易。

截屏2025-07-21 09.49.49.png

这里的接口定义是 web3 的一致的,通过区块号或者 Hash 来查询余额。下面我们来看下它的实现。

截屏2025-07-21 09.50.42.png

这里 client 就是 subxt 的客户端,它把传进来的区块号,哈希或者 Tag,统一转换成区块哈希,进行查询,并返回结果。这里不用担心 Decimal 的问题,在 Node 一侧,当要查询的是一个Eth格式的地址时,就已经做好了转换。

下面是对发送交易的实现,它会组装一个 Pallet 是 Revive,Extrinsic 是 eth_transact 的交易,然后发给 Node。这个 Extrinsic 非常的特殊,我们接下来会在分析 Revive 代码的时候看下它是怎么处理的。

截屏2025-07-21 09.51.29.png

截屏2025-07-21 09.51.33.png

Sqlite 主要来缓存一些交易的数据,还有事件日志等。

图片

Runtime

在 Runtime 中,需要包含 Revive Pallet 才能处理Eth的交易,还有对Runtime API的实现。一个最重要的代码实现是对 UncheckedExtrinsic 的重新定义,对于不需要支持 Eth 的交易,普通的 sp_runtime::generic::UncheckedExtrinsic 就可以了。为了支持对 Eth 的交易,需要使用 Revive 里面  UncheckedExtrinsic 作为包含中 Block 中的类型。

这样区块链在处理交易池里面的 Eth 交易就可以识别他们,在验证交易的时候把它转换成普通的 Extrinsic。

4.png

Revive Pallet

Revive 当然是处理交易的核心,有些设计还比较的巧妙,我们先来看它如何转换Eth的交易。对于一个提交的 Eth 交易,下面这个函数用来对它进行转换,成为普通的 Extrinsic。

截屏2025-07-21 09.53.12.png

截屏2025-07-21 09.53.18.png

截屏2025-07-21 09.53.23.png

截屏2025-07-21 09.53.28.png

首先尝试解码 payload 成一个含有 Eth 签名的交易,并得到发送交易的以太坊地址。随后做一个基本的检查,比 如nonce,gas,chain ID 等等。

下一步就是要转换成 Call 了, 这里首先有一个特殊的地址  RUNTIME_PALLETS_ADDR,它被用来直接调用 Runtime 里面的任何交易。它把输入的数据直接解码成 Call 并调用,除此之外的都会转换成 Revive 的 Call 方法,调用某个智能合约里面的一个方法。如果没有调用的合约地址,那么只能是一个部署合约的方法,会把它尝试转换成一个 eth_instantiate_with_code 的方法。

从这里我们可以看出,从 Eth 来的交易,没有只 upload_code 的方法,当然这个也不在以太坊接口的定义里面。

在下面就是对于 gas_price, gas_fee 的处理,还会把多给的 gas_fee 作 为tip。

最终返回一个 CheckedExtrinsic,它也在这里有了使用 Polkadot 帐号的签名,它来自发送交易者映射到 Polkadot 地址格式的帐号。

这里有一个非常有意思,和难理解的就是 eth_transact 方法,它除了给出一个错误之外没有任何其他逻辑。那么它的作用是什么呢?首先,它提供了一个接口给外部调用,比如我们在 RPC Server 里面使用 subxt 来调用它。其次,我们使用它就可以把提交来的交易解码成这个 Call,得到它的 payload 部分,在用 payload 解码成封装的 Eth 交易。

但是在从 UncheckedExtrinsic 到 CheckedExtrinsic 的转换中,它就被处理了,转换成了其他的方法。call 或者 eth_instantiate_with_code,因此在正常情况下不会有 dispatch 到这个方法里面的交易。这就是为什么它只有报错处理。

截屏2025-07-21 09.55.36.png

截屏2025-07-21 09.55.40.png

当然在 Revive 里面还有很多处理逻辑,包括我们前面文章提到的precompile,这里不再重复介绍。

5.png

交易在 VM 的执行

在 Revive 中处理交易中最核心的是一个 Stack 的数据结构,从这个名字来看,这里依然要模拟的还是 EVM 基于栈的处理模型。它的代码如下:

截屏2025-07-21 09.56.52.png

截屏2025-07-21 09.56.56.png

除去基本信息比如区块号,时间戳,还有就是对于计算和存贮的计量。通过 frames 来记录每次对合约更深一层的调用,和函数的逐层调用一样。

transient_storage 是一个在 EVM 中非常特殊的存贮,它在整个的交易中都是有效的,因此它的存贮也在 frame 之外,单独存放。

在进行完一系列繁琐的环境准备之后,代码最终在 PolkaVM 的开始执行。下面是一个非常重要的数据结构 PreparedCall,我们通过它来调用 PolkaVM 去执行合约编译后的 RISC-V 代码,或者说 PolkaVM(它和标准的 RISC-V 有着细小的差别). Module 主要包含的是编译好的程序代码, RawInstance 是一个 PolkaVM 的实例,用来运行虚拟机。Runtime 则是区块链节点提供给它的执行环境。

截屏2025-07-21 09.57.58.png

6.png

总结

在这个文章中,我们介绍了交易从发送到 RPC Server,到最终在 PolkaVM 里面运行的整个过程。希望能帮助大家在调试代码的时候有所帮助,能够根据错误信息,找到对应的模块,解决问题。

http://www.dtcms.com/a/303631.html

相关文章:

  • Datawhale AI夏令营 task2 笔记问题汇总收集
  • 力扣988. 从叶结点开始的最小字符串
  • 商城系统-项目测试
  • 信息搜集目的原则方法思路工具(二)
  • DDoS攻击防御:从5G到T级防护方案全对比
  • 利用软件定义无线USRP X410、X440 电推进无线原型设计
  • Sentinel 不同层面的流控保护
  • 【图像处理基石】基于暗光图像恢复颜色有哪些难点?
  • resnet中的Bottleneck
  • Google Doppl:重新定义虚拟试衣的AI革命
  • MCP协议全景解析:从工业总线到AI智能体的连接革命
  • 结合二八定律安排整块时间
  • 正向代理和反向代理的理解
  • 【安卓笔记】OOM与内存优化
  • 常见的JVM虚拟机的参数详解
  • OpenGL进阶系列22 - OpenGL SuperBible - bumpmapping 例子学习
  • Python动态规划:从基础到高阶优化的全面指南(3)
  • nvim tagbar安装
  • C#:基于 EF Core Expression 的高性能动态查询构建实战 —— 面向大数据量环境的查询优化方案(全是干货,建议收藏)
  • barba.js单页面应用程序
  • 基于VHDL的神经网络加速器设计实战
  • C++算法实例精讲
  • MKS E28H 0.05-100 Torr 加热 (100°C) Baratron 电容压力计,带蚀刻传感器 手侧
  • C++入门自学Day2-- c++类与对象(初识2)
  • 一文理清 Linux 软件管理核心知识:从程序组成到包管理工具
  • C语言中的数据结构--栈和队列(2)
  • VMware Workstation Pro 详细安装步骤
  • 线程安全
  • C++常见的仿函数,预定义函数,functor,二元操作函数(对vector操作,加减乘除取余位运算等 )
  • 异步通讯组件MQ