在我們的設計中,Europa 是Substrate 客戶端(https://github.com/paritytech/substrate/tree/master/client)的另一種實現。我們知道區塊鏈的 Runtime 是定義其行為的業務邏輯,而Substrate Runtime 需要由一個執行器和環境來運行。因此,我們設計的執行器和環境更像是一個'沙盒'來運行Substrate Runtime。

在 v0.3 中,Europa 的主要目標是提升開發者使用Europa 的易用性。

該版本提供了較為完備的前端界面,用於解析和展示Europa 執行合約的細節;加強和Patract 其他工具的協作;並且提供了Windows,macOS,Ubuntu 三個平台預打包的可執行程序。開發者不再需要為開發、調試合約構建複雜的節點環境,而是直接下載對應平台的執行程序即可使用。

Europa v0.3 的計劃摘要

Europa v0.3 的工作將會分為節點端Europa 及UI 端Europa-UI 兩塊。在下文中,Europa 用於表示Europa 的節點,Europa-UI 表示v0.3 中的產品UI 工作。

1.Europa-UI:設計並實現針對合約功能及Europa 功能的UI 組件及邏輯:

1.1強化與合約邏輯相關的功能:

合約執行過程信息的可視化;構建合約,交易與用戶之間的關聯關係;掃描當前鏈上的合約代碼及合約實例,與合約的metadata 構建關聯關係並附屬合約信息的解析。

1.2強化與 Europa 及 Redspot 工具的關聯關係

結合Europa 的workspace 進行工作空間的劃分;將Europa 特殊的RPC 調用與UI 進行結合;展示每筆交易中對狀態的變更情況;鏈接Redspot 的項目並導入Redspot 項目的合約信息。

2.Europa:

針對Europa-UI 的需求重構節點的部分功能,將需要的信息進行持久化並提供相應的RPC 給Europa-UI。升級Europa 的pallet-contracts模塊至最新的版本,並將歷史的改動進行遷移。

將Europa 與Europa-UI 合併製作成不同平台的二進制包進行分發。

Europa v0.3 的功能

在Europa v0.3 中,所有完成的功能如下:

1

Windows,macOS,Ubuntu 三個平台的可執行文件

當前可以從GitHub 的倉庫 Europa-UI

(https://github.com/patractlabs/europa-ui/releases)

上直接下載對應平台的二進製文件。該二進製文件點擊後即可運行(Linux 需要賦予執行權限)。三端平台支持的系統如下:

windows 10 21H1 及以上版本macOS 10.15.7 及以上版本Ubuntu 20.04 及以上版本

其中macOS 不支持M1,不過可以嘗試使用Rosetta 運行macOS 的二進制包,但是我們不保證全部兼容。對於Ubuntu,我們只保證Ubuntu 20.04 及以上版本能正常運行。 Ubuntu 18.04 及以下版本由於glibc 的兼容關係無法運行。

2

啟動 Europa 的相關配置

Europa 節點具備選擇數據路徑,workspace 等功能。因此Europa-UI 將這些功能做的更易使用:

這是Europa 的進入界面,我們可以看到現在Europa 與以太坊生態中的Ganache 類似,用戶可以選擇自己的數據路徑及workspace。同時也可以設置Europa 節點啟動時的Websocket 及RPC 端口。

另一方面值得注意的是,啟動配置項中可以選擇註冊Redspot Project 路徑,這樣啟動Europa 將會與Redspot 項目下已編譯的合約相關聯。

3

Europa-UI 的功能

Europa-UI 的主要功能和Polkadot/Substrate Portal (

https://polkadot.js.org/apps/

後文統稱為Apps)類似,如圖所示,列舉出的Tab 與區塊鏈元素相關。其中的Contracts 即本次Europa 重點為程序員強化的部分。 Explorer 與Apps 中的explorer 類似,用於展示當前區塊鏈的基礎信息。而在Blocks,Extrinsic 及Event 上相對於Apps 的基礎功能而言有更大的加強。整體而言,相比於Apps 這類在設計思路上主要給用戶使用的產品,Europa-UI 設計的側重點在如何更全面的展示開發者所關心的鍊及合約的信息。

3.1 Explorer

Explorer 除了展示一個區塊基礎的信息之外,Europa-UI 提供了一些調用Europa 特殊功能的操作接口:

1.“Go to Block”和“Back to Block”兩個按鈕分別表示可以直接將Europa 生產到指定高度的區塊,以及可以回滾到指定高度的區塊。點擊相應的按鈕可以調用Europa 特殊的RPC 產生或回滾區塊。

2.每個區塊的區塊號右邊有一個'<-'的箭頭。點擊該箭頭按鈕可以直接回滾到對應區塊上。

當Europa 已經打包過交易產生區塊後(例如使用'go to block' 前進幾個區塊),點擊區塊下的交易名字或者Events,可以直接條狀到交易或者event 的詳細信息頁面,看到更詳細的信息。

3.2 Account

Account 頁面的功能與Apps 中的Account 接近,可以添加或導出賬戶,並且直接調用賬戶進行轉賬。

3.3 Contracts

合約的界面相比於Apps 的合約界面就複雜的多。合約界面總共分為'Codes' 和'Instances' 兩類,分別代表著合約的代碼以及合約的實例。

3.3.1 Codes

在合約代碼界面,主要分為Deployed Codes 和Redspot Codes 兩類。

其中:

Deployed Codes :代表當前已經部署於Europa 上的代碼,表示了合約的code hash,部署所在的區塊及交易索引等重要信息,且點擊了相應的信息可以索引跳轉到相應的頁面中。

而部署的代碼會分為兩類:

一類是通過'Upload & deploy contract' 部署的合約,這類合約含有的metadata信息,例如“flipper”,因此其表現和Apps 中已部署的合約代碼一致,可以點擊deploy 再次部署。另一類是通過其他方式(例如通過腳本等方式)部署於Europa 中的合約。這類合約在Apps 中就無法展示出來,而在Europa 可以索引到。如上圖中的' ',但是由於當前Europa-UI 無法獲知這個合約對應的metadata 信息,因此他會要求開發者先上傳對應的metadata 文件。

Redspot Codes:這類合約是從關聯的Redspot 項目中索引得到的合約,這類合約已經在Redspot 的項目下獲取到的合約metadata 信息,因此其可以直接展示合約的信息並擁有deploy 按鈕。

點擊code hash,會進入該合約代碼的詳細界面。

其中在“Instances”欄下會列出Europa 索引出來的所有和這個合約代碼相關聯的合約實例。

3.3.2 Instances

在Instances 界面中,會列出當前Europa 中已經存在的所有合約實例,並非只記錄通過Europa-UI 部署的合約。當前沒有對應metadata 的合約會顯示為,而已有metadata 的合約會顯示對應的名字。

點擊合約地址會進入合約的詳細信息界面。其中Funtions 的功能與Apps一致,可以直接發送對合約的調用交易或RPC 調用。

但是Europa-UI 除了與Apps 一致的調用外,還可以通過'Call With Trace'的方式調用Europa 提供的特殊的 RPC,將本次合約調用的contract trace 也反饋出來。

contract trace 是本次的核心功能,其目的是將合約的執行過程從黑盒變為白盒執行,讓開發者獲取到豐富的調試信息。在v0.2 中,contract trace 是以日誌的形式打印到控制台中,開發者需要花費精力在很多日誌中辨別出需要的信息。而在v0.3 中這些關鍵調試信息將可以通過Europa-UI 直接看到。關於contract trace 的詳細內容在後文會詳細講解。

在Extrinsics 界面下,Europa-UI 展示了所有與這筆合約有關聯的交易,包含該合約的實例化交易以及所有的調用交易。點擊對應的交易可以跳轉到該交易的詳細信息頁面。

3.3.3 Contract Extrinsic

進入一個合約詳細界面後,可以看到Europa-UI 專門針對合約相關的交易做了特化。如圖,對於合約的調用交易,Europa-UI 顯示了本次調用的所有參數,特別是data 字段,Europa-UI 將data 部分按照合約metadata 的信息做了解析,展示了本次合約調用的參數有'to', 'value'及它們具體的值。

在參數表格的下方即是本次合約調用的contract trace 信息。

contract trace 信息分為主要信息和次要信息。主要信息包括調用者from,目標合約to,及gas 消耗等。次要信息點開'More Details' 可以看到:

詳細信息中展示了本次調用的參數信息,返回信息的'Trap Reason',以及對於調試最重要的env trace 信息。如果本次交易調用出現了異常,還會在下方出現Wasm Error 的Wasm backtrace 信息。

若本次調用是一個合約調用合約的情況:

則在contract trace 信息中將會顯示為一個合約之間'縮進'的關係,而從縮進的合約的From,to 可以觀察到合約調用之間的關聯關係。例如上圖所示即在本次調用合約'5EQLt' 中,合約'5EQLt'自己通過跨合約調用分別調用了'5D1cq'合約及'5FdGb'合約,可知本次的交易是調用all合約的方法,而在all合約中又調用了ERC20 及miner_erc20 的方法。

分別點開他們的'More Details' 信息界面,可以通過詳細信息獲取很多的細節。

3.4 Extrinsic-State

點擊Extrinsic 下的State 會進入當前這筆交易更改的state 界面。這個功能類似於Etherscan 的StateChange,例如這個鏈接

(https://etherscan.io/tx/0x820f0c222e3cdcd8890c8f107f08a7a4266d71edd68a611af83ea3e3307ad7fe#statechange)

。在v0.2 版本的Europa 中,能夠記錄一個塊中的狀態變更情況,但是沒法記錄單個Extrinsic 在執行過程中變更的交易。

因此在v0.3 的版本中,我們參考了state_traceBlock

(https://github.com/paritytech/substrate/pull/7780)

的實現,引入了使用tracing 來記錄交易執行的狀態變更,並且可以把這個變更以RPC 的形式提供給外部使用。 Europa-UI 結合了這個功能,在Extrinsic-State 中表示出來。

對於狀態的變更總共分為6類:

Put: 對某個狀態進行了修改。 PutChild: 對某個子樹(sub trie)下的某個狀態進行了修改,其中child_id指這個子樹的索引。 KillChild: 移除某個子樹下的所有存儲,多見於合約銷毀的情況。 ClearPrefix: 刪除所有匹配指定前綴的key 下的狀態。 ClearChildPrefix: 刪除某個子樹下所有匹配指定前綴的key下的狀態。 Append: 對某個key 下的狀態追加新內容,多用於添加新的Event 數據。

因此在State 頁面,以表格的形式列出了當前這筆交易對狀態的變更情況。其中若只關心合約執行對存儲的變更情況,只需要跟踪PutChild 及KillChild 及ClearChildPrefix 即可。

3.5 Developer

Developer 的功能和Apps 類似,但是Developer 下提供了'Log'頁面,其將Europa 運行的原有輸出到控制台的日誌在Europa-UI 中輸出。

由於Europa v0.3 支持了seal_debug_message 的直接打印,因此在合約運行中的日誌信息(例如在ink! 中調用ink_env::debug_println! 進行日誌打印)會打印到控制台中。而Europa-UI 接管了Europa 的啟動,因此此時需要查閱Europa 的日誌時可以在當前Log 頁面中查閱得到。

Europa v0.3 功能驗證

對於以上

Europa v0.3 中展示的功能可以通過以下方式驗證:

1.準備測試 Europa v0.3 的Redspot 項目:

git clone https://github.com/atenjin/redspot-ink-example2git checkout -b europa_v0.3 europa_v0.3cd redspot-ink-example2yarnnpx redspot compile

經過以上命令,Redspot 已經準備完畢。後續可以使用Europa 對其進行測試。

2.進入Europa-UI 的release 頁面

(https://github.com/patractlabs/europa-ui/releases)

3.啟動Europa,在開始界面設置路徑及workspace 信息,點擊More Options 添加Redsport 項目,路徑選擇在1中準備好的項目路徑,並選擇該路徑下的redspot.config.ts 文件。

啟動

Europa。

4.回到Redspot 項目,執行以下命令部署並調用測試合約

npx redspot run scripts/deploy.ts該腳本會部署3個合約:all,ERC20,miner_erc20,其中all 合約持有ERC20, miner_erc20 的地址,調用all 合約的一些方法會對ERC20,miner_erc20 合約產生跨合約調用。

5.點擊側邊欄的Explorer,點擊區塊7下的contract.call 交易。這是一個通過 all 合約調用miner_erc20 合約的例子。在details 頁面中可以看到上文介紹的contract trace 信息,在state 頁面中可以看到這次調用的state change 信息。

6.回到Explorer,點擊區塊6下的contract.call 交易,這是通過all 合約調用ERC20 合約,ERC20 執行正確,但是在all合約遇到了錯誤導致合約trap 的調用。在details 頁面下展開兩個合約的'more details'信息,可以看到'Wasm error'出現在all 合約實例中,而ERC20 的details 頁面是正常的。表示最後導致合約執行錯誤的原因是由all 合約導致。結合all 合約details 信息中的'env trace'信息可以進一步推斷錯誤位置。

7.點擊側邊欄回到Contracts 頁面,可以看到Redspot Codes 下有Redspot-ink-example2 項目下的三個合約:all,ERC20,miner_erc20。而上方的Deployed Codes 表示已經部署的合約也是這三個。點擊codehash可以看到這個合約代碼已部署的合約實例。點擊實例的地址可以跳轉到合約實例的詳細界面,在Extrinsics 頁面下可以看到與這個合約相關聯的交易,點擊可以跳轉到對應交易詳細界面中。點擊交易調用或者部署人的地址,會列出所有和賬戶有關的交易列表。這個過程表面了Europa-UI 已經將所有對開發人員重要的信息都做了關聯跳轉。

8.回到Explorer,點擊'Go to Block',輸入大於當前best區塊的數字,可以看到當前Europa 區塊已經生產並達到了指定塊高的區塊。點擊'Back to Block'輸入某個區塊高度,或者點擊區塊號右邊了'<-'箭頭可以回滾區塊到對應高度。

9.點擊側邊欄的Setting,在workspace 的輸入欄可以輸入一個新的workspace 名,點擊change 後,回到Explorer,可以看到最高區塊變為了0,表示這是一個全新的Europa 環境。這種方式可以讓開發者隔離不同的測試環境。再次點擊Setting,在workspace 上點擊出現的下拉菜單中選擇最初的workspace 名,change 後可以看到恢復到了之前的狀態。並且隨意嘗試點擊關聯關係的跳轉後都是正常的。

10.退出Europa 後再次進入,可以發現相同的workspace 下所有的關聯關係及已有的數據都能恢復,並不會因為關閉後丟失所有的關聯關係。