Solidity 中的 event 是什麼?
作者 Alchemy
Solidity 事件對智能合約開發者來說至關重要,因為它們讓智能合約可以索引變數以重建儲存狀態,協助自動更新使用者介面,並可用於測試特定變數。本文將幫助你深入理解 Solidity 事件,並加深你對 Solidity 程式語言的理解。
我們會先介紹 Solidity 事件,接著說明其分類,並提供範例。讀完本文後,你將能夠為下一個專案建立 Solidity 事件。
什麼是 Solidity 中的事件?
在 Solidity 中,事件是智能合約可以觸發的訊號。 當你呼叫事件時,會讓傳入的參數被儲存到交易日誌(transaction log)中,這是區塊鏈上一種特殊的資料結構。事件會通知外部使用者(例如監聽中的前端網站或客戶端應用程式),區塊鏈上發生了某件事。
Solidity 中事件與函式有什麼差別?
函式與事件都能接收參數並被呼叫,但函式會直接修改智能合約,而事件的作用是通知區塊鏈外部的服務,讓使用者知道發生了某件事。
Solidity 中的函式讓開發者可以在智能合約中讀取、寫入、修改及儲存資料。你可以將引數或參數傳入函式,也可以在程式碼中需要時呼叫函式。
事件同樣接受引數,但這些引數會被儲存在交易日誌中,智能合約無法存取這些資料。合約資料存放在 States trie,而事件資料則存放在 Transaction Receipts trie,這代表合約無法讀取事件資料。
與函式一樣,事件也可以被呼叫。不過呼叫或觸發事件時使用的是 emit 關鍵字。這讓開發者可以知道何時呼叫了某個事件或函式。
事件與日誌之間的關係為何?
Ethereum 的 Log 資料結構用來儲存事件所發出的資料。
Ethereum Virtual Machine(EVM)具有日誌功能,用來將資料(包含 Solidity 事件)寫入智能合約以外的結構中。
日誌與事件經常被當作同義詞使用。事件讓你可以將資訊「印出」到日誌結構中,這種方式比使用儲存變數更省 gas,因為儲存變數會佔用更多 gas。事件(或日誌)存放在 Transaction Receipts trie 中,智能合約無法存取。
Solidity 中的事件如何被索引?
Solidity 事件是與 EVM 日誌功能對接的介面。 你最多可以為三個參數加上 indexed 屬性。加上此屬性後,這些參數會出現在 topics 結構中,而非日誌的 data 部分。沒有 indexed 屬性的參數,則會以 ABI 編碼方式存入日誌的 data 部分。
Solidity 事件的類型
Solidity 事件有兩種類型:已索引(indexed)與未索引的事件。
沒有 indexed 屬性的參數,會被以 ABI 編碼存入日誌的 data 部分,這些參數會組成該事件的位元組陣列。資料會依照其型別進行編碼,並可依照 schema 進行解碼。
已加上 indexed 屬性的參數也稱為「topics」,是事件中可供搜尋的參數。透過這些 indexed 參數,你可以將其作為篩選條件來搜尋對應的事件。根據事件是否為匿名事件,你最多可以為 4 個或 3 個參數加上 indexed 屬性。
Solidity 中事件如何運作?
Solidity 事件的運作分為宣告、觸發與註冊三個步驟。
- 首先,事件型別必須使用 Solidity 中的 event 關鍵字進行宣告。
- 接著,需要使用 emit 關鍵字來觸發該事件。
- 只要區塊鏈上發生任何變化,你的程式就會自動註冊這項變化並觸發該事件。
注意: 在宣告事件後將其觸發,可讓你透過應用程式使用 Web3.js 或 Ethers.js 等函式庫「監聽」該事件。
如何在 Solidity 中宣告事件?
事件的宣告內容包含事件名稱,以及你希望在觸發事件時儲存的參數。
首先,你必須在 Solidity 中宣告一個事件,接著使用 emit 關鍵字來觸發該事件。
以下是宣告事件的範例:
事件觸發時,會通知外部應用程式區塊鏈上發生了某項變化。
Solidity 中的事件如何被觸發?
事件定義完成後,你可以使用 emit 關鍵字來觸發該事件。事件一旦被觸發,傳入的引數就會被儲存到交易日誌中。
以下語法示範如何在 Solidity 中使用 emit:
如何在 Solidity 中監聽事件
事件觸發後,你可以透過訂閱的方式來監聽這些事件,例如使用 ethers.js。之後,應用程式或任何連接到 Ethereum JSON-RPC API 的服務,都可以監聽這些事件並依此執行對應動作。
Solidity 事件範例
以下範例程式碼定義並觸發了一個用於轉帳的事件。此程式碼適用於 Ethereum 轉帳應用程式,當轉帳發生時會觸發該事件。你也可以加入額外程式碼,讓事件觸發時能更新使用者介面,以顯示轉帳已完成。

下一個範例取自 Solidity by Example,建立了一個帶有兩個參數的事件:傳送者的地址與字串訊息。觸發時,該事件會記錄「Hello World」與「Hello EVM」。

持續學習 Solidity
本文向你介紹了 Solidity 事件,並提供了說明與資源,供你在下一個專案中使用。有了 Solidity 事件,建立高效的智能合約會變得更容易。
如果你剛接觸 Solidity 語言,並期待打造你的第一個智能合約,歡迎報名 Alchemy University 免費、為期 7 週的線上 Solidity 程式課程。
相關總覽

打造區塊鏈魔法
Alchemy 結合最強大的 Web3 開發者產品與工具,並提供資源、社群與卓越的支援。


