我最近在重新學solidity,鞏固一下細節,也寫一個「Solidity 極簡入門」,供小白們使用(編程大佬可以另找教程),每週更新1-3 講。
所有代碼開源在github: github.com/AmazingAng/WTFSolidity
這一講,我們用轉賬ERC20 Token為例來介紹solidity 中的事件(event)。
事件
Solidity 中的事件(event)是EVM 上日誌的抽象,它具有兩個特點:
響應:應用程序(ether.js)可以通過RPC 接口訂閱和監聽這些事件,並在前端做響應。
經濟:事件是EVM 上比較經濟的存儲數據的方式,每個大概消耗2,000-5,000gas 不等。相比之下,存儲一個新的變量至少需要20,000gas。
規則
事件的聲明由event 關鍵字開頭,然後跟事件名稱,括號裡面寫好事件需要記錄的變量類型和變量名。以ERC20 Token合約的Transfer 事件為例:
我們可以看到,Transfer 事件共記錄了3 個變量from,to 和value,分別對應Token的轉賬地址,接收地址和轉賬數量。同時from 和to 前面帶著indexed 關鍵字,表示很重要,程序可以輕鬆的篩選出特定轉賬地址和接收地址的轉賬事件。每個事件最多有3 個帶indexed 的變量。
我們可以在函數里釋放事件。在下面的例子中,每次用_transfer() 函數進行轉賬操作的時候,都會釋放Transfer 事件,並記錄相應的變量。
在etherscan 上查詢事件
我們嘗試用_transfer() 函數在Rinkeby 測試網絡上轉賬100 Token,可以在etherscan 上查詢到相應的tx:https://rinkeby.etherscan.io/tx/0x8cf87215b23055896d93004112bbd8ab754f081b4491cb48c37592ca8f8a36c7
點擊Logs 按鈕,就能看到事件明細:
Event 明細
Topics 裡面有三個元素,[0] 是這個事件的哈希,[1] 和[2] 是我們定義的兩個indexed 變量的信息,即轉賬的轉出地址和接收地址。 Data 裡面是剩下的不帶indexed 的變量,也就是轉賬數量。
總結
這一講,我們介紹瞭如何使用和查詢solidity 中的事件。很多鏈上分析工具包括Nansen 和Dune Analysis 都是基於事件工作的。