EVM Transaction Viewer 比較
這篇文章會比較常用的三個 EVM Transaction Viewer 的優缺點
最近 Samczsun 推出了自己寫的 Transaction Viewer:https://tx.eth.samczsun.com/。因此我順便將它和其他常用的 Transaction Viewer 例如 Ethtx.info 及 Tenderly 做一個比較。
目前以 Tenderly 支援的鏈最多,tx.eth.samczsun.com 次之,Ethtx.info 只有支援 Mainnet 及 Goerli。不過 Ethtx.info 有開源,可以自己拿來跑自己想要支援的其他 EVM 鏈。
Tl;dr
- tx.eth.samczsun.com 的風格和 Ethtx.info 很像,都是走簡潔 UI 路線,但細節比 Ethtx.info 還多,除了包含一筆交易發生了什麼事、哪些地址被牽連,或細到每個 function call 實際修改了哪些 storage 都有。如果你想瞭解一筆複雜套利交易的影響或一個攻擊事件的攻擊細節,它會是一個很理想的工具。
- Tenderly 提供了很豐富的介面和操作,還可以一步一步深入每個 function call 的呼叫及執行,另外還有模擬器,非常適合你想要透過一筆交易來更深入理解 EVM 的執行、並透過模擬器實驗自己的理解及想法。
我們會以 Samczsun 當時提供的這筆套利交易為範例,展示這筆交易在三種不同 Transaction Viewer 所呈現的資訊並比較。
Ethtx.info
Ethtx.info 有如 Etherscan 上所呈現的一筆交易最基本的資訊,也有額外的資訊,包含這筆交易所影響的地址的代幣餘額變化(不只是 ETH,一般 ERC20 也會有),以及一開始 Ethtx.info 被廣泛使用的原因:呈現交易執行過程的 Execution Trace。
註:Etherscan 也可以看交易的 Execution Trace,但是是原始沒有處理過的
地址的代幣餘額變化
注意這個餘額變化是按照 Transfer
event 所計算,所以如果遇到代幣是 Spoof Token 的話,背後並不代表真的有代幣轉帳。
Label 地址
如果合約有在 Etherscan 驗證的話,Ethtx.info 會將地址 label 成合約名稱來顯示,例如上圖裡的 [receiver] SoloMargin
。點擊這些地址或合約都會直接連到它們的 Etherscan 頁面。
註:交易的 From 和 To 地址會在前面額外加上 [sender]
及 [receiver]
。
Execution Trace
每一條列都是一個 function call。這個樹狀結構的第二列([1667813]: [receiver] SoloMargin.operate(…)
)是 Top Level Call,然後依序執行 sub function call。
- 每一個條列最左邊是這個 function call 消耗的 gas,例如第一列的
1419243
。註:第二列的 gas 消耗比第一列高是因為第一列是交易執行完後的 gas 消耗,其中包含 gas refund。 - 如果有橘色框框標起來代表是 delegate call。有些會在後面用橘色顯示 delegate call 到的合約,例如第三列看到的
OperationImpl
。但像是後面 USDC 的 delegate call 就沒有顯示它 delegate call 到的合約 - 最後面的括號是這個 function call 的回傳值,例如第四列的
(value=1000...000)
tx.eth.samczsun.com
交易基本資訊
首先 tx.eth.samczsun.com 比 Ethtx.info 多了一些交易的基本資訊,例如 Nonce、Tx Index、Tx Type 及 Gas fee 等等資訊。另外交易的手續費及後面看到的代幣餘額變化,它都會把它轉換成當時的美金價值。
註:這些資訊 Etherscan 上也都會顯示,包含將代幣金額轉換成當時美金價值等等
手動 Label 地址
tx.eth.samczsun.com 讓你可以自己 label 某個地址:
地址的代幣餘額變化
它會統整一個地址的總美金價值餘額變化,點擊箭頭可以看到實際的代幣餘額變化及相對應的美金價值變化。
Decoded Actions
這個是它所解析這筆交易執行了什麼操作的列表,但不太清楚它解析的參考來源及能夠解析哪些操作。
Execution Trace/Call Trace
大致上和 Ethtx.info 很像,但其實很多細節資訊都是點擊後可以展開的
註:它的第一列就是 Top Level Call,它省去「function call 是從交易的 From 開始的」這個資訊。
另外可以看到它在每個 function call 的 gas 消耗的左邊再插入顯示 call type,例如 delegatecall
、staticcall
等。而且它還有 log
type,表示一個 event emission,這可以讓你知道哪個 function emit 了什麼 event,而不像 Ethtx.info 或 Tenderly只能一次看整筆交易所 emit 的全部 event。
點擊最左邊的框框可以看到這個 function call 更豐富的統整資訊。log
type 也可以。
再來是點擊眼睛圖示可以顯示這個 function call 所讀取、改動的 storage。
點擊 sload
/sstore
都可以看到 storage 更多資訊,例如 storage slot。它也會嘗試搭配合約原始碼來解析這個 storage slot 對應到合約的哪個變數。
Hash Preimage
如果一個 hash 值的 preimage(即 hash 的 input)出現過的話,它會將 preimage 呈現出來,以這筆交易為例:
原本 execution trace 裡只有 .push(_object=0x8cc9…dcfa, …)
,但因為前面步驟執行過 0x8cc9…dcfa = keccak(0x009311…0000)
,所以當它看到 0x8cc9…dcfa
時就可以自動將 0x8cc9…dcfa
解析成 keccak(0x009311…0000)
的形式。
以上就是 tx.eth.samczsun.com 的介紹,可以看得出來它介面和 Ethtx.info 一樣都是簡單直接的呈現方式,但它的資訊比 Ethtx.info 豐富很多。基本上可以用來取代 Ethtx.info,唯一的缺點可能是還未開源,如果突然停止服務只能先用其他選項。
Tenderly
Tenderly 的介面豐富很多,Overview 的介面就包含了交易基本資訊(但代幣不會轉換成美金價值顯示)及 Execution Trace。Overview 的 Execution Trace 只有顯示 function 名稱,但可以點擊右邊的 View in Debugger
直接跳轉到 Debugger 去進行 debug(debug 待會會介紹),Tenderly 這個 Execution Trace 的設計可以讓你快速定位到某個 function call 裡去 debug。
註:如果合約有在 Etherscan 驗證的話,點擊 function call 會顯示 function 的 snippet,但個人覺得幫助不大。
Events
Tenderly 的 events 和 Ethtx.info 一樣,都只有顯示整筆交易所有 emit 的 event。
State Changes
Tenderly 有提供 storage 變化資訊,但不像 tx.eth.samczsun.com 一樣以每個 function call 為單位來顯示,而且只有在交易結束後 storage 值有變化才會顯示。這表示你看到的是整筆交易執行完的 storage 變化,而不會包含交易曾經讀取了什麼 storage 或是如果 storage 最後被改回原本的值也不會顯示。想要了解一筆交易實際存取了哪些 storage 透過 tx.eth.samczsun.com 會比較好。
Debugger
Debugger 則是 Tenderly 強大的功能之一,清楚易讀的頁面分成四格呈現: Execution Trace(左上搭配左下)、當前的合約代碼位置(右上,如果合約有驗證才會顯示)及每個 function call 的細節(右下)。
你可以透過上圖中間藍色的 Previous
及 Next
按鈕前後來回在不同 function call 之間切換,搭配右上方的合約代碼位置來了解哪個 function call 帶了什麼 input 進來、會執行什麼運算或帶了什麼 input 到下一個 function call。
此外你還可以使用紫色的 Evaluate
按鈕來存取 function 執行當下的變數值,甚至可以直接寫 Solidity 代碼來操作這些變數或進行任何你想要的運算。
註:Evaluate 需要註冊才能使用。
最後一個很有幫助的功能則是重新模擬交易,當你研究一筆交易到某個程度,想驗證一些假設例如交易帶的 calldata 有某個值不一樣、或嘗試同樣一筆交易換到不同時空背景(例如在另一個區塊時的狀態)去執行的結果,你可以直接用 Re-simulate
來模擬。
它會帶上原本交易的資訊,但每個資訊你都可以任意修改,從交易的 From、Input Data 到區塊、時間戳、Gas 及 Gas Price 等等。
你也可以任意指定合約狀態,例如修改指定合約某個 storage 的值。這邊以修改 USDC 合約的 paused
變數為例,我們將 storage slot 0x0000000000000000000000000000000000000000000000000000000000000001
的 value 設為 0x000000000000000000000001f0d160dec1749afaf5a831668093b1431f7c8527
。(原本的 value 是 0x000000000000000000000000f0d160dec1749afaf5a831668093b1431f7c8527
)
因為 USDC 合約裡將 pauser
和 paused
兩個變數 pack 在同一個 slot,所以才會看到 value 後面有個 pauser
地址 0xf0d160dec1749afaf5a831668093b1431f7c8527
。將地址前面 1 byte 設為 true(01
)後就等於將 paused
變數設為 true。
然後執行 Simulate Transaction
或是將 1inch Aggregator 設為 USDC 黑名單(將 storage slot 0x91ae7637a1c6d8961153fa2495a272f99bc363035a969c0cc200d32f1d26bd97
的 value 設為 0x0000000000000000000000000000000000000000000000000000000000000001
)
註:要怎麼拿到交易裡這些參數確切的 storage slot 和 value?提示:前面提到過的某個 Viewer 可以查看
以上是 Ethtx.info、tx.eth.samczsun.com 及 Tenderly 這三個 Transaction Viewer 的比較。你不一定要挑一個來固定用,而是按照你當下需求來使用。
tx.eth.samczsun.com 簡潔快速,Tenderly 可深入模擬但運行速度較慢。如果只是需要快速看一筆交易的概覽的話,用 tx.eth.samczsun.com;如果想深入去實驗、理解某筆交易裡某個合約的某個 function 怎麼執行的話,用 Tenderly。