以前咱們說過NEO智能合約的調試問題,過去了一段時間,有不少東西都發生了比較大的變化。讓咱們從新再來探討一下這個話題。 git
先說日期,2018年4月27日,立刻迎來勞動節。 github
之後可能還會再次談論這個話題。 json
而後明確幾個問題,把一些常常糾結的地方先說清楚 c#
一次編碼,按下f5,一切正常,揮一揮衣袖就瀟灑的離開,那是傳說。 app
當代碼執行不符合預期時,咱們須要深刻分析問題,須要更精細的觀測手段。 工具
而NEO官方並無提供這樣的工具,因而咱們開發了一攬子工具用於解決調試問題 測試
他們是: ui
爲了3的正常運行,1 2 都是必須的,若是你想知道爲何,源碼能夠告訴你答案 編碼
https://github.com/NewEconoLab/neondebug spa
https://github.com/NewEconoLab/neo-gui-nel
你可曾聽過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的那個了,他記錄字節碼地址和源代碼地址的映射關係
生成在這個路徑也是有意義的,調試查看工具會直接來這個路徑找合約,之前須要用調試查看工具再打開一次合約,如今不用了,直接用同一個路徑。
用neogui-nel,測試執行一個合約,只有nel定製版支持。
試運行固定產生一個0x00 的log文件,看這個log就能夠調試了,這個下一節再說,咱們這裏之說產生log文件的辦法。
產生這個log是調試的惟一辦法。
調用NEOCLI -NEL的 rpc invokescript 接口,會在返回值多返回一個fulllog字段,將其保存爲文件,就是這個llvmhex文件,能夠用來調試。
只有nel定製版支持
用NEL定製版NEOGUI發起交易,只有nel定製版支持
發起交易,
會獲得交易id同名的llvm文件
Id[0]
Id[1]
這種爲鑑權合約的log
只有經過neogui nel定製版發起交易 或者 neocli nel定製版的 rpc接口 sendraw發起交易
纔會產生鑑權合約的log,才能夠調試鑑權合約,其餘只調試應用合約
只有nel定製版支持
會獲得交易id同名的llvm文件
Id[0]
Id[1]
這種爲鑑權合約的log
因爲交易會同步給每個節點,定製的neo-gui-nel,和neo-gui-cli
能夠獲得全部的交易,不管是誰產生的。
可是作智能合約的調試的LOG是很耗時的,因此他並不老是打開的,有一個開關去控制他
這個開關在config.json裏面
NEOGUI-nel的設置爲true,表示只生成這個GUI本身發起的交易的LOG
打開這個同步就會變得很是慢,調試的時候再用。
NEOGUI-nel不修改這個config 也能夠打開生成任何人發起的交易的開關
這裏按一下讓他顯示爲=false,而後以後同步的每一筆交易都會生成調試LOG了
這個只在內存修改,每次打開neo-gui都要看一眼。
編譯,啓動NeonDebugGUI
略,他也在NeonDebug倉庫中
使用Load 打開對應的llvmhex.txt文件便可調試
這兩個load,一個是打開一個對話框,一個是輸入txid本身去找,結果都同樣。
打開調試LOG之後
圖中紅黃藍部分先注意一下
紅色部分最重要,首先觀察合約執行狀態 halt break 爲vm正常停機,程序正常走到結束。
Fault break爲vm異常停機,你能夠直接反着從最下邊看看到底怎麼了。
紅色部分爲整個VM內Dump下來的執行流程,也就是整個智能合約的過程到底幹了什麼,從紅色部分選擇最上面一項,而後用鍵盤的方向鍵下,往下挪,先完整的看幾個合約,能夠創建一些基本的感受。
黃色部分爲智能合約源碼,當紅色部分選中條目變化時,若是能找到對應的源碼,黃色部分就會跳轉高亮。
一般最主要的調試觀測方法就是選紅色、看黃色。
而後藍色部分收集了全部syscall,由於neoVM的虛擬機自身是純計算,全部對鏈產生影響或者和鏈互訪的功能都是經過syscall進行的,看一個合約有哪些syscall就能快速瞭解這個合約的行爲,固然這須要創建在熟悉的基礎上,只要多看,就能熟悉。
好比
Equal指令是==表達式,他顯示的false只能告訴你是不想等,要看是誰和誰比較,往前倒退一條指令
倒退後觀測計算棧,valuetool 會幫助你顯示這個數據多是什麼
記住這一點,而不能只盯着源碼,左邊最重要,左邊要選到關鍵的代碼。
你要搞清楚那些最關鍵的指令,好比syscall appcall equal
這並不會有多複雜,知道找關鍵指令就會快不少。
最重要的storage.put 就是一個syscall