五一勞動節,講講NEO智能合約的調試

以前咱們說過NEO智能合約的調試問題,過去了一段時間,有不少東西都發生了比較大的變化。讓咱們從新再來探討一下這個話題。 git

先說日期,2018年4月27日,立刻迎來勞動節。 github

 

之後可能還會再次談論這個話題。 json

 

而後明確幾個問題,把一些常常糾結的地方先說清楚 c#

  1. 若是你連neo同步區塊還沒搞明白,先不要湊智能合約開發這個熱鬧。
  2. 咱們只討論C#開發智能合約的調試問題,其它的暫無工具開發計劃。
  3. NEO官方沒有智能合約調試工具,因此咱們的工具是有不少定製的成分。
    1. 爲何要調試

一次編碼,按下f5,一切正常,揮一揮衣袖就瀟灑的離開,那是傳說。 app

當代碼執行不符合預期時,咱們須要深刻分析問題,須要更精細的觀測手段。 工具

 

而NEO官方並無提供這樣的工具,因而咱們開發了一攬子工具用於解決調試問題 測試

他們是: ui

  1. NeonDebug 替換的c#智能合約編譯器
  2. NeoGUI-NEL 定製版NeoGUI 或者 NeoCli-NEl 定製版的NeoCli
  3. NeonDebugGUI,智能合約執行狀況觀測工具

 

爲了3的正常運行,1 2 都是必須的,若是你想知道爲何,源碼能夠告訴你答案 編碼

 

https://github.com/NewEconoLab/neondebug spa

https://github.com/NewEconoLab/neo-gui-nel

 

  1. 合約的編譯

你可曾聽過NeoVM,AVM文件,就是智能合約編譯生成的那東西,就是NeoVM的字節碼,叫AVM是由於之前叫小蟻,ant的A,這個擴展名沒一塊兒改。

 

爲了方便不那麼瞭解虛擬機的開發者理解,我和C#的類庫機制作一個對比。

 

這個AVM至關因而DLL,要調試一個c# DLL,你須要DLL PDB cs源碼三部份內容。DLL存儲字節碼,PDB存儲字節碼地址和源碼位置的映射,這樣才能在斷點時根據字節碼執行位置定位到源碼位置,而cs源碼,就是爲了讓你調試時對照到代碼

 

那麼:

DLL-》AVM

PDB-》?

cs-》cs

 

標準的c#編譯器neon.exe(若是不知道neon.exe,再好好補一下C#智能合約編譯的相關資料),只生成了一個AVM和一個ABI文件,這個ABI是接口說明。

PDB對應的角色是空缺的

 

因此你須要 NEL 的 Neon.exe ,編譯neondebug倉庫的neondebug項目能夠獲得這個替換的neon.exe

 

設置環境變量,保證在任何路徑能夠執行neon

注意紅框部分,有Debug字樣

 

這個替換的編譯器,就專門解決那個缺失的PDB問題,這個編譯器和官方編譯器代碼隨時同步更新,你直接使用這個替換的編譯器就行,任何更新都會同步,不須要切換回官方編譯器。

 

重啓VS2017以後,來編譯一個智能合約試試

注意紅框部分,已經使用了咱們的替換版本編譯 有(debug)字樣

下一行告訴你,在c:\neo\smartcontracts輸出了些什麼,讓咱們來看看。

首先原來的avm照樣輸出,這些是另外多輸出的

 

文件名所有替換爲了合約hash,avm仍是那個avm

Abi.json仍是那個abi

Cs是把智能合約源碼copy 過來的,只支持一個智能合約項目有一個代碼文件,因此不要分文件。

Map就是替代PDB的那個了,他記錄字節碼地址和源代碼地址的映射關係

 

生成在這個路徑也是有意義的,調試查看工具會直接來這個路徑找合約,之前須要用調試查看工具再打開一次合約,如今不用了,直接用同一個路徑。

 

  1. 合約的調用

A,用neogui 測試執行合約

    用neogui-nel,測試執行一個合約,只有nel定製版支持。

    

試運行固定產生一個0x00 的log文件,看這個log就能夠調試了,這個下一節再說,咱們這裏之說產生log文件的辦法。

 

產生這個log是調試的惟一辦法。

 

B 、用NEOCLI 測試執行合約

調用NEOCLI -NEL的 rpc invokescript 接口,會在返回值多返回一個fulllog字段,將其保存爲文件,就是這個llvmhex文件,能夠用來調試。

只有nel定製版支持

C、用NEOGUI發交易

用NEL定製版NEOGUI發起交易,只有nel定製版支持

 

 

發起交易,

會獲得交易id同名的llvm文件

Id[0]

Id[1]

這種爲鑑權合約的log

只有經過neogui nel定製版發起交易 或者 neocli nel定製版的 rpc接口 sendraw發起交易

纔會產生鑑權合約的log,才能夠調試鑑權合約,其餘只調試應用合約

D、經過NEOCLI的sendraw RPC 發起交易

只有nel定製版支持

會獲得交易id同名的llvm文件

Id[0]

Id[1]

這種爲鑑權合約的log

E、經過其餘方式產生的交易

因爲交易會同步給每個節點,定製的neo-gui-nel,和neo-gui-cli

能夠獲得全部的交易,不管是誰產生的。

可是作智能合約的調試的LOG是很耗時的,因此他並不老是打開的,有一個開關去控制他

這個開關在config.json裏面

NEOGUI-nel的設置爲true,表示只生成這個GUI本身發起的交易的LOG

打開這個同步就會變得很是慢,調試的時候再用。

 

NEOGUI-nel不修改這個config 也能夠打開生成任何人發起的交易的開關

這裏按一下讓他顯示爲=false,而後以後同步的每一筆交易都會生成調試LOG了

這個只在內存修改,每次打開neo-gui都要看一眼。

 

  1. 合約的調試

編譯,啓動NeonDebugGUI

略,他也在NeonDebug倉庫中

 

使用Load 打開對應的llvmhex.txt文件便可調試

這兩個load,一個是打開一個對話框,一個是輸入txid本身去找,結果都同樣。

 

功能介紹

打開調試LOG之後

圖中紅黃藍部分先注意一下

紅色部分最重要,首先觀察合約執行狀態 halt break 爲vm正常停機,程序正常走到結束。

Fault break爲vm異常停機,你能夠直接反着從最下邊看看到底怎麼了。

 

紅色部分爲整個VM內Dump下來的執行流程,也就是整個智能合約的過程到底幹了什麼,從紅色部分選擇最上面一項,而後用鍵盤的方向鍵下,往下挪,先完整的看幾個合約,能夠創建一些基本的感受。

 

黃色部分爲智能合約源碼,當紅色部分選中條目變化時,若是能找到對應的源碼,黃色部分就會跳轉高亮。

 

一般最主要的調試觀測方法就是選紅色、看黃色。

 

而後藍色部分收集了全部syscall,由於neoVM的虛擬機自身是純計算,全部對鏈產生影響或者和鏈互訪的功能都是經過syscall進行的,看一個合約有哪些syscall就能快速瞭解這個合約的行爲,固然這須要創建在熟悉的基礎上,只要多看,就能熟悉。

調試小提示

  1. 紅色部分最重要
  2. 選中條目時,執行棧顯示的這條指令執行以後的狀態。

好比

Equal指令是==表達式,他顯示的false只能告訴你是不想等,要看是誰和誰比較,往前倒退一條指令

倒退後觀測計算棧,valuetool 會幫助你顯示這個數據多是什麼

  1. 是多條虛擬機指令對應一條cs源碼,而且有些是對應不到的。

記住這一點,而不能只盯着源碼,左邊最重要,左邊要選到關鍵的代碼。

你要搞清楚那些最關鍵的指令,好比syscall appcall equal

這並不會有多複雜,知道找關鍵指令就會快不少。

  1. 必定要熟悉syscall

最重要的storage.put 就是一個syscall

相關文章
相關標籤/搜索