当前位置: 首页 > 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.lryc.cn/news/602256.html

相关文章:

  • 二、Linux文本处理与文件操作核心命令
  • 从0开始学习R语言--Day60--EM插补法
  • git stash apply 冲突合并方法解决
  • Kafka 3.9.1的KRaft模式部署
  • linux系统----Ansible中的playbook简单应用
  • 从零开始的云计算生活——第三十七天,跬步千里,ansible之playbook
  • 【Blender小技巧】Blender使用多边形建形工具创建多边形模型,挤出面,模型创建修改编辑UV贴图
  • 【第四章:大模型(LLM)】01.神经网络中的 NLP-(2)Seq2Seq 原理及代码解析
  • 从0到500账号管理:亚矩阵云手机多开组队与虚拟定位实战指南
  • 【归并排序】排序数组(medium)
  • Rust/Tauri 优秀开源项目推荐
  • C/C++ 调用lua脚本,lua脚本调用另一个lua脚本
  • 最新的前端技术和趋势(2025)
  • Maven中的bom和父依赖
  • Nginx HTTP 反向代理负载均衡实验
  • YOLO11 改进、魔改|低分辨率自注意力机制LRSA ,提取全局上下文建模与局部细节,提升小目标、密集小目标的检测能力
  • 免费 SSL 证书申请简明教程,让网站实现 HTTPS 访问
  • ADAS测试:如何用自动化手段提升VV效率
  • 【CDA干货】金融超市电商App经营数据分析案例
  • unbuntn 22.04 coreutils文件系统故障
  • GaussDB as的用法
  • 亚马逊广告关键词优化:如何精准定位目标客户
  • MyBatis中#{}与${}的实战避坑指南
  • 性能测试-技术指标的含义和计算
  • Leetcode_242.有效的字母异位词
  • Apache Commons VFS:Java内存虚拟文件系统,屏蔽不同IO细节
  • python入门篇12-虚拟环境conda的安装与使用
  • 深入Go并发编程:Channel、Goroutine与Select的协同艺术
  • 博士申请 | 荷兰阿姆斯特丹大学 招收计算机视觉(CV)方向 全奖博士生
  • 达梦有多少个模式