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.pswp.cn/diannao/93323.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/93323.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/93323.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【算法訓練營Day17】二叉樹part7

文章目錄二叉樹的最近公共祖先二叉搜索樹的最近公共祖先二叉搜索樹中的插入操作刪除二叉搜索樹中的節點二叉樹的最近公共祖先 題目鏈接:236. 二叉樹的最近公共祖先 解題邏輯: 最近公共祖先的定義為:對于有根樹 T 的兩個節點 p、q&#xff0c…

Vue插件與組件核心區別詳解

在 Vue 中,插件(Plugin) 和 組件(Component) 是兩種不同層次的概念,它們的主要區別如下:1. 組件 (Component) 定義: Vue 應用的基本構建單元,是可復用的 Vue 實例&#x…

基礎NLP | 02 深度學習基本原理

文章目錄 深度學習基本原理 數學基礎 線代 numpy 常用操作 導數, 梯度 梯度下降法 梯度下降代碼 GradientDescent.py 反向傳播 完整的反向傳播過程 權重更新方式 pytorch 網絡結構 全連接層 (線性層) 例子 - 手動實現模擬一個線性層 DNNforward.py 激活函數 激活函數-Sigmoid…

MySQL面試題及詳細答案 155道(001-020)

《前后端面試題》專欄集合了前后端各個知識模塊的面試題,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs&…

Ansible安裝與入門

目錄 Ansible ansible任務執行模式 ansible執行流程 ansible命令執行過程(背會) ansible的安裝方式 ansible的程序結構(yum安裝為例) ansible的配置文件查找順序(背會) 核心配置文件 ansible的配置…

【Spring】Spring Boot啟動過程源碼解析

目錄 一、啟動入口 二、SpringApplication的構造過程 2.1 設置應用類型 2.2 設置初始化器(Initializer) 2.2.1 獲取BootstrapRegistryInitializer對象 2.2.2 獲取ApplicationContextInitializer對象 2.3 設置監聽器(Listener&#xff…

CDN架構全景圖

CDN架構全景圖 CDN(內容分發網絡)是一種通過在全球范圍內部署邊緣節點服務器,將內容緩存至離用戶最近的位置,從而加速內容分發、降低延遲并減輕源站壓力的分布式網絡架構。其核心設計目標是優化互聯網內容傳輸效率,提升…

【pytest高階】源碼的走讀方法及插件hook

一、pytest源碼走讀方法 依賴庫認知篇 📦這是理解 pytest 源碼的 “前菜”,先認識 3 個超重要的小伙伴:iniconfig 📄:像個 “文件小管家”,專門負責讀取 ini 配置文件(比如 pytest 的配置&#…

算法訓練營day32 動態規劃理論基礎、509. 斐波那契數、70. 爬樓梯、746. 使用最小花費爬樓梯

今天開始動態規劃的部分! 其實說白了,動態規劃我感覺就是找類似遞歸的規律, 動態規劃理論基礎 動態規劃,英文:Dynamic Programming,簡稱DP,如果某一問題有很多重疊子問題,使用動態規…

基于神經網絡的手寫數字識別系統

基于神經網絡的手寫數字識別系統 結合模板匹配和神經網絡兩種方法進行手寫數字識別。這個系統包括圖像預處理、特征提取、神經網絡訓練和可視化分析。 %% 基于神經網絡的手寫數字識別系統%% 清理工作區 clear; clc; close all;%% 加載手寫數字數據集 % 使用MATLAB自帶的手寫數字…

機器學習?一文看懂這門熱門技術

🌟 什么是機器學習?一文看懂這門熱門技術在人工智能(AI)的大潮中,機器學習(Machine Learning, ML) 無疑是最耀眼的明星之一。它讓計算機具備了 “自我學習” 的能力,讓自動駕駛、智能…

Spring的初始化鉤子

1. PostConstruct JSR-250 標準注解(不是 Spring 獨有),用來標記 Bean 初始化完成后要執行的方法。會在 Bean 的構造方法執行完、依賴注入完成后執行。 使用實例: Component public class Demo {PostConstructpublic void init() …

【AI】Java生態對接大語言模型:主流框架深度解析

文章目錄1. Deep Java Library (DJL)2. LangChain4j(LLM)3. HuggingFace Inference API4. OpenAI Java Client技術對比矩陣架構設計建議在人工智能浪潮下,大語言模型(LLM)已成為技術核心。Java生態通過以下框架實現高效…

【06】C#入門到精通——C# 多個 .cs文件項目 同一項目下添加多個 .cs文件

文章目錄1 單個 .cs文件2 創建 多個 .cs文件2.1 添加Hero類2.1 添加ShowInfo類2.3 關于命名空間的引用2.4 所有.cs文件代碼3 test3項目文件下載1 單個 .cs文件 上一講中 描述游戲中英雄的角色 所有代碼在一個.cs文件中, 如果代碼很多,類很多&#xff0…

【MySQL基礎篇】:MySQL常用數據類型的選擇邏輯與正確使用

?感謝您閱讀本篇文章,文章內容是個人學習筆記的整理,如果哪里有誤的話還請您指正噢? ? 個人主頁:余輝zmh–CSDN博客 ? 文章所屬專欄:MySQL篇–CSDN博客 文章目錄數據類型1.數據類型分類2.數值類型int整形類型bit位類型float小…

三、搭建springCloudAlibaba2021.1版本分布式微服務-springcloud loadbalancer負載均衡

什么是負責均衡 Spring Cloud LoadBalancer是一個客戶端負載均衡器,類似于Ribbon,但是由于Ribbon已經進入維護模式,并且Ribbon 2并不與Ribbon 1相互兼容,所以Spring Cloud全家桶在Spring Cloud Commons項目中,添加了Sp…

Oracle不完全恢復實戰指南:從原理到操作詳解

核心提示:當誤刪表、日志損壞或控制文件丟失時,Oracle的不完全恢復是DBA最后的救命稻草。掌握關鍵恢復技術,可在數據災難中力挽狂瀾。一、不完全恢復核心概念 1. 核心特點 必須關閉數據庫:在MOUNT狀態下執行重做日志恢復權限要求&…

Linux之shell腳本篇(二)

一、shell編程之if語句引言Linux在shell編程中,通常都是以自上而下運行,但是為了提高其代碼嚴謹性,我們即引入了多條件 控制語句例如:if、for、while、case等語句,有時候針對條件我們還會結合正則表達式去運用。將這些…

如何在android framewrok dump camera data

實現dump 函數 實現1 void dumpBufferToFile(buffer_handle_t* buffer, int width, int height, int frameNum) {void* data NULL;GraphicBufferMapper::getInstance().lock(*buffer, GRALLOC_USAGE_SW_READ_OFTEN, Rect(width, height), &data);char filename[128];sprin…

機器學習中的可解釋性:深入理解SHAP值及其應用

機器學習可解釋性的重要性在人工智能技術快速發展的2025年,機器學習模型已經深度滲透到醫療診斷、金融風控、司法量刑等關鍵領域。然而,隨著模型復雜度的不斷提升,一個根本性矛盾日益凸顯:模型預測性能的提升往往以犧牲可解釋性為…